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
ac84f2ed
Commit
ac84f2ed
authored
Dec 17, 2011
by
Donald Ovcharov
Committed by
Diego Biurrun
Jan 18, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
error_resilience: K&R formatting cosmetics
Signed-off-by:
Diego Biurrun
<
diego@biurrun.de
>
parent
bbf0023b
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
749 additions
and
627 deletions
+749
-627
error_resilience.c
libavcodec/error_resilience.c
+749
-627
No files found.
libavcodec/error_resilience.c
View file @
ac84f2ed
...
@@ -40,30 +40,33 @@
...
@@ -40,30 +40,33 @@
*/
*/
#undef mb_intra
#undef mb_intra
static
void
decode_mb
(
MpegEncContext
*
s
,
int
ref
){
static
void
decode_mb
(
MpegEncContext
*
s
,
int
ref
)
s
->
dest
[
0
]
=
s
->
current_picture
.
f
.
data
[
0
]
+
(
s
->
mb_y
*
16
*
s
->
linesize
)
+
s
->
mb_x
*
16
;
{
s
->
dest
[
0
]
=
s
->
current_picture
.
f
.
data
[
0
]
+
(
s
->
mb_y
*
16
*
s
->
linesize
)
+
s
->
mb_x
*
16
;
s
->
dest
[
1
]
=
s
->
current_picture
.
f
.
data
[
1
]
+
(
s
->
mb_y
*
(
16
>>
s
->
chroma_y_shift
)
*
s
->
uvlinesize
)
+
s
->
mb_x
*
(
16
>>
s
->
chroma_x_shift
);
s
->
dest
[
1
]
=
s
->
current_picture
.
f
.
data
[
1
]
+
(
s
->
mb_y
*
(
16
>>
s
->
chroma_y_shift
)
*
s
->
uvlinesize
)
+
s
->
mb_x
*
(
16
>>
s
->
chroma_x_shift
);
s
->
dest
[
2
]
=
s
->
current_picture
.
f
.
data
[
2
]
+
(
s
->
mb_y
*
(
16
>>
s
->
chroma_y_shift
)
*
s
->
uvlinesize
)
+
s
->
mb_x
*
(
16
>>
s
->
chroma_x_shift
);
s
->
dest
[
2
]
=
s
->
current_picture
.
f
.
data
[
2
]
+
(
s
->
mb_y
*
(
16
>>
s
->
chroma_y_shift
)
*
s
->
uvlinesize
)
+
s
->
mb_x
*
(
16
>>
s
->
chroma_x_shift
);
if
(
CONFIG_H264_DECODER
&&
s
->
codec_id
==
CODEC_ID_H264
)
{
if
(
CONFIG_H264_DECODER
&&
s
->
codec_id
==
CODEC_ID_H264
)
{
H264Context
*
h
=
(
void
*
)
s
;
H264Context
*
h
=
(
void
*
)
s
;
h
->
mb_xy
=
s
->
mb_x
+
s
->
mb_y
*
s
->
mb_stride
;
h
->
mb_xy
=
s
->
mb_x
+
s
->
mb_y
*
s
->
mb_stride
;
memset
(
h
->
non_zero_count_cache
,
0
,
sizeof
(
h
->
non_zero_count_cache
));
memset
(
h
->
non_zero_count_cache
,
0
,
sizeof
(
h
->
non_zero_count_cache
));
assert
(
ref
>=
0
);
assert
(
ref
>=
0
);
/* FIXME: It is possible albeit uncommon that slice references
/* FIXME: It is possible albeit uncommon that slice references
* differ between slices. We take the easy approach and ignore
* differ between slices. We take the easy approach and ignore
* it for now. If this turns out to have any relevance in
* it for now. If this turns out to have any relevance in
* practice then correct remapping should be added. */
* practice then correct remapping should be added. */
if
(
ref
>=
h
->
ref_count
[
0
])
if
(
ref
>=
h
->
ref_count
[
0
])
ref
=
0
;
ref
=
0
;
fill_rectangle
(
&
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
h
->
mb_xy
],
2
,
2
,
2
,
ref
,
1
);
fill_rectangle
(
&
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
h
->
mb_xy
],
2
,
2
,
2
,
ref
,
1
);
fill_rectangle
(
&
h
->
ref_cache
[
0
][
scan8
[
0
]],
4
,
4
,
8
,
ref
,
1
);
fill_rectangle
(
&
h
->
ref_cache
[
0
][
scan8
[
0
]],
4
,
4
,
8
,
ref
,
1
);
fill_rectangle
(
h
->
mv_cache
[
0
][
scan8
[
0
]
],
4
,
4
,
8
,
pack16to32
(
s
->
mv
[
0
][
0
][
0
],
s
->
mv
[
0
][
0
][
1
]),
4
);
fill_rectangle
(
h
->
mv_cache
[
0
][
scan8
[
0
]],
4
,
4
,
8
,
pack16to32
(
s
->
mv
[
0
][
0
][
0
],
s
->
mv
[
0
][
0
][
1
]),
4
);
assert
(
!
FRAME_MBAFF
);
assert
(
!
FRAME_MBAFF
);
ff_h264_hl_decode_mb
(
h
);
ff_h264_hl_decode_mb
(
h
);
}
else
{
}
else
{
assert
(
ref
==
0
);
assert
(
ref
==
0
);
MPV_decode_mb
(
s
,
s
->
block
);
MPV_decode_mb
(
s
,
s
->
block
);
}
}
}
}
...
@@ -71,82 +74,89 @@ static void decode_mb(MpegEncContext *s, int ref){
...
@@ -71,82 +74,89 @@ static void decode_mb(MpegEncContext *s, int ref){
* @param stride the number of MVs to get to the next row
* @param stride the number of MVs to get to the next row
* @param mv_step the number of MVs per row or column in a macroblock
* @param mv_step the number of MVs per row or column in a macroblock
*/
*/
static
void
set_mv_strides
(
MpegEncContext
*
s
,
int
*
mv_step
,
int
*
stride
){
static
void
set_mv_strides
(
MpegEncContext
*
s
,
int
*
mv_step
,
int
*
stride
)
if
(
s
->
codec_id
==
CODEC_ID_H264
){
{
H264Context
*
h
=
(
void
*
)
s
;
if
(
s
->
codec_id
==
CODEC_ID_H264
)
{
H264Context
*
h
=
(
void
*
)
s
;
assert
(
s
->
quarter_sample
);
assert
(
s
->
quarter_sample
);
*
mv_step
=
4
;
*
mv_step
=
4
;
*
stride
=
h
->
b_stride
;
*
stride
=
h
->
b_stride
;
}
else
{
}
else
{
*
mv_step
=
2
;
*
mv_step
=
2
;
*
stride
=
s
->
b8_stride
;
*
stride
=
s
->
b8_stride
;
}
}
}
}
/**
/**
* Replace the current MB with a flat dc-only version.
* Replace the current MB with a flat dc-only version.
*/
*/
static
void
put_dc
(
MpegEncContext
*
s
,
uint8_t
*
dest_y
,
uint8_t
*
dest_cb
,
uint8_t
*
dest_cr
,
int
mb_x
,
int
mb_y
)
static
void
put_dc
(
MpegEncContext
*
s
,
uint8_t
*
dest_y
,
uint8_t
*
dest_cb
,
uint8_t
*
dest_cr
,
int
mb_x
,
int
mb_y
)
{
{
int
dc
,
dcu
,
dcv
,
y
,
i
;
int
dc
,
dcu
,
dcv
,
y
,
i
;
for
(
i
=
0
;
i
<
4
;
i
++
){
for
(
i
=
0
;
i
<
4
;
i
++
)
{
dc
=
s
->
dc_val
[
0
][
mb_x
*
2
+
(
i
&
1
)
+
(
mb_y
*
2
+
(
i
>>
1
))
*
s
->
b8_stride
];
dc
=
s
->
dc_val
[
0
][
mb_x
*
2
+
(
i
&
1
)
+
(
mb_y
*
2
+
(
i
>>
1
))
*
s
->
b8_stride
];
if
(
dc
<
0
)
dc
=
0
;
if
(
dc
<
0
)
else
if
(
dc
>
2040
)
dc
=
2040
;
dc
=
0
;
for
(
y
=
0
;
y
<
8
;
y
++
){
else
if
(
dc
>
2040
)
dc
=
2040
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
int
x
;
int
x
;
for
(
x
=
0
;
x
<
8
;
x
++
){
for
(
x
=
0
;
x
<
8
;
x
++
)
dest_y
[
x
+
(
i
&
1
)
*
8
+
(
y
+
(
i
>>
1
)
*
8
)
*
s
->
linesize
]
=
dc
/
8
;
dest_y
[
x
+
(
i
&
1
)
*
8
+
(
y
+
(
i
>>
1
)
*
8
)
*
s
->
linesize
]
=
dc
/
8
;
}
}
}
}
}
dcu
=
s
->
dc_val
[
1
][
mb_x
+
mb_y
*
s
->
mb_stride
];
dcu
=
s
->
dc_val
[
1
][
mb_x
+
mb_y
*
s
->
mb_stride
];
dcv
=
s
->
dc_val
[
2
][
mb_x
+
mb_y
*
s
->
mb_stride
];
dcv
=
s
->
dc_val
[
2
][
mb_x
+
mb_y
*
s
->
mb_stride
];
if
(
dcu
<
0
)
dcu
=
0
;
if
(
dcu
<
0
)
else
if
(
dcu
>
2040
)
dcu
=
2040
;
dcu
=
0
;
if
(
dcv
<
0
)
dcv
=
0
;
else
if
(
dcu
>
2040
)
else
if
(
dcv
>
2040
)
dcv
=
2040
;
dcu
=
2040
;
for
(
y
=
0
;
y
<
8
;
y
++
){
if
(
dcv
<
0
)
dcv
=
0
;
else
if
(
dcv
>
2040
)
dcv
=
2040
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
int
x
;
int
x
;
for
(
x
=
0
;
x
<
8
;
x
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
dest_cb
[
x
+
y
*
s
->
uvlinesize
]
=
dcu
/
8
;
dest_cb
[
x
+
y
*
s
->
uvlinesize
]
=
dcu
/
8
;
dest_cr
[
x
+
y
*
s
->
uvlinesize
]
=
dcv
/
8
;
dest_cr
[
x
+
y
*
s
->
uvlinesize
]
=
dcv
/
8
;
}
}
}
}
}
}
static
void
filter181
(
int16_t
*
data
,
int
width
,
int
height
,
int
stride
){
static
void
filter181
(
int16_t
*
data
,
int
width
,
int
height
,
int
stride
)
int
x
,
y
;
{
int
x
,
y
;
/* horizontal filter */
/* horizontal filter */
for
(
y
=
1
;
y
<
height
-
1
;
y
++
)
{
for
(
y
=
1
;
y
<
height
-
1
;
y
++
)
{
int
prev_dc
=
data
[
0
+
y
*
stride
];
int
prev_dc
=
data
[
0
+
y
*
stride
];
for
(
x
=
1
;
x
<
width
-
1
;
x
++
)
{
for
(
x
=
1
;
x
<
width
-
1
;
x
++
)
{
int
dc
;
int
dc
;
dc
=
-
prev_dc
+
dc
=
-
prev_dc
data
[
x
+
y
*
stride
]
*
8
-
+
data
[
x
+
y
*
stride
]
*
8
data
[
x
+
1
+
y
*
stride
];
-
data
[
x
+
1
+
y
*
stride
];
dc
=
(
dc
*
10923
+
32768
)
>>
16
;
dc
=
(
dc
*
10923
+
32768
)
>>
16
;
prev_dc
=
data
[
x
+
y
*
stride
];
prev_dc
=
data
[
x
+
y
*
stride
];
data
[
x
+
y
*
stride
]
=
dc
;
data
[
x
+
y
*
stride
]
=
dc
;
}
}
}
}
/* vertical filter */
/* vertical filter */
for
(
x
=
1
;
x
<
width
-
1
;
x
++
)
{
for
(
x
=
1
;
x
<
width
-
1
;
x
++
)
{
int
prev_dc
=
data
[
x
];
int
prev_dc
=
data
[
x
];
for
(
y
=
1
;
y
<
height
-
1
;
y
++
)
{
for
(
y
=
1
;
y
<
height
-
1
;
y
++
)
{
int
dc
;
int
dc
;
dc
=
-
prev_dc
dc
=
-
prev_dc
+
+
data
[
x
+
y
*
stride
]
*
8
data
[
x
+
y
*
stride
]
*
8
-
-
data
[
x
+
(
y
+
1
)
*
stride
];
data
[
x
+
(
y
+
1
)
*
stride
];
dc
=
(
dc
*
10923
+
32768
)
>>
16
;
dc
=
(
dc
*
10923
+
32768
)
>>
16
;
prev_dc
=
data
[
x
+
y
*
stride
];
prev_dc
=
data
[
x
+
y
*
stride
];
data
[
x
+
y
*
stride
]
=
dc
;
data
[
x
+
y
*
stride
]
=
dc
;
}
}
}
}
}
}
...
@@ -156,81 +166,83 @@ static void filter181(int16_t *data, int width, int height, int stride){
...
@@ -156,81 +166,83 @@ static void filter181(int16_t *data, int width, int height, int stride){
* @param w width in 8 pixel blocks
* @param w width in 8 pixel blocks
* @param h height in 8 pixel blocks
* @param h height in 8 pixel blocks
*/
*/
static
void
guess_dc
(
MpegEncContext
*
s
,
int16_t
*
dc
,
int
w
,
int
h
,
int
stride
,
int
is_luma
){
static
void
guess_dc
(
MpegEncContext
*
s
,
int16_t
*
dc
,
int
w
,
int
h
,
int
stride
,
int
is_luma
)
{
int
b_x
,
b_y
;
int
b_x
,
b_y
;
for
(
b_y
=
0
;
b_y
<
h
;
b_y
++
)
{
for
(
b_y
=
0
;
b_y
<
h
;
b_y
++
)
{
for
(
b_x
=
0
;
b_x
<
w
;
b_x
++
)
{
for
(
b_x
=
0
;
b_x
<
w
;
b_x
++
)
{
int
color
[
4
]
=
{
1024
,
1024
,
1024
,
1024
};
int
color
[
4
]
=
{
1024
,
1024
,
1024
,
1024
};
int
distance
[
4
]
=
{
9999
,
9999
,
9999
,
9999
};
int
distance
[
4
]
=
{
9999
,
9999
,
9999
,
9999
};
int
mb_index
,
error
,
j
;
int
mb_index
,
error
,
j
;
int64_t
guess
,
weight_sum
;
int64_t
guess
,
weight_sum
;
mb_index
=
(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
;
error
=
s
->
error_status_table
[
mb_index
];
mb_index
=
(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
;
if
(
IS_INTER
(
s
->
current_picture
.
f
.
mb_type
[
mb_index
]))
continue
;
// inter
error
=
s
->
error_status_table
[
mb_index
];
if
(
!
(
error
&
ER_DC_ERROR
))
continue
;
// dc-ok
if
(
IS_INTER
(
s
->
current_picture
.
f
.
mb_type
[
mb_index
]))
continue
;
//inter
if
(
!
(
error
&
ER_DC_ERROR
))
continue
;
//dc-ok
/* right block */
/* right block */
for
(
j
=
b_x
+
1
;
j
<
w
;
j
++
)
{
for
(
j
=
b_x
+
1
;
j
<
w
;
j
++
)
{
int
mb_index_j
=
(
j
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
;
int
mb_index_j
=
(
j
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
;
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
color
[
0
]
=
dc
[
j
+
b_y
*
stride
];
color
[
0
]
=
dc
[
j
+
b_y
*
stride
];
distance
[
0
]
=
j
-
b_x
;
distance
[
0
]
=
j
-
b_x
;
break
;
break
;
}
}
}
}
/* left block */
/* left block */
for
(
j
=
b_x
-
1
;
j
>=
0
;
j
--
)
{
for
(
j
=
b_x
-
1
;
j
>=
0
;
j
--
)
{
int
mb_index_j
=
(
j
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
;
int
mb_index_j
=
(
j
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
;
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
color
[
1
]
=
dc
[
j
+
b_y
*
stride
];
color
[
1
]
=
dc
[
j
+
b_y
*
stride
];
distance
[
1
]
=
b_x
-
j
;
distance
[
1
]
=
b_x
-
j
;
break
;
break
;
}
}
}
}
/* bottom block */
/* bottom block */
for
(
j
=
b_y
+
1
;
j
<
h
;
j
++
){
for
(
j
=
b_y
+
1
;
j
<
h
;
j
++
)
{
int
mb_index_j
=
(
b_x
>>
is_luma
)
+
(
j
>>
is_luma
)
*
s
->
mb_stride
;
int
mb_index_j
=
(
b_x
>>
is_luma
)
+
(
j
>>
is_luma
)
*
s
->
mb_stride
;
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
)){
color
[
2
]
=
dc
[
b_x
+
j
*
stride
];
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
distance
[
2
]
=
j
-
b_y
;
color
[
2
]
=
dc
[
b_x
+
j
*
stride
];
distance
[
2
]
=
j
-
b_y
;
break
;
break
;
}
}
}
}
/* top block */
/* top block */
for
(
j
=
b_y
-
1
;
j
>=
0
;
j
--
)
{
for
(
j
=
b_y
-
1
;
j
>=
0
;
j
--
)
{
int
mb_index_j
=
(
b_x
>>
is_luma
)
+
(
j
>>
is_luma
)
*
s
->
mb_stride
;
int
mb_index_j
=
(
b_x
>>
is_luma
)
+
(
j
>>
is_luma
)
*
s
->
mb_stride
;
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
error_j
=
s
->
error_status_table
[
mb_index_j
];
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
int
intra_j
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_index_j
]);
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
if
(
intra_j
==
0
||
!
(
error_j
&
ER_DC_ERROR
))
{
color
[
3
]
=
dc
[
b_x
+
j
*
stride
];
color
[
3
]
=
dc
[
b_x
+
j
*
stride
];
distance
[
3
]
=
b_y
-
j
;
distance
[
3
]
=
b_y
-
j
;
break
;
break
;
}
}
}
}
weight_sum
=
0
;
weight_sum
=
0
;
guess
=
0
;
guess
=
0
;
for
(
j
=
0
;
j
<
4
;
j
++
)
{
for
(
j
=
0
;
j
<
4
;
j
++
)
{
int64_t
weight
=
256
*
256
*
256
*
16
/
distance
[
j
];
int64_t
weight
=
256
*
256
*
256
*
16
/
distance
[
j
];
guess
+=
weight
*
(
int64_t
)
color
[
j
];
guess
+=
weight
*
(
int64_t
)
color
[
j
];
weight_sum
+=
weight
;
weight_sum
+=
weight
;
}
}
guess
=
(
guess
+
weight_sum
/
2
)
/
weight_sum
;
guess
=
(
guess
+
weight_sum
/
2
)
/
weight_sum
;
dc
[
b_x
+
b_y
*
stride
]
=
guess
;
dc
[
b_x
+
b_y
*
stride
]
=
guess
;
}
}
}
}
}
}
...
@@ -240,58 +252,63 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
...
@@ -240,58 +252,63 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i
* @param w width in 8 pixel blocks
* @param w width in 8 pixel blocks
* @param h height in 8 pixel blocks
* @param h height in 8 pixel blocks
*/
*/
static
void
h_block_filter
(
MpegEncContext
*
s
,
uint8_t
*
dst
,
int
w
,
int
h
,
int
stride
,
int
is_luma
){
static
void
h_block_filter
(
MpegEncContext
*
s
,
uint8_t
*
dst
,
int
w
,
int
h
,
int
stride
,
int
is_luma
)
{
int
b_x
,
b_y
,
mvx_stride
,
mvy_stride
;
int
b_x
,
b_y
,
mvx_stride
,
mvy_stride
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
set_mv_strides
(
s
,
&
mvx_stride
,
&
mvy_stride
);
set_mv_strides
(
s
,
&
mvx_stride
,
&
mvy_stride
);
mvx_stride
>>=
is_luma
;
mvx_stride
>>=
is_luma
;
mvy_stride
*=
mvx_stride
;
mvy_stride
*=
mvx_stride
;
for
(
b_y
=
0
;
b_y
<
h
;
b_y
++
)
{
for
(
b_y
=
0
;
b_y
<
h
;
b_y
++
)
{
for
(
b_x
=
0
;
b_x
<
w
-
1
;
b_x
++
)
{
for
(
b_x
=
0
;
b_x
<
w
-
1
;
b_x
++
)
{
int
y
;
int
y
;
int
left_status
=
s
->
error_status_table
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
];
int
left_status
=
s
->
error_status_table
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
];
int
right_status
=
s
->
error_status_table
[((
b_x
+
1
)
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
];
int
right_status
=
s
->
error_status_table
[((
b_x
+
1
)
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
];
int
left_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
]);
int
left_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
]);
int
right_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[((
b_x
+
1
)
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
]);
int
right_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[((
b_x
+
1
)
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
]);
int
left_damage
=
left_status
&
ER_MB_ERROR
;
int
left_damage
=
left_status
&
ER_MB_ERROR
;
int
right_damage
=
right_status
&
ER_MB_ERROR
;
int
right_damage
=
right_status
&
ER_MB_ERROR
;
int
offset
=
b_x
*
8
+
b_y
*
stride
*
8
;
int
offset
=
b_x
*
8
+
b_y
*
stride
*
8
;
int16_t
*
left_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
b_y
+
mvx_stride
*
b_x
];
int16_t
*
left_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
b_y
+
mvx_stride
*
b_x
];
int16_t
*
right_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
b_y
+
mvx_stride
*
(
b_x
+
1
)];
int16_t
*
right_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
b_y
+
mvx_stride
*
(
b_x
+
1
)];
if
(
!
(
left_damage
||
right_damage
))
if
(
!
(
left_damage
||
right_damage
))
continue
;
// both undamaged
continue
;
// both undamaged
if
((
!
left_intra
)
&&
(
!
right_intra
)
&&
if
(
(
!
left_intra
)
&&
(
!
right_intra
)
FFABS
(
left_mv
[
0
]
-
right_mv
[
0
])
+
&&
FFABS
(
left_mv
[
0
]
-
right_mv
[
0
])
+
FFABS
(
left_mv
[
1
]
+
right_mv
[
1
])
<
2
)
continue
;
FFABS
(
left_mv
[
1
]
+
right_mv
[
1
])
<
2
)
continue
;
for
(
y
=
0
;
y
<
8
;
y
++
){
int
a
,
b
,
c
,
d
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
int
a
,
b
,
c
,
d
;
a
=
dst
[
offset
+
7
+
y
*
stride
]
-
dst
[
offset
+
6
+
y
*
stride
];
b
=
dst
[
offset
+
8
+
y
*
stride
]
-
dst
[
offset
+
7
+
y
*
stride
];
a
=
dst
[
offset
+
7
+
y
*
stride
]
-
dst
[
offset
+
6
+
y
*
stride
];
c
=
dst
[
offset
+
9
+
y
*
stride
]
-
dst
[
offset
+
8
+
y
*
stride
];
b
=
dst
[
offset
+
8
+
y
*
stride
]
-
dst
[
offset
+
7
+
y
*
stride
];
c
=
dst
[
offset
+
9
+
y
*
stride
]
-
dst
[
offset
+
8
+
y
*
stride
];
d
=
FFABS
(
b
)
-
((
FFABS
(
a
)
+
FFABS
(
c
)
+
1
)
>>
1
);
d
=
FFMAX
(
d
,
0
);
d
=
FFABS
(
b
)
-
((
FFABS
(
a
)
+
FFABS
(
c
)
+
1
)
>>
1
);
if
(
b
<
0
)
d
=
-
d
;
d
=
FFMAX
(
d
,
0
);
if
(
b
<
0
)
if
(
d
==
0
)
continue
;
d
=
-
d
;
if
(
!
(
left_damage
&&
right_damage
))
if
(
d
==
0
)
d
=
d
*
16
/
9
;
continue
;
if
(
left_damage
){
if
(
!
(
left_damage
&&
right_damage
))
dst
[
offset
+
7
+
y
*
stride
]
=
cm
[
dst
[
offset
+
7
+
y
*
stride
]
+
((
d
*
7
)
>>
4
)];
d
=
d
*
16
/
9
;
dst
[
offset
+
6
+
y
*
stride
]
=
cm
[
dst
[
offset
+
6
+
y
*
stride
]
+
((
d
*
5
)
>>
4
)];
dst
[
offset
+
5
+
y
*
stride
]
=
cm
[
dst
[
offset
+
5
+
y
*
stride
]
+
((
d
*
3
)
>>
4
)];
if
(
left_damage
)
{
dst
[
offset
+
4
+
y
*
stride
]
=
cm
[
dst
[
offset
+
4
+
y
*
stride
]
+
((
d
*
1
)
>>
4
)];
dst
[
offset
+
7
+
y
*
stride
]
=
cm
[
dst
[
offset
+
7
+
y
*
stride
]
+
((
d
*
7
)
>>
4
)];
dst
[
offset
+
6
+
y
*
stride
]
=
cm
[
dst
[
offset
+
6
+
y
*
stride
]
+
((
d
*
5
)
>>
4
)];
dst
[
offset
+
5
+
y
*
stride
]
=
cm
[
dst
[
offset
+
5
+
y
*
stride
]
+
((
d
*
3
)
>>
4
)];
dst
[
offset
+
4
+
y
*
stride
]
=
cm
[
dst
[
offset
+
4
+
y
*
stride
]
+
((
d
*
1
)
>>
4
)];
}
}
if
(
right_damage
)
{
if
(
right_damage
)
{
dst
[
offset
+
8
+
y
*
stride
]
=
cm
[
dst
[
offset
+
8
+
y
*
stride
]
-
((
d
*
7
)
>>
4
)];
dst
[
offset
+
8
+
y
*
stride
]
=
cm
[
dst
[
offset
+
8
+
y
*
stride
]
-
((
d
*
7
)
>>
4
)];
dst
[
offset
+
9
+
y
*
stride
]
=
cm
[
dst
[
offset
+
9
+
y
*
stride
]
-
((
d
*
5
)
>>
4
)];
dst
[
offset
+
9
+
y
*
stride
]
=
cm
[
dst
[
offset
+
9
+
y
*
stride
]
-
((
d
*
5
)
>>
4
)];
dst
[
offset
+
10
+
y
*
stride
]
=
cm
[
dst
[
offset
+
10
+
y
*
stride
]
-
((
d
*
3
)
>>
4
)];
dst
[
offset
+
10
+
y
*
stride
]
=
cm
[
dst
[
offset
+
10
+
y
*
stride
]
-
((
d
*
3
)
>>
4
)];
dst
[
offset
+
11
+
y
*
stride
]
=
cm
[
dst
[
offset
+
11
+
y
*
stride
]
-
((
d
*
1
)
>>
4
)];
dst
[
offset
+
11
+
y
*
stride
]
=
cm
[
dst
[
offset
+
11
+
y
*
stride
]
-
((
d
*
1
)
>>
4
)];
}
}
}
}
}
}
...
@@ -303,231 +320,271 @@ static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
...
@@ -303,231 +320,271 @@ static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int st
* @param w width in 8 pixel blocks
* @param w width in 8 pixel blocks
* @param h height in 8 pixel blocks
* @param h height in 8 pixel blocks
*/
*/
static
void
v_block_filter
(
MpegEncContext
*
s
,
uint8_t
*
dst
,
int
w
,
int
h
,
int
stride
,
int
is_luma
){
static
void
v_block_filter
(
MpegEncContext
*
s
,
uint8_t
*
dst
,
int
w
,
int
h
,
int
stride
,
int
is_luma
)
{
int
b_x
,
b_y
,
mvx_stride
,
mvy_stride
;
int
b_x
,
b_y
,
mvx_stride
,
mvy_stride
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
uint8_t
*
cm
=
ff_cropTbl
+
MAX_NEG_CROP
;
set_mv_strides
(
s
,
&
mvx_stride
,
&
mvy_stride
);
set_mv_strides
(
s
,
&
mvx_stride
,
&
mvy_stride
);
mvx_stride
>>=
is_luma
;
mvx_stride
>>=
is_luma
;
mvy_stride
*=
mvx_stride
;
mvy_stride
*=
mvx_stride
;
for
(
b_y
=
0
;
b_y
<
h
-
1
;
b_y
++
)
{
for
(
b_y
=
0
;
b_y
<
h
-
1
;
b_y
++
)
{
for
(
b_x
=
0
;
b_x
<
w
;
b_x
++
)
{
for
(
b_x
=
0
;
b_x
<
w
;
b_x
++
)
{
int
x
;
int
x
;
int
top_status
=
s
->
error_status_table
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
];
int
top_status
=
s
->
error_status_table
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
];
int
bottom_status
=
s
->
error_status_table
[(
b_x
>>
is_luma
)
+
((
b_y
+
1
)
>>
is_luma
)
*
s
->
mb_stride
];
int
bottom_status
=
s
->
error_status_table
[(
b_x
>>
is_luma
)
+
((
b_y
+
1
)
>>
is_luma
)
*
s
->
mb_stride
];
int
top_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
]);
int
top_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[(
b_x
>>
is_luma
)
+
(
b_y
>>
is_luma
)
*
s
->
mb_stride
]);
int
bottom_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[(
b_x
>>
is_luma
)
+
((
b_y
+
1
)
>>
is_luma
)
*
s
->
mb_stride
]);
int
bottom_intra
=
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[(
b_x
>>
is_luma
)
+
((
b_y
+
1
)
>>
is_luma
)
*
s
->
mb_stride
]);
int
top_damage
=
top_status
&
ER_MB_ERROR
;
int
top_damage
=
top_status
&
ER_MB_ERROR
;
int
bottom_damage
=
bottom_status
&
ER_MB_ERROR
;
int
bottom_damage
=
bottom_status
&
ER_MB_ERROR
;
int
offset
=
b_x
*
8
+
b_y
*
stride
*
8
;
int
offset
=
b_x
*
8
+
b_y
*
stride
*
8
;
int16_t
*
top_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
b_y
+
mvx_stride
*
b_x
];
int16_t
*
top_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
b_y
+
mvx_stride
*
b_x
];
int16_t
*
bottom_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
(
b_y
+
1
)
+
mvx_stride
*
b_x
];
int16_t
*
bottom_mv
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mvy_stride
*
(
b_y
+
1
)
+
mvx_stride
*
b_x
];
if
(
!
(
top_damage
||
bottom_damage
))
continue
;
// both undamaged
if
(
!
(
top_damage
||
bottom_damage
))
continue
;
// both undamaged
if
(
(
!
top_intra
)
&&
(
!
bottom_intra
)
if
((
!
top_intra
)
&&
(
!
bottom_intra
)
&&
&&
FFABS
(
top_mv
[
0
]
-
bottom_mv
[
0
])
+
FFABS
(
top_mv
[
1
]
+
bottom_mv
[
1
])
<
2
)
continue
;
FFABS
(
top_mv
[
0
]
-
bottom_mv
[
0
])
+
FFABS
(
top_mv
[
1
]
+
bottom_mv
[
1
])
<
2
)
continue
;
for
(
x
=
0
;
x
<
8
;
x
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
int
a
,
b
,
c
,
d
;
int
a
,
b
,
c
,
d
;
a
=
dst
[
offset
+
x
+
7
*
stride
]
-
dst
[
offset
+
x
+
6
*
stride
];
a
=
dst
[
offset
+
x
+
7
*
stride
]
-
dst
[
offset
+
x
+
6
*
stride
];
b
=
dst
[
offset
+
x
+
8
*
stride
]
-
dst
[
offset
+
x
+
7
*
stride
];
b
=
dst
[
offset
+
x
+
8
*
stride
]
-
dst
[
offset
+
x
+
7
*
stride
];
c
=
dst
[
offset
+
x
+
9
*
stride
]
-
dst
[
offset
+
x
+
8
*
stride
];
c
=
dst
[
offset
+
x
+
9
*
stride
]
-
dst
[
offset
+
x
+
8
*
stride
];
d
=
FFABS
(
b
)
-
((
FFABS
(
a
)
+
FFABS
(
c
)
+
1
)
>>
1
);
d
=
FFABS
(
b
)
-
((
FFABS
(
a
)
+
FFABS
(
c
)
+
1
)
>>
1
);
d
=
FFMAX
(
d
,
0
);
d
=
FFMAX
(
d
,
0
);
if
(
b
<
0
)
d
=
-
d
;
if
(
b
<
0
)
d
=
-
d
;
if
(
d
==
0
)
continue
;
if
(
d
==
0
)
continue
;
if
(
!
(
top_damage
&&
bottom_damage
))
if
(
!
(
top_damage
&&
bottom_damage
))
d
=
d
*
16
/
9
;
d
=
d
*
16
/
9
;
if
(
top_damage
)
{
if
(
top_damage
)
{
dst
[
offset
+
x
+
7
*
stride
]
=
cm
[
dst
[
offset
+
x
+
7
*
stride
]
+
((
d
*
7
)
>>
4
)];
dst
[
offset
+
x
+
7
*
stride
]
=
cm
[
dst
[
offset
+
x
+
7
*
stride
]
+
((
d
*
7
)
>>
4
)];
dst
[
offset
+
x
+
6
*
stride
]
=
cm
[
dst
[
offset
+
x
+
6
*
stride
]
+
((
d
*
5
)
>>
4
)];
dst
[
offset
+
x
+
6
*
stride
]
=
cm
[
dst
[
offset
+
x
+
6
*
stride
]
+
((
d
*
5
)
>>
4
)];
dst
[
offset
+
x
+
5
*
stride
]
=
cm
[
dst
[
offset
+
x
+
5
*
stride
]
+
((
d
*
3
)
>>
4
)];
dst
[
offset
+
x
+
5
*
stride
]
=
cm
[
dst
[
offset
+
x
+
5
*
stride
]
+
((
d
*
3
)
>>
4
)];
dst
[
offset
+
x
+
4
*
stride
]
=
cm
[
dst
[
offset
+
x
+
4
*
stride
]
+
((
d
*
1
)
>>
4
)];
dst
[
offset
+
x
+
4
*
stride
]
=
cm
[
dst
[
offset
+
x
+
4
*
stride
]
+
((
d
*
1
)
>>
4
)];
}
}
if
(
bottom_damage
)
{
if
(
bottom_damage
)
{
dst
[
offset
+
x
+
8
*
stride
]
=
cm
[
dst
[
offset
+
x
+
8
*
stride
]
-
((
d
*
7
)
>>
4
)];
dst
[
offset
+
x
+
8
*
stride
]
=
cm
[
dst
[
offset
+
x
+
8
*
stride
]
-
((
d
*
7
)
>>
4
)];
dst
[
offset
+
x
+
9
*
stride
]
=
cm
[
dst
[
offset
+
x
+
9
*
stride
]
-
((
d
*
5
)
>>
4
)];
dst
[
offset
+
x
+
9
*
stride
]
=
cm
[
dst
[
offset
+
x
+
9
*
stride
]
-
((
d
*
5
)
>>
4
)];
dst
[
offset
+
x
+
10
*
stride
]
=
cm
[
dst
[
offset
+
x
+
10
*
stride
]
-
((
d
*
3
)
>>
4
)];
dst
[
offset
+
x
+
10
*
stride
]
=
cm
[
dst
[
offset
+
x
+
10
*
stride
]
-
((
d
*
3
)
>>
4
)];
dst
[
offset
+
x
+
11
*
stride
]
=
cm
[
dst
[
offset
+
x
+
11
*
stride
]
-
((
d
*
1
)
>>
4
)];
dst
[
offset
+
x
+
11
*
stride
]
=
cm
[
dst
[
offset
+
x
+
11
*
stride
]
-
((
d
*
1
)
>>
4
)];
}
}
}
}
}
}
}
}
}
}
static
void
guess_mv
(
MpegEncContext
*
s
){
static
void
guess_mv
(
MpegEncContext
*
s
)
{
uint8_t
fixed
[
s
->
mb_stride
*
s
->
mb_height
];
uint8_t
fixed
[
s
->
mb_stride
*
s
->
mb_height
];
#define MV_FROZEN 3
#define MV_FROZEN 3
#define MV_CHANGED 2
#define MV_CHANGED 2
#define MV_UNCHANGED 1
#define MV_UNCHANGED 1
const
int
mb_stride
=
s
->
mb_stride
;
const
int
mb_stride
=
s
->
mb_stride
;
const
int
mb_width
=
s
->
mb_width
;
const
int
mb_width
=
s
->
mb_width
;
const
int
mb_height
=
s
->
mb_height
;
const
int
mb_height
=
s
->
mb_height
;
int
i
,
depth
,
num_avail
;
int
i
,
depth
,
num_avail
;
int
mb_x
,
mb_y
,
mot_step
,
mot_stride
;
int
mb_x
,
mb_y
,
mot_step
,
mot_stride
;
set_mv_strides
(
s
,
&
mot_step
,
&
mot_stride
);
set_mv_strides
(
s
,
&
mot_step
,
&
mot_stride
);
num_avail
=
0
;
num_avail
=
0
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
f
=
0
;
int
f
=
0
;
int
error
=
s
->
error_status_table
[
mb_xy
];
int
error
=
s
->
error_status_table
[
mb_xy
];
if
(
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
f
=
MV_FROZEN
;
//intra //FIXME check
if
(
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
if
(
!
(
error
&
ER_MV_ERROR
))
f
=
MV_FROZEN
;
//inter with undamaged MV
f
=
MV_FROZEN
;
// intra // FIXME check
if
(
!
(
error
&
ER_MV_ERROR
))
f
=
MV_FROZEN
;
// inter with undamaged MV
fixed
[
mb_xy
]
=
f
;
fixed
[
mb_xy
]
=
f
;
if
(
f
==
MV_FROZEN
)
if
(
f
==
MV_FROZEN
)
num_avail
++
;
num_avail
++
;
}
}
if
((
!
(
s
->
avctx
->
error_concealment
&
FF_EC_GUESS_MVS
))
||
num_avail
<=
mb_width
/
2
){
if
((
!
(
s
->
avctx
->
error_concealment
&
FF_EC_GUESS_MVS
))
||
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
){
num_avail
<=
mb_width
/
2
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
){
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
if
(
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
continue
;
if
(
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
if
(
!
(
s
->
error_status_table
[
mb_xy
]
&
ER_MV_ERROR
))
continue
;
continue
;
if
(
!
(
s
->
error_status_table
[
mb_xy
]
&
ER_MV_ERROR
))
continue
;
s
->
mv_dir
=
s
->
last_picture
.
f
.
data
[
0
]
?
MV_DIR_FORWARD
:
MV_DIR_BACKWARD
;
s
->
mv_dir
=
s
->
last_picture
.
f
.
data
[
0
]
?
MV_DIR_FORWARD
s
->
mb_intra
=
0
;
:
MV_DIR_BACKWARD
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mb_intra
=
0
;
s
->
mb_skipped
=
0
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mb_skipped
=
0
;
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
mb_x
=
mb_x
;
s
->
mb_x
=
mb_x
;
s
->
mb_y
=
mb_y
;
s
->
mb_y
=
mb_y
;
s
->
mv
[
0
][
0
][
0
]
=
0
;
s
->
mv
[
0
][
0
][
0
]
=
0
;
s
->
mv
[
0
][
0
][
1
]
=
0
;
s
->
mv
[
0
][
0
][
1
]
=
0
;
decode_mb
(
s
,
0
);
decode_mb
(
s
,
0
);
}
}
}
}
return
;
return
;
}
}
for
(
depth
=
0
;;
depth
++
)
{
for
(
depth
=
0
;
;
depth
++
)
{
int
changed
,
pass
,
none_left
;
int
changed
,
pass
,
none_left
;
none_left
=
1
;
none_left
=
1
;
changed
=
1
;
changed
=
1
;
for
(
pass
=
0
;
(
changed
||
pass
<
2
)
&&
pass
<
10
;
pass
++
)
{
for
(
pass
=
0
;
(
changed
||
pass
<
2
)
&&
pass
<
10
;
pass
++
)
{
int
mb_x
,
mb_y
;
int
mb_x
,
mb_y
;
int
score_sum
=
0
;
int
score_sum
=
0
;
changed
=
0
;
changed
=
0
;
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
int
mv_predictor
[
8
][
2
]
=
{{
0
}
};
int
mv_predictor
[
8
][
2
]
=
{
{
0
}
};
int
ref
[
8
]
=
{
0
};
int
ref
[
8
]
=
{
0
};
int
pred_count
=
0
;
int
pred_count
=
0
;
int
j
;
int
j
;
int
best_score
=
256
*
256
*
256
*
64
;
int
best_score
=
256
*
256
*
256
*
64
;
int
best_pred
=
0
;
int
best_pred
=
0
;
const
int
mot_index
=
(
mb_x
+
mb_y
*
mot_stride
)
*
mot_step
;
const
int
mot_index
=
(
mb_x
+
mb_y
*
mot_stride
)
*
mot_step
;
int
prev_x
,
prev_y
,
prev_ref
;
int
prev_x
,
prev_y
,
prev_ref
;
if
((
mb_x
^
mb_y
^
pass
)
&
1
)
continue
;
if
((
mb_x
^
mb_y
^
pass
)
&
1
)
continue
;
if
(
fixed
[
mb_xy
]
==
MV_FROZEN
)
continue
;
if
(
fixed
[
mb_xy
]
==
MV_FROZEN
)
continue
;
assert
(
!
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]));
assert
(
!
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]));
assert
(
s
->
last_picture_ptr
&&
s
->
last_picture_ptr
->
f
.
data
[
0
]);
assert
(
s
->
last_picture_ptr
&&
s
->
last_picture_ptr
->
f
.
data
[
0
]);
j
=
0
;
j
=
0
;
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
]
==
MV_FROZEN
)
j
=
1
;
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
]
==
MV_FROZEN
)
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
]
==
MV_FROZEN
)
j
=
1
;
j
=
1
;
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
]
==
MV_FROZEN
)
j
=
1
;
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
]
==
MV_FROZEN
)
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
]
==
MV_FROZEN
)
j
=
1
;
j
=
1
;
if
(
j
==
0
)
continue
;
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
]
==
MV_FROZEN
)
j
=
1
;
j
=
0
;
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
]
==
MV_FROZEN
)
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
]
==
MV_CHANGED
)
j
=
1
;
j
=
1
;
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
]
==
MV_CHANGED
)
j
=
1
;
if
(
j
==
0
)
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
]
==
MV_CHANGED
)
j
=
1
;
continue
;
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
]
==
MV_CHANGED
)
j
=
1
;
if
(
j
==
0
&&
pass
>
1
)
continue
;
j
=
0
;
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
]
==
MV_CHANGED
)
none_left
=
0
;
j
=
1
;
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
]
==
MV_CHANGED
)
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
]){
j
=
1
;
mv_predictor
[
pred_count
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_step
][
0
];
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
]
==
MV_CHANGED
)
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_step
][
1
];
j
=
1
;
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
-
1
)];
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
]
==
MV_CHANGED
)
j
=
1
;
if
(
j
==
0
&&
pass
>
1
)
continue
;
none_left
=
0
;
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
])
{
mv_predictor
[
pred_count
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_step
][
0
];
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_step
][
1
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
-
1
)];
pred_count
++
;
pred_count
++
;
}
}
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
]){
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
])
{
mv_predictor
[
pred_count
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_step
][
0
];
mv_predictor
[
pred_count
][
0
]
=
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_step
][
1
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_step
][
0
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
+
1
)];
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_step
][
1
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
+
1
)];
pred_count
++
;
pred_count
++
;
}
}
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
]){
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
])
{
mv_predictor
[
pred_count
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_stride
*
mot_step
][
0
];
mv_predictor
[
pred_count
][
0
]
=
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_stride
*
mot_step
][
1
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_stride
*
mot_step
][
0
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
-
s
->
mb_stride
)];
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
-
mot_stride
*
mot_step
][
1
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
-
s
->
mb_stride
)];
pred_count
++
;
pred_count
++
;
}
}
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
]){
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
])
{
mv_predictor
[
pred_count
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_stride
*
mot_step
][
0
];
mv_predictor
[
pred_count
][
0
]
=
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_stride
*
mot_step
][
1
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_stride
*
mot_step
][
0
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
+
s
->
mb_stride
)];
mv_predictor
[
pred_count
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
mot_stride
*
mot_step
][
1
];
ref
[
pred_count
]
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
(
mb_xy
+
s
->
mb_stride
)];
pred_count
++
;
pred_count
++
;
}
}
if
(
pred_count
==
0
)
continue
;
if
(
pred_count
==
0
)
continue
;
if
(
pred_count
>
1
)
{
if
(
pred_count
>
1
)
{
int
sum_x
=
0
,
sum_y
=
0
,
sum_r
=
0
;
int
sum_x
=
0
,
sum_y
=
0
,
sum_r
=
0
;
int
max_x
,
max_y
,
min_x
,
min_y
,
max_r
,
min_r
;
int
max_x
,
max_y
,
min_x
,
min_y
,
max_r
,
min_r
;
for
(
j
=
0
;
j
<
pred_count
;
j
++
)
{
for
(
j
=
0
;
j
<
pred_count
;
j
++
)
{
sum_x
+=
mv_predictor
[
j
][
0
];
sum_x
+=
mv_predictor
[
j
][
0
];
sum_y
+=
mv_predictor
[
j
][
1
];
sum_y
+=
mv_predictor
[
j
][
1
];
sum_r
+=
ref
[
j
];
sum_r
+=
ref
[
j
];
if
(
j
&&
ref
[
j
]
!=
ref
[
j
-
1
])
if
(
j
&&
ref
[
j
]
!=
ref
[
j
-
1
])
goto
skip_mean_and_median
;
goto
skip_mean_and_median
;
}
}
/* mean */
/* mean */
mv_predictor
[
pred_count
][
0
]
=
sum_x
/
j
;
mv_predictor
[
pred_count
][
0
]
=
sum_x
/
j
;
mv_predictor
[
pred_count
][
1
]
=
sum_y
/
j
;
mv_predictor
[
pred_count
][
1
]
=
sum_y
/
j
;
ref
[
pred_count
]
=
sum_r
/
j
;
ref
[
pred_count
]
=
sum_r
/
j
;
/* median */
/* median */
if
(
pred_count
>=
3
)
{
if
(
pred_count
>=
3
)
{
min_y
=
min_x
=
min_r
=
99999
;
min_y
=
min_x
=
min_r
=
99999
;
max_y
=
max_x
=
max_r
=
-
99999
;
max_y
=
max_x
=
max_r
=
-
99999
;
}
else
{
}
else
{
min_x
=
min_y
=
max_x
=
max_y
=
min_r
=
max_r
=
0
;
min_x
=
min_y
=
max_x
=
max_y
=
min_r
=
max_r
=
0
;
}
}
for
(
j
=
0
;
j
<
pred_count
;
j
++
)
{
for
(
j
=
0
;
j
<
pred_count
;
j
++
)
{
max_x
=
FFMAX
(
max_x
,
mv_predictor
[
j
][
0
]);
max_x
=
FFMAX
(
max_x
,
mv_predictor
[
j
][
0
]);
max_y
=
FFMAX
(
max_y
,
mv_predictor
[
j
][
1
]);
max_y
=
FFMAX
(
max_y
,
mv_predictor
[
j
][
1
]);
max_r
=
FFMAX
(
max_r
,
ref
[
j
]);
max_r
=
FFMAX
(
max_r
,
ref
[
j
]);
min_x
=
FFMIN
(
min_x
,
mv_predictor
[
j
][
0
]);
min_x
=
FFMIN
(
min_x
,
mv_predictor
[
j
][
0
]);
min_y
=
FFMIN
(
min_y
,
mv_predictor
[
j
][
1
]);
min_y
=
FFMIN
(
min_y
,
mv_predictor
[
j
][
1
]);
min_r
=
FFMIN
(
min_r
,
ref
[
j
]);
min_r
=
FFMIN
(
min_r
,
ref
[
j
]);
}
}
mv_predictor
[
pred_count
+
1
][
0
]
=
sum_x
-
max_x
-
min_x
;
mv_predictor
[
pred_count
+
1
][
0
]
=
sum_x
-
max_x
-
min_x
;
mv_predictor
[
pred_count
+
1
][
1
]
=
sum_y
-
max_y
-
min_y
;
mv_predictor
[
pred_count
+
1
][
1
]
=
sum_y
-
max_y
-
min_y
;
ref
[
pred_count
+
1
]
=
sum_r
-
max_r
-
min_r
;
ref
[
pred_count
+
1
]
=
sum_r
-
max_r
-
min_r
;
if
(
pred_count
==
4
)
{
if
(
pred_count
==
4
)
{
mv_predictor
[
pred_count
+
1
][
0
]
/=
2
;
mv_predictor
[
pred_count
+
1
][
0
]
/=
2
;
mv_predictor
[
pred_count
+
1
][
1
]
/=
2
;
mv_predictor
[
pred_count
+
1
][
1
]
/=
2
;
ref
[
pred_count
+
1
]
/=
2
;
ref
[
pred_count
+
1
]
/=
2
;
}
}
pred_count
+=
2
;
pred_count
+=
2
;
}
}
skip_mean_and_median
:
skip_mean_and_median:
/* zero MV */
/* zero MV */
pred_count
++
;
pred_count
++
;
...
@@ -541,76 +598,83 @@ skip_mean_and_median:
...
@@ -541,76 +598,83 @@ skip_mean_and_median:
if
(
!
s
->
last_picture
.
f
.
motion_val
[
0
]
||
if
(
!
s
->
last_picture
.
f
.
motion_val
[
0
]
||
!
s
->
last_picture
.
f
.
ref_index
[
0
])
!
s
->
last_picture
.
f
.
ref_index
[
0
])
goto
skip_last_mv
;
goto
skip_last_mv
;
prev_x
=
s
->
last_picture
.
f
.
motion_val
[
0
][
mot_index
][
0
];
prev_x
=
s
->
last_picture
.
f
.
motion_val
[
0
][
mot_index
][
0
];
prev_y
=
s
->
last_picture
.
f
.
motion_val
[
0
][
mot_index
][
1
];
prev_y
=
s
->
last_picture
.
f
.
motion_val
[
0
][
mot_index
][
1
];
prev_ref
=
s
->
last_picture
.
f
.
ref_index
[
0
][
4
*
mb_xy
];
prev_ref
=
s
->
last_picture
.
f
.
ref_index
[
0
][
4
*
mb_xy
];
}
else
{
}
else
{
prev_x
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
0
];
prev_x
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
0
];
prev_y
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
1
];
prev_y
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
1
];
prev_ref
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
mb_xy
];
prev_ref
=
s
->
current_picture
.
f
.
ref_index
[
0
][
4
*
mb_xy
];
}
}
/* last MV */
/* last MV */
mv_predictor
[
pred_count
][
0
]
=
prev_x
;
mv_predictor
[
pred_count
][
0
]
=
prev_x
;
mv_predictor
[
pred_count
][
1
]
=
prev_y
;
mv_predictor
[
pred_count
][
1
]
=
prev_y
;
ref
[
pred_count
]
=
prev_ref
;
ref
[
pred_count
]
=
prev_ref
;
pred_count
++
;
pred_count
++
;
skip_last_mv
:
s
->
mv_dir
=
MV_DIR_FORWARD
;
skip_last_mv:
s
->
mb_intra
=
0
;
s
->
mv_dir
=
MV_DIR_FORWARD
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mb_intra
=
0
;
s
->
mb_skipped
=
0
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mb_skipped
=
0
;
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
mb_x
=
mb_x
;
s
->
mb_x
=
mb_x
;
s
->
mb_y
=
mb_y
;
s
->
mb_y
=
mb_y
;
for
(
j
=
0
;
j
<
pred_count
;
j
++
){
for
(
j
=
0
;
j
<
pred_count
;
j
++
)
{
int
score
=
0
;
int
score
=
0
;
uint8_t
*
src
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
uint8_t
*
src
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
0
]
=
s
->
mv
[
0
][
0
][
0
]
=
mv_predictor
[
j
][
0
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
1
]
=
s
->
mv
[
0
][
0
][
1
]
=
mv_predictor
[
j
][
1
];
s
->
mv
[
0
][
0
][
0
]
=
mv_predictor
[
j
][
0
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
][
1
]
=
s
->
mv
[
0
][
0
][
1
]
=
mv_predictor
[
j
][
1
];
if
(
ref
[
j
]
<
0
)
//predictor intra or otherwise not available
// predictor intra or otherwise not available
if
(
ref
[
j
]
<
0
)
continue
;
continue
;
decode_mb
(
s
,
ref
[
j
]);
decode_mb
(
s
,
ref
[
j
]);
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
])
{
if
(
mb_x
>
0
&&
fixed
[
mb_xy
-
1
])
{
int
k
;
int
k
;
for
(
k
=
0
;
k
<
16
;
k
++
)
for
(
k
=
0
;
k
<
16
;
k
++
)
score
+=
FFABS
(
src
[
k
*
s
->
linesize
-
1
]
-
src
[
k
*
s
->
linesize
]);
score
+=
FFABS
(
src
[
k
*
s
->
linesize
-
1
]
-
src
[
k
*
s
->
linesize
]);
}
}
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
])
{
if
(
mb_x
+
1
<
mb_width
&&
fixed
[
mb_xy
+
1
])
{
int
k
;
int
k
;
for
(
k
=
0
;
k
<
16
;
k
++
)
for
(
k
=
0
;
k
<
16
;
k
++
)
score
+=
FFABS
(
src
[
k
*
s
->
linesize
+
15
]
-
src
[
k
*
s
->
linesize
+
16
]);
score
+=
FFABS
(
src
[
k
*
s
->
linesize
+
15
]
-
src
[
k
*
s
->
linesize
+
16
]);
}
}
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
])
{
if
(
mb_y
>
0
&&
fixed
[
mb_xy
-
mb_stride
])
{
int
k
;
int
k
;
for
(
k
=
0
;
k
<
16
;
k
++
)
for
(
k
=
0
;
k
<
16
;
k
++
)
score
+=
FFABS
(
src
[
k
-
s
->
linesize
]
-
src
[
k
]);
score
+=
FFABS
(
src
[
k
-
s
->
linesize
]
-
src
[
k
]);
}
}
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
])
{
if
(
mb_y
+
1
<
mb_height
&&
fixed
[
mb_xy
+
mb_stride
])
{
int
k
;
int
k
;
for
(
k
=
0
;
k
<
16
;
k
++
)
for
(
k
=
0
;
k
<
16
;
k
++
)
score
+=
FFABS
(
src
[
k
+
s
->
linesize
*
15
]
-
src
[
k
+
s
->
linesize
*
16
]);
score
+=
FFABS
(
src
[
k
+
s
->
linesize
*
15
]
-
src
[
k
+
s
->
linesize
*
16
]);
}
}
if
(
score
<=
best_score
)
{
// <= will favor the last MV
if
(
score
<=
best_score
)
{
// <= will favor the last MV
best_score
=
score
;
best_score
=
score
;
best_pred
=
j
;
best_pred
=
j
;
}
}
}
}
score_sum
+=
best_score
;
score_sum
+=
best_score
;
s
->
mv
[
0
][
0
][
0
]
=
mv_predictor
[
best_pred
][
0
];
s
->
mv
[
0
][
0
][
0
]
=
mv_predictor
[
best_pred
][
0
];
s
->
mv
[
0
][
0
][
1
]
=
mv_predictor
[
best_pred
][
1
];
s
->
mv
[
0
][
0
][
1
]
=
mv_predictor
[
best_pred
][
1
];
for
(
i
=
0
;
i
<
mot_step
;
i
++
)
for
(
i
=
0
;
i
<
mot_step
;
i
++
)
for
(
j
=
0
;
j
<
mot_step
;
j
++
)
{
for
(
j
=
0
;
j
<
mot_step
;
j
++
)
{
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
i
+
j
*
mot_stride
][
0
]
=
s
->
mv
[
0
][
0
][
0
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
i
+
j
*
mot_stride
][
0
]
=
s
->
mv
[
0
][
0
][
0
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
i
+
j
*
mot_stride
][
1
]
=
s
->
mv
[
0
][
0
][
1
];
s
->
current_picture
.
f
.
motion_val
[
0
][
mot_index
+
i
+
j
*
mot_stride
][
1
]
=
s
->
mv
[
0
][
0
][
1
];
}
}
...
@@ -618,73 +682,83 @@ score_sum+= best_score;
...
@@ -618,73 +682,83 @@ score_sum+= best_score;
decode_mb
(
s
,
ref
[
best_pred
]);
decode_mb
(
s
,
ref
[
best_pred
]);
if
(
s
->
mv
[
0
][
0
][
0
]
!=
prev_x
||
s
->
mv
[
0
][
0
][
1
]
!=
prev_y
)
{
if
(
s
->
mv
[
0
][
0
][
0
]
!=
prev_x
||
s
->
mv
[
0
][
0
][
1
]
!=
prev_y
)
{
fixed
[
mb_xy
]
=
MV_CHANGED
;
fixed
[
mb_xy
]
=
MV_CHANGED
;
changed
++
;
changed
++
;
}
else
}
else
fixed
[
mb_xy
]
=
MV_UNCHANGED
;
fixed
[
mb_xy
]
=
MV_UNCHANGED
;
}
}
}
}
//
printf(".%d/%d", changed, score_sum); fflush(stdout);
//
printf(".%d/%d", changed, score_sum); fflush(stdout);
}
}
if
(
none_left
)
if
(
none_left
)
return
;
return
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
mb_xy
=
s
->
mb_index2xy
[
i
];
if
(
fixed
[
mb_xy
])
if
(
fixed
[
mb_xy
])
fixed
[
mb_xy
]
=
MV_FROZEN
;
fixed
[
mb_xy
]
=
MV_FROZEN
;
}
}
//
printf(":"); fflush(stdout);
//
printf(":"); fflush(stdout);
}
}
}
}
static
int
is_intra_more_likely
(
MpegEncContext
*
s
){
static
int
is_intra_more_likely
(
MpegEncContext
*
s
)
{
int
is_intra_likely
,
i
,
j
,
undamaged_count
,
skip_amount
,
mb_x
,
mb_y
;
int
is_intra_likely
,
i
,
j
,
undamaged_count
,
skip_amount
,
mb_x
,
mb_y
;
if
(
!
s
->
last_picture_ptr
||
!
s
->
last_picture_ptr
->
f
.
data
[
0
])
return
1
;
//no previous frame available -> use spatial prediction
if
(
!
s
->
last_picture_ptr
||
!
s
->
last_picture_ptr
->
f
.
data
[
0
])
return
1
;
// no previous frame available -> use spatial prediction
undamaged_count
=
0
;
undamaged_count
=
0
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
error
=
s
->
error_status_table
[
mb_xy
];
const
int
error
=
s
->
error_status_table
[
mb_xy
];
if
(
!
((
error
&
ER_DC_ERROR
)
&&
(
error
&
ER_MV_ERROR
)))
if
(
!
((
error
&
ER_DC_ERROR
)
&&
(
error
&
ER_MV_ERROR
)))
undamaged_count
++
;
undamaged_count
++
;
}
}
if
(
s
->
codec_id
==
CODEC_ID_H264
){
if
(
s
->
codec_id
==
CODEC_ID_H264
)
{
H264Context
*
h
=
(
void
*
)
s
;
H264Context
*
h
=
(
void
*
)
s
;
if
(
h
->
list_count
<=
0
||
h
->
ref_count
[
0
]
<=
0
||
!
h
->
ref_list
[
0
][
0
].
f
.
data
[
0
])
if
(
h
->
list_count
<=
0
||
h
->
ref_count
[
0
]
<=
0
||
!
h
->
ref_list
[
0
][
0
].
f
.
data
[
0
])
return
1
;
return
1
;
}
}
if
(
undamaged_count
<
5
)
return
0
;
//almost all MBs damaged -> use temporal prediction
if
(
undamaged_count
<
5
)
return
0
;
// almost all MBs damaged -> use temporal prediction
//prevent dsp.sad() check, that requires access to the image
// prevent dsp.sad() check, that requires access to the image
if
(
CONFIG_MPEG_XVMC_DECODER
&&
s
->
avctx
->
xvmc_acceleration
&&
s
->
pict_type
==
AV_PICTURE_TYPE_I
)
if
(
CONFIG_MPEG_XVMC_DECODER
&&
s
->
avctx
->
xvmc_acceleration
&&
s
->
pict_type
==
AV_PICTURE_TYPE_I
)
return
1
;
return
1
;
skip_amount
=
FFMAX
(
undamaged_count
/
50
,
1
);
// check only up to 50 MBs
skip_amount
=
FFMAX
(
undamaged_count
/
50
,
1
);
// check only up to 50 MBs
is_intra_likely
=
0
;
is_intra_likely
=
0
;
j
=
0
;
j
=
0
;
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
-
1
;
mb_y
++
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
-
1
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
int
error
;
int
error
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
((
error
&
ER_DC_ERROR
)
&&
(
error
&
ER_MV_ERROR
))
if
((
error
&
ER_DC_ERROR
)
&&
(
error
&
ER_MV_ERROR
))
continue
;
//skip damaged
continue
;
//
skip damaged
j
++
;
j
++
;
if
((
j
%
skip_amount
)
!=
0
)
continue
;
//skip a few to speed things up
// skip a few to speed things up
if
((
j
%
skip_amount
)
!=
0
)
continue
;
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_I
){
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_I
)
{
uint8_t
*
mb_ptr
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
uint8_t
*
mb_ptr
=
s
->
current_picture
.
f
.
data
[
0
]
+
uint8_t
*
last_mb_ptr
=
s
->
last_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
uint8_t
*
last_mb_ptr
=
s
->
last_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
if
(
s
->
avctx
->
codec_id
==
CODEC_ID_H264
)
{
if
(
s
->
avctx
->
codec_id
==
CODEC_ID_H264
)
{
// FIXME
// FIXME
...
@@ -692,9 +766,12 @@ static int is_intra_more_likely(MpegEncContext *s){
...
@@ -692,9 +766,12 @@ static int is_intra_more_likely(MpegEncContext *s){
ff_thread_await_progress
((
AVFrame
*
)
s
->
last_picture_ptr
,
ff_thread_await_progress
((
AVFrame
*
)
s
->
last_picture_ptr
,
mb_y
,
0
);
mb_y
,
0
);
}
}
is_intra_likely
+=
s
->
dsp
.
sad
[
0
](
NULL
,
last_mb_ptr
,
mb_ptr
,
s
->
linesize
,
16
);
is_intra_likely
+=
s
->
dsp
.
sad
[
0
](
NULL
,
last_mb_ptr
,
mb_ptr
,
is_intra_likely
-=
s
->
dsp
.
sad
[
0
](
NULL
,
last_mb_ptr
,
last_mb_ptr
+
s
->
linesize
*
16
,
s
->
linesize
,
16
);
s
->
linesize
,
16
);
}
else
{
is_intra_likely
-=
s
->
dsp
.
sad
[
0
](
NULL
,
last_mb_ptr
,
last_mb_ptr
+
s
->
linesize
*
16
,
s
->
linesize
,
16
);
}
else
{
if
(
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
if
(
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
is_intra_likely
++
;
is_intra_likely
++
;
else
else
...
@@ -702,117 +779,133 @@ static int is_intra_more_likely(MpegEncContext *s){
...
@@ -702,117 +779,133 @@ static int is_intra_more_likely(MpegEncContext *s){
}
}
}
}
}
}
//
printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
//
printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
return
is_intra_likely
>
0
;
return
is_intra_likely
>
0
;
}
}
void
ff_er_frame_start
(
MpegEncContext
*
s
){
void
ff_er_frame_start
(
MpegEncContext
*
s
)
if
(
!
s
->
err_recognition
)
return
;
{
if
(
!
s
->
err_recognition
)
return
;
memset
(
s
->
error_status_table
,
ER_MB_ERROR
|
VP_START
|
ER_MB_END
,
s
->
mb_stride
*
s
->
mb_height
*
sizeof
(
uint8_t
));
memset
(
s
->
error_status_table
,
ER_MB_ERROR
|
VP_START
|
ER_MB_END
,
s
->
error_count
=
3
*
s
->
mb_num
;
s
->
mb_stride
*
s
->
mb_height
*
sizeof
(
uint8_t
));
s
->
error_count
=
3
*
s
->
mb_num
;
s
->
error_occurred
=
0
;
s
->
error_occurred
=
0
;
}
}
/**
/**
* Add a slice.
* Add a slice.
* @param endx x component of the last macroblock, can be -1 for the last of the previous line
* @param endx x component of the last macroblock, can be -1
* @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is assumed that no earlier end or
* for the last of the previous line
* error of the same type occurred
* @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
* assumed that no earlier end or error of the same type occurred
*/
*/
void
ff_er_add_slice
(
MpegEncContext
*
s
,
int
startx
,
int
starty
,
int
endx
,
int
endy
,
int
status
){
void
ff_er_add_slice
(
MpegEncContext
*
s
,
int
startx
,
int
starty
,
const
int
start_i
=
av_clip
(
startx
+
starty
*
s
->
mb_width
,
0
,
s
->
mb_num
-
1
);
int
endx
,
int
endy
,
int
status
)
const
int
end_i
=
av_clip
(
endx
+
endy
*
s
->
mb_width
,
0
,
s
->
mb_num
);
{
const
int
start_xy
=
s
->
mb_index2xy
[
start_i
];
const
int
start_i
=
av_clip
(
startx
+
starty
*
s
->
mb_width
,
0
,
s
->
mb_num
-
1
);
const
int
end_xy
=
s
->
mb_index2xy
[
end_i
];
const
int
end_i
=
av_clip
(
endx
+
endy
*
s
->
mb_width
,
0
,
s
->
mb_num
);
int
mask
=
-
1
;
const
int
start_xy
=
s
->
mb_index2xy
[
start_i
];
const
int
end_xy
=
s
->
mb_index2xy
[
end_i
];
if
(
s
->
avctx
->
hwaccel
)
int
mask
=
-
1
;
if
(
s
->
avctx
->
hwaccel
)
return
;
return
;
if
(
start_i
>
end_i
||
start_xy
>
end_xy
){
if
(
start_i
>
end_i
||
start_xy
>
end_xy
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"internal error, slice end before start
\n
"
);
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"internal error, slice end before start
\n
"
);
return
;
return
;
}
}
if
(
!
s
->
err_recognition
)
return
;
if
(
!
s
->
err_recognition
)
return
;
mask
&=
~
VP_START
;
mask
&=
~
VP_START
;
if
(
status
&
(
ER_AC_ERROR
|
ER_AC_END
))
{
if
(
status
&
(
ER_AC_ERROR
|
ER_AC_END
))
{
mask
&=
~
(
ER_AC_ERROR
|
ER_AC_END
);
mask
&=
~
(
ER_AC_ERROR
|
ER_AC_END
);
s
->
error_count
-=
end_i
-
start_i
+
1
;
s
->
error_count
-=
end_i
-
start_i
+
1
;
}
}
if
(
status
&
(
ER_DC_ERROR
|
ER_DC_END
))
{
if
(
status
&
(
ER_DC_ERROR
|
ER_DC_END
))
{
mask
&=
~
(
ER_DC_ERROR
|
ER_DC_END
);
mask
&=
~
(
ER_DC_ERROR
|
ER_DC_END
);
s
->
error_count
-=
end_i
-
start_i
+
1
;
s
->
error_count
-=
end_i
-
start_i
+
1
;
}
}
if
(
status
&
(
ER_MV_ERROR
|
ER_MV_END
))
{
if
(
status
&
(
ER_MV_ERROR
|
ER_MV_END
))
{
mask
&=
~
(
ER_MV_ERROR
|
ER_MV_END
);
mask
&=
~
(
ER_MV_ERROR
|
ER_MV_END
);
s
->
error_count
-=
end_i
-
start_i
+
1
;
s
->
error_count
-=
end_i
-
start_i
+
1
;
}
}
if
(
status
&
ER_MB_ERROR
)
{
if
(
status
&
ER_MB_ERROR
)
{
s
->
error_occurred
=
1
;
s
->
error_occurred
=
1
;
s
->
error_count
=
INT_MAX
;
s
->
error_count
=
INT_MAX
;
}
}
if
(
mask
==
~
0x7F
){
if
(
mask
==
~
0x7F
)
{
memset
(
&
s
->
error_status_table
[
start_xy
],
0
,
(
end_xy
-
start_xy
)
*
sizeof
(
uint8_t
));
memset
(
&
s
->
error_status_table
[
start_xy
],
0
,
}
else
{
(
end_xy
-
start_xy
)
*
sizeof
(
uint8_t
));
}
else
{
int
i
;
int
i
;
for
(
i
=
start_xy
;
i
<
end_xy
;
i
++
){
for
(
i
=
start_xy
;
i
<
end_xy
;
i
++
)
s
->
error_status_table
[
i
]
&=
mask
;
s
->
error_status_table
[
i
]
&=
mask
;
}
}
}
if
(
end_i
==
s
->
mb_num
)
if
(
end_i
==
s
->
mb_num
)
s
->
error_count
=
INT_MAX
;
s
->
error_count
=
INT_MAX
;
else
{
else
{
s
->
error_status_table
[
end_xy
]
&=
mask
;
s
->
error_status_table
[
end_xy
]
&=
mask
;
s
->
error_status_table
[
end_xy
]
|=
status
;
s
->
error_status_table
[
end_xy
]
|=
status
;
}
}
s
->
error_status_table
[
start_xy
]
|=
VP_START
;
s
->
error_status_table
[
start_xy
]
|=
VP_START
;
if
(
start_xy
>
0
&&
s
->
avctx
->
thread_count
<=
1
&&
s
->
avctx
->
skip_top
*
s
->
mb_width
<
start_i
){
if
(
start_xy
>
0
&&
s
->
avctx
->
thread_count
<=
1
&&
int
prev_status
=
s
->
error_status_table
[
s
->
mb_index2xy
[
start_i
-
1
]
];
s
->
avctx
->
skip_top
*
s
->
mb_width
<
start_i
)
{
int
prev_status
=
s
->
error_status_table
[
s
->
mb_index2xy
[
start_i
-
1
]];
prev_status
&=
~
VP_START
;
prev_status
&=
~
VP_START
;
if
(
prev_status
!=
(
ER_MV_END
|
ER_DC_END
|
ER_AC_END
))
s
->
error_count
=
INT_MAX
;
if
(
prev_status
!=
(
ER_MV_END
|
ER_DC_END
|
ER_AC_END
))
s
->
error_count
=
INT_MAX
;
}
}
}
}
void
ff_er_frame_end
(
MpegEncContext
*
s
){
void
ff_er_frame_end
(
MpegEncContext
*
s
)
{
int
i
,
mb_x
,
mb_y
,
error
,
error_type
,
dc_error
,
mv_error
,
ac_error
;
int
i
,
mb_x
,
mb_y
,
error
,
error_type
,
dc_error
,
mv_error
,
ac_error
;
int
distance
;
int
distance
;
int
threshold_part
[
4
]
=
{
100
,
100
,
100
};
int
threshold_part
[
4
]
=
{
100
,
100
,
100
};
int
threshold
=
50
;
int
threshold
=
50
;
int
is_intra_likely
;
int
is_intra_likely
;
int
size
=
s
->
b8_stride
*
2
*
s
->
mb_height
;
int
size
=
s
->
b8_stride
*
2
*
s
->
mb_height
;
Picture
*
pic
=
s
->
current_picture_ptr
;
Picture
*
pic
=
s
->
current_picture_ptr
;
if
(
!
s
->
err_recognition
||
s
->
error_count
==
0
||
s
->
avctx
->
lowres
||
/* We do not support ER of field pictures yet,
s
->
avctx
->
hwaccel
||
* though it should not crash if enabled. */
s
->
avctx
->
codec
->
capabilities
&
CODEC_CAP_HWACCEL_VDPAU
||
if
(
!
s
->
err_recognition
||
s
->
error_count
==
0
||
s
->
avctx
->
lowres
||
s
->
picture_structure
!=
PICT_FRAME
||
// we do not support ER of field pictures yet, though it should not crash if enabled
s
->
avctx
->
hwaccel
||
s
->
error_count
==
3
*
s
->
mb_width
*
(
s
->
avctx
->
skip_top
+
s
->
avctx
->
skip_bottom
))
return
;
s
->
avctx
->
codec
->
capabilities
&
CODEC_CAP_HWACCEL_VDPAU
||
s
->
picture_structure
!=
PICT_FRAME
||
s
->
error_count
==
3
*
s
->
mb_width
*
(
s
->
avctx
->
skip_top
+
s
->
avctx
->
skip_bottom
))
{
return
;
};
if
(
s
->
current_picture
.
f
.
motion_val
[
0
]
==
NULL
)
{
if
(
s
->
current_picture
.
f
.
motion_val
[
0
]
==
NULL
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Warning MVs not available
\n
"
);
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Warning MVs not available
\n
"
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
pic
->
f
.
ref_index
[
i
]
=
av_mallocz
(
s
->
mb_stride
*
s
->
mb_height
*
4
*
sizeof
(
uint8_t
));
pic
->
f
.
ref_index
[
i
]
=
av_mallocz
(
s
->
mb_stride
*
s
->
mb_height
*
4
*
sizeof
(
uint8_t
));
pic
->
motion_val_base
[
i
]
=
av_mallocz
((
size
+
4
)
*
2
*
sizeof
(
uint16_t
));
pic
->
motion_val_base
[
i
]
=
av_mallocz
((
size
+
4
)
*
2
*
sizeof
(
uint16_t
));
pic
->
f
.
motion_val
[
i
]
=
pic
->
motion_val_base
[
i
]
+
4
;
pic
->
f
.
motion_val
[
i
]
=
pic
->
motion_val_base
[
i
]
+
4
;
}
}
pic
->
f
.
motion_subsample_log2
=
3
;
pic
->
f
.
motion_subsample_log2
=
3
;
s
->
current_picture
=
*
s
->
current_picture_ptr
;
s
->
current_picture
=
*
s
->
current_picture_ptr
;
}
}
if
(
s
->
avctx
->
debug
&
FF_DEBUG_ER
)
{
if
(
s
->
avctx
->
debug
&
FF_DEBUG_ER
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
int
status
=
s
->
error_status_table
[
mb_x
+
mb_y
*
s
->
mb_stride
];
int
status
=
s
->
error_status_table
[
mb_x
+
mb_y
*
s
->
mb_stride
];
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"%2X "
,
status
);
av_log
(
s
->
avctx
,
AV_LOG_DEBUG
,
"%2X "
,
status
);
}
}
...
@@ -821,140 +914,149 @@ void ff_er_frame_end(MpegEncContext *s){
...
@@ -821,140 +914,149 @@ void ff_er_frame_end(MpegEncContext *s){
}
}
/* handle overlapping slices */
/* handle overlapping slices */
for
(
error_type
=
1
;
error_type
<=
3
;
error_type
++
)
{
for
(
error_type
=
1
;
error_type
<=
3
;
error_type
++
)
{
int
end_ok
=
0
;
int
end_ok
=
0
;
for
(
i
=
s
->
mb_num
-
1
;
i
>=
0
;
i
--
)
{
for
(
i
=
s
->
mb_num
-
1
;
i
>=
0
;
i
--
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
error
=
s
->
error_status_table
[
mb_xy
];
int
error
=
s
->
error_status_table
[
mb_xy
];
if
(
error
&
(
1
<<
error_type
))
if
(
error
&
(
1
<<
error_type
))
end_ok
=
1
;
end_ok
=
1
;
if
(
error
&
(
8
<<
error_type
))
if
(
error
&
(
8
<<
error_type
))
end_ok
=
1
;
end_ok
=
1
;
if
(
!
end_ok
)
if
(
!
end_ok
)
s
->
error_status_table
[
mb_xy
]
|=
1
<<
error_type
;
s
->
error_status_table
[
mb_xy
]
|=
1
<<
error_type
;
if
(
error
&
VP_START
)
if
(
error
&
VP_START
)
end_ok
=
0
;
end_ok
=
0
;
}
}
}
}
/* handle slices with partitions of different length */
/* handle slices with partitions of different length */
if
(
s
->
partitioned_frame
)
{
if
(
s
->
partitioned_frame
)
{
int
end_ok
=
0
;
int
end_ok
=
0
;
for
(
i
=
s
->
mb_num
-
1
;
i
>=
0
;
i
--
)
{
for
(
i
=
s
->
mb_num
-
1
;
i
>=
0
;
i
--
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
error
=
s
->
error_status_table
[
mb_xy
];
int
error
=
s
->
error_status_table
[
mb_xy
];
if
(
error
&
ER_AC_END
)
if
(
error
&
ER_AC_END
)
end_ok
=
0
;
end_ok
=
0
;
if
((
error
&
ER_MV_END
)
||
(
error
&
ER_DC_END
)
||
(
error
&
ER_AC_ERROR
))
if
((
error
&
ER_MV_END
)
||
end_ok
=
1
;
(
error
&
ER_DC_END
)
||
(
error
&
ER_AC_ERROR
))
end_ok
=
1
;
if
(
!
end_ok
)
if
(
!
end_ok
)
s
->
error_status_table
[
mb_xy
]
|=
ER_AC_ERROR
;
s
->
error_status_table
[
mb_xy
]
|=
ER_AC_ERROR
;
if
(
error
&
VP_START
)
if
(
error
&
VP_START
)
end_ok
=
0
;
end_ok
=
0
;
}
}
}
}
/* handle missing slices */
/* handle missing slices */
if
(
s
->
err_recognition
&
AV_EF_EXPLODE
){
if
(
s
->
err_recognition
&
AV_EF_EXPLODE
)
{
int
end_ok
=
1
;
int
end_ok
=
1
;
for
(
i
=
s
->
mb_num
-
2
;
i
>=
s
->
mb_width
+
100
;
i
--
){
//FIXME +100 hack
// FIXME + 100 hack
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
for
(
i
=
s
->
mb_num
-
2
;
i
>=
s
->
mb_width
+
100
;
i
--
)
{
int
error1
=
s
->
error_status_table
[
mb_xy
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
error2
=
s
->
error_status_table
[
s
->
mb_index2xy
[
i
+
1
]];
int
error1
=
s
->
error_status_table
[
mb_xy
];
int
error2
=
s
->
error_status_table
[
s
->
mb_index2xy
[
i
+
1
]];
if
(
error1
&
VP_START
)
end_ok
=
1
;
if
(
error1
&
VP_START
)
end_ok
=
1
;
if
(
error2
==
(
VP_START
|
ER_MB_ERROR
|
ER_MB_END
)
&&
error1
!=
(
VP_START
|
ER_MB_ERROR
|
ER_MB_END
)
if
(
error2
==
(
VP_START
|
ER_MB_ERROR
|
ER_MB_END
)
&&
&&
((
error1
&
ER_AC_END
)
||
(
error1
&
ER_DC_END
)
||
(
error1
&
ER_MV_END
))){
//end & uninit
error1
!=
(
VP_START
|
ER_MB_ERROR
|
ER_MB_END
)
&&
end_ok
=
0
;
((
error1
&
ER_AC_END
)
||
(
error1
&
ER_DC_END
)
||
(
error1
&
ER_MV_END
)))
{
// end & uninit
end_ok
=
0
;
}
}
if
(
!
end_ok
)
if
(
!
end_ok
)
s
->
error_status_table
[
mb_xy
]
|=
ER_MB_ERROR
;
s
->
error_status_table
[
mb_xy
]
|=
ER_MB_ERROR
;
}
}
}
}
/* backward mark errors */
/* backward mark errors */
distance
=
9999999
;
distance
=
9999999
;
for
(
error_type
=
1
;
error_type
<=
3
;
error_type
++
)
{
for
(
error_type
=
1
;
error_type
<=
3
;
error_type
++
)
{
for
(
i
=
s
->
mb_num
-
1
;
i
>=
0
;
i
--
)
{
for
(
i
=
s
->
mb_num
-
1
;
i
>=
0
;
i
--
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
error
=
s
->
error_status_table
[
mb_xy
];
int
error
=
s
->
error_status_table
[
mb_xy
];
if
(
!
s
->
mbskip_table
[
mb_xy
])
//
FIXME partition specific
if
(
!
s
->
mbskip_table
[
mb_xy
])
//
FIXME partition specific
distance
++
;
distance
++
;
if
(
error
&
(
1
<<
error_type
))
if
(
error
&
(
1
<<
error_type
))
distance
=
0
;
distance
=
0
;
if
(
s
->
partitioned_frame
)
{
if
(
s
->
partitioned_frame
)
{
if
(
distance
<
threshold_part
[
error_type
-
1
])
if
(
distance
<
threshold_part
[
error_type
-
1
])
s
->
error_status_table
[
mb_xy
]
|=
1
<<
error_type
;
s
->
error_status_table
[
mb_xy
]
|=
1
<<
error_type
;
}
else
{
}
else
{
if
(
distance
<
threshold
)
if
(
distance
<
threshold
)
s
->
error_status_table
[
mb_xy
]
|=
1
<<
error_type
;
s
->
error_status_table
[
mb_xy
]
|=
1
<<
error_type
;
}
}
if
(
error
&
VP_START
)
if
(
error
&
VP_START
)
distance
=
9999999
;
distance
=
9999999
;
}
}
}
}
/* forward mark errors */
/* forward mark errors */
error
=
0
;
error
=
0
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
old_error
=
s
->
error_status_table
[
mb_xy
];
int
old_error
=
s
->
error_status_table
[
mb_xy
];
if
(
old_error
&
VP_START
)
if
(
old_error
&
VP_START
)
{
error
=
old_error
&
ER_MB_ERROR
;
error
=
old_error
&
ER_MB_ERROR
;
else
{
}
else
{
error
|=
old_error
&
ER_MB_ERROR
;
error
|=
old_error
&
ER_MB_ERROR
;
s
->
error_status_table
[
mb_xy
]
|=
error
;
s
->
error_status_table
[
mb_xy
]
|=
error
;
}
}
}
}
/* handle not partitioned case */
/* handle not partitioned case */
if
(
!
s
->
partitioned_frame
)
{
if
(
!
s
->
partitioned_frame
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
error
&
ER_MB_ERROR
)
if
(
error
&
ER_MB_ERROR
)
error
|=
ER_MB_ERROR
;
error
|=
ER_MB_ERROR
;
s
->
error_status_table
[
mb_xy
]
=
error
;
s
->
error_status_table
[
mb_xy
]
=
error
;
}
}
}
}
dc_error
=
ac_error
=
mv_error
=
0
;
dc_error
=
ac_error
=
mv_error
=
0
;
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
){
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
error
&
ER_DC_ERROR
)
dc_error
++
;
if
(
error
&
ER_DC_ERROR
)
if
(
error
&
ER_AC_ERROR
)
ac_error
++
;
dc_error
++
;
if
(
error
&
ER_MV_ERROR
)
mv_error
++
;
if
(
error
&
ER_AC_ERROR
)
ac_error
++
;
if
(
error
&
ER_MV_ERROR
)
mv_error
++
;
}
}
av_log
(
s
->
avctx
,
AV_LOG_INFO
,
"concealing %d DC, %d AC, %d MV errors
\n
"
,
dc_error
,
ac_error
,
mv_error
);
av_log
(
s
->
avctx
,
AV_LOG_INFO
,
"concealing %d DC, %d AC, %d MV errors
\n
"
,
dc_error
,
ac_error
,
mv_error
);
is_intra_likely
=
is_intra_more_likely
(
s
);
is_intra_likely
=
is_intra_more_likely
(
s
);
/* set unknown mb-type to most likely */
/* set unknown mb-type to most likely */
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
!
((
error
&
ER_DC_ERROR
)
&&
(
error
&
ER_MV_ERROR
)))
if
(
!
((
error
&
ER_DC_ERROR
)
&&
(
error
&
ER_MV_ERROR
)))
continue
;
continue
;
if
(
is_intra_likely
)
if
(
is_intra_likely
)
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]
=
MB_TYPE_INTRA4x4
;
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]
=
MB_TYPE_INTRA4x4
;
else
else
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]
=
MB_TYPE_16x16
|
MB_TYPE_L0
;
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]
=
MB_TYPE_16x16
|
MB_TYPE_L0
;
...
@@ -962,164 +1064,177 @@ void ff_er_frame_end(MpegEncContext *s){
...
@@ -962,164 +1064,177 @@ void ff_er_frame_end(MpegEncContext *s){
// change inter to intra blocks if no reference frames are available
// change inter to intra blocks if no reference frames are available
if
(
!
s
->
last_picture
.
f
.
data
[
0
]
&&
!
s
->
next_picture
.
f
.
data
[
0
])
if
(
!
s
->
last_picture
.
f
.
data
[
0
]
&&
!
s
->
next_picture
.
f
.
data
[
0
])
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
if
(
!
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
if
(
!
IS_INTRA
(
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]))
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]
=
MB_TYPE_INTRA4x4
;
s
->
current_picture
.
f
.
mb_type
[
mb_xy
]
=
MB_TYPE_INTRA4x4
;
}
}
/* handle inter blocks with damaged AC */
/* handle inter blocks with damaged AC */
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
){
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
){
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
int
dir
=
!
s
->
last_picture
.
f
.
data
[
0
];
int
dir
=
!
s
->
last_picture
.
f
.
data
[
0
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
IS_INTRA
(
mb_type
))
continue
;
//intra
if
(
error
&
ER_MV_ERROR
)
continue
;
//inter with damaged MV
if
(
IS_INTRA
(
mb_type
))
if
(
!
(
error
&
ER_AC_ERROR
))
continue
;
//undamaged inter
continue
;
// intra
if
(
error
&
ER_MV_ERROR
)
s
->
mv_dir
=
dir
?
MV_DIR_BACKWARD
:
MV_DIR_FORWARD
;
continue
;
// inter with damaged MV
s
->
mb_intra
=
0
;
if
(
!
(
error
&
ER_AC_ERROR
))
s
->
mb_skipped
=
0
;
continue
;
// undamaged inter
if
(
IS_8X8
(
mb_type
)){
int
mb_index
=
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
;
s
->
mv_dir
=
dir
?
MV_DIR_BACKWARD
:
MV_DIR_FORWARD
;
s
->
mb_intra
=
0
;
s
->
mb_skipped
=
0
;
if
(
IS_8X8
(
mb_type
))
{
int
mb_index
=
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
;
int
j
;
int
j
;
s
->
mv_type
=
MV_TYPE_8X8
;
s
->
mv_type
=
MV_TYPE_8X8
;
for
(
j
=
0
;
j
<
4
;
j
++
)
{
for
(
j
=
0
;
j
<
4
;
j
++
)
{
s
->
mv
[
0
][
j
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_index
+
(
j
&
1
)
+
(
j
>>
1
)
*
s
->
b8_stride
][
0
];
s
->
mv
[
0
][
j
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_index
+
(
j
&
1
)
+
(
j
>>
1
)
*
s
->
b8_stride
][
0
];
s
->
mv
[
0
][
j
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_index
+
(
j
&
1
)
+
(
j
>>
1
)
*
s
->
b8_stride
][
1
];
s
->
mv
[
0
][
j
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_index
+
(
j
&
1
)
+
(
j
>>
1
)
*
s
->
b8_stride
][
1
];
}
}
}
else
{
}
else
{
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mv
[
0
][
0
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
][
0
];
s
->
mv
[
0
][
0
][
0
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
][
0
];
s
->
mv
[
0
][
0
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
][
1
];
s
->
mv
[
0
][
0
][
1
]
=
s
->
current_picture
.
f
.
motion_val
[
dir
][
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
][
1
];
}
}
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
mb_x
=
mb_x
;
s
->
mb_x
=
mb_x
;
s
->
mb_y
=
mb_y
;
s
->
mb_y
=
mb_y
;
decode_mb
(
s
,
0
/*FIXME h264 partitioned slices need this set
*/
);
decode_mb
(
s
,
0
/* FIXME h264 partitioned slices need this set
*/
);
}
}
}
}
/* guess MVs */
/* guess MVs */
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
){
if
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
){
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
){
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
int
xy
=
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
;
int
xy
=
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
IS_INTRA
(
mb_type
))
continue
;
if
(
!
(
error
&
ER_MV_ERROR
))
continue
;
//inter with undamaged MV
if
(
IS_INTRA
(
mb_type
))
if
(
!
(
error
&
ER_AC_ERROR
))
continue
;
//undamaged inter
continue
;
if
(
!
(
error
&
ER_MV_ERROR
))
s
->
mv_dir
=
MV_DIR_FORWARD
|
MV_DIR_BACKWARD
;
continue
;
// inter with undamaged MV
if
(
!
s
->
last_picture
.
f
.
data
[
0
])
s
->
mv_dir
&=
~
MV_DIR_FORWARD
;
if
(
!
(
error
&
ER_AC_ERROR
))
if
(
!
s
->
next_picture
.
f
.
data
[
0
])
s
->
mv_dir
&=
~
MV_DIR_BACKWARD
;
continue
;
// undamaged inter
s
->
mb_intra
=
0
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mv_dir
=
MV_DIR_FORWARD
|
MV_DIR_BACKWARD
;
s
->
mb_skipped
=
0
;
if
(
!
s
->
last_picture
.
f
.
data
[
0
])
s
->
mv_dir
&=
~
MV_DIR_FORWARD
;
if
(
s
->
pp_time
){
if
(
!
s
->
next_picture
.
f
.
data
[
0
])
int
time_pp
=
s
->
pp_time
;
s
->
mv_dir
&=
~
MV_DIR_BACKWARD
;
int
time_pb
=
s
->
pb_time
;
s
->
mb_intra
=
0
;
s
->
mv_type
=
MV_TYPE_16X16
;
s
->
mb_skipped
=
0
;
if
(
s
->
pp_time
)
{
int
time_pp
=
s
->
pp_time
;
int
time_pb
=
s
->
pb_time
;
if
(
s
->
avctx
->
codec_id
==
CODEC_ID_H264
)
{
if
(
s
->
avctx
->
codec_id
==
CODEC_ID_H264
)
{
//FIXME
//
FIXME
}
else
{
}
else
{
ff_thread_await_progress
((
AVFrame
*
)
s
->
next_picture_ptr
,
ff_thread_await_progress
((
AVFrame
*
)
s
->
next_picture_ptr
,
mb_y
,
0
);
mb_y
,
0
);
}
}
s
->
mv
[
0
][
0
][
0
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
0
]
*
time_pb
/
time_pp
;
s
->
mv
[
0
][
0
][
0
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
0
]
*
time_pb
/
time_pp
;
s
->
mv
[
0
][
0
][
1
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
1
]
*
time_pb
/
time_pp
;
s
->
mv
[
0
][
0
][
1
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
1
]
*
time_pb
/
time_pp
;
s
->
mv
[
1
][
0
][
0
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
0
]
*
(
time_pb
-
time_pp
)
/
time_pp
;
s
->
mv
[
1
][
0
][
0
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
0
]
*
(
time_pb
-
time_pp
)
/
time_pp
;
s
->
mv
[
1
][
0
][
1
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
1
]
*
(
time_pb
-
time_pp
)
/
time_pp
;
s
->
mv
[
1
][
0
][
1
]
=
s
->
next_picture
.
f
.
motion_val
[
0
][
xy
][
1
]
*
(
time_pb
-
time_pp
)
/
time_pp
;
}
else
{
}
else
{
s
->
mv
[
0
][
0
][
0
]
=
0
;
s
->
mv
[
0
][
0
][
0
]
=
0
;
s
->
mv
[
0
][
0
][
1
]
=
0
;
s
->
mv
[
0
][
0
][
1
]
=
0
;
s
->
mv
[
1
][
0
][
0
]
=
0
;
s
->
mv
[
1
][
0
][
0
]
=
0
;
s
->
mv
[
1
][
0
][
1
]
=
0
;
s
->
mv
[
1
][
0
][
1
]
=
0
;
}
}
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
dsp
.
clear_blocks
(
s
->
block
[
0
]);
s
->
mb_x
=
mb_x
;
s
->
mb_x
=
mb_x
;
s
->
mb_y
=
mb_y
;
s
->
mb_y
=
mb_y
;
decode_mb
(
s
,
0
);
decode_mb
(
s
,
0
);
}
}
}
}
}
else
}
else
guess_mv
(
s
);
guess_mv
(
s
);
/* the filters below are not XvMC compatible, skip them */
/* the filters below are not XvMC compatible, skip them */
if
(
CONFIG_MPEG_XVMC_DECODER
&&
s
->
avctx
->
xvmc_acceleration
)
if
(
CONFIG_MPEG_XVMC_DECODER
&&
s
->
avctx
->
xvmc_acceleration
)
goto
ec_clean
;
goto
ec_clean
;
/* fill DC for inter blocks */
/* fill DC for inter blocks */
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
int
dc
,
dcu
,
dcv
,
y
,
n
;
int
dc
,
dcu
,
dcv
,
y
,
n
;
int16_t
*
dc_ptr
;
int16_t
*
dc_ptr
;
uint8_t
*
dest_y
,
*
dest_cb
,
*
dest_cr
;
uint8_t
*
dest_y
,
*
dest_cb
,
*
dest_cr
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
IS_INTRA
(
mb_type
)
&&
s
->
partitioned_frame
)
continue
;
if
(
IS_INTRA
(
mb_type
)
&&
s
->
partitioned_frame
)
// if(error&ER_MV_ERROR) continue; //inter data damaged FIXME is this good?
continue
;
// if (error & ER_MV_ERROR)
// continue; // inter data damaged FIXME is this good?
dest_y
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
dest_y
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
dest_cb
=
s
->
current_picture
.
f
.
data
[
1
]
+
mb_x
*
8
+
mb_y
*
8
*
s
->
uvlinesize
;
dest_cb
=
s
->
current_picture
.
f
.
data
[
1
]
+
mb_x
*
8
+
mb_y
*
8
*
s
->
uvlinesize
;
dest_cr
=
s
->
current_picture
.
f
.
data
[
2
]
+
mb_x
*
8
+
mb_y
*
8
*
s
->
uvlinesize
;
dest_cr
=
s
->
current_picture
.
f
.
data
[
2
]
+
mb_x
*
8
+
mb_y
*
8
*
s
->
uvlinesize
;
dc_ptr
=
&
s
->
dc_val
[
0
][
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
];
dc_ptr
=
&
s
->
dc_val
[
0
][
mb_x
*
2
+
mb_y
*
2
*
s
->
b8_stride
];
for
(
n
=
0
;
n
<
4
;
n
++
)
{
for
(
n
=
0
;
n
<
4
;
n
++
)
{
dc
=
0
;
dc
=
0
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
y
=
0
;
y
<
8
;
y
++
)
{
int
x
;
int
x
;
for
(
x
=
0
;
x
<
8
;
x
++
){
for
(
x
=
0
;
x
<
8
;
x
++
)
dc
+=
dest_y
[
x
+
(
n
&
1
)
*
8
+
(
y
+
(
n
>>
1
)
*
8
)
*
s
->
linesize
];
dc
+=
dest_y
[
x
+
(
n
&
1
)
*
8
+
}
(
y
+
(
n
>>
1
)
*
8
)
*
s
->
linesize
];
}
}
dc_ptr
[(
n
&
1
)
+
(
n
>>
1
)
*
s
->
b8_stride
]
=
(
dc
+
4
)
>>
3
;
dc_ptr
[(
n
&
1
)
+
(
n
>>
1
)
*
s
->
b8_stride
]
=
(
dc
+
4
)
>>
3
;
}
}
dcu
=
dcv
=
0
;
dcu
=
dcv
=
0
;
for
(
y
=
0
;
y
<
8
;
y
++
)
{
for
(
y
=
0
;
y
<
8
;
y
++
)
{
int
x
;
int
x
;
for
(
x
=
0
;
x
<
8
;
x
++
)
{
for
(
x
=
0
;
x
<
8
;
x
++
)
{
dcu
+=
dest_cb
[
x
+
y
*
s
->
uvlinesize
];
dcu
+=
dest_cb
[
x
+
y
*
s
->
uvlinesize
];
dcv
+=
dest_cr
[
x
+
y
*
s
->
uvlinesize
];
dcv
+=
dest_cr
[
x
+
y
*
s
->
uvlinesize
];
}
}
}
}
s
->
dc_val
[
1
][
mb_x
+
mb_y
*
s
->
mb_stride
]
=
(
dcu
+
4
)
>>
3
;
s
->
dc_val
[
1
][
mb_x
+
mb_y
*
s
->
mb_stride
]
=
(
dcu
+
4
)
>>
3
;
s
->
dc_val
[
2
][
mb_x
+
mb_y
*
s
->
mb_stride
]
=
(
dcv
+
4
)
>>
3
;
s
->
dc_val
[
2
][
mb_x
+
mb_y
*
s
->
mb_stride
]
=
(
dcv
+
4
)
>>
3
;
}
}
}
}
/* guess DC for damaged blocks */
/* guess DC for damaged blocks */
guess_dc
(
s
,
s
->
dc_val
[
0
],
s
->
mb_width
*
2
,
s
->
mb_height
*
2
,
s
->
b8_stride
,
1
);
guess_dc
(
s
,
s
->
dc_val
[
0
],
s
->
mb_width
*
2
,
s
->
mb_height
*
2
,
s
->
b8_stride
,
1
);
guess_dc
(
s
,
s
->
dc_val
[
1
],
s
->
mb_width
,
s
->
mb_height
,
s
->
mb_stride
,
0
);
guess_dc
(
s
,
s
->
dc_val
[
1
],
s
->
mb_width
,
s
->
mb_height
,
s
->
mb_stride
,
0
);
guess_dc
(
s
,
s
->
dc_val
[
2
],
s
->
mb_width
,
s
->
mb_height
,
s
->
mb_stride
,
0
);
guess_dc
(
s
,
s
->
dc_val
[
2
],
s
->
mb_width
,
s
->
mb_height
,
s
->
mb_stride
,
0
);
/* filter luma DC */
/* filter luma DC */
filter181
(
s
->
dc_val
[
0
],
s
->
mb_width
*
2
,
s
->
mb_height
*
2
,
s
->
b8_stride
);
filter181
(
s
->
dc_val
[
0
],
s
->
mb_width
*
2
,
s
->
mb_height
*
2
,
s
->
b8_stride
);
/* render DC only intra */
/* render DC only intra */
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_y
=
0
;
mb_y
<
s
->
mb_height
;
mb_y
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
for
(
mb_x
=
0
;
mb_x
<
s
->
mb_width
;
mb_x
++
)
{
uint8_t
*
dest_y
,
*
dest_cb
,
*
dest_cr
;
uint8_t
*
dest_y
,
*
dest_cb
,
*
dest_cr
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_xy
=
mb_x
+
mb_y
*
s
->
mb_stride
;
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
const
int
mb_type
=
s
->
current_picture
.
f
.
mb_type
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
error
=
s
->
error_status_table
[
mb_xy
];
if
(
IS_INTER
(
mb_type
))
continue
;
if
(
IS_INTER
(
mb_type
))
if
(
!
(
error
&
ER_AC_ERROR
))
continue
;
//undamaged
continue
;
if
(
!
(
error
&
ER_AC_ERROR
))
continue
;
// undamaged
dest_y
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
dest_y
=
s
->
current_picture
.
f
.
data
[
0
]
+
mb_x
*
16
+
mb_y
*
16
*
s
->
linesize
;
dest_cb
=
s
->
current_picture
.
f
.
data
[
1
]
+
mb_x
*
8
+
mb_y
*
8
*
s
->
uvlinesize
;
dest_cb
=
s
->
current_picture
.
f
.
data
[
1
]
+
mb_x
*
8
+
mb_y
*
8
*
s
->
uvlinesize
;
...
@@ -1129,27 +1244,34 @@ void ff_er_frame_end(MpegEncContext *s){
...
@@ -1129,27 +1244,34 @@ void ff_er_frame_end(MpegEncContext *s){
}
}
}
}
if
(
s
->
avctx
->
error_concealment
&
FF_EC_DEBLOCK
)
{
if
(
s
->
avctx
->
error_concealment
&
FF_EC_DEBLOCK
)
{
/* filter horizontal block boundaries */
/* filter horizontal block boundaries */
h_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
0
],
s
->
mb_width
*
2
,
s
->
mb_height
*
2
,
s
->
linesize
,
1
);
h_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
0
],
s
->
mb_width
*
2
,
h_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
1
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
s
->
mb_height
*
2
,
s
->
linesize
,
1
);
h_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
2
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
h_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
1
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
h_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
2
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
/* filter vertical block boundaries */
/* filter vertical block boundaries */
v_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
0
],
s
->
mb_width
*
2
,
s
->
mb_height
*
2
,
s
->
linesize
,
1
);
v_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
0
],
s
->
mb_width
*
2
,
v_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
1
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
s
->
mb_height
*
2
,
s
->
linesize
,
1
);
v_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
2
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
v_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
1
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
v_block_filter
(
s
,
s
->
current_picture
.
f
.
data
[
2
],
s
->
mb_width
,
s
->
mb_height
,
s
->
uvlinesize
,
0
);
}
}
ec_clean:
ec_clean:
/* clean a few tables */
/* clean a few tables */
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
for
(
i
=
0
;
i
<
s
->
mb_num
;
i
++
)
{
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
const
int
mb_xy
=
s
->
mb_index2xy
[
i
];
int
error
=
s
->
error_status_table
[
mb_xy
];
int
error
=
s
->
error_status_table
[
mb_xy
];
if
(
s
->
pict_type
!=
AV_PICTURE_TYPE_B
&&
(
error
&
(
ER_DC_ERROR
|
ER_MV_ERROR
|
ER_AC_ERROR
))){
if
(
s
->
pict_type
!=
AV_PICTURE_TYPE_B
&&
s
->
mbskip_table
[
mb_xy
]
=
0
;
(
error
&
(
ER_DC_ERROR
|
ER_MV_ERROR
|
ER_AC_ERROR
)))
{
s
->
mbskip_table
[
mb_xy
]
=
0
;
}
}
s
->
mbintra_table
[
mb_xy
]
=
1
;
s
->
mbintra_table
[
mb_xy
]
=
1
;
}
}
}
}
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