Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
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