Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
aom-rav1e
Commits
8565a1c9
Commit
8565a1c9
authored
Jul 02, 2015
by
Jingning Han
Committed by
Gerrit Code Review
Jul 02, 2015
Browse files
Merge "Use vpx prefix for codec independent threading functions"
parents
66cf8098
04d2e574
Changes
15
Hide whitespace changes
Inline
Side-by-side
test/vp9_thread_test.cc
View file @
8565a1c9
...
...
@@ -24,27 +24,27 @@ namespace {
using
std
::
string
;
class
VP
9
WorkerThreadTest
:
public
::
testing
::
TestWithParam
<
bool
>
{
class
VP
x
WorkerThreadTest
:
public
::
testing
::
TestWithParam
<
bool
>
{
protected:
virtual
~
VP
9
WorkerThreadTest
()
{}
virtual
~
VP
x
WorkerThreadTest
()
{}
virtual
void
SetUp
()
{
vp
9
_get_worker_interface
()
->
init
(
&
worker_
);
vp
x
_get_worker_interface
()
->
init
(
&
worker_
);
}
virtual
void
TearDown
()
{
vp
9
_get_worker_interface
()
->
end
(
&
worker_
);
vp
x
_get_worker_interface
()
->
end
(
&
worker_
);
}
void
Run
(
VP
9
Worker
*
worker
)
{
void
Run
(
VP
x
Worker
*
worker
)
{
const
bool
synchronous
=
GetParam
();
if
(
synchronous
)
{
vp
9
_get_worker_interface
()
->
execute
(
worker
);
vp
x
_get_worker_interface
()
->
execute
(
worker
);
}
else
{
vp
9
_get_worker_interface
()
->
launch
(
worker
);
vp
x
_get_worker_interface
()
->
launch
(
worker
);
}
}
VP
9
Worker
worker_
;
VP
x
Worker
worker_
;
};
int
ThreadHook
(
void
*
data
,
void
*
return_value
)
{
...
...
@@ -53,12 +53,12 @@ int ThreadHook(void* data, void* return_value) {
return
*
reinterpret_cast
<
int
*>
(
return_value
);
}
TEST_P
(
VP
9
WorkerThreadTest
,
HookSuccess
)
{
TEST_P
(
VP
x
WorkerThreadTest
,
HookSuccess
)
{
// should be a no-op.
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
reset
(
&
worker_
),
0
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
reset
(
&
worker_
),
0
);
int
hook_data
=
0
;
int
return_value
=
1
;
// return successfully from the hook
...
...
@@ -67,17 +67,17 @@ TEST_P(VP9WorkerThreadTest, HookSuccess) {
worker_
.
data2
=
&
return_value
;
Run
(
&
worker_
);
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
EXPECT_FALSE
(
worker_
.
had_error
);
EXPECT_EQ
(
5
,
hook_data
);
// should be a no-op.
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
}
}
TEST_P
(
VP
9
WorkerThreadTest
,
HookFailure
)
{
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
reset
(
&
worker_
),
0
);
TEST_P
(
VP
x
WorkerThreadTest
,
HookFailure
)
{
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
reset
(
&
worker_
),
0
);
int
hook_data
=
0
;
int
return_value
=
0
;
// return failure from the hook
...
...
@@ -86,29 +86,29 @@ TEST_P(VP9WorkerThreadTest, HookFailure) {
worker_
.
data2
=
&
return_value
;
Run
(
&
worker_
);
EXPECT_FALSE
(
vp
9
_get_worker_interface
()
->
sync
(
&
worker_
));
EXPECT_FALSE
(
vp
x
_get_worker_interface
()
->
sync
(
&
worker_
));
EXPECT_EQ
(
1
,
worker_
.
had_error
);
// Ensure _reset() clears the error and _launch() can be called again.
return_value
=
1
;
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
reset
(
&
worker_
),
0
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
reset
(
&
worker_
),
0
);
EXPECT_FALSE
(
worker_
.
had_error
);
vp
9
_get_worker_interface
()
->
launch
(
&
worker_
);
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
vp
x
_get_worker_interface
()
->
launch
(
&
worker_
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
sync
(
&
worker_
),
0
);
EXPECT_FALSE
(
worker_
.
had_error
);
}
TEST_P
(
VP
9
WorkerThreadTest
,
EndWithoutSync
)
{
TEST_P
(
VP
x
WorkerThreadTest
,
EndWithoutSync
)
{
// Create a large number of threads to increase the chances of detecting a
// race. Doing more work in the hook is no guarantee as any race would occur
// post hook execution in the main thread loop driver.
static
const
int
kNumWorkers
=
64
;
VP
9
Worker
workers
[
kNumWorkers
];
VP
x
Worker
workers
[
kNumWorkers
];
int
hook_data
[
kNumWorkers
];
int
return_value
[
kNumWorkers
];
for
(
int
n
=
0
;
n
<
kNumWorkers
;
++
n
)
{
vp
9
_get_worker_interface
()
->
init
(
&
workers
[
n
]);
vp
x
_get_worker_interface
()
->
init
(
&
workers
[
n
]);
return_value
[
n
]
=
1
;
// return successfully from the hook
workers
[
n
].
hook
=
ThreadHook
;
workers
[
n
].
data1
=
&
hook_data
[
n
];
...
...
@@ -117,7 +117,7 @@ TEST_P(VP9WorkerThreadTest, EndWithoutSync) {
for
(
int
i
=
0
;
i
<
2
;
++
i
)
{
for
(
int
n
=
0
;
n
<
kNumWorkers
;
++
n
)
{
EXPECT_NE
(
vp
9
_get_worker_interface
()
->
reset
(
&
workers
[
n
]),
0
);
EXPECT_NE
(
vp
x
_get_worker_interface
()
->
reset
(
&
workers
[
n
]),
0
);
hook_data
[
n
]
=
0
;
}
...
...
@@ -126,16 +126,16 @@ TEST_P(VP9WorkerThreadTest, EndWithoutSync) {
}
for
(
int
n
=
kNumWorkers
-
1
;
n
>=
0
;
--
n
)
{
vp
9
_get_worker_interface
()
->
end
(
&
workers
[
n
]);
vp
x
_get_worker_interface
()
->
end
(
&
workers
[
n
]);
}
}
}
TEST
(
VP
9
WorkerThreadTest
,
TestInterfaceAPI
)
{
EXPECT_EQ
(
0
,
vp
9
_set_worker_interface
(
NULL
));
EXPECT_TRUE
(
vp
9
_get_worker_interface
()
!=
NULL
);
TEST
(
VP
x
WorkerThreadTest
,
TestInterfaceAPI
)
{
EXPECT_EQ
(
0
,
vp
x
_set_worker_interface
(
NULL
));
EXPECT_TRUE
(
vp
x
_get_worker_interface
()
!=
NULL
);
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
VP
9
WorkerInterface
winterface
=
*
vp
9
_get_worker_interface
();
VP
x
WorkerInterface
winterface
=
*
vp
x
_get_worker_interface
();
switch
(
i
)
{
default:
case
0
:
winterface
.
init
=
NULL
;
break
;
...
...
@@ -145,7 +145,7 @@ TEST(VP9WorkerThreadTest, TestInterfaceAPI) {
case
4
:
winterface
.
execute
=
NULL
;
break
;
case
5
:
winterface
.
end
=
NULL
;
break
;
}
EXPECT_EQ
(
0
,
vp
9
_set_worker_interface
(
&
winterface
));
EXPECT_EQ
(
0
,
vp
x
_set_worker_interface
(
&
winterface
));
}
}
...
...
@@ -202,21 +202,21 @@ void DecodeFiles(const FileList files[]) {
// hang.
namespace
impl
{
void
Init
(
VP
9
Worker
*
const
worker
)
{
memset
(
worker
,
0
,
sizeof
(
*
worker
));
}
int
Reset
(
VP
9
Worker
*
const
/*worker*/
)
{
return
1
;
}
int
Sync
(
VP
9
Worker
*
const
worker
)
{
return
!
worker
->
had_error
;
}
void
Init
(
VP
x
Worker
*
const
worker
)
{
memset
(
worker
,
0
,
sizeof
(
*
worker
));
}
int
Reset
(
VP
x
Worker
*
const
/*worker*/
)
{
return
1
;
}
int
Sync
(
VP
x
Worker
*
const
worker
)
{
return
!
worker
->
had_error
;
}
void
Execute
(
VP
9
Worker
*
const
worker
)
{
void
Execute
(
VP
x
Worker
*
const
worker
)
{
worker
->
had_error
|=
!
worker
->
hook
(
worker
->
data1
,
worker
->
data2
);
}
void
Launch
(
VP
9
Worker
*
const
worker
)
{
Execute
(
worker
);
}
void
End
(
VP
9
Worker
*
const
/*worker*/
)
{}
void
Launch
(
VP
x
Worker
*
const
worker
)
{
Execute
(
worker
);
}
void
End
(
VP
x
Worker
*
const
/*worker*/
)
{}
}
// namespace impl
TEST
(
VP
9
WorkerThreadTest
,
TestSerialInterface
)
{
static
const
VP
9
WorkerInterface
serial_interface
=
{
TEST
(
VP
x
WorkerThreadTest
,
TestSerialInterface
)
{
static
const
VP
x
WorkerInterface
serial_interface
=
{
impl
::
Init
,
impl
::
Reset
,
impl
::
Sync
,
impl
::
Launch
,
impl
::
Execute
,
impl
::
End
};
// TODO(jzern): Avoid using a file that will use the row-based thread
...
...
@@ -225,13 +225,13 @@ TEST(VP9WorkerThreadTest, TestSerialInterface) {
// progress in the row above before proceeding.
static
const
char
expected_md5
[]
=
"b35a1b707b28e82be025d960aba039bc"
;
static
const
char
filename
[]
=
"vp90-2-03-size-226x226.webm"
;
VP
9
WorkerInterface
default_interface
=
*
vp
9
_get_worker_interface
();
VP
x
WorkerInterface
default_interface
=
*
vp
x
_get_worker_interface
();
EXPECT_NE
(
vp
9
_set_worker_interface
(
&
serial_interface
),
0
);
EXPECT_NE
(
vp
x
_set_worker_interface
(
&
serial_interface
),
0
);
EXPECT_EQ
(
expected_md5
,
DecodeFile
(
filename
,
2
));
// Reset the interface.
EXPECT_NE
(
vp
9
_set_worker_interface
(
&
default_interface
),
0
);
EXPECT_NE
(
vp
x
_set_worker_interface
(
&
default_interface
),
0
);
EXPECT_EQ
(
expected_md5
,
DecodeFile
(
filename
,
2
));
}
...
...
@@ -309,6 +309,6 @@ TEST(VP9DecodeMultiThreadedTest, Decode3) {
}
#endif // CONFIG_WEBM_IO
INSTANTIATE_TEST_CASE_P
(
Synchronous
,
VP
9
WorkerThreadTest
,
::
testing
::
Bool
());
INSTANTIATE_TEST_CASE_P
(
Synchronous
,
VP
x
WorkerThreadTest
,
::
testing
::
Bool
());
}
// namespace
vp9/common/vp9_onyxc_int.h
View file @
8565a1c9
...
...
@@ -80,7 +80,7 @@ typedef struct {
// frame_worker_owner indicates which FrameWorker owns this buffer. NULL means
// that no FrameWorker owns, or is decoding, this buffer.
VP
9
Worker
*
frame_worker_owner
;
VP
x
Worker
*
frame_worker_owner
;
// row and col indicate which position frame has been decoded to in real
// pixel unit. They are reset to -1 when decoding begins and set to INT_MAX
...
...
vp9/common/vp9_thread_common.c
View file @
8565a1c9
...
...
@@ -157,9 +157,9 @@ static void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame,
VP9_COMMON
*
cm
,
struct
macroblockd_plane
planes
[
MAX_MB_PLANE
],
int
start
,
int
stop
,
int
y_only
,
VP
9
Worker
*
workers
,
int
nworkers
,
VP
x
Worker
*
workers
,
int
nworkers
,
VP9LfSync
*
lf_sync
)
{
const
VP
9
WorkerInterface
*
const
winterface
=
vp
9
_get_worker_interface
();
const
VP
x
WorkerInterface
*
const
winterface
=
vp
x
_get_worker_interface
();
// Number of superblock rows and cols
const
int
sb_rows
=
mi_cols_aligned_to_sb
(
cm
->
mi_rows
)
>>
MI_BLOCK_SIZE_LOG2
;
// Decoder may allocate more threads than number of tiles based on user's
...
...
@@ -186,10 +186,10 @@ static void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame,
// because of contention. If the multithreading code changes in the future
// then the number of workers used by the loopfilter should be revisited.
for
(
i
=
0
;
i
<
num_workers
;
++
i
)
{
VP
9
Worker
*
const
worker
=
&
workers
[
i
];
VP
x
Worker
*
const
worker
=
&
workers
[
i
];
LFWorkerData
*
const
lf_data
=
&
lf_sync
->
lfdata
[
i
];
worker
->
hook
=
(
VP
9
WorkerHook
)
loop_filter_row_worker
;
worker
->
hook
=
(
VP
x
WorkerHook
)
loop_filter_row_worker
;
worker
->
data1
=
lf_sync
;
worker
->
data2
=
lf_data
;
...
...
@@ -218,7 +218,7 @@ void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame,
struct
macroblockd_plane
planes
[
MAX_MB_PLANE
],
int
frame_filter_level
,
int
y_only
,
int
partial_frame
,
VP
9
Worker
*
workers
,
int
num_workers
,
VP
x
Worker
*
workers
,
int
num_workers
,
VP9LfSync
*
lf_sync
)
{
int
start_mi_row
,
end_mi_row
,
mi_rows_to_filter
;
...
...
vp9/common/vp9_thread_common.h
View file @
8565a1c9
...
...
@@ -48,7 +48,7 @@ void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame,
struct
macroblockd_plane
planes
[
MAX_MB_PLANE
],
int
frame_filter_level
,
int
y_only
,
int
partial_frame
,
VP
9
Worker
*
workers
,
int
num_workers
,
VP
x
Worker
*
workers
,
int
num_workers
,
VP9LfSync
*
lf_sync
);
void
vp9_accumulate_frame_counts
(
struct
VP9Common
*
cm
,
...
...
vp9/decoder/vp9_decodeframe.c
View file @
8565a1c9
...
...
@@ -1259,7 +1259,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
const
uint8_t
*
data
,
const
uint8_t
*
data_end
)
{
VP9_COMMON
*
const
cm
=
&
pbi
->
common
;
const
VP
9
WorkerInterface
*
const
winterface
=
vp
9
_get_worker_interface
();
const
VP
x
WorkerInterface
*
const
winterface
=
vp
x
_get_worker_interface
();
const
int
aligned_cols
=
mi_cols_aligned_to_sb
(
cm
->
mi_cols
);
const
int
tile_cols
=
1
<<
cm
->
log2_tile_cols
;
const
int
tile_rows
=
1
<<
cm
->
log2_tile_rows
;
...
...
@@ -1272,7 +1272,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
pbi
->
lf_worker
.
data1
==
NULL
)
{
CHECK_MEM_ERROR
(
cm
,
pbi
->
lf_worker
.
data1
,
vpx_memalign
(
32
,
sizeof
(
LFWorkerData
)));
pbi
->
lf_worker
.
hook
=
(
VP
9
WorkerHook
)
vp9_loop_filter_worker
;
pbi
->
lf_worker
.
hook
=
(
VP
x
WorkerHook
)
vp9_loop_filter_worker
;
if
(
pbi
->
max_threads
>
1
&&
!
winterface
->
reset
(
&
pbi
->
lf_worker
))
{
vpx_internal_error
(
&
cm
->
error
,
VPX_CODEC_ERROR
,
"Loop filter thread creation failed"
);
...
...
@@ -1434,7 +1434,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
const
uint8_t
*
data
,
const
uint8_t
*
data_end
)
{
VP9_COMMON
*
const
cm
=
&
pbi
->
common
;
const
VP
9
WorkerInterface
*
const
winterface
=
vp
9
_get_worker_interface
();
const
VP
x
WorkerInterface
*
const
winterface
=
vp
x
_get_worker_interface
();
const
uint8_t
*
bit_reader_end
=
NULL
;
const
int
aligned_mi_cols
=
mi_cols_aligned_to_sb
(
cm
->
mi_cols
);
const
int
tile_cols
=
1
<<
cm
->
log2_tile_cols
;
...
...
@@ -1464,7 +1464,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
CHECK_MEM_ERROR
(
cm
,
pbi
->
tile_worker_info
,
vpx_malloc
(
num_threads
*
sizeof
(
*
pbi
->
tile_worker_info
)));
for
(
i
=
0
;
i
<
num_threads
;
++
i
)
{
VP
9
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
];
VP
x
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
];
++
pbi
->
num_tile_workers
;
winterface
->
init
(
worker
);
...
...
@@ -1477,9 +1477,9 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
// Reset tile decoding hook
for
(
n
=
0
;
n
<
num_workers
;
++
n
)
{
VP
9
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
n
];
VP
x
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
n
];
winterface
->
sync
(
worker
);
worker
->
hook
=
(
VP
9
WorkerHook
)
tile_worker_hook
;
worker
->
hook
=
(
VP
x
WorkerHook
)
tile_worker_hook
;
worker
->
data1
=
&
pbi
->
tile_worker_data
[
n
];
worker
->
data2
=
&
pbi
->
tile_worker_info
[
n
];
}
...
...
@@ -1529,7 +1529,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
while
(
n
<
tile_cols
)
{
int
i
;
for
(
i
=
0
;
i
<
num_workers
&&
n
<
tile_cols
;
++
i
)
{
VP
9
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
];
VP
x
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
];
TileWorkerData
*
const
tile_data
=
(
TileWorkerData
*
)
worker
->
data1
;
TileInfo
*
const
tile
=
(
TileInfo
*
)
worker
->
data2
;
TileBuffer
*
const
buf
=
&
tile_buffers
[
0
][
n
];
...
...
@@ -1561,7 +1561,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
}
for
(;
i
>
0
;
--
i
)
{
VP
9
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
-
1
];
VP
x
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
-
1
];
// TODO(jzern): The tile may have specific error data associated with
// its vpx_internal_error_info which could be propagated to the main info
// in cm. Additionally once the threads have been synced and an error is
...
...
@@ -2020,7 +2020,7 @@ void vp9_decode_frame(VP9Decoder *pbi,
// If encoded in frame parallel mode, frame context is ready after decoding
// the frame header.
if
(
pbi
->
frame_parallel_decode
&&
cm
->
frame_parallel_decoding_mode
)
{
VP
9
Worker
*
const
worker
=
pbi
->
frame_worker_owner
;
VP
x
Worker
*
const
worker
=
pbi
->
frame_worker_owner
;
FrameWorkerData
*
const
frame_worker_data
=
worker
->
data1
;
if
(
cm
->
refresh_frame_context
)
{
context_updated
=
1
;
...
...
vp9/decoder/vp9_decoder.c
View file @
8565a1c9
...
...
@@ -118,7 +118,7 @@ VP9Decoder *vp9_decoder_create(BufferPool *const pool) {
cm
->
error
.
setjmp
=
0
;
vp
9
_get_worker_interface
()
->
init
(
&
pbi
->
lf_worker
);
vp
x
_get_worker_interface
()
->
init
(
&
pbi
->
lf_worker
);
return
pbi
;
}
...
...
@@ -126,12 +126,12 @@ VP9Decoder *vp9_decoder_create(BufferPool *const pool) {
void
vp9_decoder_remove
(
VP9Decoder
*
pbi
)
{
int
i
;
vp
9
_get_worker_interface
()
->
end
(
&
pbi
->
lf_worker
);
vp
x
_get_worker_interface
()
->
end
(
&
pbi
->
lf_worker
);
vpx_free
(
pbi
->
lf_worker
.
data1
);
vpx_free
(
pbi
->
tile_data
);
for
(
i
=
0
;
i
<
pbi
->
num_tile_workers
;
++
i
)
{
VP
9
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
];
vp
9
_get_worker_interface
()
->
end
(
worker
);
VP
x
Worker
*
const
worker
=
&
pbi
->
tile_workers
[
i
];
vp
x
_get_worker_interface
()
->
end
(
worker
);
}
vpx_free
(
pbi
->
tile_worker_data
);
vpx_free
(
pbi
->
tile_worker_info
);
...
...
@@ -311,7 +311,7 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
pbi
->
hold_ref_buf
=
0
;
if
(
pbi
->
frame_parallel_decode
)
{
VP
9
Worker
*
const
worker
=
pbi
->
frame_worker_owner
;
VP
x
Worker
*
const
worker
=
pbi
->
frame_worker_owner
;
vp9_frameworker_lock_stats
(
worker
);
frame_bufs
[
cm
->
new_fb_idx
].
frame_worker_owner
=
worker
;
// Reset decoding progress.
...
...
@@ -325,7 +325,7 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
if
(
setjmp
(
cm
->
error
.
jmp
))
{
const
VP
9
WorkerInterface
*
const
winterface
=
vp
9
_get_worker_interface
();
const
VP
x
WorkerInterface
*
const
winterface
=
vp
x
_get_worker_interface
();
int
i
;
cm
->
error
.
setjmp
=
0
;
...
...
@@ -387,7 +387,7 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
if
(
pbi
->
frame_parallel_decode
)
{
// Need to lock the mutex here as another thread may
// be accessing this buffer.
VP
9
Worker
*
const
worker
=
pbi
->
frame_worker_owner
;
VP
x
Worker
*
const
worker
=
pbi
->
frame_worker_owner
;
FrameWorkerData
*
const
frame_worker_data
=
worker
->
data1
;
vp9_frameworker_lock_stats
(
worker
);
...
...
vp9/decoder/vp9_decoder.h
View file @
8565a1c9
...
...
@@ -57,9 +57,9 @@ typedef struct VP9Decoder {
// the same.
RefCntBuffer
*
cur_buf
;
// Current decoding frame buffer.
VP
9
Worker
*
frame_worker_owner
;
// frame_worker that owns this pbi.
VP
9
Worker
lf_worker
;
VP
9
Worker
*
tile_workers
;
VP
x
Worker
*
frame_worker_owner
;
// frame_worker that owns this pbi.
VP
x
Worker
lf_worker
;
VP
x
Worker
*
tile_workers
;
TileWorkerData
*
tile_worker_data
;
TileInfo
*
tile_worker_info
;
int
num_tile_workers
;
...
...
vp9/decoder/vp9_dthread.c
View file @
8565a1c9
...
...
@@ -17,7 +17,7 @@
// #define DEBUG_THREAD
// TODO(hkuang): Clean up all the #ifdef in this file.
void
vp9_frameworker_lock_stats
(
VP
9
Worker
*
const
worker
)
{
void
vp9_frameworker_lock_stats
(
VP
x
Worker
*
const
worker
)
{
#if CONFIG_MULTITHREAD
FrameWorkerData
*
const
worker_data
=
worker
->
data1
;
pthread_mutex_lock
(
&
worker_data
->
stats_mutex
);
...
...
@@ -26,7 +26,7 @@ void vp9_frameworker_lock_stats(VP9Worker *const worker) {
#endif
}
void
vp9_frameworker_unlock_stats
(
VP
9
Worker
*
const
worker
)
{
void
vp9_frameworker_unlock_stats
(
VP
x
Worker
*
const
worker
)
{
#if CONFIG_MULTITHREAD
FrameWorkerData
*
const
worker_data
=
worker
->
data1
;
pthread_mutex_unlock
(
&
worker_data
->
stats_mutex
);
...
...
@@ -35,7 +35,7 @@ void vp9_frameworker_unlock_stats(VP9Worker *const worker) {
#endif
}
void
vp9_frameworker_signal_stats
(
VP
9
Worker
*
const
worker
)
{
void
vp9_frameworker_signal_stats
(
VP
x
Worker
*
const
worker
)
{
#if CONFIG_MULTITHREAD
FrameWorkerData
*
const
worker_data
=
worker
->
data1
;
...
...
@@ -59,7 +59,7 @@ void vp9_frameworker_signal_stats(VP9Worker *const worker) {
#endif
// TODO(hkuang): Remove worker parameter as it is only used in debug code.
void
vp9_frameworker_wait
(
VP
9
Worker
*
const
worker
,
RefCntBuffer
*
const
ref_buf
,
void
vp9_frameworker_wait
(
VP
x
Worker
*
const
worker
,
RefCntBuffer
*
const
ref_buf
,
int
row
)
{
#if CONFIG_MULTITHREAD
if
(
!
ref_buf
)
...
...
@@ -74,7 +74,7 @@ void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
{
// Find the worker thread that owns the reference frame. If the reference
// frame has been fully decoded, it may not have owner.
VP
9
Worker
*
const
ref_worker
=
ref_buf
->
frame_worker_owner
;
VP
x
Worker
*
const
ref_worker
=
ref_buf
->
frame_worker_owner
;
FrameWorkerData
*
const
ref_worker_data
=
(
FrameWorkerData
*
)
ref_worker
->
data1
;
const
VP9Decoder
*
const
pbi
=
ref_worker_data
->
pbi
;
...
...
@@ -114,7 +114,7 @@ void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
void
vp9_frameworker_broadcast
(
RefCntBuffer
*
const
buf
,
int
row
)
{
#if CONFIG_MULTITHREAD
VP
9
Worker
*
worker
=
buf
->
frame_worker_owner
;
VP
x
Worker
*
worker
=
buf
->
frame_worker_owner
;
#ifdef DEBUG_THREAD
{
...
...
@@ -134,8 +134,8 @@ void vp9_frameworker_broadcast(RefCntBuffer *const buf, int row) {
#endif // CONFIG_MULTITHREAD
}
void
vp9_frameworker_copy_context
(
VP
9
Worker
*
const
dst_worker
,
VP
9
Worker
*
const
src_worker
)
{
void
vp9_frameworker_copy_context
(
VP
x
Worker
*
const
dst_worker
,
VP
x
Worker
*
const
src_worker
)
{
#if CONFIG_MULTITHREAD
FrameWorkerData
*
const
src_worker_data
=
(
FrameWorkerData
*
)
src_worker
->
data1
;
FrameWorkerData
*
const
dst_worker_data
=
(
FrameWorkerData
*
)
dst_worker
->
data1
;
...
...
vp9/decoder/vp9_dthread.h
View file @
8565a1c9
...
...
@@ -44,15 +44,15 @@ typedef struct FrameWorkerData {
int
frame_decoded
;
// Finished decoding current frame.
}
FrameWorkerData
;
void
vp9_frameworker_lock_stats
(
VP
9
Worker
*
const
worker
);
void
vp9_frameworker_unlock_stats
(
VP
9
Worker
*
const
worker
);
void
vp9_frameworker_signal_stats
(
VP
9
Worker
*
const
worker
);
void
vp9_frameworker_lock_stats
(
VP
x
Worker
*
const
worker
);
void
vp9_frameworker_unlock_stats
(
VP
x
Worker
*
const
worker
);
void
vp9_frameworker_signal_stats
(
VP
x
Worker
*
const
worker
);
// Wait until ref_buf has been decoded to row in real pixel unit.
// Note: worker may already finish decoding ref_buf and release it in order to
// start decoding next frame. So need to check whether worker is still decoding
// ref_buf.
void
vp9_frameworker_wait
(
VP
9
Worker
*
const
worker
,
RefCntBuffer
*
const
ref_buf
,
void
vp9_frameworker_wait
(
VP
x
Worker
*
const
worker
,
RefCntBuffer
*
const
ref_buf
,
int
row
);
// FrameWorker broadcasts its decoding progress so other workers that are
...
...
@@ -60,7 +60,7 @@ void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
void
vp9_frameworker_broadcast
(
RefCntBuffer
*
const
buf
,
int
row
);
// Copy necessary decoding context from src worker to dst worker.
void
vp9_frameworker_copy_context
(
VP
9
Worker
*
const
dst_worker
,
VP
9
Worker
*
const
src_worker
);
void
vp9_frameworker_copy_context
(
VP
x
Worker
*
const
dst_worker
,
VP
x
Worker
*
const
src_worker
);
#endif // VP9_DECODER_VP9_DTHREAD_H_
vp9/encoder/vp9_encoder.c
View file @
8565a1c9
...
...
@@ -2013,11 +2013,11 @@ void vp9_remove_compressor(VP9_COMP *cpi) {
#endif
for
(
t
=
0
;
t
<
cpi
->
num_workers
;
++
t
)
{
VP
9
Worker
*
const
worker
=
&
cpi
->
workers
[
t
];
VP
x
Worker
*
const
worker
=
&
cpi
->
workers
[
t
];
EncWorkerData
*
const
thread_data
=
&
cpi
->
tile_thr_data
[
t
];
// Deallocate allocated threads.
vp
9
_get_worker_interface
()
->
end
(
worker
);
vp
x
_get_worker_interface
()
->
end
(
worker
);
// Deallocate allocated thread data.
if
(
t
<
cpi
->
num_workers
-
1
)
{
...
...
vp9/encoder/vp9_encoder.h
View file @
8565a1c9
...
...
@@ -497,7 +497,7 @@ typedef struct VP9_COMP {
// Multi-threading
int
num_workers
;
VP
9
Worker
*
workers
;
VP
x
Worker
*
workers
;
struct
EncWorkerData
*
tile_thr_data
;
VP9LfSync
lf_row_sync
;
}
VP9_COMP
;
...
...
vp9/encoder/vp9_ethread.c
View file @
8565a1c9
...
...
@@ -69,7 +69,7 @@ static int get_max_tile_cols(VP9_COMP *cpi) {
void
vp9_encode_tiles_mt
(
VP9_COMP
*
cpi
)
{
VP9_COMMON
*
const
cm
=
&
cpi
->
common
;
const
int
tile_cols
=
1
<<
cm
->
log2_tile_cols
;
const
VP
9
WorkerInterface
*
const
winterface
=
vp
9
_get_worker_interface
();
const
VP
x
WorkerInterface
*
const
winterface
=
vp
x
_get_worker_interface
();
const
int
num_workers
=
MIN
(
cpi
->
oxcf
.
max_threads
,
tile_cols
);
int
i
;
...
...
@@ -94,7 +94,7 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
sizeof
(
*
cpi
->
tile_thr_data
)));
for
(
i
=
0
;
i
<
allocated_workers
;
i
++
)
{
VP
9
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
VP
x
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
EncWorkerData
*
thread_data
=
&
cpi
->
tile_thr_data
[
i
];
++
cpi
->
num_workers
;
...
...
@@ -132,10 +132,10 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
}
for
(
i
=
0
;
i
<
num_workers
;
i
++
)
{
VP
9
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
VP
x
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
EncWorkerData
*
thread_data
;
worker
->
hook
=
(
VP
9
WorkerHook
)
enc_worker_hook
;
worker
->
hook
=
(
VP
x
WorkerHook
)
enc_worker_hook
;
worker
->
data1
=
&
cpi
->
tile_thr_data
[
i
];
worker
->
data2
=
NULL
;
thread_data
=
(
EncWorkerData
*
)
worker
->
data1
;
...
...
@@ -170,7 +170,7 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
// Encode a frame
for
(
i
=
0
;
i
<
num_workers
;
i
++
)
{
VP
9
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
VP
x
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
EncWorkerData
*
const
thread_data
=
(
EncWorkerData
*
)
worker
->
data1
;
// Set the starting tile for each thread.
...
...
@@ -184,12 +184,12 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
// Encoding ends.
for
(
i
=
0
;
i
<
num_workers
;
i
++
)
{
VP
9
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
VP
x
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
winterface
->
sync
(
worker
);
}
for
(
i
=
0
;
i
<
num_workers
;
i
++
)
{
VP
9
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
VP
x
Worker
*
const
worker
=
&
cpi
->
workers
[
i
];
EncWorkerData
*
const
thread_data
=
(
EncWorkerData
*
)
worker
->
data1
;
// Accumulate counters.
...
...
vp9/vp9_dx_iface.c
View file @
8565a1c9
...
...
@@ -59,7 +59,7 @@ struct vpx_codec_alg_priv {
// Frame parallel related.
int
frame_parallel_decode
;
// frame-based threading.
VP
9
Worker
*
frame_workers
;
VP
x
Worker
*
frame_workers
;
int
num_frame_workers
;
int
next_submit_worker_id
;
int
last_submit_worker_id
;
...
...
@@ -112,10 +112,10 @@ static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
if
(
ctx
->
frame_workers
!=
NULL
)
{
int
i
;
for
(
i
=
0
;
i
<
ctx
->
num_frame_workers
;
++
i
)
{
VP
9
Worker
*
const
worker
=
&
ctx
->
frame_workers
[
i
];
VP
x
Worker
*
const
worker
=
&
ctx
->
frame_workers
[
i
];
FrameWorkerData
*
const
frame_worker_data
=
(
FrameWorkerData
*
)
worker
->
data1
;
vp
9
_get_worker_interface
()
->
end
(
worker
);
vp
x
_get_worker_interface
()
->
end
(
worker
);
vp9_remove_common
(
&
frame_worker_data
->
pbi
->
common
);
#if CONFIG_VP9_POSTPROC
vp9_free_postproc_buffers
(
&
frame_worker_data
->
pbi
->
common
);
...
...
@@ -279,7 +279,7 @@ static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
int
i
;
for
(
i
=
0
;
i
<
ctx
->
num_frame_workers
;
++
i
)
{
VP
9
Worker
*
const
worker
=
&
ctx
->
frame_workers
[
i
];
VP
x
Worker
*
const
worker
=
&
ctx
->
frame_workers
[
i
];
FrameWorkerData
*
const
frame_worker_data
=
(
FrameWorkerData
*
)
worker
->
data1
;
VP9_COMMON
*
const
cm
=
&
frame_worker_data
->
pbi
->
common
;
BufferPool
*
const
pool
=
cm
->
buffer_pool
;
...
...
@@ -336,7 +336,7 @@ static int frame_worker_hook(void *arg1, void *arg2) {
// the compressed data.
if
(
frame_worker_data
->
result
!=
0
||
frame_worker_data
->
data
+
frame_worker_data
->
data_size
-
1
>
data
)
{
VP
9
Worker
*
const
worker
=
frame_worker_data
->
pbi
->
frame_worker_owner
;
VP
x
Worker
*
const
worker
=
frame_worker_data
->
pbi
->
frame_worker_owner
;
BufferPool
*
const
pool
=
frame_worker_data
->
pbi
->
common
.
buffer_pool
;
// Signal all the other threads that are waiting for this frame.
vp9_frameworker_lock_stats
(
worker
);
...