Fix 10-bit video decode failure with --frame-parallel mode.

Also add unit test to avoid same error in the future.

Issue:981

Change-Id: Iaf9889d8d5514cfdff1ea098e6ae133be56d501f
This commit is contained in:
hkuang
2015-03-26 17:37:17 -07:00
parent 1c39c5b96f
commit 1582ac851f
2 changed files with 38 additions and 23 deletions

View File

@@ -29,7 +29,7 @@ using std::string;
#if CONFIG_WEBM_IO #if CONFIG_WEBM_IO
struct FileList { struct PauseFileList {
const char *name; const char *name;
// md5 sum for decoded frames which does not include skipped frames. // md5 sum for decoded frames which does not include skipped frames.
const char *expected_md5; const char *expected_md5;
@@ -39,7 +39,8 @@ struct FileList {
// Decodes |filename| with |num_threads|. Pause at the specified frame_num, // Decodes |filename| with |num_threads|. Pause at the specified frame_num,
// seek to next key frame and then continue decoding until the end. Return // seek to next key frame and then continue decoding until the end. Return
// the md5 of the decoded frames which does not include skipped frames. // the md5 of the decoded frames which does not include skipped frames.
string DecodeFile(const string &filename, int num_threads, int pause_num) { string DecodeFileWithPause(const string &filename, int num_threads,
int pause_num) {
libvpx_test::WebMVideoSource video(filename); libvpx_test::WebMVideoSource video(filename);
video.Init(); video.Init();
int in_frames = 0; int in_frames = 0;
@@ -92,12 +93,12 @@ string DecodeFile(const string &filename, int num_threads, int pause_num) {
return string(md5.Get()); return string(md5.Get());
} }
void DecodeFiles(const FileList files[]) { void DecodeFilesWithPause(const PauseFileList files[]) {
for (const FileList *iter = files; iter->name != NULL; ++iter) { for (const PauseFileList *iter = files; iter->name != NULL; ++iter) {
SCOPED_TRACE(iter->name); SCOPED_TRACE(iter->name);
for (int t = 2; t <= 8; ++t) { for (int t = 2; t <= 8; ++t) {
EXPECT_EQ(iter->expected_md5, EXPECT_EQ(iter->expected_md5,
DecodeFile(iter->name, t, iter->pause_frame_num)) DecodeFileWithPause(iter->name, t, iter->pause_frame_num))
<< "threads = " << t; << "threads = " << t;
} }
} }
@@ -106,7 +107,7 @@ void DecodeFiles(const FileList files[]) {
TEST(VP9MultiThreadedFrameParallel, PauseSeekResume) { TEST(VP9MultiThreadedFrameParallel, PauseSeekResume) {
// vp90-2-07-frame_parallel-1.webm is a 40 frame video file with // vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
// one key frame for every ten frames. // one key frame for every ten frames.
static const FileList files[] = { static const PauseFileList files[] = {
{ "vp90-2-07-frame_parallel-1.webm", { "vp90-2-07-frame_parallel-1.webm",
"6ea7c3875d67252e7caf2bc6e75b36b1", 6 }, "6ea7c3875d67252e7caf2bc6e75b36b1", 6 },
{ "vp90-2-07-frame_parallel-1.webm", { "vp90-2-07-frame_parallel-1.webm",
@@ -115,10 +116,10 @@ TEST(VP9MultiThreadedFrameParallel, PauseSeekResume) {
"89772591e6ef461f9fa754f916c78ed8", 26 }, "89772591e6ef461f9fa754f916c78ed8", 26 },
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
}; };
DecodeFiles(files); DecodeFilesWithPause(files);
} }
struct InvalidFileList { struct FileList {
const char *name; const char *name;
// md5 sum for decoded frames which does not include corrupted frames. // md5 sum for decoded frames which does not include corrupted frames.
const char *expected_md5; const char *expected_md5;
@@ -128,7 +129,7 @@ struct InvalidFileList {
// Decodes |filename| with |num_threads|. Return the md5 of the decoded // Decodes |filename| with |num_threads|. Return the md5 of the decoded
// frames which does not include corrupted frames. // frames which does not include corrupted frames.
string DecodeInvalidFile(const string &filename, int num_threads, string DecodeFile(const string &filename, int num_threads,
int expected_frame_count) { int expected_frame_count) {
libvpx_test::WebMVideoSource video(filename); libvpx_test::WebMVideoSource video(filename);
video.Init(); video.Init();
@@ -173,19 +174,19 @@ string DecodeInvalidFile(const string &filename, int num_threads,
return string(md5.Get()); return string(md5.Get());
} }
void DecodeInvalidFiles(const InvalidFileList files[]) { void DecodeFiles(const FileList files[]) {
for (const InvalidFileList *iter = files; iter->name != NULL; ++iter) { for (const FileList *iter = files; iter->name != NULL; ++iter) {
SCOPED_TRACE(iter->name); SCOPED_TRACE(iter->name);
for (int t = 2; t <= 8; ++t) { for (int t = 2; t <= 8; ++t) {
EXPECT_EQ(iter->expected_md5, EXPECT_EQ(iter->expected_md5,
DecodeInvalidFile(iter->name, t, iter->expected_frame_count)) DecodeFile(iter->name, t, iter->expected_frame_count))
<< "threads = " << t; << "threads = " << t;
} }
} }
} }
TEST(VP9MultiThreadedFrameParallel, InvalidFileTest) { TEST(VP9MultiThreadedFrameParallel, InvalidFileTest) {
static const InvalidFileList files[] = { static const FileList files[] = {
// invalid-vp90-2-07-frame_parallel-1.webm is a 40 frame video file with // invalid-vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
// one key frame for every ten frames. The 11th frame has corrupted data. // one key frame for every ten frames. The 11th frame has corrupted data.
{ "invalid-vp90-2-07-frame_parallel-1.webm", { "invalid-vp90-2-07-frame_parallel-1.webm",
@@ -202,8 +203,18 @@ TEST(VP9MultiThreadedFrameParallel, InvalidFileTest) {
"8256544308de926b0681e04685b98677", 27 }, "8256544308de926b0681e04685b98677", 27 },
{ NULL, NULL, 0 }, { NULL, NULL, 0 },
}; };
DecodeInvalidFiles(files); DecodeFiles(files);
} }
TEST(VP9MultiThreadedFrameParallel, ValidFileTest) {
static const FileList files[] = {
#if CONFIG_VP9_HIGHBITDEPTH
{ "vp92-2-20-10bit-yuv420.webm",
"a16b99df180c584e8db2ffeda987d293", 10 },
#endif
{ NULL, NULL, 0 },
};
DecodeFiles(files);
}
#endif // CONFIG_WEBM_IO #endif // CONFIG_WEBM_IO
} // namespace } // namespace

View File

@@ -155,6 +155,10 @@ void vp9_frameworker_copy_context(VP9Worker *const dst_worker,
dst_worker_data->pbi->need_resync = src_worker_data->pbi->need_resync; dst_worker_data->pbi->need_resync = src_worker_data->pbi->need_resync;
vp9_frameworker_unlock_stats(src_worker); vp9_frameworker_unlock_stats(src_worker);
dst_cm->bit_depth = src_cm->bit_depth;
#if CONFIG_VP9_HIGHBITDEPTH
dst_cm->use_highbitdepth = src_cm->use_highbitdepth;
#endif
dst_cm->prev_frame = src_cm->show_existing_frame ? dst_cm->prev_frame = src_cm->show_existing_frame ?
src_cm->prev_frame : src_cm->cur_frame; src_cm->prev_frame : src_cm->cur_frame;
dst_cm->last_width = !src_cm->show_existing_frame ? dst_cm->last_width = !src_cm->show_existing_frame ?