ref: 727f3840851b33213967c3f1e61e08d74c2fde09
parent: 4109b8e5357ccfe95841fde1b8f8c36d1e402114
parent: c447a50aea7afe54bb7f7f71650bbd71a96bf66a
author: Deb Mukherjee <[email protected]>
date: Thu Jul 17 23:23:51 EDT 2014
Merge "Separates profile 2 into 2 profiles 2 and 3"
--- a/test/decode_test_driver.cc
+++ b/test/decode_test_driver.cc
@@ -39,12 +39,34 @@
return res_dec;
}
+bool Decoder::IsVP8() const {
+ const char *codec_name = GetDecoderName();
+ return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
+}
+
+void DecoderTest::HandlePeekResult(Decoder *const decoder,
+ CompressedVideoSource *video,
+ const vpx_codec_err_t res_peek) {
+ const bool is_vp8 = decoder->IsVP8();
+ if (is_vp8) {
+ /* Vp8's implementation of PeekStream returns an error if the frame you
+ * pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
+ * frame, which must be a keyframe. */
+ if (video->frame_number() == 0)
+ ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
+ << vpx_codec_err_to_string(res_peek);
+ } else {
+ /* The Vp9 implementation of PeekStream returns an error only if the
+ * data passed to it isn't a valid Vp9 chunk. */
+ ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
+ << vpx_codec_err_to_string(res_peek);
+ }
+}
+
void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_codec_dec_cfg_t &dec_cfg) {
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
ASSERT_TRUE(decoder != NULL);
- const char *codec_name = decoder->GetDecoderName();
- const bool is_vp8 = strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
// Decode frames.
for (video->Begin(); !::testing::Test::HasFailure() && video->cxdata();
@@ -56,19 +78,8 @@
const vpx_codec_err_t res_peek = decoder->PeekStream(video->cxdata(),
video->frame_size(),
&stream_info);
- if (is_vp8) {
- /* Vp8's implementation of PeekStream returns an error if the frame you
- * pass it is not a keyframe, so we only expect VPX_CODEC_OK on the first
- * frame, which must be a keyframe. */
- if (video->frame_number() == 0)
- ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
- << vpx_codec_err_to_string(res_peek);
- } else {
- /* The Vp9 implementation of PeekStream returns an error only if the
- * data passed to it isn't a valid Vp9 chunk. */
- ASSERT_EQ(VPX_CODEC_OK, res_peek) << "Peek return failed: "
- << vpx_codec_err_to_string(res_peek);
- }
+ HandlePeekResult(decoder, video, res_peek);
+ ASSERT_FALSE(::testing::Test::HasFailure());
vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
video->frame_size());
--- a/test/decode_test_driver.h
+++ b/test/decode_test_driver.h
@@ -91,10 +91,12 @@
&decoder_, cb_get, cb_release, user_priv);
}
- const char* GetDecoderName() {
+ const char* GetDecoderName() const {
return vpx_codec_iface_name(CodecInterface());
}
+ bool IsVP8() const;
+
protected:
virtual vpx_codec_iface_t* CodecInterface() const = 0;
@@ -137,6 +139,11 @@
// Hook to be called on every decompressed frame.
virtual void DecompressedFrameHook(const vpx_image_t& img,
const unsigned int frame_number) {}
+
+ // Hook to be called on peek result
+ virtual void HandlePeekResult(Decoder* const decoder,
+ CompressedVideoSource *video,
+ const vpx_codec_err_t res_peek);
protected:
explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {}
--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -70,46 +70,49 @@
return !HasFailure();
}
- private:
- FILE *res_file_;
-};
+ void RunTest() {
+ const DecodeParam input = GET_PARAM(1);
+ libvpx_test::CompressedVideoSource *video = NULL;
+ vpx_codec_dec_cfg_t cfg = {0};
+ cfg.threads = input.threads;
+ const std::string filename = input.filename;
-TEST_P(InvalidFileTest, ReturnCode) {
- libvpx_test::CompressedVideoSource *video = NULL;
- const DecodeParam input = GET_PARAM(1);
- vpx_codec_dec_cfg_t cfg = {0};
- cfg.threads = input.threads;
- const std::string filename = input.filename;
-
- // Open compressed video file.
- if (filename.substr(filename.length() - 3, 3) == "ivf") {
- video = new libvpx_test::IVFVideoSource(filename);
- } else if (filename.substr(filename.length() - 4, 4) == "webm") {
+ // Open compressed video file.
+ if (filename.substr(filename.length() - 3, 3) == "ivf") {
+ video = new libvpx_test::IVFVideoSource(filename);
+ } else if (filename.substr(filename.length() - 4, 4) == "webm") {
#if CONFIG_WEBM_IO
- video = new libvpx_test::WebMVideoSource(filename);
+ video = new libvpx_test::WebMVideoSource(filename);
#else
- fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
- filename.c_str());
- return;
+ fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
+ filename.c_str());
+ return;
#endif
+ }
+ video->Init();
+
+ // Construct result file name. The file holds a list of expected integer
+ // results, one for each decoded frame. Any result that doesn't match
+ // the files list will cause a test failure.
+ const std::string res_filename = filename + ".res";
+ OpenResFile(res_filename);
+
+ // Decode frame, and check the md5 matching.
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
+ delete video;
}
- video->Init();
- // Construct result file name. The file holds a list of expected integer
- // results, one for each decoded frame. Any result that doesn't match
- // the files list will cause a test failure.
- const std::string res_filename = filename + ".res";
- OpenResFile(res_filename);
+ private:
+ FILE *res_file_;
+};
- // Decode frame, and check the md5 matching.
- ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
- delete video;
+TEST_P(InvalidFileTest, ReturnCode) {
+ RunTest();
}
const DecodeParam kVP9InvalidFileTests[] = {
- {1, "invalid-vp90-01-v2.webm"},
{1, "invalid-vp90-02-v2.webm"},
- {1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf"},
+ {1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"},
{1, "invalid-vp90-03-v2.webm"},
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"},
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"},
@@ -117,6 +120,27 @@
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
::testing::ValuesIn(kVP9InvalidFileTests));
+
+// This class will include test vectors that are expected to fail
+// peek. However they are still expected to have no fatal failures.
+class InvalidFileInvalidPeekTest : public InvalidFileTest {
+ protected:
+ InvalidFileInvalidPeekTest() : InvalidFileTest() {}
+ virtual void HandlePeekResult(libvpx_test::Decoder *const decoder,
+ libvpx_test::CompressedVideoSource *video,
+ const vpx_codec_err_t res_peek) {}
+};
+
+TEST_P(InvalidFileInvalidPeekTest, ReturnCode) {
+ RunTest();
+}
+
+const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
+ {1, "invalid-vp90-01-v2.webm"},
+};
+
+VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
+ ::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests));
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
{4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -1,11 +1,19 @@
d5dfb0151c9051f8c85999255645d7a23916d3c0 hantro_collage_w352h288.yuv
b87815bf86020c592ccc7a846ba2e28ec8043902 hantro_odd.yuv
-fe346136b9b8c1e6f6084cc106485706915795e4 invalid-vp90-01.webm
-25751f5d3b05ff03f0719ad42cd625348eb8961e invalid-vp90-01.webm.res
-d78e2fceba5ac942246503ec8366f879c4775ca5 invalid-vp90-02.webm
-2dadee5306245fa5eeb0f99652d0e17afbcba96d invalid-vp90-02.webm.res
-df1a1453feb3c00d7d89746c7003b4163523bff3 invalid-vp90-03.webm
-8fe6fd82bf537340f586f97a7ae31fb37ccda302 invalid-vp90-03.webm.res
+76024eb753cdac6a5e5703aaea189d35c3c30ac7 invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf
+7448d8798a4380162d4b56f9b452e2f6f9e24e7a invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res
+83f50908c8dc0ef8760595447a2ff7727489542e invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf
+456d1493e52d32a5c30edf44a27debc1fa6b253a invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
+c123d1f9f02fb4143abb5e271916e3a3080de8f6 invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
+456d1493e52d32a5c30edf44a27debc1fa6b253a invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
+fe346136b9b8c1e6f6084cc106485706915795e4 invalid-vp90-01-v2.webm
+25751f5d3b05ff03f0719ad42cd625348eb8961e invalid-vp90-01-v2.webm.res
+d78e2fceba5ac942246503ec8366f879c4775ca5 invalid-vp90-02-v2.webm
+8e2eff4af87d2b561cce2365713269e301457ef3 invalid-vp90-02-v2.webm.res
+df1a1453feb3c00d7d89746c7003b4163523bff3 invalid-vp90-03-v2.webm
+25dd58c22d23f75304d7ce7f69f4e5b02ef9119a invalid-vp90-03-v2.webm.res
+d637297561dd904eb2c97a9015deeb31c4a1e8d2 invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
+3a204bdbeaa3c6458b77bcebb8366d107267f55d invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
a432f96ff0a787268e2f94a8092ab161a18d1b06 park_joy_90p_10_420.y4m
0b194cc312c3a2e84d156a221b0a5eb615dfddc5 park_joy_90p_10_422.y4m
ff0e0a21dc2adc95b8c1b37902713700655ced17 park_joy_90p_10_444.y4m
@@ -661,17 +669,3 @@
cc75f351818b9a619818f5cc77b9bc013d0c1e11 vp90-2-17-show-existing-frame.webm.md5
0321d507ce62dedc8a51b4e9011f7a19aed9c3dc vp91-2-04-yuv444.webm
367e423dd41fdb49aa028574a2cfec5c2f325c5c vp91-2-04-yuv444.webm.md5
-76024eb753cdac6a5e5703aaea189d35c3c30ac7 invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf
-d3964f9dad9f60363c81b688324d95b4ec7c8038 invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf.res
-83f50908c8dc0ef8760595447a2ff7727489542e invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf
-456d1493e52d32a5c30edf44a27debc1fa6b253a invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
-c123d1f9f02fb4143abb5e271916e3a3080de8f6 invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
-456d1493e52d32a5c30edf44a27debc1fa6b253a invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
-fe346136b9b8c1e6f6084cc106485706915795e4 invalid-vp90-01-v2.webm
-25751f5d3b05ff03f0719ad42cd625348eb8961e invalid-vp90-01-v2.webm.res
-d78e2fceba5ac942246503ec8366f879c4775ca5 invalid-vp90-02-v2.webm
-8e2eff4af87d2b561cce2365713269e301457ef3 invalid-vp90-02-v2.webm.res
-df1a1453feb3c00d7d89746c7003b4163523bff3 invalid-vp90-03-v2.webm
-25dd58c22d23f75304d7ce7f69f4e5b02ef9119a invalid-vp90-03-v2.webm.res
-d637297561dd904eb2c97a9015deeb31c4a1e8d2 invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
-3a204bdbeaa3c6458b77bcebb8366d107267f55d invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
--- a/test/test.mk
+++ b/test/test.mk
@@ -786,8 +786,8 @@
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v2.webm.res
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf
-LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf.res
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf
+LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
--- a/vp9/common/vp9_enums.h
+++ b/vp9/common/vp9_enums.h
@@ -25,15 +25,18 @@
#define MI_MASK (MI_BLOCK_SIZE - 1)
-// Bitstream profiles indicated by 2 bits in the uncompressed header.
-// 00: Profile 0. 4:2:0 only.
-// 10: Profile 1. adds 4:4:4, 4:2:2, alpha.
-// 01: Profile 2. Supports 10-bit and 12-bit color only.
-// 11: Undefined profile.
+// Bitstream profiles indicated by 2-3 bits in the uncompressed header.
+// 00: Profile 0. 8-bit 4:2:0 only.
+// 10: Profile 1. Adds 4:4:4, 4:2:2, alpha to Profile 0.
+// 01: Profile 2. Supports 10-bit and 12-bit color only, with 4:2:0 sampling.
+// 110: Profile 3. Supports 10-bit and 12-bit color only, with 4:2:2/4:4:4
+// sampling and alpha.
+// 111: Undefined profile.
typedef enum BITSTREAM_PROFILE {
PROFILE_0,
PROFILE_1,
PROFILE_2,
+ PROFILE_3,
MAX_PROFILES
} BITSTREAM_PROFILE;
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -1071,9 +1071,11 @@
vp9_rb_read_literal(rb, 8) == VP9_SYNC_CODE_2;
}
-static BITSTREAM_PROFILE read_profile(struct vp9_read_bit_buffer *rb) {
+BITSTREAM_PROFILE vp9_read_profile(struct vp9_read_bit_buffer *rb) {
int profile = vp9_rb_read_bit(rb);
profile |= vp9_rb_read_bit(rb) << 1;
+ if (profile > 2)
+ profile += vp9_rb_read_bit(rb);
return (BITSTREAM_PROFILE) profile;
}
@@ -1089,7 +1091,7 @@
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
"Invalid frame marker");
- cm->profile = read_profile(rb);
+ cm->profile = vp9_read_profile(rb);
if (cm->profile >= MAX_PROFILES)
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
"Unsupported bitstream profile");
@@ -1124,7 +1126,7 @@
cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
if (cm->color_space != SRGB) {
vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range
- if (cm->profile >= PROFILE_1) {
+ if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
cm->subsampling_x = vp9_rb_read_bit(rb);
cm->subsampling_y = vp9_rb_read_bit(rb);
vp9_rb_read_bit(rb); // has extra plane
@@ -1132,12 +1134,12 @@
cm->subsampling_y = cm->subsampling_x = 1;
}
} else {
- if (cm->profile >= PROFILE_1) {
+ if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
cm->subsampling_y = cm->subsampling_x = 0;
vp9_rb_read_bit(rb); // has extra plane
} else {
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
- "RGB not supported in profile 0");
+ "4:4:4 color not supported in profile 0");
}
}
--- a/vp9/decoder/vp9_decodeframe.h
+++ b/vp9/decoder/vp9_decodeframe.h
@@ -29,6 +29,7 @@
int vp9_read_sync_code(struct vp9_read_bit_buffer *const rb);
void vp9_read_frame_size(struct vp9_read_bit_buffer *rb,
int *width, int *height);
+BITSTREAM_PROFILE vp9_read_profile(struct vp9_read_bit_buffer *rb);
#ifdef __cplusplus
} // extern "C"
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1024,9 +1024,22 @@
static void write_profile(BITSTREAM_PROFILE profile,
struct vp9_write_bit_buffer *wb) {
- assert(profile < MAX_PROFILES);
- vp9_wb_write_bit(wb, profile & 1);
- vp9_wb_write_bit(wb, profile >> 1);
+ switch (profile) {
+ case PROFILE_0:
+ vp9_wb_write_literal(wb, 0, 2);
+ break;
+ case PROFILE_1:
+ vp9_wb_write_literal(wb, 2, 2);
+ break;
+ case PROFILE_2:
+ vp9_wb_write_literal(wb, 1, 2);
+ break;
+ case PROFILE_3:
+ vp9_wb_write_literal(wb, 6, 3);
+ break;
+ default:
+ assert(0);
+ }
}
static void write_uncompressed_header(VP9_COMP *cpi,
@@ -1052,13 +1065,13 @@
vp9_wb_write_literal(wb, cs, 3);
if (cs != SRGB) {
vp9_wb_write_bit(wb, 0); // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
- if (cm->profile >= PROFILE_1) {
+ if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
vp9_wb_write_bit(wb, cm->subsampling_x);
vp9_wb_write_bit(wb, cm->subsampling_y);
vp9_wb_write_bit(wb, 0); // has extra plane
}
} else {
- assert(cm->profile == PROFILE_1);
+ assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3);
vp9_wb_write_bit(wb, 0); // has extra plane
}
--- a/vp9/vp9_dx_iface.c
+++ b/vp9/vp9_dx_iface.c
@@ -122,13 +122,12 @@
int error_resilient;
struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL };
const int frame_marker = vp9_rb_read_literal(&rb, 2);
- const int version = vp9_rb_read_bit(&rb);
- (void) vp9_rb_read_bit(&rb); // unused version bit
+ const BITSTREAM_PROFILE profile = vp9_read_profile(&rb);
if (frame_marker != VP9_FRAME_MARKER)
return VPX_CODEC_UNSUP_BITSTREAM;
- if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM;
+ if (profile >= MAX_PROFILES) return VPX_CODEC_UNSUP_BITSTREAM;
if (vp9_rb_read_bit(&rb)) { // show an existing frame
vp9_rb_read_literal(&rb, 3); // Frame buffer to show.
@@ -149,15 +148,17 @@
if (!vp9_read_sync_code(&rb))
return VPX_CODEC_UNSUP_BITSTREAM;
+ if (profile > PROFILE_1)
+ rb.bit_offset += 1; // Bit-depth 10 or 12
colorspace = vp9_rb_read_literal(&rb, 3);
if (colorspace != sRGB) {
rb.bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range
- if (version == 1) {
+ if (profile == PROFILE_1 || profile == PROFILE_3) {
rb.bit_offset += 2; // subsampling x/y
rb.bit_offset += 1; // has extra plane
}
} else {
- if (version == 1) {
+ if (profile == PROFILE_1 || profile == PROFILE_3) {
rb.bit_offset += 1; // has extra plane
} else {
// RGB is only available in version 1