Compare commits

..

144 Commits

Author SHA1 Message Date
Peter de Rivaz
fd05fb0c21 Corrected optimization of 8x8 DCT code
The 8x8 DCT uses a fast version whenever possible.
There was a mistake in the checking code which
meant sometimes the fast version was used when it
was not safe to do so.

Change-Id: I154c84c9e2d836764768a11082947ca30f4b5ab7
2014-12-11 15:54:23 +00:00
Debargha Mukherjee
39da55a49f Merge "Added tests for high bitdepth variance sse2 functions" into highbitdepth 2014-11-10 14:42:26 -08:00
Peter de Rivaz
6d741e4d76 Added tests for high bitdepth variance sse2 functions
Change-Id: I72735e2e07464a0f7e44968fb14a195c84a58992
2014-11-10 20:42:24 +00:00
Peter de Rivaz
db7192e0b0 Added highbitdepth sse2 acceleration for quantize and block error
Change-Id: Idef18f90b111a0d0c9546543d3347e551908fd78
2014-11-10 10:47:39 -08:00
Peter de Rivaz
08d2f54800 Fixed idct16x16_10 highbitdepth transform
In the case when there are only non-zero coefficients
in the first 4x4 block a special routine is called.
The highbitdepth optimized version of this routine
examined the wrong positions when deciding whether
to call an assembler or C inverse transform.

Change-Id: I62da663ca11775dadb66e402e42f4a1cb1927893
2014-11-10 16:17:49 +00:00
Deb Mukherjee
a1b726117f Iadst transforms to use internal low precision
Change-Id: I266777d40c300bc53b45b205144520b85b0d6e58
2014-11-06 13:57:04 -08:00
Peter de Rivaz
005d80cd05 Added high bitdepth sse2 transform functions
Change-Id: If359f0e9a71bca9c2ba685a87a355873536bb282
2014-11-06 11:50:47 -08:00
Peter de Rivaz
d7422b2b1e Added sse2 acceleration for highbitdepth variance
Change-Id: I446bdf3a405e4e9d2aa633d6281d66ea0cdfd79f
2014-11-04 10:06:06 -08:00
Peter de Rivaz
454342d4e7 Refactored idct routines and headers
This change is made in preparation for a
subsequent patch which adds acceleration
for the highbitdepth transform functions.

The highbitdepth transform functions attempt
to use 16/32bit sse instructions where possible,
but fallback to using the C implementations if
potential overflow is detected.  For this reason
the dct routines are made global so they can be
called from the acceleration functions in the
subsequent patch.

Change-Id: Ia921f191bf6936ccba4f13e8461624b120c1f665
2014-10-24 08:37:39 +01:00
Debargha Mukherjee
cda2ad0121 Merge "Fixed calling of highbd transform." into highbitdepth 2014-10-22 12:57:43 -07:00
Debargha Mukherjee
6b378b8868 Merge "Tidy up of highbitdepth loopfilter and convolution" into highbitdepth 2014-10-22 09:58:29 -07:00
Peter de Rivaz
123f29d1d7 Tidy up of highbitdepth loopfilter and convolution
Change-Id: I65531cc55d3d6949e164e2e26f92ee44a1921f7e
2014-10-22 09:43:03 +01:00
Peter de Rivaz
4230c2306c Fixed calling of highbd transform.
This patch does not change behaviour because
vp9_fwht4x4 is identical to vp9_highbd_fwht4x4,
but it becomes important when accelerations are made
to vp9_highbd_fwht4x4 in a later patch.

Change-Id: I2b790316cdd498727c4951a9e591edb291de3ac8
2014-10-22 09:26:39 +01:00
Alex Converse
5b76018057 Merge "Added highbitdepth sse2 SAD acceleration and tests" into highbitdepth 2014-10-20 09:55:41 -07:00
Peter de Rivaz
b1a6f6b9cb Added highbitdepth sse2 SAD acceleration and tests
Change-Id: I9f09e404e3136951e5cc15bf40b915c1fe10b620
2014-10-20 09:51:01 +01:00
Debargha Mukherjee
a92f987a6b Merge "Add highbitdepth function for vp9_avg_8x8" into highbitdepth 2014-10-16 14:39:14 -07:00
Peter de Rivaz
1bf87dc353 Add highbitdepth function for vp9_avg_8x8
Change-Id: I6903e4e4cb57d90590725c8a1c64c23da7ae65e8
2014-10-16 14:36:07 +01:00
Deb Mukherjee
b84bf3323b Fix in bit-shift operation for highbitdepth decode
Fixes a bug introduced in a previous refactoring patch.

Change-Id: I243e74637cfd7a997c7a1fef03b06c290dd0dee6
2014-10-15 10:28:30 -07:00
Deb Mukherjee
563aeba901 Merge 'origin/master' into highbitdepth
Conflicts:
	examples/vp9_spatial_svc_encoder.c
	examples/vpx_temporal_svc_encoder.c
	test/convolve_test.cc
	test/dct16x16_test.cc
	test/dct32x32_test.cc
	test/fdct4x4_test.cc
	test/fdct8x8_test.cc
	test/lpf_8_test.cc
	test/partial_idct_test.cc
	test/test.mk
	test/vp9_intrapred_test.cc
	tools_common.c
	vp8/vp8_cx_iface.c
	vp9/common/vp9_alloccommon.c
	vp9/common/vp9_common.h
	vp9/common/vp9_convolve.c
	vp9/common/vp9_convolve.h
	vp9/common/vp9_entropy.c
	vp9/common/vp9_entropy.h
	vp9/common/vp9_idct.c
	vp9/common/vp9_idct.h
	vp9/common/vp9_loopfilter.c
	vp9/common/vp9_loopfilter_filters.c
	vp9/common/vp9_onyxc_int.h
	vp9/common/vp9_postproc.c
	vp9/common/vp9_quant_common.c
	vp9/common/vp9_quant_common.h
	vp9/common/vp9_reconinter.c
	vp9/common/vp9_reconinter.h
	vp9/common/vp9_reconintra.c
	vp9/common/vp9_rtcd_defs.pl
	vp9/common/vp9_scale.c
	vp9/common/vp9_scale.h
	vp9/common/x86/vp9_asm_stubs.c
	vp9/common/x86/vp9_high_intrapred_sse2.asm
	vp9/common/x86/vp9_high_loopfilter_intrin_sse2.c
	vp9/common/x86/vp9_high_subpixel_8t_sse2.asm
	vp9/common/x86/vp9_high_subpixel_bilinear_sse2.asm
	vp9/decoder/vp9_decodeframe.c
	vp9/decoder/vp9_detokenize.c
	vp9/encoder/vp9_aq_complexity.c
	vp9/encoder/vp9_aq_cyclicrefresh.c
	vp9/encoder/vp9_aq_variance.c
	vp9/encoder/vp9_bitstream.c
	vp9/encoder/vp9_block.h
	vp9/encoder/vp9_context_tree.h
	vp9/encoder/vp9_dct.c
	vp9/encoder/vp9_encodeframe.c
	vp9/encoder/vp9_encodemb.c
	vp9/encoder/vp9_encoder.c
	vp9/encoder/vp9_encoder.h
	vp9/encoder/vp9_extend.c
	vp9/encoder/vp9_firstpass.c
	vp9/encoder/vp9_lookahead.c
	vp9/encoder/vp9_lookahead.h
	vp9/encoder/vp9_mcomp.c
	vp9/encoder/vp9_picklpf.c
	vp9/encoder/vp9_pickmode.c
	vp9/encoder/vp9_quantize.c
	vp9/encoder/vp9_quantize.h
	vp9/encoder/vp9_ratectrl.c
	vp9/encoder/vp9_rd.c
	vp9/encoder/vp9_rdopt.c
	vp9/encoder/vp9_resize.c
	vp9/encoder/vp9_resize.h
	vp9/encoder/vp9_sad.c
	vp9/encoder/vp9_ssim.c
	vp9/encoder/vp9_ssim.h
	vp9/encoder/vp9_temporal_filter.c
	vp9/encoder/vp9_tokenize.c
	vp9/encoder/vp9_tokenize.h
	vp9/encoder/vp9_variance.c
	vp9/encoder/vp9_variance.h
	vp9/vp9_common.mk
	vp9/vp9_cx_iface.c
	vp9/vp9_dx_iface.c
	vp9/vp9_iface_common.h
	vpx/src/svc_encodeframe.c
	vpx/src/vpx_image.c
	vpx/vp8dx.h
	vpx/vpx_codec.h
	vpx/vpx_encoder.h
	vpx/vpx_image.h
	vpx_mem/vpx_mem.c
	vpx_mem/vpx_mem.h
	vpx_scale/generic/yv12config.c
	vpx_scale/generic/yv12extend.c
	vpx_scale/yv12config.h
	vpxdec.c
	vpxenc.c

Change-Id: I699c833f7da96569d2581af7e045ce523bf72d3b
2014-10-14 10:08:15 -07:00
Debargha Mukherjee
93657ee6ec Merge "Add bit_depth to internal image structure" into highbitdepth 2014-09-22 10:03:09 -07:00
Peter de Rivaz
3df0e78eae Add bit_depth to internal image structure
This change is made to allow show_existing_frame
to display an image of a different bit depth to
the frames currently being decoded.

Change-Id: Ia150bde2a4ed56fe3892a53fd7b5b9f5182ad59f
2014-09-22 16:02:30 +01:00
Peter de Rivaz
e27a93fe25 Fix for when profile switches back to 8bit
Change-Id: I820027d8aebef67cb8380c47475ee59e19d7a97b
2014-09-22 10:02:55 +01:00
Deb Mukherjee
159247f30c Merge "Add missing sse code for some functions" into highbitdepth 2014-09-16 16:54:25 -07:00
Deb Mukherjee
06cfc9f3e1 Add missing sse code for some functions
Change-Id: I9830217108a74f546e707ab82a15e278319f4360
2014-09-16 11:37:37 -07:00
Deb Mukherjee
85dba225a8 Merge "Fix 2x scaling bug" into highbitdepth 2014-09-16 09:39:36 -07:00
Deb Mukherjee
53ef87e0c7 Fix asserts in high_convolve
Change-Id: I89fb190ef22d8edf7622dea5ef1c0e47faa95d23
2014-09-15 11:33:27 -07:00
Deb Mukherjee
09faceb706 Fix 2x scaling bug
Reported by Alexander Voronov

Change-Id: I463ba323cc9f4e345b7e6f759565725737793086
2014-09-15 09:48:35 -07:00
Deb Mukherjee
75c8fc2412 Deprecate vpx_bit_depth_to_bps function
Function not needed.

Change-Id: Icaad4cbd218ddd8e3720a7d9aad6b69aeffa369b
2014-09-12 16:40:26 -07:00
Deb Mukherjee
635bb7aed4 Change macros to be compatible with master branch
Changes image fmt and codec capability macro names.

Change-Id: Ic07fbd8de307cb1bfcf9ed4b4bc3feaa5767c53b
2014-09-12 11:47:39 -07:00
Deb Mukherjee
dd0a5ecd2c Minor Refactor of variance functions
Change-Id: If27a938cefeb6e8439f897900e17e2e85a2239d1
2014-09-11 23:10:49 -07:00
Deb Mukherjee
3d170a834a change data type in vp9_idct.c
Change-Id: I2efb51e0e94fd4d42334d86c7dcee08d1a1cc672
2014-09-11 20:14:35 -07:00
Debargha Mukherjee
1db0b0ff1b Merge "Reinitialize dequantizer when switching from 10/12 bit to 8 bit." into highbitdepth 2014-09-11 20:05:33 -07:00
Alexander Voronov
902529c595 Reinitialize dequantizer when switching from 10/12 bit to 8 bit.
Change-Id: Id294cf8d314a3f8aaf4ca2a6b3da052cc898a78c
2014-09-11 21:00:51 +04:00
Alexander Voronov
7dc3cdba0c Make --output-bit-depth option working with variable resolution.
Buffer for bit-depth conversion was allocated only on the first frame.
The next frame with resolution different from the first one led to
decoding error. With this changes decoder performs buffer reallocation
in such case.

Change-Id: I3a701ca8df53a60246354876856624e70efe81aa
2014-09-10 16:30:30 +04:00
Alexander Voronov
f9b4008020 Fix chroma plane size in bit-depth conversion.
Change-Id: Ie75ef8f934d02b57b543ca308ae304458d3962a8
2014-09-10 15:03:50 +04:00
Alexander Voronov
64fca22b4d Fix Visual Studio build.
Change-Id: I6fc8cf7af19b884366ec45e0b8f1e500015b38b8
2014-09-09 11:35:12 +04:00
Peter de Rivaz
b94a475d7b In profile3 we need 2 bytes to show a previous frame
Change-Id: I208632dd94dfc45ab78312e26fee569270ce0ba8
2014-09-01 16:09:07 +01:00
Deb Mukherjee
325fe4a430 Merge "Replace CONVERT_TO_SHORTPTR/BYTEPTR" into highbitdepth 2014-08-29 12:24:07 -07:00
Deb Mukherjee
484a7f31a6 Replace CONVERT_TO_SHORTPTR/BYTEPTR
Uses uintptr_t instead of uint32_t or uint64_t

Change-Id: Id21204969d2723e6c64c29a5d39ec85bfbba9ea8
2014-08-29 10:05:50 -07:00
Deb Mukherjee
059a721d92 Change vpx bit depth enum type to be more natural
Also moves bit_depth_to_bps function to the vpx level.

Change-Id: I7c24f80b2b5bd2fcc6552b61aacee4c7954cc54b
2014-08-28 23:57:57 -07:00
Deb Mukherjee
23b5c58174 Set scaled image format correctly
Change-Id: Ic4ced4208375ca31f8adb73a5ee9ddd7da50dfac
2014-08-22 23:33:29 -07:00
Deb Mukherjee
02118dcb3b Makes high_quant enabled by default
Wtth this change, when --enable-vp9-high is used, high quantization is
used by default, unless it is turned off with --disable-high-quant.

Change-Id: I8a127428181d5dd726a4f3f225ea80f3215201ba
2014-08-19 14:51:00 -07:00
James Hutchinson
3489c19d2b Merge branch 'master' into highbitdepth
Conflicts:
	configure
	test/convolve_test.cc
	test/dct16x16_test.cc
	test/dct32x32_test.cc
	test/fdct4x4_test.cc
	test/fdct8x8_test.cc
	test/partial_idct_test.cc
	third_party/libyuv/README.libvpx
	vp9/common/vp9_enums.h
	vp9/common/vp9_idct.h
	vp9/common/vp9_rtcd_defs.pl
	vp9/decoder/vp9_decodeframe.c
	vp9/encoder/vp9_bitstream.c
	vp9/encoder/vp9_encodeframe.c
	vp9/encoder/vp9_encoder.c
	vp9/encoder/vp9_encoder.h
	vp9/encoder/vp9_extend.c
	vp9/encoder/vp9_quantize.c
	vp9/encoder/vp9_rd.c
	vp9/encoder/vp9_rdopt.c
	vp9/vp9_cx_iface.c
	vp9/vp9_dx_iface.c
	vp9/vp9_iface_common.h
	vpx/vp8cx.h
	vpx_scale/generic/yv12config.c
	vpxdec.c
	vpxenc.c

Change-Id: If4104c5a7cd0a29dd0bed7c3804837ba40ba7e0c
2014-08-19 10:58:02 -07:00
Deb Mukherjee
9595633751 Merge "Hdr change for profiles > 1 for intra-only frames" into highbitdepth 2014-08-07 11:19:55 -07:00
Deb Mukherjee
cea11ebb1e Hdr change for profiles > 1 for intra-only frames
Adds bitdepth, color sampling ind color space information to header
for intra only frames in profile > 0.
Also enforces profile 1 and 3 exclusive usage for non 420 color
sampling.

Change-Id: I92b0630d5193fdbc6e71fa909d684521c12b5d99
2014-08-07 09:55:19 -07:00
Yaowu Xu
60ee54352e fix build errors in vs2012
Macro expansion in VS2012 does not work with existing code, change in
this commit help VS2012 to properly expand the macros and avoid build
errors for test_libvpx project.

Change-Id: I642921462ee4869ea07f90795d7de0f6eaf7655b
2014-08-06 14:47:50 -07:00
Debargha Mukherjee
4b11ea5e32 Merge "Merged vp9_high and high_transforms options" into highbitdepth 2014-08-04 11:47:05 -07:00
Peter de Rivaz
27dc02de95 Remove warnings about uninitialized variables
Change-Id: I25c8b393239e9a5ba5a0f5a5c5897bb38915f33e
2014-07-29 16:21:43 +01:00
Peter de Rivaz
b7327fd3ea Merged vp9_high and high_transforms options
Using --enable-vp9-high now automatically uses
the high precision transform code.

(Before you needed to specify both
--enable-vp9-high and --enable-high-transforms)

Change-Id: I742d5b82601bc38eb81c95d7ecd3f78b9ff0df57
2014-07-29 15:59:06 +01:00
Peter de Rivaz
6791a9b1d5 Added high bitdepth to SVC example
Change-Id: I24498bace25b01f796f530699b58aa1e460f5ebc
2014-07-22 10:59:59 +01:00
Peter de Rivaz
3edc408011 Added high bitdepth support to temporal example
Change-Id: I80f802ecf82ecf18952f025643a56e1986def887
2014-07-22 10:53:50 +01:00
James Hutchinson
41c8641b6b Merge branch 'master' into highbitdepth
Conflicts:
    configure
    test/convolve_test.cc
    test/dct16x16_test.cc
    test/dct32x32_test.cc
    test/fdct4x4_test.cc
    test/fdct8x8_test.cc
    vp9/common/vp9_alloccommon.c
    vp9/common/vp9_entropy.c
    vp9/common/vp9_enums.h
    vp9/common/vp9_quant_common.c
    vp9/common/vp9_quant_common.h
    vp9/common/vp9_rtcd_defs.pl
    vp9/common/vp9_scale.c
    vp9/decoder/vp9_decodeframe.c
    vp9/decoder/vp9_decodeframe.h
    vp9/decoder/vp9_detokenize.c
    vp9/encoder/vp9_aq_complexity.c
    vp9/encoder/vp9_bitstream.c
    vp9/encoder/vp9_encodeframe.c
    vp9/encoder/vp9_encodemb.c
    vp9/encoder/vp9_encoder.c
    vp9/encoder/vp9_firstpass.c
    vp9/encoder/vp9_mcomp.c
    vp9/encoder/vp9_pickmode.c
    vp9/encoder/vp9_quantize.c
    vp9/encoder/vp9_ratectrl.c
    vp9/encoder/vp9_rd.c
    vp9/encoder/vp9_rdopt.c
    vp9/encoder/vp9_temporal_filter.c
    vp9/encoder/vp9_tokenize.c
    vp9/vp9_cx_iface.c
    vp9/vp9_dx_iface.c
    vpx/vpx_codec.h
    vpx/vpx_image.h
    vpx_scale/generic/yv12config.c
    vpxdec.c
    vpxenc.c
    vpxenc.h
    y4menc.c
    y4minput.c

Change-Id: I53b19ea1d9818a4440481920065d70164348d02e
2014-07-18 14:58:26 -07:00
Deb Mukherjee
0a904797f6 Merge "Support for raw yuv input in 422/444 sampling" into highbitdepth 2014-07-16 10:59:14 -07:00
Deb Mukherjee
cc3e6d68df Support for raw yuv input in 422/444 sampling
Adds options --i422 and --i444 which along with --input-bit-depth
will allow raw video input in 422 and 444 sampling at the given
bit-depth. For the decoder, the new option --rawvideo allows
decoding to raw yuv at the color sampling of the decoded bit-stream.

Change-Id: I5b3979be66c0dd2672391400850c97260cc8e1e8
2014-07-16 09:21:16 -07:00
Deb Mukherjee
aba709a5ec Change extra bit prob tables for HBD
Improves coding performance a little.

Change-Id: I9cb3279cec201274ecaa972f270156677e1bdf98
2014-07-16 03:53:39 -07:00
Deb Mukherjee
b0bcd57d12 Generalize read_yuv_frame
Change-Id: I52288ff1a01e6b68fc7eb85425e750b909e56d0c
2014-07-12 01:37:51 -07:00
Deb Mukherjee
78df9ead21 Fix for raw yuv input
Sets fmt correctly for raw yuv inputs, and reads frame
correctly.

Change-Id: I05405b2265545d5c6d1cf7b086db9548cbe5d8ba
2014-07-12 00:19:57 -07:00
Deb Mukherjee
cba05a9ecb Merge "Tokenization separated for 10 and 12 bit" into highbitdepth 2014-07-11 10:50:17 -07:00
Deb Mukherjee
87d40bbafc Tokenization separated for 10 and 12 bit
Enables tuning the probabilities separately, also
reduces the number of bool decodes for 10-bit cat 6
tokens.

Change-Id: Ib237ad07983f43048ba47245efe8fa53c0d25819
2014-07-11 07:00:14 -07:00
Deb Mukherjee
da82f64342 Set default bit_depth to 8 for vp8
Also adds some cleanups

Change-Id: I86af7590397e5a281b3808a36031642c1705a17a
2014-07-11 06:22:43 -07:00
Peter de Rivaz
02c3221593 Allow more combinations for output bitdepth
Change-Id: I1e5de85320d825ffdf90be53720e581f72a5f701
2014-07-10 11:50:25 +01:00
Deb Mukherjee
139ac07ae7 Changes quantization tables to improve quality
Changes quantization tables so that the scale factor diff against
8-bt version is 1 at the low q end and increases to 4 (16) at the
high q end for 10 (12) bit versions, using a logarithmic like
function.

This change improves the quality gap aginst the no-high-quant version,
for both 10-bit and 12-bit. 10-bit is virtually similar in performance
to the no-high-quant version, while the gap for 12-bit is reduced to
the 0.3% range.

Change-Id: I08cc329a77aeb19cc232f8e4458f188c6ae65363
2014-07-09 16:20:15 -07:00
Debargha Mukherjee
209885c785 Merge "Added SSE2 high bitdepth loopfilter" into highbitdepth 2014-07-08 09:49:47 -07:00
Debargha Mukherjee
000ea5e446 Merge "Fixes for highbitdepth on 32bit x86" into highbitdepth 2014-07-08 09:34:20 -07:00
Peter de Rivaz
c62b82d7c9 Added SSE2 high bitdepth loopfilter
Change-Id: I4e5ecaaf956d30bd2e5301d57f02e277100ceb7f
2014-07-08 16:49:59 +01:00
Peter de Rivaz
7e802a5bba Fixes for highbitdepth on 32bit x86
Some of the assembler routines only work for 64bit
architectures.  This patch makes such routines  fall
back to using C implementations.

Change-Id: Ia1e59d9ce5856eca0d56ab59fbc9436fa2838745
2014-07-08 16:12:25 +01:00
Deb Mukherjee
8a50b60c9c Change quantizer to start from 4
Fixes lossless quantizer

Change-Id: I2b9d00afc65c5a374f7b988c5082738d4b1a0bea
2014-07-08 08:10:22 -07:00
Deb Mukherjee
d5f6cd1b38 Changes quantization values for 10/12 bit
Improves performance by eliminating some values at the very low
quantizer range, because entropy coding is not too efficient
at this range.

Change-Id: I3cacc7352dc2e58cfe8448d89a693e992ef93ee7
2014-07-07 12:30:43 -07:00
Peter de Rivaz
91c222491e Alternate high bitdepth quantizer changes
In this proposal, the qindex range is kept at 0 to 255
but the values are remapped to cover an extended range of
quantizer values.

This simplifies the code and bitstream compared to the 8-bit version.

Change-Id: I0dda61388cef41e21a0d5c34d817c862de637580
2014-07-03 13:53:02 +01:00
Debargha Mukherjee
2cf1232bd6 Merge "Modify initial value for avg_frame_qindex" into highbitdepth 2014-07-02 14:30:32 -07:00
Peter de Rivaz
3cd669c548 Modify initial value for avg_frame_qindex
In high bitdepth mode there is an extended quantizer range.
This means that it takes longer for the avg_frame_qindex
to ramp up and this results in coding loss for short
low bitrate sequences.

This patch adds a boost in high bitdepth mode to compensate
for this effect.

This helps with the bowing_cif.y4m sequence at 50kbps.

Change-Id: Ie1575d88e8de4f0297cf86da50eb36dfc5442c70
2014-07-02 20:50:21 +01:00
Peter de Rivaz
56f2cb9478 Added config-enable-hw-high
In the inverse transform code, overflow results in
implementation defined behaviour.

Hardware implementations are expected to wrap on
overflow in order to use the smallest data path
possible.  The new config option makes the C reference code
use wrap on overflow.

Encoders are recommended to not generate bitstreams that
result in overflow in the inverse transform.

Change-Id: I73836ccfb925b4dbfb29c257a3784fa7733db877
2014-07-02 20:20:08 +01:00
Peter de Rivaz
6dd6bb6602 Added SSE2 intra prediction high bitdepth
Change-Id: I2c02a6b42378e130f693aadbe92e85727b28ec7c
2014-07-02 15:07:16 +01:00
Deb Mukherjee
225c60848b Adds comment why avx2 removed for high transforms
Change-Id: I87efe103017e80414082830987343a053e1e8cd8
2014-07-02 06:05:12 -07:00
Peter de Rivaz
67dd2eaff7 Added SSE2 high bitdepth convolution
Change-Id: I525cda28b273aa7ef4fcb2c8f690273cb719562c
2014-07-02 12:11:35 +01:00
Debargha Mukherjee
d61fbfd760 Merge "AVX2 optimization is not valid with HIGH_TRANSFORMS" into highbitdepth 2014-07-01 09:49:21 -07:00
Peter de Rivaz
6c9426809f AVX2 optimization is not valid with HIGH_TRANSFORMS
With CONFIG_HIGH_TRANSFORMS, the transform coefficients
are held in 32bit values, so the assembler code for
vp9_block_error can no longer be used.

Change-Id: I2c7d8a81a32fe4dfcac045588ea1c9e89a267f1f
2014-07-01 15:55:28 +01:00
Deb Mukherjee
7f0eaadadc Merge "Extending y4m writing" into highbitdepth 2014-06-30 16:49:18 -07:00
Deb Mukherjee
7051f38e5a Extending y4m writing
Also adds some cleanups.

Change-Id: I0b35c6645236c7ca3f05e3ed9eae4571fd8249d2
2014-06-27 15:35:36 -07:00
Peter de Rivaz
d21a89895f Use high_precision_mv for highbitdepth
The use of high precision motion vectors depends
on the qindex level.  For highbitdepth it improves PSNR
to use high precision motion vectors for more values of
qindex.

Change-Id: I1dc5a4cc38dc0ac71a2a37dfd478f37d7c361b19
2014-06-24 12:25:33 -07:00
Debargha Mukherjee
149c891dac Merge "Merge branch 'master' into highbitdepth" into highbitdepth 2014-06-24 11:28:56 -07:00
James Hutchinson
939f871ccc Merge branch 'master' into highbitdepth
Conflicts:
	configure
	test/dct16x16_test.cc
	test/dct32x32_test.cc
	test/fdct4x4_test.cc
	test/fdct8x8_test.cc
	test/partial_idct_test.cc
	vp9/common/vp9_blockd.h
	vp9/common/vp9_idct.h
	vp9/common/vp9_rtcd_defs.pl
	vp9/decoder/vp9_decodeframe.c
	vp9/encoder/vp9_aq_complexity.c
	vp9/encoder/vp9_block.h
	vp9/encoder/vp9_dct.c
	vp9/encoder/vp9_encodeframe.c
	vp9/encoder/vp9_encodemb.c
	vp9/encoder/vp9_encoder.c
	vp9/encoder/vp9_firstpass.c
	vp9/encoder/vp9_pickmode.c
	vp9/encoder/vp9_quantize.c
	vp9/encoder/vp9_quantize.h
	vp9/encoder/vp9_ratectrl.c
	vp9/vp9_cx_iface.c

Change-Id: I402e1e91c6207c41a5bc1508ccfceec62196772b
2014-06-24 09:58:17 -07:00
Peter de Rivaz
6eb5e8ded6 Fix fps messages for 8bit mode
The addition of the high bitdepth image shifting
broke the fps measurement for the 8bit encoder.

Change-Id: I70144fe5c9a821b582d461091c616b0a3f666cbe
2014-06-24 14:20:27 +01:00
Peter de Rivaz
a13f2137fa Corrected check for valid upshifts
When converting 8-bit input streams to 10 or 12 bitdepth
an error message was incorrectly triggering.

Change-Id: I6252e2a6c8304863cc71b8764830c713ccee2ff2
2014-06-19 09:12:03 +01:00
Debargha Mukherjee
8ba0eeba1b Merge "Extended quantizer range for high bitdepth" into highbitdepth 2014-06-19 00:00:55 -07:00
Peter de Rivaz
8ca39ede47 Extended quantizer range for high bitdepth
These changes allow 10 and 12 bit depth streams
to encode at higher quality by using a finer
quantizer.  Category 6 tokens now transmit 18
extra bits instead of 14 in order to be able to
encode the greater range of output coefficients.

The extended quantizer range is only used when
configured with the following options:
--enable-vp9-high
--enable-high-transforms
--enable-high-quant

Change-Id: I58d2981676d67b65cc022e98cf443603d38ba6ff
2014-06-18 13:36:36 +01:00
Debargha Mukherjee
db55558e0b Merge "Allow encoding 10 bit input at 12 bitdepth" into highbitdepth 2014-06-17 09:43:37 -07:00
Peter de Rivaz
4c017c00e6 Allow encoding 10 bit input at 12 bitdepth
Change-Id: I85c3a08e97e738237527762d323ce22522ded304
2014-06-16 10:58:37 +01:00
Deb Mukherjee
20e745e8e4 Cosmetic cleanups
Use bit_depth_to_bps() inline function for consistency

Change-Id: Id79c8a82d40eab8fd87526a165837f7618e33993
2014-06-12 17:13:24 -07:00
Debargha Mukherjee
e0305995f3 Merge "Corrected highbitdepth aq variance" into highbitdepth 2014-06-12 08:31:32 -07:00
Peter de Rivaz
7ea0334f9a Corrected highbitdepth aq variance
Change-Id: Idfa10a8f92e2a4bd4c75cda68f3b800f119a4b1e
2014-06-12 13:44:23 +01:00
Peter de Rivaz
65d2615208 Fixed overflow in highbitdepth deblocking
Change-Id: Ia9f592e9ca3a1b8414c6bb39541a7fbdada4702a
2014-06-12 13:35:10 +01:00
Deb Mukherjee
9b33e1088f Adding error checking for 422/444 inputs.
For 422 and 444 inputs, adds checks for profile.

Change-Id: I1d8e1120d4214101ba9c27b81d4381dc61b22de5
2014-06-11 11:43:58 -07:00
Deb Mukherjee
8b72b71c1c Merge "Reworks high-bit-depth profiles" into highbitdepth 2014-06-11 06:04:14 -07:00
Deb Mukherjee
093a32ffd7 Reworks high-bit-depth profiles
Splits profile 2 into Profile 2 and 3, where profile 2
ony supports 420 sampling, while profile 3 adds 422/444 and
alpha. Keeps room for further expansion.

Also makes some minor changes in the decoder parameters,
replacing --convert-to-8bit with output-bit-depth.

Change-Id: I713525880512de6c36698d212795db1543c1d0dd
2014-06-10 17:30:45 -07:00
Peter de Rivaz
321bd42060 Improved highbitdepth RDO
Change-Id: I5bc6e94d9f3f64b2467f357da0d097347ad5f0c6
2014-06-10 16:52:31 -07:00
Deb Mukherjee
f08489e609 Better block error computation
Shift is applied after high-precision arithmetic rather than
before.

Change-Id: Ibd178fe8d10600935f6d5e790e89f3b2f8b4afcf
2014-06-09 17:41:42 -07:00
Peter de Rivaz
4320ac26ee Fixed overflow in high transforms
Added extremal forward and inverse tests
for the 8x8 DCT.

Change-Id: I5445c6449b0a9bda1359072617b915446510db69
2014-06-09 09:53:45 +01:00
Deb Mukherjee
e91d29dea3 Alternate rounding
Improves performance on derf by 0.89% for 10-bit internal
and by 0.55% for 12-bit internal, both for 8-bit sources.

Change-Id: I181fd9fb10e2259233d67cdd7933fb3cae334afc
2014-06-06 05:10:31 -07:00
Peter de Rivaz
091829d376 Scaled deblocking limits for highbitdepth
Slightly improves PSNR for some sequences.
Also fixes a bug.

Change-Id: Ibc4c2f5f5c280470c99dad642d153bd91cd90798
2014-06-05 03:22:28 -07:00
Peter de Rivaz
666fd1300c Added high precision transforms
The high precision are only used if
configured with --enable-high-transforms

It gives greater precision in the transform.
This gives PSNR improvements when encoding
true 10 and 12 bit streams.

At the moment, the quantizer used is shifted
up by 2/4 for 10/12 bits so that the quantized
coefficients fit in the current token range.

Change-Id: Ia9c19a417cf030b8a7a889fcb3f5788bfca8215f
2014-06-05 01:09:32 -07:00
Debargha Mukherjee
47354ee2f4 Merge "Fixed C postproc implementation" into highbitdepth 2014-06-04 11:23:40 -07:00
Debargha Mukherjee
0c95fcc25c Merge "Corrected highbitdepth temporal filter" into highbitdepth 2014-06-04 11:22:45 -07:00
Peter de Rivaz
3224fd3c66 Fixed C postproc implementation
Destination stride was not used correctly.

Change-Id: I503d037608fdcde3f433a87e103426ad4a6b9ef4
2014-06-04 17:28:24 +01:00
Peter de Rivaz
822c27cd42 Corrected highbitdepth temporal filter
Change-Id: Ic9aa3672ce0fe257133938b8e3a93f28d3cbb877
2014-06-04 16:07:24 +01:00
Peter de Rivaz
42a1a3e3ba Fix temporal filter for 422
Change-Id: I8f2fb8b8860010f0460a200c31edec4a17c773d8
2014-06-04 13:17:46 +01:00
Deb Mukherjee
51790ab228 Some code cleanups
Removes duplicate enums and other cosmetic changes.

Change-Id: Ic8b47534ac3b2b554a79ff1437fbe5f0503a5732
2014-06-03 16:20:23 -07:00
Peter de Rivaz
1ff621ec99 Added support for 10/12bit y4m
vpxenc now accepts high bitdepth y4m files
vpxdec now produces high bitdepth y4m files
(Only if the bitstream is high bitdepth)
Can force 8bit output via --covert-to-8bit

Change-Id: Ife9fc40772aceed32ba47d7ca81024ed09563721
2014-06-03 17:46:06 +01:00
Peter de Rivaz
b7649e15c2 Improved highbitdepth temporal filter
Increasing the strength when filtering
frames for highbitdepth gives a PSNR gain.

Change-Id: Iee2f776c1ae7b8da2ca4d5e58bb11fd0be2483f4
2014-06-03 14:22:43 +01:00
Peter de Rivaz
a79f06696d Changed rounding in high bitdepth
Doing the round before the subtraction
gives PSNR improvements.

Change-Id: Ic6fd16a9df9b9fdc2a4fa4140e8fa0994bd261a0
2014-06-03 14:07:10 +01:00
Peter de Rivaz
2baec56312 Tidied high bitdepth variance
Refactored code to match current style on master.
Also fixed a bug where some sse results were
not being shifted for high bitdepth.
Also increased internal bitdepth for variance to
avoid saturation.
Also added rounding for variance when computing
shifted results.

Change-Id: I322bbc1b9abe82c8ef72ab97991720240ddf755c
2014-06-03 12:47:17 +01:00
Deb Mukherjee
eb863b46f3 Reworks PSNR/SSIM to work on source bit-depth
Change-Id: Ifcd31186b67a57d57abd112d64d163c7b76728e9
2014-05-29 17:52:28 -07:00
Deb Mukherjee
5a2a78117f Adds input bit depth parameter and refactoring
Adds a place holder input bit depth parameter. Also
implements the bit-depth parameter and the new paramter
directly using config paramters rather than controls.
That makes it more convenient to handle.

Change-Id: Ie5bdc2d8eb5627d7a5f520b3d241aac5395dcf3d
2014-05-27 22:34:30 -07:00
Peter de Rivaz
cab30216a5 Merge branch 'master' into highbitdepth
Merges from master (May 26) to highbitdepth.

Change-Id: I553888a7b169b48e7bea07325d1127627a8f944e
2014-05-27 09:53:35 -07:00
Peter de Rivaz
efd115c415 Merge commit '9e7b09bc' into highbitdepth
Change-Id: I0376c867e7abfa7713ac6e7a4e604c8384fff58b
2014-05-23 14:06:31 -07:00
Deb Mukherjee
edd1fa0487 Rename test-high-internal to test-16bit-internal
More intuitive parameter naming.

Change-Id: Ie99ed54f5e832aa4c3893612c396b2b78722e275
2014-05-18 05:38:26 -07:00
Deb Mukherjee
747f0e3b8e Deprecates --input-shift parameter
Deprecates --input-shift parameter and instead derives that from
bit-depth assuming 8-bit input source. Eventually this needs to be
derived from the input-bit-depth parameter once we support high
bit depth input. Another parameter --test-high-internal is added
to force use of 16 bit internal buffers for testing purposes, in
profile 0 and 1.

Also --bit-depth parameter now uses values 8/10/12 which is more
intuitive than 0/1/2.

Also includes some cleanups.

Change-Id: I0bdd6d9caae8bb339d217551bb35a001057805ec
2014-05-16 22:32:22 -07:00
Debargha Mukherjee
094f0024c3 Merge changes Ida70ca48,Ieb2945bb into highbitdepth
* changes:
  Added rounding when using --output-shift
  Changed --output-shift option
2014-05-15 14:36:17 -07:00
Debargha Mukherjee
018173cf91 Merge "Fixed temporal filter rounding" into highbitdepth 2014-05-15 14:35:50 -07:00
Peter de Rivaz
87a571a34e Fixed temporal filter rounding
The temporal filter goes wrong
when strength is equal to 0.

See Issue 787.

Change-Id: I983c5983c34359ca78743a2434fb536c3a9b3e72
2014-05-15 16:23:55 +01:00
Peter de Rivaz
e037f0fa0c Fixed --test-decode for high bitdepth
Change-Id: I02b72dafad80a22ff0546a64c4a0fe757ac66861
2014-05-15 16:13:11 +01:00
Peter de Rivaz
4cba43ac3d Added rounding when using --output-shift
PSNR values are slightly improved by using
rounding when shifting images back to 8bit.

Change-Id: Ida70ca48588f933a92f906cd1ebc8e88134c07f5
2014-05-14 13:41:13 -07:00
Peter de Rivaz
aa2d8ca7e2 Changed --output-shift option
--output-shift now infers the amount to shift
from the bitdepth of the decoded file.

Option has been renamed to
--convert-to-8bit

Change-Id: Ieb2945bb282bb81c52a0c4f1b691c82bec5ec18c
2014-05-14 21:32:35 +01:00
Peter de Rivaz
c4a5ef1ced Added rounding to highbitdepth subtraction
This improves encoding performance for high
bitrate sequences when using 10 or 12bit.

Change-Id: I358d30a69251d58589c075b7d52c0d9ae76b26ee
2014-05-12 11:54:09 +01:00
Peter de Rivaz
99e1518a16 Added high bitdepth decoder scaling support
Change-Id: Id88da51d7f200ff347658140be3b5f6fe2d78121
2014-05-12 10:54:47 +01:00
Peter de Rivaz
83e566029c Changed debug function to also work with 16bit YUV
Change-Id: I14cd322d6e360dcd6499e0dc9cfdf44d9f6336e8
2014-05-12 10:52:48 +01:00
Peter de Rivaz
2535202902 Decoder can now output 16bit YUV
Change-Id: I9c390030571388fe4e9a463a3ee959364c9c7386
2014-05-12 10:49:36 +01:00
Peter de Rivaz
a9ed7c4434 Added high bitdepth support for decoder postproc
Change-Id: Id1fdf5c3c75b6b92a144f06284a7e0051345e60b
2014-05-12 10:46:44 +01:00
Peter de Rivaz
6956f43a90 Fixed bug in scale_and_extend_frame for 16bit
When configured in high bitdepth mode,
scale_and_extend_frame was always calling the
16bit code instead of dynamically switching.

Change-Id: I0542398d214a091d0740615689c786026aacedd6
2014-05-08 15:09:07 +01:00
Peter de Rivaz
9d427884e9 Fixed libyuv image copy for high bitdepth
When scaling and extending frames in high bitdepth,
there is a special case when no scaling is required.
This triggers a code path that calls CopyPlane16.
In this case the high bitdepth code was not
copying enough bytes.

Change-Id: I0fe2dc667ca8d7b0d03c0290a5716d53309c8198
2014-05-08 15:04:51 +01:00
Peter de Rivaz
ed352156c9 Added missing 8-bit image formats to vpx_image
This is needed for the high bitdepth work because
we use vpx image to allocate an output 8bit buffer.

Change-Id: I5404a628e9d207bf0a3a94bdb514611c836b68bd
2014-05-06 05:12:10 -07:00
Peter de Rivaz
df64b3d04a Added high bitdepth resize plane function.
Change-Id: I9b9d95fbed19f711a54a22d3181aca109a69f8f3
2014-05-06 05:12:00 -07:00
Peter de Rivaz
11f75a26c1 Use 16bit scaling function in vpxenc.
Change-Id: Ib8b25b558c0a0c1bc87863f592ea043cf65cc792
2014-05-06 05:11:51 -07:00
Peter de Rivaz
81758337d5 Added high bitdepth ssim functions.
Change-Id: Ib52d6882e1b9e58cd41d2771258a7a8c959730ec
2014-05-06 13:10:19 +01:00
Peter de Rivaz
4e016f6e21 Added call to high bitdepth sse in partition fn.
Change-Id: I647522cf1a633ec9a9db12f163c75f572081ecb7
2014-05-06 02:13:27 -07:00
Peter de Rivaz
22fbe77710 Corrected block_variance computation for high bitdepth.
Change-Id: I84ffe759b2a32ba208f915684a7a75f7f78ffa0b
2014-05-06 02:13:19 -07:00
Peter de Rivaz
d26ae35646 Fixed PSNR calculation for high bitdepth.
Change-Id: I7b60bd8b1c7a67aabf152f2f6f0c1ff5a7fbb43c
2014-05-06 02:12:48 -07:00
Peter de Rivaz
0b8ae49a05 Add control to read bit_depth
This is needed to calculate high bitdepth PSNR in vpxenc.c.

Change-Id: I60cea0e0a263e33ee1a8706517131c4b9fa1aafd
2014-05-06 02:12:21 -07:00
Peter de Rivaz
d868780eb9 Added high bitdepth support to postprocessing deblock and denoise.
Change-Id: I68d5521349dde2bc1832562cfd6f879966b8fcf1
2014-05-06 10:10:47 +01:00
Peter de Rivaz
bc0bc688c2 Added 16bit scaling functions to libyuv
This is an unoptimized C implementation of a 16bit
scaling function.

Change-Id: I4241442dde3cbf347988c555776a5cdd0189bb4d
2014-05-01 12:05:39 +01:00
Peter de Rivaz
a242def2aa Adding sad function generation macros
Tidying up the high bitdepth SAD implementation to match
the corresponding change 69783 on master.

Change-Id: I9c415a996a3ff237b2d25c57ad874284a45793fc
2014-05-01 11:49:44 +01:00
Peter de Rivaz
a0c772e381 Fix SAD adjustment to stop overrunning array
Change-Id: Ib98f5688abc80ebbaa6512f9b052b40640507744
2014-05-01 11:34:14 +01:00
Peter de Rivaz
d3e62b846b Template macros to generate subpix variance functions.
Tidying up the high bitdepth variance implementation to match
the corresponding change 69840 on master.

Change-Id: I213d28950e63cef7b9664639bc266f6a6a99c5f5
2014-05-01 10:23:12 +01:00
Peter de Rivaz
bdd7f74c3f Added initial support for 16-bit framebuffers.
Changes in this patch are only enabled if configured with
--enable-experimental --enable-vp9_high

Using a encoder command line argument of --input-shift=0 tells the coder
to work with 16bit framebuffers.
The output should be identical to before. Some features (such as input
image resizing) are not yet supported in 16bit mode.

Specifically, the behavior of the input-shift parameter is as follows:
* No argument : Behaviour as before, using 8bit frame buffers
* --experimental-bitstream --profile=2 --input-shift=0: Uses
  16bit frame buffers to store 8-bit data, should give identical output
  to before.
* --experimental-bitstream --profile=2 --input-shift=2 --bit-depth=1: Uses
  16bit frame buffers to store 10-bit data, encodes a version 2 stream
  with bitdepth 10
* --experimental-bitstream --profile=2 --input-shift=4 --bit-depth=2: Uses
  16bit frame buffers to store 12-bit data, encodes a version 2 stream
  with bitdepth 12

The decoder has an --output-shift argument which should be used when
decoding profile 2 streams.

So far support for the following has been added:
Intra filtering
Deblocking
Motion compensation
Variance calculation
Sad calculation
Transform

Change-Id: If345c88234aafdd40caea0d88935b1f07aaebe22
2014-04-28 22:11:19 -07:00
801 changed files with 85776 additions and 116756 deletions

6
.gitignore vendored
View File

@@ -30,32 +30,28 @@
/examples/decode_with_partial_drops /examples/decode_with_partial_drops
/examples/example_xma /examples/example_xma
/examples/postproc /examples/postproc
/examples/resize_util
/examples/set_maps /examples/set_maps
/examples/simple_decoder /examples/simple_decoder
/examples/simple_encoder /examples/simple_encoder
/examples/twopass_encoder /examples/twopass_encoder
/examples/vp8_multi_resolution_encoder /examples/vp8_multi_resolution_encoder
/examples/vp8cx_set_ref /examples/vp8cx_set_ref
/examples/vp9_lossless_encoder
/examples/vp9_spatial_scalable_encoder /examples/vp9_spatial_scalable_encoder
/examples/vpx_temporal_scalable_patterns /examples/vpx_temporal_scalable_patterns
/examples/vpx_temporal_svc_encoder
/ivfdec /ivfdec
/ivfdec.dox /ivfdec.dox
/ivfenc /ivfenc
/ivfenc.dox /ivfenc.dox
/libvpx.so* /libvpx.so*
/libvpx.ver /libvpx.ver
/obj_int_extract
/samples.dox /samples.dox
/test_intra_pred_speed
/test_libvpx /test_libvpx
/vp8_api1_migration.dox /vp8_api1_migration.dox
/vp[89x]_rtcd.h /vp[89x]_rtcd.h
/vpx.pc /vpx.pc
/vpx_config.c /vpx_config.c
/vpx_config.h /vpx_config.h
/vpx_dsp_rtcd.h
/vpx_scale_rtcd.h /vpx_scale_rtcd.h
/vpx_version.h /vpx_version.h
/vpxdec /vpxdec

View File

@@ -1,36 +1,18 @@
Adrian Grange <agrange@google.com> Adrian Grange <agrange@google.com>
Adrian Grange <agrange@google.com> <agrange@agrange-macbookpro.roam.corp.google.com>
Aex Converse <aconverse@google.com>
Aex Converse <aconverse@google.com> <alex.converse@gmail.com>
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com> Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
Alpha Lam <hclam@google.com> <hclam@chromium.org>
Deb Mukherjee <debargha@google.com>
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
Hangyu Kuang <hkuang@google.com> Hangyu Kuang <hkuang@google.com>
Hangyu Kuang <hkuang@google.com> <hkuang@hkuang-macbookpro.roam.corp.google.com>
Hui Su <huisu@google.com>
Jacky Chen <jackychen@google.com>
Jim Bankoski <jimbankoski@google.com> Jim Bankoski <jimbankoski@google.com>
John Koleszar <jkoleszar@google.com>
Johann Koenig <johannkoenig@google.com> Johann Koenig <johannkoenig@google.com>
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com> Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
Johann Koenig <johannkoenig@google.com> <johannkoenig@dhcp-172-19-7-52.mtv.corp.google.com> Johann Koenig <johannkoenig@google.com> <johannkoenig@dhcp-172-19-7-52.mtv.corp.google.com>
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.com>
John Koleszar <jkoleszar@google.com>
Joshua Litt <joshualitt@google.com> <joshualitt@chromium.org>
Marco Paniconi <marpan@google.com>
Marco Paniconi <marpan@google.com> <marpan@chromium.org>
Pascal Massimino <pascal.massimino@gmail.com> Pascal Massimino <pascal.massimino@gmail.com>
Paul Wilkins <paulwilkins@google.com>
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
Sami Pietilä <samipietila@google.com> Sami Pietilä <samipietila@google.com>
Tamar Levy <tamar.levy@intel.com>
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com> Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com> Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
Tom Finegan <tomfinegan@google.com> Tom Finegan <tomfinegan@google.com>
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org> Ralph Giles <giles@xiph.org> <giles@entropywave.com>
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
Alpha Lam <hclam@google.com> <hclam@chromium.org>
Deb Mukherjee <debargha@google.com>
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com> Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
Yaowu Xu <yaowu@google.com> <yaowu@YAOWU2-W.ad.corp.google.com>

40
AUTHORS
View File

@@ -3,11 +3,10 @@
Aaron Watry <awatry@gmail.com> Aaron Watry <awatry@gmail.com>
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com> Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
Adam Xu <adam@xuyaowu.com>
Adrian Grange <agrange@google.com> Adrian Grange <agrange@google.com>
Aex Converse <aconverse@google.com>
Ahmad Sharif <asharif@google.com> Ahmad Sharif <asharif@google.com>
Alexander Voronov <avoronov@graphics.cs.msu.ru> Alexander Voronov <avoronov@graphics.cs.msu.ru>
Alex Converse <alex.converse@gmail.com>
Alexis Ballier <aballier@gentoo.org> Alexis Ballier <aballier@gentoo.org>
Alok Ahuja <waveletcoeff@gmail.com> Alok Ahuja <waveletcoeff@gmail.com>
Alpha Lam <hclam@google.com> Alpha Lam <hclam@google.com>
@@ -15,65 +14,44 @@ A.Mahfoodh <ab.mahfoodh@gmail.com>
Ami Fischman <fischman@chromium.org> Ami Fischman <fischman@chromium.org>
Andoni Morales Alastruey <ylatuya@gmail.com> Andoni Morales Alastruey <ylatuya@gmail.com>
Andres Mejia <mcitadel@gmail.com> Andres Mejia <mcitadel@gmail.com>
Andrew Russell <anrussell@google.com>
Angie Chiang <angiebird@google.com>
Aron Rosenberg <arosenberg@logitech.com> Aron Rosenberg <arosenberg@logitech.com>
Attila Nagy <attilanagy@google.com> Attila Nagy <attilanagy@google.com>
Brion Vibber <bvibber@wikimedia.org>
changjun.yang <changjun.yang@intel.com> changjun.yang <changjun.yang@intel.com>
Charles 'Buck' Krasic <ckrasic@google.com>
chm <chm@rock-chips.com> chm <chm@rock-chips.com>
Christian Duvivier <cduvivier@google.com> Christian Duvivier <cduvivier@google.com>
Daniel Kang <ddkang@google.com> Daniel Kang <ddkang@google.com>
Deb Mukherjee <debargha@google.com> Deb Mukherjee <debargha@google.com>
Dim Temp <dimtemp0@gmail.com>
Dmitry Kovalev <dkovalev@google.com> Dmitry Kovalev <dkovalev@google.com>
Dragan Mrdjan <dmrdjan@mips.com> Dragan Mrdjan <dmrdjan@mips.com>
Ed Baker <edward.baker@intel.com> Erik Niemeyer <erik.a.niemeyer@gmail.com>
Ehsan Akhgari <ehsan.akhgari@gmail.com>
Erik Niemeyer <erik.a.niemeyer@intel.com>
Fabio Pedretti <fabio.ped@libero.it> Fabio Pedretti <fabio.ped@libero.it>
Frank Galligan <fgalligan@google.com> Frank Galligan <fgalligan@google.com>
Fredrik Söderquist <fs@opera.com> Fredrik Söderquist <fs@opera.com>
Fritz Koenig <frkoenig@google.com> Fritz Koenig <frkoenig@google.com>
Gaute Strokkenes <gaute.strokkenes@broadcom.com> Gaute Strokkenes <gaute.strokkenes@broadcom.com>
Geza Lore <gezalore@gmail.com>
Ghislain MARY <ghislainmary2@gmail.com>
Giuseppe Scrivano <gscrivano@gnu.org> Giuseppe Scrivano <gscrivano@gnu.org>
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
Guillaume Martres <gmartres@google.com> Guillaume Martres <gmartres@google.com>
Guillermo Ballester Valor <gbvalor@gmail.com> Guillermo Ballester Valor <gbvalor@gmail.com>
Hangyu Kuang <hkuang@google.com> Hangyu Kuang <hkuang@google.com>
Hanno Böck <hanno@hboeck.de>
Henrik Lundin <hlundin@google.com> Henrik Lundin <hlundin@google.com>
Hui Su <huisu@google.com> Hui Su <huisu@google.com>
Ivan Maltz <ivanmaltz@google.com> Ivan Maltz <ivanmaltz@google.com>
Jacek Caban <cjacek@gmail.com>
Jacky Chen <jackychen@google.com>
James Berry <jamesberry@google.com> James Berry <jamesberry@google.com>
James Yu <james.yu@linaro.org>
James Zern <jzern@google.com> James Zern <jzern@google.com>
Jan Gerber <j@mailb.org>
Jan Kratochvil <jan.kratochvil@redhat.com> Jan Kratochvil <jan.kratochvil@redhat.com>
Janne Salonen <jsalonen@google.com> Janne Salonen <jsalonen@google.com>
Jeff Faust <jfaust@google.com> Jeff Faust <jfaust@google.com>
Jeff Muizelaar <jmuizelaar@mozilla.com> Jeff Muizelaar <jmuizelaar@mozilla.com>
Jeff Petkau <jpet@chromium.org> Jeff Petkau <jpet@chromium.org>
Jia Jia <jia.jia@linaro.org>
Jim Bankoski <jimbankoski@google.com> Jim Bankoski <jimbankoski@google.com>
Jingning Han <jingning@google.com> Jingning Han <jingning@google.com>
Joey Parrish <joeyparrish@google.com>
Johann Koenig <johannkoenig@google.com> Johann Koenig <johannkoenig@google.com>
John Koleszar <jkoleszar@google.com> John Koleszar <jkoleszar@google.com>
Johnny Klonaris <google@jawknee.com>
John Stark <jhnstrk@gmail.com>
Joshua Bleecher Snyder <josh@treelinelabs.com> Joshua Bleecher Snyder <josh@treelinelabs.com>
Joshua Litt <joshualitt@google.com> Joshua Litt <joshualitt@google.com>
Julia Robson <juliamrobson@gmail.com>
Justin Clift <justin@salasaga.org> Justin Clift <justin@salasaga.org>
Justin Lebar <justin.lebar@gmail.com> Justin Lebar <justin.lebar@gmail.com>
KO Myung-Hun <komh@chollian.net> KO Myung-Hun <komh@chollian.net>
Lawrence Velázquez <larryv@macports.org>
Lou Quillio <louquillio@google.com> Lou Quillio <louquillio@google.com>
Luca Barbato <lu_zero@gentoo.org> Luca Barbato <lu_zero@gentoo.org>
Makoto Kato <makoto.kt@gmail.com> Makoto Kato <makoto.kt@gmail.com>
@@ -87,48 +65,36 @@ Michael Kohler <michaelkohler@live.com>
Mike Frysinger <vapier@chromium.org> Mike Frysinger <vapier@chromium.org>
Mike Hommey <mhommey@mozilla.com> Mike Hommey <mhommey@mozilla.com>
Mikhal Shemer <mikhal@google.com> Mikhal Shemer <mikhal@google.com>
Minghai Shang <minghai@google.com>
Morton Jonuschat <yabawock@gmail.com> Morton Jonuschat <yabawock@gmail.com>
Nico Weber <thakis@chromium.org>
Parag Salasakar <img.mips1@gmail.com> Parag Salasakar <img.mips1@gmail.com>
Pascal Massimino <pascal.massimino@gmail.com> Pascal Massimino <pascal.massimino@gmail.com>
Patrik Westin <patrik.westin@gmail.com> Patrik Westin <patrik.westin@gmail.com>
Paul Wilkins <paulwilkins@google.com> Paul Wilkins <paulwilkins@google.com>
Pavol Rusnak <stick@gk2.sk> Pavol Rusnak <stick@gk2.sk>
Paweł Hajdan <phajdan@google.com> Paweł Hajdan <phajdan@google.com>
Pengchong Jin <pengchong@google.com>
Peter de Rivaz <peter.derivaz@gmail.com>
Philip Jägenstedt <philipj@opera.com> Philip Jägenstedt <philipj@opera.com>
Priit Laes <plaes@plaes.org> Priit Laes <plaes@plaes.org>
Rafael Ávila de Espíndola <rafael.espindola@gmail.com> Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
Rafaël Carré <funman@videolan.org> Rafaël Carré <funman@videolan.org>
Ralph Giles <giles@xiph.org> Ralph Giles <giles@xiph.org>
Rob Bradford <rob@linux.intel.com> Rob Bradford <rob@linux.intel.com>
Ronald S. Bultje <rsbultje@gmail.com> Ronald S. Bultje <rbultje@google.com>
Rui Ueyama <ruiu@google.com>
Sami Pietilä <samipietila@google.com> Sami Pietilä <samipietila@google.com>
Scott Graham <scottmg@chromium.org> Scott Graham <scottmg@chromium.org>
Scott LaVarnway <slavarnway@google.com> Scott LaVarnway <slavarnway@google.com>
Sean McGovern <gseanmcg@gmail.com>
Sergey Ulanov <sergeyu@chromium.org>
Shimon Doodkin <helpmepro1@gmail.com> Shimon Doodkin <helpmepro1@gmail.com>
Shunyao Li <shunyaoli@google.com>
Stefan Holmer <holmer@google.com> Stefan Holmer <holmer@google.com>
Suman Sunkara <sunkaras@google.com> Suman Sunkara <sunkaras@google.com>
Taekhyun Kim <takim@nvidia.com> Taekhyun Kim <takim@nvidia.com>
Takanori MATSUURA <t.matsuu@gmail.com> Takanori MATSUURA <t.matsuu@gmail.com>
Tamar Levy <tamar.levy@intel.com> Tamar Levy <tamar.levy@intel.com>
Tao Bai <michaelbai@chromium.org>
Tero Rintaluoma <teror@google.com> Tero Rintaluoma <teror@google.com>
Thijs Vermeir <thijsvermeir@gmail.com> Thijs Vermeir <thijsvermeir@gmail.com>
Tim Kopp <tkopp@google.com>
Timothy B. Terriberry <tterribe@xiph.org> Timothy B. Terriberry <tterribe@xiph.org>
Tom Finegan <tomfinegan@google.com> Tom Finegan <tomfinegan@google.com>
Vignesh Venkatasubramanian <vigneshv@google.com> Vignesh Venkatasubramanian <vigneshv@google.com>
Yaowu Xu <yaowu@google.com> Yaowu Xu <yaowu@google.com>
Yongzhe Wang <yongzhe@google.com>
Yunqing Wang <yunqingwang@google.com> Yunqing Wang <yunqingwang@google.com>
Zoe Liu <zoeliu@google.com>
Google Inc. Google Inc.
The Mozilla Foundation The Mozilla Foundation
The Xiph.Org Foundation The Xiph.Org Foundation

View File

@@ -1,43 +1,3 @@
2015-11-09 v1.5.0 "Javan Whistling Duck"
This release improves upon the VP9 encoder and speeds up the encoding and
decoding processes.
- Upgrading:
This release is ABI incompatible with 1.4.0. It drops deprecated VP8
controls and adds a variety of VP9 controls for testing.
The vpxenc utility now prefers VP9 by default.
- Enhancements:
Faster VP9 encoding and decoding
Smaller library size by combining functions used by VP8 and VP9
- Bug Fixes:
A variety of fuzzing issues
2015-04-03 v1.4.0 "Indian Runner Duck"
This release includes significant improvements to the VP9 codec.
- Upgrading:
This release is ABI incompatible with 1.3.0. It drops the compatibility
layer, requiring VPX_IMG_FMT_* instead of IMG_FMT_*, and adds several codec
controls for VP9.
- Enhancements:
Faster VP9 encoding and decoding
Multithreaded VP9 decoding (tile and frame-based)
Multithreaded VP9 encoding - on by default
YUV 4:2:2 and 4:4:4 support in VP9
10 and 12bit support in VP9
64bit ARM support by replacing ARM assembly with intrinsics
- Bug Fixes:
Fixes a VP9 bitstream issue in Profile 1. This only affected non-YUV 4:2:0
files.
- Known Issues:
Frame Parallel decoding fails for segmented and non-420 files.
2013-11-15 v1.3.0 "Forest" 2013-11-15 v1.3.0 "Forest"
This release introduces the VP9 codec in a backward-compatible way. This release introduces the VP9 codec in a backward-compatible way.
All existing users of VP8 can continue to use the library without All existing users of VP8 can continue to use the library without

View File

@@ -17,7 +17,7 @@ or agree to the institution of patent litigation or any other patent
enforcement activity against any entity (including a cross-claim or enforcement activity against any entity (including a cross-claim or
counterclaim in a lawsuit) alleging that any of these implementations of WebM counterclaim in a lawsuit) alleging that any of these implementations of WebM
or any code incorporated within any of these implementations of WebM or any code incorporated within any of these implementations of WebM
constitute direct or contributory patent infringement, or inducement of constitutes direct or contributory patent infringement, or inducement of
patent infringement, then any patent rights granted to you under this License patent infringement, then any patent rights granted to you under this License
for these implementations of WebM shall terminate as of the date such for these implementations of WebM shall terminate as of the date such
litigation is filed. litigation is filed.

24
README
View File

@@ -1,4 +1,4 @@
README - 23 March 2015 README - 30 May 2014
Welcome to the WebM VP8/VP9 Codec SDK! Welcome to the WebM VP8/VP9 Codec SDK!
@@ -47,6 +47,10 @@ COMPILING THE APPLICATIONS/LIBRARIES:
--help output of the configure script. As of this writing, the list of --help output of the configure script. As of this writing, the list of
available targets is: available targets is:
armv5te-android-gcc
armv5te-linux-rvct
armv5te-linux-gcc
armv5te-none-rvct
armv6-darwin-gcc armv6-darwin-gcc
armv6-linux-rvct armv6-linux-rvct
armv6-linux-gcc armv6-linux-gcc
@@ -59,10 +63,15 @@ COMPILING THE APPLICATIONS/LIBRARIES:
armv7-none-rvct armv7-none-rvct
armv7-win32-vs11 armv7-win32-vs11
armv7-win32-vs12 armv7-win32-vs12
armv7-win32-vs14
armv7s-darwin-gcc armv7s-darwin-gcc
mips32-linux-gcc mips32-linux-gcc
mips64-linux-gcc mips64-linux-gcc
ppc32-darwin8-gcc
ppc32-darwin9-gcc
ppc32-linux-gcc
ppc64-darwin8-gcc
ppc64-darwin9-gcc
ppc64-linux-gcc
sparc-solaris-gcc sparc-solaris-gcc
x86-android-gcc x86-android-gcc
x86-darwin8-gcc x86-darwin8-gcc
@@ -73,7 +82,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86-darwin11-gcc x86-darwin11-gcc
x86-darwin12-gcc x86-darwin12-gcc
x86-darwin13-gcc x86-darwin13-gcc
x86-darwin14-gcc
x86-iphonesimulator-gcc x86-iphonesimulator-gcc
x86-linux-gcc x86-linux-gcc
x86-linux-icc x86-linux-icc
@@ -86,14 +94,11 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86-win32-vs10 x86-win32-vs10
x86-win32-vs11 x86-win32-vs11
x86-win32-vs12 x86-win32-vs12
x86-win32-vs14
x86_64-android-gcc
x86_64-darwin9-gcc x86_64-darwin9-gcc
x86_64-darwin10-gcc x86_64-darwin10-gcc
x86_64-darwin11-gcc x86_64-darwin11-gcc
x86_64-darwin12-gcc x86_64-darwin12-gcc
x86_64-darwin13-gcc x86_64-darwin13-gcc
x86_64-darwin14-gcc
x86_64-iphonesimulator-gcc x86_64-iphonesimulator-gcc
x86_64-linux-gcc x86_64-linux-gcc
x86_64-linux-icc x86_64-linux-icc
@@ -104,7 +109,12 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86_64-win64-vs10 x86_64-win64-vs10
x86_64-win64-vs11 x86_64-win64-vs11
x86_64-win64-vs12 x86_64-win64-vs12
x86_64-win64-vs14 universal-darwin8-gcc
universal-darwin9-gcc
universal-darwin10-gcc
universal-darwin11-gcc
universal-darwin12-gcc
universal-darwin13-gcc
generic-gnu generic-gnu
The generic-gnu target, in conjunction with the CROSS environment variable, The generic-gnu target, in conjunction with the CROSS environment variable,

4
args.c
View File

@@ -14,7 +14,9 @@
#include <limits.h> #include <limits.h>
#include "args.h" #include "args.h"
#include "vpx_ports/msvc.h" #ifdef _MSC_VER
#define snprintf _snprintf
#endif
#if defined(__GNUC__) && __GNUC__ #if defined(__GNUC__) && __GNUC__
extern void die(const char *fmt, ...) __attribute__((noreturn)); extern void die(const char *fmt, ...) __attribute__((noreturn));

View File

@@ -0,0 +1,18 @@
REM Copyright (c) 2013 The WebM project authors. All Rights Reserved.
REM
REM Use of this source code is governed by a BSD-style license
REM that can be found in the LICENSE file in the root of the source
REM tree. An additional intellectual property rights grant can be found
REM in the file PATENTS. All contributing project authors may
REM be found in the AUTHORS file in the root of the source tree.
echo on
REM Arguments:
REM %1 - Relative path to the directory containing the vp8 and vpx_scale
REM source directories.
REM %2 - Path to obj_int_extract.exe.
cl /I. /I%1 /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%~1/vp8/encoder/vp8_asm_enc_offsets.c"
%2\obj_int_extract.exe rvds "vp8_asm_enc_offsets.obj" > "vp8_asm_enc_offsets.asm"
cl /I. /I%1 /nologo /c /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP "%~1/vpx_scale/vpx_scale_asm_offsets.c"
%2\obj_int_extract.exe rvds "vpx_scale_asm_offsets.obj" > "vpx_scale_asm_offsets.asm"

View File

@@ -43,7 +43,7 @@
# will remove any NEON dependency. # will remove any NEON dependency.
# To change to building armeabi, run ./libvpx/configure again, but with # To change to building armeabi, run ./libvpx/configure again, but with
# --target=armv6-android-gcc and modify the Application.mk file to # --target=arm5te-android-gcc and modify the Application.mk file to
# set APP_ABI := armeabi # set APP_ABI := armeabi
# #
# Running ndk-build will build libvpx and include it in your project. # Running ndk-build will build libvpx and include it in your project.
@@ -60,15 +60,13 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
include $(CONFIG_DIR)libs-armv7-android-gcc.mk include $(CONFIG_DIR)libs-armv7-android-gcc.mk
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),armeabi) else ifeq ($(TARGET_ARCH_ABI),armeabi)
include $(CONFIG_DIR)libs-armv6-android-gcc.mk include $(CONFIG_DIR)libs-armv5te-android-gcc.mk
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a) else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
include $(CONFIG_DIR)libs-armv8-android-gcc.mk include $(CONFIG_DIR)libs-armv8-android-gcc.mk
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),x86) else ifeq ($(TARGET_ARCH_ABI),x86)
include $(CONFIG_DIR)libs-x86-android-gcc.mk include $(CONFIG_DIR)libs-x86-android-gcc.mk
else ifeq ($(TARGET_ARCH_ABI),x86_64)
include $(CONFIG_DIR)libs-x86_64-android-gcc.mk
else ifeq ($(TARGET_ARCH_ABI),mips) else ifeq ($(TARGET_ARCH_ABI),mips)
include $(CONFIG_DIR)libs-mips-android-gcc.mk include $(CONFIG_DIR)libs-mips-android-gcc.mk
else else
@@ -93,8 +91,51 @@ LOCAL_CFLAGS := -O3
# like x86inc.asm and x86_abi_support.asm # like x86inc.asm and x86_abi_support.asm
LOCAL_ASMFLAGS := -I$(LIBVPX_PATH) LOCAL_ASMFLAGS := -I$(LIBVPX_PATH)
# -----------------------------------------------------------------------------
# Template : asm_offsets_template
# Arguments : 1: assembly offsets file to be created
# 2: c file to base assembly offsets on
# Returns : None
# Usage : $(eval $(call asm_offsets_template,<asmfile>, <srcfile>
# Rationale : Create offsets at compile time using for structures that are
# defined in c, but used in assembly functions.
# -----------------------------------------------------------------------------
define asm_offsets_template
_SRC:=$(2)
_OBJ:=$(ASM_CNV_PATH)/$$(notdir $(2)).S
_FLAGS = $$($$(my)CFLAGS) \
$$(call get-src-file-target-cflags,$(2)) \
$$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(CONFIG_DIR)) \
$$(LOCAL_CFLAGS) \
$$(NDK_APP_CFLAGS) \
$$(call host-c-includes,$$($(my)C_INCLUDES)) \
-DINLINE_ASM \
-S \
_TEXT = "Compile $$(call get-src-file-text,$(2))"
_CC = $$(TARGET_CC)
$$(eval $$(call ev-build-file))
$(1) : $$(_OBJ) $(2)
@mkdir -p $$(dir $$@)
@grep $(OFFSET_PATTERN) $$< | tr -d '\#' | $(CONFIG_DIR)$(ASM_CONVERSION) > $$@
endef
# Use ads2gas script to convert from RVCT format to GAS format. This
# puts the processed file under $(ASM_CNV_PATH). Local clean rule
# to handle removing these
ifeq ($(CONFIG_VP8_ENCODER), yes)
ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/vp8_asm_enc_offsets.asm
endif
ifeq ($(HAVE_NEON_ASM), yes)
ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/vpx_scale_asm_offsets.asm
endif
.PRECIOUS: %.asm.s .PRECIOUS: %.asm.s
$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm $(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm $(ASM_CNV_OFFSETS_DEPEND)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@ @$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
@@ -160,44 +201,45 @@ LOCAL_CFLAGS += \
LOCAL_MODULE := libvpx LOCAL_MODULE := libvpx
LOCAL_LDLIBS := -llog
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes) ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
LOCAL_STATIC_LIBRARIES := cpufeatures LOCAL_STATIC_LIBRARIES := cpufeatures
endif endif
# Add a dependency to force generation of the RTCD files. # Add a dependency to force generation of the RTCD files.
define rtcd_dep_template
rtcd_dep_template_SRCS := $(addprefix $(LOCAL_PATH)/, $(LOCAL_SRC_FILES))
rtcd_dep_template_SRCS := $$(rtcd_dep_template_SRCS:.neon=)
ifeq ($(CONFIG_VP8), yes) ifeq ($(CONFIG_VP8), yes)
$$(rtcd_dep_template_SRCS): vp8_rtcd.h $(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp8_rtcd.h
endif endif
ifeq ($(CONFIG_VP9), yes) ifeq ($(CONFIG_VP9), yes)
$$(rtcd_dep_template_SRCS): vp9_rtcd.h $(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp9_rtcd.h
endif endif
ifeq ($(CONFIG_VP10), yes) $(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_scale_rtcd.h
$$(rtcd_dep_template_SRCS): vp10_rtcd.h
endif
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
ifneq ($(findstring $(TARGET_ARCH_ABI),x86 x86_64),) ifeq ($(TARGET_ARCH_ABI),x86)
$$(rtcd_dep_template_SRCS): vpx_config.asm $(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_config.asm
endif endif
endef
$(eval $(call rtcd_dep_template))
.PHONY: clean .PHONY: clean
clean: clean:
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]" @echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS) @$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
@$(RM) $(patsubst %.asm, %.*, $(ASM_CNV_OFFSETS_DEPEND))
@$(RM) -r $(ASM_CNV_PATH) @$(RM) -r $(ASM_CNV_PATH)
@$(RM) $(CLEAN-OBJS) @$(RM) $(CLEAN-OBJS)
ifeq ($(ENABLE_SHARED),1) include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)
else ifeq ($(HAVE_NEON), yes)
include $(BUILD_STATIC_LIBRARY) $(eval $(call asm_offsets_template,\
$(ASM_CNV_PATH)/vpx_scale_asm_offsets.asm, \
$(LIBVPX_PATH)/vpx_scale/vpx_scale_asm_offsets.c))
endif
ifeq ($(CONFIG_VP8_ENCODER), yes)
$(eval $(call asm_offsets_template,\
$(ASM_CNV_PATH)/vp8_asm_enc_offsets.asm, \
$(LIBVPX_PATH)/vp8/encoder/vp8_asm_enc_offsets.c))
endif endif
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes) ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)

View File

@@ -22,10 +22,8 @@ clean:: .DEFAULT
exampletest: .DEFAULT exampletest: .DEFAULT
install:: .DEFAULT install:: .DEFAULT
test:: .DEFAULT test:: .DEFAULT
test-no-data-check:: .DEFAULT
testdata:: .DEFAULT testdata:: .DEFAULT
utiltest: .DEFAULT utiltest: .DEFAULT
exampletest-no-data-check utiltest-no-data-check: .DEFAULT
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be # Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
@@ -58,10 +56,13 @@ dist:
fi fi
endif endif
# Since we invoke make recursively for multiple targets we need to include the
# .mk file for the correct target, but only when $(target) is non-empty.
ifneq ($(target),) ifneq ($(target),)
include $(target)-$(TOOLCHAIN).mk # Normally, we want to build the filename from the target and the toolchain.
# This disambiguates from the $(target).mk file that exists in the source tree.
# However, the toolchain is part of the target in universal builds, so we
# don't want to include TOOLCHAIN in that case. FAT_ARCHS is used to test
# if we're in the universal case.
include $(target)$(if $(FAT_ARCHS),,-$(TOOLCHAIN)).mk
endif endif
BUILD_ROOT?=. BUILD_ROOT?=.
VPATH=$(SRC_PATH_BARE) VPATH=$(SRC_PATH_BARE)
@@ -115,9 +116,6 @@ test::
testdata:: testdata::
.PHONY: utiltest .PHONY: utiltest
utiltest: utiltest:
.PHONY: test-no-data-check exampletest-no-data-check utiltest-no-data-check
test-no-data-check::
exampletest-no-data-check utiltest-no-data-check:
# Add compiler flags for intrinsic files # Add compiler flags for intrinsic files
ifeq ($(TOOLCHAIN), x86-os2-gcc) ifeq ($(TOOLCHAIN), x86-os2-gcc)
@@ -140,8 +138,6 @@ $(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx $(STACKREALIGN)
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx $(STACKREALIGN) $(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx $(STACKREALIGN)
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 $(STACKREALIGN) $(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 $(STACKREALIGN)
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 $(STACKREALIGN) $(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 $(STACKREALIGN)
$(BUILD_PFX)%vp9_reconintra.c.d: CFLAGS += $(STACKREALIGN)
$(BUILD_PFX)%vp9_reconintra.c.o: CFLAGS += $(STACKREALIGN)
$(BUILD_PFX)%.c.d: %.c $(BUILD_PFX)%.c.d: %.c
$(if $(quiet),@echo " [DEP] $@") $(if $(quiet),@echo " [DEP] $@")
@@ -150,7 +146,6 @@ $(BUILD_PFX)%.c.d: %.c
$(BUILD_PFX)%.c.o: %.c $(BUILD_PFX)%.c.o: %.c
$(if $(quiet),@echo " [CC] $@") $(if $(quiet),@echo " [CC] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $< $(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $<
$(BUILD_PFX)%.cc.d: %.cc $(BUILD_PFX)%.cc.d: %.cc
@@ -160,7 +155,6 @@ $(BUILD_PFX)%.cc.d: %.cc
$(BUILD_PFX)%.cc.o: %.cc $(BUILD_PFX)%.cc.o: %.cc
$(if $(quiet),@echo " [CXX] $@") $(if $(quiet),@echo " [CXX] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
$(BUILD_PFX)%.cpp.d: %.cpp $(BUILD_PFX)%.cpp.d: %.cpp
@@ -170,7 +164,6 @@ $(BUILD_PFX)%.cpp.d: %.cpp
$(BUILD_PFX)%.cpp.o: %.cpp $(BUILD_PFX)%.cpp.o: %.cpp
$(if $(quiet),@echo " [CXX] $@") $(if $(quiet),@echo " [CXX] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $< $(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
$(BUILD_PFX)%.asm.d: %.asm $(BUILD_PFX)%.asm.d: %.asm
@@ -181,7 +174,6 @@ $(BUILD_PFX)%.asm.d: %.asm
$(BUILD_PFX)%.asm.o: %.asm $(BUILD_PFX)%.asm.o: %.asm
$(if $(quiet),@echo " [AS] $@") $(if $(quiet),@echo " [AS] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(AS) $(ASFLAGS) -o $@ $< $(qexec)$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_PFX)%.s.d: %.s $(BUILD_PFX)%.s.d: %.s
@@ -192,14 +184,12 @@ $(BUILD_PFX)%.s.d: %.s
$(BUILD_PFX)%.s.o: %.s $(BUILD_PFX)%.s.o: %.s
$(if $(quiet),@echo " [AS] $@") $(if $(quiet),@echo " [AS] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(AS) $(ASFLAGS) -o $@ $< $(qexec)$(AS) $(ASFLAGS) -o $@ $<
.PRECIOUS: %.c.S .PRECIOUS: %.c.S
%.c.S: CFLAGS += -DINLINE_ASM %.c.S: CFLAGS += -DINLINE_ASM
$(BUILD_PFX)%.c.S: %.c $(BUILD_PFX)%.c.S: %.c
$(if $(quiet),@echo " [GEN] $@") $(if $(quiet),@echo " [GEN] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CC) -S $(CFLAGS) -o $@ $< $(qexec)$(CC) -S $(CFLAGS) -o $@ $<
.PRECIOUS: %.asm.s .PRECIOUS: %.asm.s
@@ -226,6 +216,14 @@ else
$(qexec)cp $< $@ $(qexec)cp $< $@
endif endif
#
# Rule to extract assembly constants from C sources
#
obj_int_extract: build/make/obj_int_extract.c
$(if $(quiet),@echo " [HOSTCC] $@")
$(qexec)$(HOSTCC) -I. -I$(SRC_PATH_BARE) -o $@ $<
CLEAN-OBJS += obj_int_extract
# #
# Utility functions # Utility functions
# #
@@ -287,7 +285,7 @@ define archive_template
# for creating them. # for creating them.
$(1): $(1):
$(if $(quiet),@echo " [AR] $$@") $(if $(quiet),@echo " [AR] $$@")
$(qexec)$$(AR) $$(ARFLAGS) $$@ $$^ $(qexec)$$(AR) $$(ARFLAGS) $$@ $$?
endef endef
define so_template define so_template
@@ -317,15 +315,18 @@ $(1):
$$(filter %.o,$$^) $$(extralibs) $$(filter %.o,$$^) $$(extralibs)
endef endef
define dll_template
# Not using a pattern rule here because we don't want to generate empty
# archives when they are listed as a dependency in files not responsible define lipo_lib_template
# for creating them. $(1): $(addsuffix /$(1),$(FAT_ARCHS))
$(1): $(if $(quiet),@echo " [LIPO] $$@")
$(if $(quiet),@echo " [LD] $$@") $(qexec)libtool -static -o $$@ $$?
$(qexec)$$(LD) -Zdll $$(LDFLAGS) \ endef
-o $$@ \
$$(filter %.o,$$^) $$(extralibs) $$(EXPORTS_FILE) define lipo_bin_template
$(1): $(addsuffix /$(1),$(FAT_ARCHS))
$(if $(quiet),@echo " [LIPO] $$@")
$(qexec)lipo -output $$@ -create $$?
endef endef
@@ -339,11 +340,9 @@ endif
skip_deps := $(filter %clean,$(MAKECMDGOALS)) skip_deps := $(filter %clean,$(MAKECMDGOALS))
skip_deps += $(findstring testdata,$(MAKECMDGOALS)) skip_deps += $(findstring testdata,$(MAKECMDGOALS))
ifeq ($(strip $(skip_deps)),) ifeq ($(strip $(skip_deps)),)
ifeq ($(CONFIG_DEPENDENCY_TRACKING),yes) # Older versions of make don't like -include directives with no arguments
# Older versions of make don't like -include directives with no arguments ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),)
ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),) -include $(filter %.d,$(OBJS-yes:.o=.d))
-include $(filter %.d,$(OBJS-yes:.o=.d))
endif
endif endif
endif endif
@@ -384,9 +383,8 @@ LIBS=$(call enabled,LIBS)
.libs: $(LIBS) .libs: $(LIBS)
@touch $@ @touch $@
$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib)))) $(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib))))
$(foreach lib,$(filter %so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR).$(SO_VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib)))) $(foreach lib,$(filter %so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib))))
$(foreach lib,$(filter %$(SO_VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib)))) $(foreach lib,$(filter %$(VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib))))
$(foreach lib,$(filter %$(SO_VERSION_MAJOR).dll,$(LIBS)),$(eval $(call dll_template,$(lib))))
INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS) INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS)
ifeq ($(MAKECMDGOALS),dist) ifeq ($(MAKECMDGOALS),dist)
@@ -426,7 +424,11 @@ ifneq ($(call enabled,DIST-SRCS),)
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh
DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh
DIST-SRCS-$(CONFIG_MSVS) += build/x86-msvs/obj_int_extract.bat
DIST-SRCS-$(CONFIG_MSVS) += build/arm-msvs/obj_int_extract.bat
DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh
# Include obj_int_extract if we use offsets from *_asm_*_offsets
DIST-SRCS-$(ARCH_ARM)$(ARCH_X86)$(ARCH_X86_64) += build/make/obj_int_extract.c
DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas.pl DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas.pl
DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas_apple.pl DIST-SRCS-$(ARCH_ARM) += build/make/ads2gas_apple.pl
DIST-SRCS-$(ARCH_ARM) += build/make/ads2armasm_ms.pl DIST-SRCS-$(ARCH_ARM) += build/make/ads2armasm_ms.pl

File diff suppressed because it is too large Load Diff

View File

@@ -73,10 +73,6 @@ generate_filter() {
open_tag File RelativePath="$f" open_tag File RelativePath="$f"
if [ "$pat" == "asm" ] && $asm_use_custom_step; then if [ "$pat" == "asm" ] && $asm_use_custom_step; then
# Avoid object file name collisions, i.e. vpx_config.c and
# vpx_config.asm produce the same object file without
# this additional suffix.
objf=${objf%.obj}_asm.obj
for plat in "${platforms[@]}"; do for plat in "${platforms[@]}"; do
for cfg in Debug Release; do for cfg in Debug Release; do
open_tag FileConfiguration \ open_tag FileConfiguration \
@@ -299,7 +295,22 @@ generate_vcproj() {
case "$target" in case "$target" in
x86*) x86*)
case "$name" in case "$name" in
obj_int_extract)
tag Tool \
Name="VCCLCompilerTool" \
Optimization="0" \
AdditionalIncludeDirectories="$incs" \
PreprocessorDefinitions="WIN32;DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \
RuntimeLibrary="$debug_runtime" \
WarningLevel="3" \
DebugInformationFormat="1" \
$warn_64bit \
;;
vpx) vpx)
tag Tool \
Name="VCPreBuildEventTool" \
CommandLine="call obj_int_extract.bat &quot;$src_path_bare&quot; $plat_no_ws\\\$(ConfigurationName)" \
tag Tool \ tag Tool \
Name="VCCLCompilerTool" \ Name="VCCLCompilerTool" \
Optimization="0" \ Optimization="0" \
@@ -336,6 +347,11 @@ generate_vcproj() {
case "$target" in case "$target" in
x86*) x86*)
case "$name" in case "$name" in
obj_int_extract)
tag Tool \
Name="VCLinkerTool" \
GenerateDebugInformation="true" \
;;
*) *)
tag Tool \ tag Tool \
Name="VCLinkerTool" \ Name="VCLinkerTool" \
@@ -384,7 +400,24 @@ generate_vcproj() {
case "$target" in case "$target" in
x86*) x86*)
case "$name" in case "$name" in
obj_int_extract)
tag Tool \
Name="VCCLCompilerTool" \
Optimization="2" \
FavorSizeorSpeed="1" \
AdditionalIncludeDirectories="$incs" \
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" \
RuntimeLibrary="$release_runtime" \
UsePrecompiledHeader="0" \
WarningLevel="3" \
DebugInformationFormat="0" \
$warn_64bit \
;;
vpx) vpx)
tag Tool \
Name="VCPreBuildEventTool" \
CommandLine="call obj_int_extract.bat &quot;$src_path_bare&quot; $plat_no_ws\\\$(ConfigurationName)" \
tag Tool \ tag Tool \
Name="VCCLCompilerTool" \ Name="VCCLCompilerTool" \
Optimization="2" \ Optimization="2" \
@@ -423,6 +456,11 @@ generate_vcproj() {
case "$target" in case "$target" in
x86*) x86*)
case "$name" in case "$name" in
obj_int_extract)
tag Tool \
Name="VCLinkerTool" \
GenerateDebugInformation="true" \
;;
*) *)
tag Tool \ tag Tool \
Name="VCLinkerTool" \ Name="VCLinkerTool" \

View File

@@ -19,13 +19,13 @@ show_help() {
cat <<EOF cat <<EOF
Usage: ${self_basename} [options] file1 [file2 ...] Usage: ${self_basename} [options] file1 [file2 ...]
This script generates a Visual Studio solution file from a list of project This script generates a Visual Studio 2005 solution file from a list of project
files. files.
Options: Options:
--help Print this message --help Print this message
--out=outfile Redirect output to a file --out=outfile Redirect output to a file
--ver=version Version (7,8,9,10,11,12,14) of visual studio to generate for --ver=version Version (7,8,9,10,11) of visual studio to generate for
--target=isa-os-cc Target specifier --target=isa-os-cc Target specifier
EOF EOF
exit 1 exit 1
@@ -255,7 +255,7 @@ for opt in "$@"; do
;; ;;
--ver=*) vs_ver="$optval" --ver=*) vs_ver="$optval"
case $optval in case $optval in
[789]|10|11|12|14) [789]|10|11|12)
;; ;;
*) die Unrecognized Visual Studio Version in $opt *) die Unrecognized Visual Studio Version in $opt
;; ;;
@@ -300,15 +300,12 @@ case "${vs_ver:-8}" in
12) sln_vers="12.00" 12) sln_vers="12.00"
sln_vers_str="Visual Studio 2013" sln_vers_str="Visual Studio 2013"
;; ;;
14) sln_vers="14.00"
sln_vers_str="Visual Studio 2015"
;;
esac esac
case "${vs_ver:-8}" in case "${vs_ver:-8}" in
[789]) [789])
sfx=vcproj sfx=vcproj
;; ;;
10|11|12|14) 10|11|12)
sfx=vcxproj sfx=vcxproj
;; ;;
esac esac

View File

@@ -34,7 +34,7 @@ Options:
--name=project_name Name of the project (required) --name=project_name Name of the project (required)
--proj-guid=GUID GUID to use for the project --proj-guid=GUID GUID to use for the project
--module-def=filename File containing export definitions (for DLLs) --module-def=filename File containing export definitions (for DLLs)
--ver=version Version (10,11,12,14) of visual studio to generate for --ver=version Version (10,11,12) of visual studio to generate for
--src-path-bare=dir Path to root of source tree --src-path-bare=dir Path to root of source tree
-Ipath/to/include Additional include directories -Ipath/to/include Additional include directories
-DFLAG[=value] Preprocessor macros to define -DFLAG[=value] Preprocessor macros to define
@@ -168,7 +168,7 @@ for opt in "$@"; do
--ver=*) --ver=*)
vs_ver="$optval" vs_ver="$optval"
case "$optval" in case "$optval" in
10|11|12|14) 10|11|12)
;; ;;
*) die Unrecognized Visual Studio Version in $opt *) die Unrecognized Visual Studio Version in $opt
;; ;;
@@ -218,7 +218,7 @@ guid=${guid:-`generate_uuid`}
asm_use_custom_step=false asm_use_custom_step=false
uses_asm=${uses_asm:-false} uses_asm=${uses_asm:-false}
case "${vs_ver:-11}" in case "${vs_ver:-11}" in
10|11|12|14) 10|11|12)
asm_use_custom_step=$uses_asm asm_use_custom_step=$uses_asm
;; ;;
esac esac
@@ -262,9 +262,15 @@ case "$target" in
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;%(FullPath)&quot;" asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;%(FullPath)&quot;"
;; ;;
arm*) arm*)
platforms[0]="ARM" asm_Debug_cmdline="armasm -nologo &quot;%(FullPath)&quot;"
asm_Debug_cmdline="armasm -nologo -oldit &quot;%(FullPath)&quot;" asm_Release_cmdline="armasm -nologo &quot;%(FullPath)&quot;"
asm_Release_cmdline="armasm -nologo -oldit &quot;%(FullPath)&quot;" if [ "$name" = "obj_int_extract" ]; then
# We don't want to build this tool for the target architecture,
# but for an architecture we can run locally during the build.
platforms[0]="Win32"
else
platforms[0]="ARM"
fi
;; ;;
*) die "Unsupported target $target!" *) die "Unsupported target $target!"
;; ;;
@@ -344,9 +350,6 @@ generate_vcxproj() {
# has to enable AppContainerApplication as well. # has to enable AppContainerApplication as well.
tag_content PlatformToolset v120 tag_content PlatformToolset v120
fi fi
if [ "$vs_ver" = "14" ]; then
tag_content PlatformToolset v140
fi
tag_content CharacterSet Unicode tag_content CharacterSet Unicode
if [ "$config" = "Release" ]; then if [ "$config" = "Release" ]; then
tag_content WholeProgramOptimization true tag_content WholeProgramOptimization true
@@ -397,13 +400,23 @@ generate_vcxproj() {
if [ "$hostplat" == "ARM" ]; then if [ "$hostplat" == "ARM" ]; then
hostplat=Win32 hostplat=Win32
fi fi
open_tag PreBuildEvent
tag_content Command "call obj_int_extract.bat &quot;$src_path_bare&quot; $hostplat\\\$(Configuration)"
close_tag PreBuildEvent
fi fi
open_tag ClCompile open_tag ClCompile
if [ "$config" = "Debug" ]; then if [ "$config" = "Debug" ]; then
opt=Disabled opt=Disabled
runtime=$debug_runtime runtime=$debug_runtime
curlibs=$debug_libs curlibs=$debug_libs
debug=_DEBUG case "$name" in
obj_int_extract)
debug=DEBUG
;;
*)
debug=_DEBUG
;;
esac
else else
opt=MaxSpeed opt=MaxSpeed
runtime=$release_runtime runtime=$release_runtime
@@ -411,7 +424,14 @@ generate_vcxproj() {
tag_content FavorSizeOrSpeed Speed tag_content FavorSizeOrSpeed Speed
debug=NDEBUG debug=NDEBUG
fi fi
extradefines=";$defines" case "$name" in
obj_int_extract)
extradefines=";_CONSOLE"
;;
*)
extradefines=";$defines"
;;
esac
tag_content Optimization $opt tag_content Optimization $opt
tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)" tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)"
tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)" tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)"
@@ -431,6 +451,10 @@ generate_vcxproj() {
case "$proj_kind" in case "$proj_kind" in
exe) exe)
open_tag Link open_tag Link
if [ "$name" != "obj_int_extract" ]; then
tag_content AdditionalDependencies "$curlibs;%(AdditionalDependencies)"
tag_content AdditionalLibraryDirectories "$libdirs;%(AdditionalLibraryDirectories)"
fi
tag_content GenerateDebugInformation true tag_content GenerateDebugInformation true
# Console is the default normally, but if # Console is the default normally, but if
# AppContainerApplication is set, we need to override it. # AppContainerApplication is set, we need to override it.

View File

@@ -18,18 +18,15 @@ set -e
devnull='> /dev/null 2>&1' devnull='> /dev/null 2>&1'
BUILD_ROOT="_iosbuild" BUILD_ROOT="_iosbuild"
CONFIGURE_ARGS="--disable-docs
--disable-examples
--disable-libyuv
--disable-unit-tests"
DIST_DIR="_dist" DIST_DIR="_dist"
FRAMEWORK_DIR="VPX.framework" FRAMEWORK_DIR="VPX.framework"
HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx" HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx"
SCRIPT_DIR=$(dirname "$0") MAKE_JOBS=1
LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd) LIBVPX_SOURCE_DIR=$(dirname "$0" | sed -e s,/build/make,,)
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo) LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
ORIG_PWD="$(pwd)" ORIG_PWD="$(pwd)"
TARGETS="arm64-darwin-gcc TARGETS="arm64-darwin-gcc
armv6-darwin-gcc
armv7-darwin-gcc armv7-darwin-gcc
armv7s-darwin-gcc armv7s-darwin-gcc
x86-iphonesimulator-gcc x86-iphonesimulator-gcc
@@ -40,24 +37,15 @@ TARGETS="arm64-darwin-gcc
build_target() { build_target() {
local target="$1" local target="$1"
local old_pwd="$(pwd)" local old_pwd="$(pwd)"
local target_specific_flags=""
vlog "***Building target: ${target}***" vlog "***Building target: ${target}***"
case "${target}" in
x86-*)
target_specific_flags="--enable-pic"
vlog "Enabled PIC for ${target}"
;;
esac
mkdir "${target}" mkdir "${target}"
cd "${target}" cd "${target}"
eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \ eval "../../${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${target_specific_flags} \ --disable-docs ${EXTRA_CONFIGURE_ARGS} ${devnull}
${devnull}
export DIST_DIR export DIST_DIR
eval make dist ${devnull} eval make -j ${MAKE_JOBS} dist ${devnull}
cd "${old_pwd}" cd "${old_pwd}"
vlog "***Done building target: ${target}***" vlog "***Done building target: ${target}***"
@@ -70,6 +58,9 @@ target_to_preproc_symbol() {
arm64-*) arm64-*)
echo "__aarch64__" echo "__aarch64__"
;; ;;
armv6-*)
echo "__ARM_ARCH_6__"
;;
armv7-*) armv7-*)
echo "__ARM_ARCH_7A__" echo "__ARM_ARCH_7A__"
;; ;;
@@ -185,13 +176,8 @@ build_framework() {
# Trap function. Cleans up the subtree used to build all targets contained in # Trap function. Cleans up the subtree used to build all targets contained in
# $TARGETS. # $TARGETS.
cleanup() { cleanup() {
local readonly res=$?
cd "${ORIG_PWD}" cd "${ORIG_PWD}"
if [ $res -ne 0 ]; then
elog "build exited with error ($res)"
fi
if [ "${PRESERVE_BUILD_OUTPUT}" != "yes" ]; then if [ "${PRESERVE_BUILD_OUTPUT}" != "yes" ]; then
rm -rf "${BUILD_ROOT}" rm -rf "${BUILD_ROOT}"
fi fi
@@ -201,22 +187,14 @@ iosbuild_usage() {
cat << EOF cat << EOF
Usage: ${0##*/} [arguments] Usage: ${0##*/} [arguments]
--help: Display this message and exit. --help: Display this message and exit.
--extra-configure-args <args>: Extra args to pass when configuring libvpx. --jobs: Number of make jobs.
--preserve-build-output: Do not delete the build directory. --preserve-build-output: Do not delete the build directory.
--show-build-output: Show output from each library build. --show-build-output: Show output from each library build.
--targets <targets>: Override default target list. Defaults:
${TARGETS}
--test-link: Confirms all targets can be linked. Functionally identical to
passing --enable-examples via --extra-configure-args.
--verbose: Output information about the environment and each stage of the --verbose: Output information about the environment and each stage of the
build. build.
EOF EOF
} }
elog() {
echo "${0##*/} failed because: $@" 1>&2
}
vlog() { vlog() {
if [ "${VERBOSE}" = "yes" ]; then if [ "${VERBOSE}" = "yes" ]; then
echo "$@" echo "$@"
@@ -236,19 +214,16 @@ while [ -n "$1" ]; do
iosbuild_usage iosbuild_usage
exit exit
;; ;;
--jobs)
MAKE_JOBS="$2"
shift
;;
--preserve-build-output) --preserve-build-output)
PRESERVE_BUILD_OUTPUT=yes PRESERVE_BUILD_OUTPUT=yes
;; ;;
--show-build-output) --show-build-output)
devnull= devnull=
;; ;;
--test-link)
EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --enable-examples"
;;
--targets)
TARGETS="$2"
shift
;;
--verbose) --verbose)
VERBOSE=yes VERBOSE=yes
;; ;;
@@ -264,19 +239,16 @@ if [ "${VERBOSE}" = "yes" ]; then
cat << EOF cat << EOF
BUILD_ROOT=${BUILD_ROOT} BUILD_ROOT=${BUILD_ROOT}
DIST_DIR=${DIST_DIR} DIST_DIR=${DIST_DIR}
CONFIGURE_ARGS=${CONFIGURE_ARGS}
EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS} EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
FRAMEWORK_DIR=${FRAMEWORK_DIR} FRAMEWORK_DIR=${FRAMEWORK_DIR}
HEADER_DIR=${HEADER_DIR} HEADER_DIR=${HEADER_DIR}
MAKE_JOBS=${MAKE_JOBS}
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR} LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR}
LIPO=${LIPO} LIPO=${LIPO}
MAKEFLAGS=${MAKEFLAGS}
ORIG_PWD=${ORIG_PWD} ORIG_PWD=${ORIG_PWD}
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
TARGETS="${TARGETS}" TARGETS="${TARGETS}"
EOF EOF
fi fi
build_framework "${TARGETS}" build_framework "${TARGETS}"
echo "Successfully built '${FRAMEWORK_DIR}' for:"
echo " ${TARGETS}"

View File

@@ -0,0 +1,857 @@
/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vpx_config.h"
#include "vpx/vpx_integer.h"
typedef enum {
OUTPUT_FMT_PLAIN,
OUTPUT_FMT_RVDS,
OUTPUT_FMT_GAS,
OUTPUT_FMT_C_HEADER,
} output_fmt_t;
int log_msg(const char *fmt, ...) {
int res;
va_list ap;
va_start(ap, fmt);
res = vfprintf(stderr, fmt, ap);
va_end(ap);
return res;
}
#if defined(__GNUC__) && __GNUC__
#if defined(FORCE_PARSE_ELF)
#if defined(__MACH__)
#undef __MACH__
#endif
#if !defined(__ELF__)
#define __ELF__
#endif
#endif
#if defined(__MACH__)
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
int print_macho_equ(output_fmt_t mode, uint8_t* name, int val) {
switch (mode) {
case OUTPUT_FMT_RVDS:
printf("%-40s EQU %5d\n", name, val);
return 0;
case OUTPUT_FMT_GAS:
printf(".set %-40s, %5d\n", name, val);
return 0;
case OUTPUT_FMT_C_HEADER:
printf("#define %-40s %5d\n", name, val);
return 0;
default:
log_msg("Unsupported mode: %d", mode);
return 1;
}
}
int parse_macho(uint8_t *base_buf, size_t sz, output_fmt_t mode) {
int i, j;
struct mach_header header;
uint8_t *buf = base_buf;
int base_data_section = 0;
int bits = 0;
/* We can read in mach_header for 32 and 64 bit architectures
* because it's identical to mach_header_64 except for the last
* element (uint32_t reserved), which we don't use. Then, when
* we know which architecture we're looking at, increment buf
* appropriately.
*/
memcpy(&header, buf, sizeof(struct mach_header));
if (header.magic == MH_MAGIC) {
if (header.cputype == CPU_TYPE_ARM
|| header.cputype == CPU_TYPE_X86) {
bits = 32;
buf += sizeof(struct mach_header);
} else {
log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_[ARM|X86].\n");
goto bail;
}
} else if (header.magic == MH_MAGIC_64) {
if (header.cputype == CPU_TYPE_X86_64) {
bits = 64;
buf += sizeof(struct mach_header_64);
} else {
log_msg("Bad cputype for object file. Currently only tested for CPU_TYPE_X86_64.\n");
goto bail;
}
} else {
log_msg("Bad magic number for object file. 0x%x or 0x%x expected, 0x%x found.\n",
MH_MAGIC, MH_MAGIC_64, header.magic);
goto bail;
}
if (header.filetype != MH_OBJECT) {
log_msg("Bad filetype for object file. Currently only tested for MH_OBJECT.\n");
goto bail;
}
for (i = 0; i < header.ncmds; i++) {
struct load_command lc;
memcpy(&lc, buf, sizeof(struct load_command));
if (lc.cmd == LC_SEGMENT) {
uint8_t *seg_buf = buf;
struct section s;
struct segment_command seg_c;
memcpy(&seg_c, seg_buf, sizeof(struct segment_command));
seg_buf += sizeof(struct segment_command);
/* Although each section is given it's own offset, nlist.n_value
* references the offset of the first section. This isn't
* apparent without debug information because the offset of the
* data section is the same as the first section. However, with
* debug sections mixed in, the offset of the debug section
* increases but n_value still references the first section.
*/
if (seg_c.nsects < 1) {
log_msg("Not enough sections\n");
goto bail;
}
memcpy(&s, seg_buf, sizeof(struct section));
base_data_section = s.offset;
} else if (lc.cmd == LC_SEGMENT_64) {
uint8_t *seg_buf = buf;
struct section_64 s;
struct segment_command_64 seg_c;
memcpy(&seg_c, seg_buf, sizeof(struct segment_command_64));
seg_buf += sizeof(struct segment_command_64);
/* Explanation in LG_SEGMENT */
if (seg_c.nsects < 1) {
log_msg("Not enough sections\n");
goto bail;
}
memcpy(&s, seg_buf, sizeof(struct section_64));
base_data_section = s.offset;
} else if (lc.cmd == LC_SYMTAB) {
if (base_data_section != 0) {
struct symtab_command sc;
uint8_t *sym_buf = base_buf;
uint8_t *str_buf = base_buf;
memcpy(&sc, buf, sizeof(struct symtab_command));
if (sc.cmdsize != sizeof(struct symtab_command)) {
log_msg("Can't find symbol table!\n");
goto bail;
}
sym_buf += sc.symoff;
str_buf += sc.stroff;
for (j = 0; j < sc.nsyms; j++) {
/* Location of string is cacluated each time from the
* start of the string buffer. On darwin the symbols
* are prefixed by "_", so we bump the pointer by 1.
* The target value is defined as an int in *_asm_*_offsets.c,
* which is 4 bytes on all targets we currently use.
*/
if (bits == 32) {
struct nlist nl;
int val;
memcpy(&nl, sym_buf, sizeof(struct nlist));
sym_buf += sizeof(struct nlist);
memcpy(&val, base_buf + base_data_section + nl.n_value,
sizeof(val));
print_macho_equ(mode, str_buf + nl.n_un.n_strx + 1, val);
} else { /* if (bits == 64) */
struct nlist_64 nl;
int val;
memcpy(&nl, sym_buf, sizeof(struct nlist_64));
sym_buf += sizeof(struct nlist_64);
memcpy(&val, base_buf + base_data_section + nl.n_value,
sizeof(val));
print_macho_equ(mode, str_buf + nl.n_un.n_strx + 1, val);
}
}
}
}
buf += lc.cmdsize;
}
return 0;
bail:
return 1;
}
#elif defined(__ELF__)
#include "elf.h"
#define COPY_STRUCT(dst, buf, ofst, sz) do {\
if(ofst + sizeof((*(dst))) > sz) goto bail;\
memcpy(dst, buf+ofst, sizeof((*(dst))));\
} while(0)
#define ENDIAN_ASSIGN(val, memb) do {\
if(!elf->le_data) {log_msg("Big Endian data not supported yet!\n");goto bail;}\
(val) = (memb);\
} while(0)
#define ENDIAN_ASSIGN_IN_PLACE(memb) do {\
ENDIAN_ASSIGN(memb, memb);\
} while(0)
typedef struct {
uint8_t *buf; /* Buffer containing ELF data */
size_t sz; /* Buffer size */
int le_data; /* Data is little-endian */
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
int bits; /* 32 or 64 */
Elf32_Ehdr hdr32;
Elf64_Ehdr hdr64;
} elf_obj_t;
int parse_elf_header(elf_obj_t *elf) {
int res;
/* Verify ELF Magic numbers */
COPY_STRUCT(&elf->e_ident, elf->buf, 0, elf->sz);
res = elf->e_ident[EI_MAG0] == ELFMAG0;
res &= elf->e_ident[EI_MAG1] == ELFMAG1;
res &= elf->e_ident[EI_MAG2] == ELFMAG2;
res &= elf->e_ident[EI_MAG3] == ELFMAG3;
res &= elf->e_ident[EI_CLASS] == ELFCLASS32
|| elf->e_ident[EI_CLASS] == ELFCLASS64;
res &= elf->e_ident[EI_DATA] == ELFDATA2LSB;
if (!res) goto bail;
elf->le_data = elf->e_ident[EI_DATA] == ELFDATA2LSB;
/* Read in relevant values */
if (elf->e_ident[EI_CLASS] == ELFCLASS32) {
elf->bits = 32;
COPY_STRUCT(&elf->hdr32, elf->buf, 0, elf->sz);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_type);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_machine);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_version);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_entry);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phoff);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shoff);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_flags);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_ehsize);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phentsize);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_phnum);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shentsize);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shnum);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr32.e_shstrndx);
} else { /* if (elf->e_ident[EI_CLASS] == ELFCLASS64) */
elf->bits = 64;
COPY_STRUCT(&elf->hdr64, elf->buf, 0, elf->sz);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_type);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_machine);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_version);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_entry);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phoff);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shoff);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_flags);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_ehsize);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phentsize);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_phnum);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shentsize);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shnum);
ENDIAN_ASSIGN_IN_PLACE(elf->hdr64.e_shstrndx);
}
return 0;
bail:
log_msg("Failed to parse ELF file header");
return 1;
}
int parse_elf_section(elf_obj_t *elf, int idx, Elf32_Shdr *hdr32, Elf64_Shdr *hdr64) {
if (hdr32) {
if (idx >= elf->hdr32.e_shnum)
goto bail;
COPY_STRUCT(hdr32, elf->buf, elf->hdr32.e_shoff + idx * elf->hdr32.e_shentsize,
elf->sz);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_name);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_type);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_flags);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addr);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_offset);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_size);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_link);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_info);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_addralign);
ENDIAN_ASSIGN_IN_PLACE(hdr32->sh_entsize);
} else { /* if (hdr64) */
if (idx >= elf->hdr64.e_shnum)
goto bail;
COPY_STRUCT(hdr64, elf->buf, elf->hdr64.e_shoff + idx * elf->hdr64.e_shentsize,
elf->sz);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_name);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_type);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_flags);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addr);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_offset);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_size);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_link);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_info);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_addralign);
ENDIAN_ASSIGN_IN_PLACE(hdr64->sh_entsize);
}
return 0;
bail:
return 1;
}
const char *parse_elf_string_table(elf_obj_t *elf, int s_idx, int idx) {
if (elf->bits == 32) {
Elf32_Shdr shdr;
if (parse_elf_section(elf, s_idx, &shdr, NULL)) {
log_msg("Failed to parse ELF string table: section %d, index %d\n",
s_idx, idx);
return "";
}
return (char *)(elf->buf + shdr.sh_offset + idx);
} else { /* if (elf->bits == 64) */
Elf64_Shdr shdr;
if (parse_elf_section(elf, s_idx, NULL, &shdr)) {
log_msg("Failed to parse ELF string table: section %d, index %d\n",
s_idx, idx);
return "";
}
return (char *)(elf->buf + shdr.sh_offset + idx);
}
}
int parse_elf_symbol(elf_obj_t *elf, unsigned int ofst, Elf32_Sym *sym32, Elf64_Sym *sym64) {
if (sym32) {
COPY_STRUCT(sym32, elf->buf, ofst, elf->sz);
ENDIAN_ASSIGN_IN_PLACE(sym32->st_name);
ENDIAN_ASSIGN_IN_PLACE(sym32->st_value);
ENDIAN_ASSIGN_IN_PLACE(sym32->st_size);
ENDIAN_ASSIGN_IN_PLACE(sym32->st_info);
ENDIAN_ASSIGN_IN_PLACE(sym32->st_other);
ENDIAN_ASSIGN_IN_PLACE(sym32->st_shndx);
} else { /* if (sym64) */
COPY_STRUCT(sym64, elf->buf, ofst, elf->sz);
ENDIAN_ASSIGN_IN_PLACE(sym64->st_name);
ENDIAN_ASSIGN_IN_PLACE(sym64->st_value);
ENDIAN_ASSIGN_IN_PLACE(sym64->st_size);
ENDIAN_ASSIGN_IN_PLACE(sym64->st_info);
ENDIAN_ASSIGN_IN_PLACE(sym64->st_other);
ENDIAN_ASSIGN_IN_PLACE(sym64->st_shndx);
}
return 0;
bail:
return 1;
}
int parse_elf(uint8_t *buf, size_t sz, output_fmt_t mode) {
elf_obj_t elf;
unsigned int ofst;
int i;
Elf32_Off strtab_off32;
Elf64_Off strtab_off64; /* save String Table offset for later use */
memset(&elf, 0, sizeof(elf));
elf.buf = buf;
elf.sz = sz;
/* Parse Header */
if (parse_elf_header(&elf))
goto bail;
if (elf.bits == 32) {
Elf32_Shdr shdr;
for (i = 0; i < elf.hdr32.e_shnum; i++) {
parse_elf_section(&elf, i, &shdr, NULL);
if (shdr.sh_type == SHT_STRTAB) {
char strtsb_name[128];
strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
if (!(strcmp(strtsb_name, ".shstrtab"))) {
/* log_msg("found section: %s\n", strtsb_name); */
strtab_off32 = shdr.sh_offset;
break;
}
}
}
} else { /* if (elf.bits == 64) */
Elf64_Shdr shdr;
for (i = 0; i < elf.hdr64.e_shnum; i++) {
parse_elf_section(&elf, i, NULL, &shdr);
if (shdr.sh_type == SHT_STRTAB) {
char strtsb_name[128];
strcpy(strtsb_name, (char *)(elf.buf + shdr.sh_offset + shdr.sh_name));
if (!(strcmp(strtsb_name, ".shstrtab"))) {
/* log_msg("found section: %s\n", strtsb_name); */
strtab_off64 = shdr.sh_offset;
break;
}
}
}
}
/* Parse all Symbol Tables */
if (elf.bits == 32) {
Elf32_Shdr shdr;
for (i = 0; i < elf.hdr32.e_shnum; i++) {
parse_elf_section(&elf, i, &shdr, NULL);
if (shdr.sh_type == SHT_SYMTAB) {
for (ofst = shdr.sh_offset;
ofst < shdr.sh_offset + shdr.sh_size;
ofst += shdr.sh_entsize) {
Elf32_Sym sym;
parse_elf_symbol(&elf, ofst, &sym, NULL);
/* For all OBJECTS (data objects), extract the value from the
* proper data segment.
*/
/* if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
log_msg("found data object %s\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name));
*/
if (ELF32_ST_TYPE(sym.st_info) == STT_OBJECT
&& sym.st_size == 4) {
Elf32_Shdr dhdr;
int val = 0;
char section_name[128];
parse_elf_section(&elf, sym.st_shndx, &dhdr, NULL);
/* For explanition - refer to _MSC_VER version of code */
strcpy(section_name, (char *)(elf.buf + strtab_off32 + dhdr.sh_name));
/* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
if (strcmp(section_name, ".bss")) {
if (sizeof(val) != sym.st_size) {
/* The target value is declared as an int in
* *_asm_*_offsets.c, which is 4 bytes on all
* targets we currently use. Complain loudly if
* this is not true.
*/
log_msg("Symbol size is wrong\n");
goto bail;
}
memcpy(&val,
elf.buf + dhdr.sh_offset + sym.st_value,
sym.st_size);
}
if (!elf.le_data) {
log_msg("Big Endian data not supported yet!\n");
goto bail;
}
switch (mode) {
case OUTPUT_FMT_RVDS:
printf("%-40s EQU %5d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
break;
case OUTPUT_FMT_GAS:
printf(".equ %-40s, %5d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
break;
case OUTPUT_FMT_C_HEADER:
printf("#define %-40s %5d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
break;
default:
printf("%s = %d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
}
}
}
}
}
} else { /* if (elf.bits == 64) */
Elf64_Shdr shdr;
for (i = 0; i < elf.hdr64.e_shnum; i++) {
parse_elf_section(&elf, i, NULL, &shdr);
if (shdr.sh_type == SHT_SYMTAB) {
for (ofst = shdr.sh_offset;
ofst < shdr.sh_offset + shdr.sh_size;
ofst += shdr.sh_entsize) {
Elf64_Sym sym;
parse_elf_symbol(&elf, ofst, NULL, &sym);
/* For all OBJECTS (data objects), extract the value from the
* proper data segment.
*/
/* if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT && sym.st_name)
log_msg("found data object %s\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name));
*/
if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT
&& sym.st_size == 4) {
Elf64_Shdr dhdr;
int val = 0;
char section_name[128];
parse_elf_section(&elf, sym.st_shndx, NULL, &dhdr);
/* For explanition - refer to _MSC_VER version of code */
strcpy(section_name, (char *)(elf.buf + strtab_off64 + dhdr.sh_name));
/* log_msg("Section_name: %s, Section_type: %d\n", section_name, dhdr.sh_type); */
if ((strcmp(section_name, ".bss"))) {
if (sizeof(val) != sym.st_size) {
/* The target value is declared as an int in
* *_asm_*_offsets.c, which is 4 bytes on all
* targets we currently use. Complain loudly if
* this is not true.
*/
log_msg("Symbol size is wrong\n");
goto bail;
}
memcpy(&val,
elf.buf + dhdr.sh_offset + sym.st_value,
sym.st_size);
}
if (!elf.le_data) {
log_msg("Big Endian data not supported yet!\n");
goto bail;
}
switch (mode) {
case OUTPUT_FMT_RVDS:
printf("%-40s EQU %5d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
break;
case OUTPUT_FMT_GAS:
printf(".equ %-40s, %5d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
break;
default:
printf("%s = %d\n",
parse_elf_string_table(&elf,
shdr.sh_link,
sym.st_name),
val);
}
}
}
}
}
}
if (mode == OUTPUT_FMT_RVDS)
printf(" END\n");
return 0;
bail:
log_msg("Parse error: File does not appear to be valid ELF32 or ELF64\n");
return 1;
}
#endif
#endif /* defined(__GNUC__) && __GNUC__ */
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
/* See "Microsoft Portable Executable and Common Object File Format Specification"
for reference.
*/
#define get_le32(x) ((*(x)) | (*(x+1)) << 8 |(*(x+2)) << 16 | (*(x+3)) << 24 )
#define get_le16(x) ((*(x)) | (*(x+1)) << 8)
int parse_coff(uint8_t *buf, size_t sz) {
unsigned int nsections, symtab_ptr, symtab_sz, strtab_ptr;
unsigned int sectionrawdata_ptr;
unsigned int i;
uint8_t *ptr;
uint32_t symoffset;
char **sectionlist; // this array holds all section names in their correct order.
// it is used to check if the symbol is in .bss or .rdata section.
nsections = get_le16(buf + 2);
symtab_ptr = get_le32(buf + 8);
symtab_sz = get_le32(buf + 12);
strtab_ptr = symtab_ptr + symtab_sz * 18;
if (nsections > 96) {
log_msg("Too many sections\n");
return 1;
}
sectionlist = malloc(nsections * sizeof(sectionlist));
if (sectionlist == NULL) {
log_msg("Allocating first level of section list failed\n");
return 1;
}
// log_msg("COFF: Found %u symbols in %u sections.\n", symtab_sz, nsections);
/*
The size of optional header is always zero for an obj file. So, the section header
follows the file header immediately.
*/
ptr = buf + 20; // section header
for (i = 0; i < nsections; i++) {
char sectionname[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
strncpy(sectionname, ptr, 8);
// log_msg("COFF: Parsing section %s\n",sectionname);
sectionlist[i] = malloc(strlen(sectionname) + 1);
if (sectionlist[i] == NULL) {
log_msg("Allocating storage for %s failed\n", sectionname);
goto bail;
}
strcpy(sectionlist[i], sectionname);
// check if it's .rdata and is not a COMDAT section.
if (!strcmp(sectionname, ".rdata") &&
(get_le32(ptr + 36) & 0x1000) == 0) {
sectionrawdata_ptr = get_le32(ptr + 20);
}
ptr += 40;
}
// log_msg("COFF: Symbol table at offset %u\n", symtab_ptr);
// log_msg("COFF: raw data pointer ofset for section .rdata is %u\n", sectionrawdata_ptr);
/* The compiler puts the data with non-zero offset in .rdata section, but puts the data with
zero offset in .bss section. So, if the data in in .bss section, set offset=0.
Note from Wiki: In an object module compiled from C, the bss section contains
the local variables (but not functions) that were declared with the static keyword,
except for those with non-zero initial values. (In C, static variables are initialized
to zero by default.) It also contains the non-local (both extern and static) variables
that are also initialized to zero (either explicitly or by default).
*/
// move to symbol table
/* COFF symbol table:
offset field
0 Name(*)
8 Value
12 SectionNumber
14 Type
16 StorageClass
17 NumberOfAuxSymbols
*/
ptr = buf + symtab_ptr;
for (i = 0; i < symtab_sz; i++) {
int16_t section = get_le16(ptr + 12); // section number
if (section > 0 && ptr[16] == 2) {
// if(section > 0 && ptr[16] == 3 && get_le32(ptr+8)) {
if (get_le32(ptr)) {
char name[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
strncpy(name, ptr, 8);
// log_msg("COFF: Parsing symbol %s\n",name);
/* The 64bit Windows compiler doesn't prefix with an _.
* Check what's there, and bump if necessary
*/
if (name[0] == '_')
printf("%-40s EQU ", name + 1);
else
printf("%-40s EQU ", name);
} else {
// log_msg("COFF: Parsing symbol %s\n",
// buf + strtab_ptr + get_le32(ptr+4));
if ((buf + strtab_ptr + get_le32(ptr + 4))[0] == '_')
printf("%-40s EQU ",
buf + strtab_ptr + get_le32(ptr + 4) + 1);
else
printf("%-40s EQU ", buf + strtab_ptr + get_le32(ptr + 4));
}
if (!(strcmp(sectionlist[section - 1], ".bss"))) {
symoffset = 0;
} else {
symoffset = get_le32(buf + sectionrawdata_ptr + get_le32(ptr + 8));
}
// log_msg(" Section: %d\n",section);
// log_msg(" Class: %d\n",ptr[16]);
// log_msg(" Address: %u\n",get_le32(ptr+8));
// log_msg(" Offset: %u\n", symoffset);
printf("%5d\n", symoffset);
}
ptr += 18;
}
printf(" END\n");
for (i = 0; i < nsections; i++) {
free(sectionlist[i]);
}
free(sectionlist);
return 0;
bail:
for (i = 0; i < nsections; i++) {
free(sectionlist[i]);
}
free(sectionlist);
return 1;
}
#endif /* defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) */
int main(int argc, char **argv) {
output_fmt_t mode = OUTPUT_FMT_PLAIN;
const char *f;
uint8_t *file_buf;
int res;
FILE *fp;
long int file_size;
if (argc < 2 || argc > 3) {
fprintf(stderr, "Usage: %s [output format] <obj file>\n\n", argv[0]);
fprintf(stderr, " <obj file>\tobject file to parse\n");
fprintf(stderr, "Output Formats:\n");
fprintf(stderr, " gas - compatible with GNU assembler\n");
fprintf(stderr, " rvds - compatible with armasm\n");
fprintf(stderr, " cheader - c/c++ header file\n");
goto bail;
}
f = argv[2];
if (!strcmp(argv[1], "rvds"))
mode = OUTPUT_FMT_RVDS;
else if (!strcmp(argv[1], "gas"))
mode = OUTPUT_FMT_GAS;
else if (!strcmp(argv[1], "cheader"))
mode = OUTPUT_FMT_C_HEADER;
else
f = argv[1];
fp = fopen(f, "rb");
if (!fp) {
perror("Unable to open file");
goto bail;
}
if (fseek(fp, 0, SEEK_END)) {
perror("stat");
goto bail;
}
file_size = ftell(fp);
file_buf = malloc(file_size);
if (!file_buf) {
perror("malloc");
goto bail;
}
rewind(fp);
if (fread(file_buf, sizeof(char), file_size, fp) != file_size) {
perror("read");
goto bail;
}
if (fclose(fp)) {
perror("close");
goto bail;
}
#if defined(__GNUC__) && __GNUC__
#if defined(__MACH__)
res = parse_macho(file_buf, file_size, mode);
#elif defined(__ELF__)
res = parse_elf(file_buf, file_size, mode);
#endif
#endif
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
res = parse_coff(file_buf, file_size);
#endif
free(file_buf);
if (!res)
return EXIT_SUCCESS;
bail:
return EXIT_FAILURE;
}

View File

@@ -319,15 +319,14 @@ EOF
print <<EOF; print <<EOF;
#if HAVE_DSPR2 #if HAVE_DSPR2
void vpx_dsputil_static_init();
#if CONFIG_VP8 #if CONFIG_VP8
void dsputil_static_init(); void dsputil_static_init();
#endif
vpx_dsputil_static_init();
#if CONFIG_VP8
dsputil_static_init(); dsputil_static_init();
#endif #endif
#if CONFIG_VP9
void vp9_dsputil_static_init();
vp9_dsputil_static_init();
#endif
#endif #endif
} }
#endif #endif
@@ -377,18 +376,17 @@ if ($opts{arch} eq 'x86') {
@ALL_ARCHS = filter("$opts{arch}", qw/dspr2/); @ALL_ARCHS = filter("$opts{arch}", qw/dspr2/);
last; last;
} }
if (/HAVE_MSA=yes/) {
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
last;
}
} }
close CONFIG_FILE; close CONFIG_FILE;
mips; mips;
} elsif ($opts{arch} eq 'armv6') { } elsif ($opts{arch} eq 'armv5te') {
@ALL_ARCHS = filter(qw/media/); @ALL_ARCHS = filter(qw/edsp/);
arm; arm;
} elsif ($opts{arch} =~ /armv7\w?/) { } elsif ($opts{arch} eq 'armv6') {
@ALL_ARCHS = filter(qw/media neon_asm neon/); @ALL_ARCHS = filter(qw/edsp media/);
arm;
} elsif ($opts{arch} eq 'armv7') {
@ALL_ARCHS = filter(qw/edsp media neon_asm neon/);
@REQUIRES = filter(keys %required ? keys %required : qw/media/); @REQUIRES = filter(keys %required ? keys %required : qw/media/);
&require(@REQUIRES); &require(@REQUIRES);
arm; arm;

View File

@@ -0,0 +1,15 @@
REM Copyright (c) 2011 The WebM project authors. All Rights Reserved.
REM
REM Use of this source code is governed by a BSD-style license
REM that can be found in the LICENSE file in the root of the source
REM tree. An additional intellectual property rights grant can be found
REM in the file PATENTS. All contributing project authors may
REM be found in the AUTHORS file in the root of the source tree.
echo on
REM Arguments:
REM %1 - Relative path to the directory containing the vp8 source directory.
REM %2 - Path to obj_int_extract.exe.
cl /I. /I%1 /nologo /c "%~1/vp8/encoder/vp8_asm_enc_offsets.c"
%2\obj_int_extract.exe rvds "vp8_asm_enc_offsets.obj" > "vp8_asm_enc_offsets.asm"

View File

@@ -1,4 +0,0 @@
# This file is used by gcl to get repository specific information.
GERRIT_HOST: chromium-review.googlesource.com
GERRIT_PORT: 29418
CODE_REVIEW_SERVER: chromium-review.googlesource.com

158
configure vendored
View File

@@ -26,19 +26,19 @@ Advanced options:
${toggle_unit_tests} unit tests ${toggle_unit_tests} unit tests
${toggle_decode_perf_tests} build decoder perf tests with unit tests ${toggle_decode_perf_tests} build decoder perf tests with unit tests
${toggle_encode_perf_tests} build encoder perf tests with unit tests ${toggle_encode_perf_tests} build encoder perf tests with unit tests
--cpu=CPU tune for the specified CPU (ARM: cortex-a8, X86: sse3)
--libc=PATH path to alternate libc --libc=PATH path to alternate libc
--size-limit=WxH max size to allow in the decoder --size-limit=WxH max size to allow in the decoder
--as={yasm|nasm|auto} use specified assembler [auto, yasm preferred] --as={yasm|nasm|auto} use specified assembler [auto, yasm preferred]
--sdk-path=PATH path to root of sdk (android builds only) --sdk-path=PATH path to root of sdk (android builds only)
${toggle_fast_unaligned} don't use unaligned accesses, even when
supported by hardware [auto]
${toggle_codec_srcs} in/exclude codec library source code ${toggle_codec_srcs} in/exclude codec library source code
${toggle_debug_libs} in/exclude debug version of libraries ${toggle_debug_libs} in/exclude debug version of libraries
${toggle_static_msvcrt} use static MSVCRT (VS builds only) ${toggle_static_msvcrt} use static MSVCRT (VS builds only)
${toggle_vp9_highbitdepth} use VP9 high bit depth (10/12) profiles
${toggle_vp8} VP8 codec support ${toggle_vp8} VP8 codec support
${toggle_vp9} VP9 codec support ${toggle_vp9} VP9 codec support
${toggle_vp10} VP10 codec support
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders) ${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
${toggle_mem_tracker} track memory usage
${toggle_postproc} postprocessing ${toggle_postproc} postprocessing
${toggle_vp9_postproc} vp9 specific postprocessing ${toggle_vp9_postproc} vp9 specific postprocessing
${toggle_multithread} multithreaded encoding and decoding ${toggle_multithread} multithreaded encoding and decoding
@@ -56,8 +56,6 @@ Advanced options:
${toggle_postproc_visualizer} macro block / block level visualizers ${toggle_postproc_visualizer} macro block / block level visualizers
${toggle_multi_res_encoding} enable multiple-resolution encoding ${toggle_multi_res_encoding} enable multiple-resolution encoding
${toggle_temporal_denoising} enable temporal denoising and disable the spatial denoiser ${toggle_temporal_denoising} enable temporal denoising and disable the spatial denoiser
${toggle_vp9_temporal_denoising}
enable vp9 temporal denoising
${toggle_webm_io} enable input from and output to WebM container ${toggle_webm_io} enable input from and output to WebM container
${toggle_libyuv} enable libyuv ${toggle_libyuv} enable libyuv
@@ -95,6 +93,10 @@ EOF
# all_platforms is a list of all supported target platforms. Maintain # all_platforms is a list of all supported target platforms. Maintain
# alphabetically by architecture, generic-gnu last. # alphabetically by architecture, generic-gnu last.
all_platforms="${all_platforms} armv5te-android-gcc"
all_platforms="${all_platforms} armv5te-linux-rvct"
all_platforms="${all_platforms} armv5te-linux-gcc"
all_platforms="${all_platforms} armv5te-none-rvct"
all_platforms="${all_platforms} armv6-darwin-gcc" all_platforms="${all_platforms} armv6-darwin-gcc"
all_platforms="${all_platforms} armv6-linux-rvct" all_platforms="${all_platforms} armv6-linux-rvct"
all_platforms="${all_platforms} armv6-linux-gcc" all_platforms="${all_platforms} armv6-linux-gcc"
@@ -107,10 +109,15 @@ all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8
all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8 all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
all_platforms="${all_platforms} armv7-win32-vs11" all_platforms="${all_platforms} armv7-win32-vs11"
all_platforms="${all_platforms} armv7-win32-vs12" all_platforms="${all_platforms} armv7-win32-vs12"
all_platforms="${all_platforms} armv7-win32-vs14"
all_platforms="${all_platforms} armv7s-darwin-gcc" all_platforms="${all_platforms} armv7s-darwin-gcc"
all_platforms="${all_platforms} mips32-linux-gcc" all_platforms="${all_platforms} mips32-linux-gcc"
all_platforms="${all_platforms} mips64-linux-gcc" all_platforms="${all_platforms} mips64-linux-gcc"
all_platforms="${all_platforms} ppc32-darwin8-gcc"
all_platforms="${all_platforms} ppc32-darwin9-gcc"
all_platforms="${all_platforms} ppc32-linux-gcc"
all_platforms="${all_platforms} ppc64-darwin8-gcc"
all_platforms="${all_platforms} ppc64-darwin9-gcc"
all_platforms="${all_platforms} ppc64-linux-gcc"
all_platforms="${all_platforms} sparc-solaris-gcc" all_platforms="${all_platforms} sparc-solaris-gcc"
all_platforms="${all_platforms} x86-android-gcc" all_platforms="${all_platforms} x86-android-gcc"
all_platforms="${all_platforms} x86-darwin8-gcc" all_platforms="${all_platforms} x86-darwin8-gcc"
@@ -121,7 +128,6 @@ all_platforms="${all_platforms} x86-darwin10-gcc"
all_platforms="${all_platforms} x86-darwin11-gcc" all_platforms="${all_platforms} x86-darwin11-gcc"
all_platforms="${all_platforms} x86-darwin12-gcc" all_platforms="${all_platforms} x86-darwin12-gcc"
all_platforms="${all_platforms} x86-darwin13-gcc" all_platforms="${all_platforms} x86-darwin13-gcc"
all_platforms="${all_platforms} x86-darwin14-gcc"
all_platforms="${all_platforms} x86-iphonesimulator-gcc" all_platforms="${all_platforms} x86-iphonesimulator-gcc"
all_platforms="${all_platforms} x86-linux-gcc" all_platforms="${all_platforms} x86-linux-gcc"
all_platforms="${all_platforms} x86-linux-icc" all_platforms="${all_platforms} x86-linux-icc"
@@ -134,14 +140,11 @@ all_platforms="${all_platforms} x86-win32-vs9"
all_platforms="${all_platforms} x86-win32-vs10" all_platforms="${all_platforms} x86-win32-vs10"
all_platforms="${all_platforms} x86-win32-vs11" all_platforms="${all_platforms} x86-win32-vs11"
all_platforms="${all_platforms} x86-win32-vs12" all_platforms="${all_platforms} x86-win32-vs12"
all_platforms="${all_platforms} x86-win32-vs14"
all_platforms="${all_platforms} x86_64-android-gcc"
all_platforms="${all_platforms} x86_64-darwin9-gcc" all_platforms="${all_platforms} x86_64-darwin9-gcc"
all_platforms="${all_platforms} x86_64-darwin10-gcc" all_platforms="${all_platforms} x86_64-darwin10-gcc"
all_platforms="${all_platforms} x86_64-darwin11-gcc" all_platforms="${all_platforms} x86_64-darwin11-gcc"
all_platforms="${all_platforms} x86_64-darwin12-gcc" all_platforms="${all_platforms} x86_64-darwin12-gcc"
all_platforms="${all_platforms} x86_64-darwin13-gcc" all_platforms="${all_platforms} x86_64-darwin13-gcc"
all_platforms="${all_platforms} x86_64-darwin14-gcc"
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc" all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
all_platforms="${all_platforms} x86_64-linux-gcc" all_platforms="${all_platforms} x86_64-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc" all_platforms="${all_platforms} x86_64-linux-icc"
@@ -152,7 +155,12 @@ all_platforms="${all_platforms} x86_64-win64-vs9"
all_platforms="${all_platforms} x86_64-win64-vs10" all_platforms="${all_platforms} x86_64-win64-vs10"
all_platforms="${all_platforms} x86_64-win64-vs11" all_platforms="${all_platforms} x86_64-win64-vs11"
all_platforms="${all_platforms} x86_64-win64-vs12" all_platforms="${all_platforms} x86_64-win64-vs12"
all_platforms="${all_platforms} x86_64-win64-vs14" all_platforms="${all_platforms} universal-darwin8-gcc"
all_platforms="${all_platforms} universal-darwin9-gcc"
all_platforms="${all_platforms} universal-darwin10-gcc"
all_platforms="${all_platforms} universal-darwin11-gcc"
all_platforms="${all_platforms} universal-darwin12-gcc"
all_platforms="${all_platforms} universal-darwin13-gcc"
all_platforms="${all_platforms} generic-gnu" all_platforms="${all_platforms} generic-gnu"
# all_targets is a list of all targets that can be configured # all_targets is a list of all targets that can be configured
@@ -189,14 +197,6 @@ if [ ${doxy_major:-0} -ge 1 ]; then
[ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable_feature doxygen [ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable_feature doxygen
fi fi
# disable codecs when their source directory does not exist
[ -d "${source_path}/vp8" ] || disable_feature vp8
[ -d "${source_path}/vp9" ] || disable_feature vp9
[ -d "${source_path}/vp10" ] || disable_feature vp10
# disable vp10 codec by default
disable_feature vp10
# install everything except the sources, by default. sources will have # install everything except the sources, by default. sources will have
# to be enabled when doing dist builds, since that's no longer a common # to be enabled when doing dist builds, since that's no longer a common
# case. # case.
@@ -206,31 +206,45 @@ enable_feature install_libs
enable_feature static enable_feature static
enable_feature optimizations enable_feature optimizations
enable_feature dependency_tracking enable_feature fast_unaligned #allow unaligned accesses, if supported by hw
enable_feature spatial_resampling enable_feature spatial_resampling
enable_feature multithread enable_feature multithread
enable_feature os_support enable_feature os_support
enable_feature temporal_denoising enable_feature temporal_denoising
CODECS=" [ -d "${source_path}/../include" ] && enable_feature alt_tree_layout
vp8_encoder for d in vp8 vp9; do
vp8_decoder [ -d "${source_path}/${d}" ] && disable_feature alt_tree_layout;
vp9_encoder done
vp9_decoder
vp10_encoder if ! enabled alt_tree_layout; then
vp10_decoder # development environment
" [ -d "${source_path}/vp8" ] && CODECS="${CODECS} vp8_encoder vp8_decoder"
CODEC_FAMILIES=" [ -d "${source_path}/vp9" ] && CODECS="${CODECS} vp9_encoder vp9_decoder"
vp8 else
vp9 # customer environment
vp10 [ -f "${source_path}/../include/vpx/vp8cx.h" ] && CODECS="${CODECS} vp8_encoder"
" [ -f "${source_path}/../include/vpx/vp8dx.h" ] && CODECS="${CODECS} vp8_decoder"
[ -f "${source_path}/../include/vpx/vp9cx.h" ] && CODECS="${CODECS} vp9_encoder"
[ -f "${source_path}/../include/vpx/vp9dx.h" ] && CODECS="${CODECS} vp9_decoder"
[ -f "${source_path}/../include/vpx/vp8cx.h" ] || disable_feature vp8_encoder
[ -f "${source_path}/../include/vpx/vp8dx.h" ] || disable_feature vp8_decoder
[ -f "${source_path}/../include/vpx/vp9cx.h" ] || disable_feature vp9_encoder
[ -f "${source_path}/../include/vpx/vp9dx.h" ] || disable_feature vp9_decoder
[ -f "${source_path}/../lib/*/*mt.lib" ] && soft_enable static_msvcrt
fi
CODECS="$(echo ${CODECS} | tr ' ' '\n')"
CODEC_FAMILIES="$(for c in ${CODECS}; do echo ${c%_*}; done | sort | uniq)"
ARCH_LIST=" ARCH_LIST="
arm arm
mips mips
x86 x86
x86_64 x86_64
ppc32
ppc64
" "
ARCH_EXT_LIST=" ARCH_EXT_LIST="
edsp edsp
@@ -240,7 +254,7 @@ ARCH_EXT_LIST="
mips32 mips32
dspr2 dspr2
msa
mips64 mips64
mmx mmx
@@ -251,23 +265,25 @@ ARCH_EXT_LIST="
sse4_1 sse4_1
avx avx
avx2 avx2
altivec
" "
HAVE_LIST=" HAVE_LIST="
${ARCH_EXT_LIST} ${ARCH_EXT_LIST}
vpx_ports vpx_ports
stdint_h stdint_h
alt_tree_layout
pthread_h pthread_h
sys_mman_h sys_mman_h
unistd_h unistd_h
" "
EXPERIMENT_LIST=" EXPERIMENT_LIST="
spatial_svc spatial_svc
vp9_temporal_denoising
fp_mb_stats fp_mb_stats
emulate_hardware emulate_hardware
misc_fixes
" "
CONFIG_LIST=" CONFIG_LIST="
dependency_tracking
external_build external_build
install_docs install_docs
install_bins install_bins
@@ -285,6 +301,10 @@ CONFIG_LIST="
codec_srcs codec_srcs
debug_libs debug_libs
fast_unaligned
mem_manager
mem_tracker
mem_checks
dequant_tokens dequant_tokens
dc_recon dc_recon
@@ -314,7 +334,6 @@ CONFIG_LIST="
encode_perf_tests encode_perf_tests
multi_res_encoding multi_res_encoding
temporal_denoising temporal_denoising
vp9_temporal_denoising
coefficient_range_checking coefficient_range_checking
vp9_highbitdepth vp9_highbitdepth
experimental experimental
@@ -322,7 +341,6 @@ CONFIG_LIST="
${EXPERIMENT_LIST} ${EXPERIMENT_LIST}
" "
CMDLINE_SELECT=" CMDLINE_SELECT="
dependency_tracking
external_build external_build
extra_warnings extra_warnings
werror werror
@@ -346,6 +364,7 @@ CMDLINE_SELECT="
libc libc
as as
size_limit size_limit
fast_unaligned
codec_srcs codec_srcs
debug_libs debug_libs
@@ -358,6 +377,7 @@ CMDLINE_SELECT="
${CODECS} ${CODECS}
${CODEC_FAMILIES} ${CODEC_FAMILIES}
static_msvcrt static_msvcrt
mem_tracker
spatial_resampling spatial_resampling
realtime_only realtime_only
onthefly_bitpacking onthefly_bitpacking
@@ -373,7 +393,6 @@ CMDLINE_SELECT="
encode_perf_tests encode_perf_tests
multi_res_encoding multi_res_encoding
temporal_denoising temporal_denoising
vp9_temporal_denoising
coefficient_range_checking coefficient_range_checking
vp9_highbitdepth vp9_highbitdepth
experimental experimental
@@ -430,8 +449,24 @@ post_process_cmdline() {
process_targets() { process_targets() {
enabled child || write_common_config_banner enabled child || write_common_config_banner
write_common_target_config_h ${BUILD_PFX}vpx_config.h enabled universal || write_common_target_config_h ${BUILD_PFX}vpx_config.h
# TODO: add host tools target (obj_int_extract, etc)
# For fat binaries, call configure recursively to configure for each
# binary architecture to be included.
if enabled universal; then
# Call configure (ourselves) for each subarchitecture
for arch in $fat_bin_archs; do
BUILD_PFX=${arch}/ toolchain=${arch} $self --child $cmdline_args || exit $?
done
fi
# The write_common_config (config.mk) logic is deferred until after the
# recursive calls to configure complete, because we want our universal
# targets to be executed last.
write_common_config_targets write_common_config_targets
enabled universal && echo "FAT_ARCHS=${fat_bin_archs}" >> config.mk
# Calculate the default distribution name, based on the enabled features # Calculate the default distribution name, based on the enabled features
cf="" cf=""
@@ -507,11 +542,11 @@ process_detect() {
# Can only build shared libs on a subset of platforms. Doing this check # Can only build shared libs on a subset of platforms. Doing this check
# here rather than at option parse time because the target auto-detect # here rather than at option parse time because the target auto-detect
# magic happens after the command line has been parsed. # magic happens after the command line has been parsed.
if ! enabled linux && ! enabled os2; then if ! enabled linux; then
if enabled gnu; then if enabled gnu; then
echo "--enable-shared is only supported on ELF; assuming this is OK" echo "--enable-shared is only supported on ELF; assuming this is OK"
else else
die "--enable-shared only supported on ELF and OS/2 for now" die "--enable-shared only supported on ELF for now"
fi fi
fi fi
fi fi
@@ -576,6 +611,30 @@ EOF
process_toolchain() { process_toolchain() {
process_common_toolchain process_common_toolchain
# Handle universal binaries for this architecture
case $toolchain in
universal-darwin*)
darwin_ver=${tgt_os##darwin}
# Snow Leopard (10.6/darwin10) dropped support for PPC
# Include PPC support for all prior versions
if [ $darwin_ver -lt 10 ]; then
fat_bin_archs="$fat_bin_archs ppc32-${tgt_os}-gcc"
fi
# Tiger (10.4/darwin8) brought support for x86
if [ $darwin_ver -ge 8 ]; then
fat_bin_archs="$fat_bin_archs x86-${tgt_os}-${tgt_cc}"
fi
# Leopard (10.5/darwin9) brought 64 bit support
if [ $darwin_ver -ge 9 ]; then
fat_bin_archs="$fat_bin_archs x86_64-${tgt_os}-${tgt_cc}"
fi
;;
esac
# Enable some useful compiler flags # Enable some useful compiler flags
if enabled gcc; then if enabled gcc; then
enabled werror && check_add_cflags -Werror enabled werror && check_add_cflags -Werror
@@ -651,7 +710,7 @@ process_toolchain() {
VCPROJ_SFX=vcproj VCPROJ_SFX=vcproj
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh
;; ;;
10|11|12|14) 10|11|12)
VCPROJ_SFX=vcxproj VCPROJ_SFX=vcxproj
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror" enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
@@ -663,7 +722,7 @@ process_toolchain() {
esac esac
# Other toolchain specific defaults # Other toolchain specific defaults
case $toolchain in x86*) soft_enable postproc;; esac case $toolchain in x86*|ppc*|universal*) soft_enable postproc;; esac
if enabled postproc_visualizer; then if enabled postproc_visualizer; then
enabled postproc || die "postproc_visualizer requires postproc to be enabled" enabled postproc || die "postproc_visualizer requires postproc to be enabled"
@@ -717,16 +776,6 @@ EOF
esac esac
# libwebm needs to be linked with C++ standard library # libwebm needs to be linked with C++ standard library
enabled webm_io && LD=${CXX} enabled webm_io && LD=${CXX}
# append any user defined extra cflags
if [ -n "${extra_cflags}" ] ; then
check_add_cflags ${extra_cflags} || \
die "Requested extra CFLAGS '${extra_cflags}' not supported by compiler"
fi
if [ -n "${extra_cxxflags}" ]; then
check_add_cxxflags ${extra_cxxflags} || \
die "Requested extra CXXFLAGS '${extra_cxxflags}' not supported by compiler"
fi
} }
@@ -737,7 +786,6 @@ CONFIGURE_ARGS="$@"
process "$@" process "$@"
print_webm_license ${BUILD_PFX}vpx_config.c "/*" " */" print_webm_license ${BUILD_PFX}vpx_config.c "/*" " */"
cat <<EOF >> ${BUILD_PFX}vpx_config.c cat <<EOF >> ${BUILD_PFX}vpx_config.c
#include "vpx/vpx_codec.h"
static const char* const cfg = "$CONFIGURE_ARGS"; static const char* const cfg = "$CONFIGURE_ARGS";
const char *vpx_codec_build_config(void) {return cfg;} const char *vpx_codec_build_config(void) {return cfg;}
EOF EOF

View File

@@ -22,22 +22,19 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
third_party/libyuv/source/planar_functions.cc \ third_party/libyuv/source/planar_functions.cc \
third_party/libyuv/source/row_any.cc \ third_party/libyuv/source/row_any.cc \
third_party/libyuv/source/row_common.cc \ third_party/libyuv/source/row_common.cc \
third_party/libyuv/source/row_gcc.cc \
third_party/libyuv/source/row_mips.cc \ third_party/libyuv/source/row_mips.cc \
third_party/libyuv/source/row_neon.cc \ third_party/libyuv/source/row_neon.cc \
third_party/libyuv/source/row_neon64.cc \ third_party/libyuv/source/row_neon64.cc \
third_party/libyuv/source/row_posix.cc \
third_party/libyuv/source/row_win.cc \ third_party/libyuv/source/row_win.cc \
third_party/libyuv/source/scale.cc \ third_party/libyuv/source/scale.cc \
third_party/libyuv/source/scale_any.cc \
third_party/libyuv/source/scale_common.cc \ third_party/libyuv/source/scale_common.cc \
third_party/libyuv/source/scale_gcc.cc \
third_party/libyuv/source/scale_mips.cc \ third_party/libyuv/source/scale_mips.cc \
third_party/libyuv/source/scale_neon.cc \ third_party/libyuv/source/scale_neon.cc \
third_party/libyuv/source/scale_neon64.cc \ third_party/libyuv/source/scale_neon64.cc \
third_party/libyuv/source/scale_posix.cc \
third_party/libyuv/source/scale_win.cc \ third_party/libyuv/source/scale_win.cc \
LIBWEBM_COMMON_SRCS += third_party/libwebm/webmids.hpp
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \ LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \
third_party/libwebm/mkvmuxerutil.cpp \ third_party/libwebm/mkvmuxerutil.cpp \
third_party/libwebm/mkvwriter.cpp \ third_party/libwebm/mkvwriter.cpp \
@@ -45,7 +42,8 @@ LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \
third_party/libwebm/mkvmuxertypes.hpp \ third_party/libwebm/mkvmuxertypes.hpp \
third_party/libwebm/mkvmuxerutil.hpp \ third_party/libwebm/mkvmuxerutil.hpp \
third_party/libwebm/mkvparser.hpp \ third_party/libwebm/mkvparser.hpp \
third_party/libwebm/mkvwriter.hpp third_party/libwebm/mkvwriter.hpp \
third_party/libwebm/webmids.hpp
LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser.cpp \ LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser.cpp \
third_party/libwebm/mkvreader.cpp \ third_party/libwebm/mkvreader.cpp \
@@ -58,7 +56,6 @@ UTILS-$(CONFIG_DECODERS) += vpxdec.c
vpxdec.SRCS += md5_utils.c md5_utils.h vpxdec.SRCS += md5_utils.c md5_utils.h
vpxdec.SRCS += vpx_ports/mem_ops.h vpxdec.SRCS += vpx_ports/mem_ops.h
vpxdec.SRCS += vpx_ports/mem_ops_aligned.h vpxdec.SRCS += vpx_ports/mem_ops_aligned.h
vpxdec.SRCS += vpx_ports/msvc.h
vpxdec.SRCS += vpx_ports/vpx_timer.h vpxdec.SRCS += vpx_ports/vpx_timer.h
vpxdec.SRCS += vpx/vpx_integer.h vpxdec.SRCS += vpx/vpx_integer.h
vpxdec.SRCS += args.c args.h vpxdec.SRCS += args.c args.h
@@ -69,7 +66,6 @@ ifeq ($(CONFIG_LIBYUV),yes)
vpxdec.SRCS += $(LIBYUV_SRCS) vpxdec.SRCS += $(LIBYUV_SRCS)
endif endif
ifeq ($(CONFIG_WEBM_IO),yes) ifeq ($(CONFIG_WEBM_IO),yes)
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS) vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS)
vpxdec.SRCS += webmdec.cc webmdec.h vpxdec.SRCS += webmdec.cc webmdec.h
endif endif
@@ -84,14 +80,12 @@ vpxenc.SRCS += tools_common.c tools_common.h
vpxenc.SRCS += warnings.c warnings.h vpxenc.SRCS += warnings.c warnings.h
vpxenc.SRCS += vpx_ports/mem_ops.h vpxenc.SRCS += vpx_ports/mem_ops.h
vpxenc.SRCS += vpx_ports/mem_ops_aligned.h vpxenc.SRCS += vpx_ports/mem_ops_aligned.h
vpxenc.SRCS += vpx_ports/msvc.h
vpxenc.SRCS += vpx_ports/vpx_timer.h vpxenc.SRCS += vpx_ports/vpx_timer.h
vpxenc.SRCS += vpxstats.c vpxstats.h vpxenc.SRCS += vpxstats.c vpxstats.h
ifeq ($(CONFIG_LIBYUV),yes) ifeq ($(CONFIG_LIBYUV),yes)
vpxenc.SRCS += $(LIBYUV_SRCS) vpxenc.SRCS += $(LIBYUV_SRCS)
endif endif
ifeq ($(CONFIG_WEBM_IO),yes) ifeq ($(CONFIG_WEBM_IO),yes)
vpxenc.SRCS += $(LIBWEBM_COMMON_SRCS)
vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS) vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS)
vpxenc.SRCS += webmenc.cc webmenc.h vpxenc.SRCS += webmenc.cc webmenc.h
endif endif
@@ -104,7 +98,6 @@ ifeq ($(CONFIG_SPATIAL_SVC),yes)
vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h vp9_spatial_svc_encoder.SRCS += tools_common.c tools_common.h
vp9_spatial_svc_encoder.SRCS += video_common.h vp9_spatial_svc_encoder.SRCS += video_common.h
vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c vp9_spatial_svc_encoder.SRCS += video_writer.h video_writer.c
vp9_spatial_svc_encoder.SRCS += vpx_ports/msvc.h
vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h vp9_spatial_svc_encoder.SRCS += vpxstats.c vpxstats.h
vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D vp9_spatial_svc_encoder.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D
vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder
@@ -119,7 +112,6 @@ vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h
vpx_temporal_svc_encoder.SRCS += video_common.h vpx_temporal_svc_encoder.SRCS += video_common.h
vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c
vpx_temporal_svc_encoder.SRCS += vpx_ports/msvc.h
vpx_temporal_svc_encoder.GUID = B18C08F2-A439-4502-A78E-849BE3D60947 vpx_temporal_svc_encoder.GUID = B18C08F2-A439-4502-A78E-849BE3D60947
vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder
EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
@@ -130,7 +122,6 @@ simple_decoder.SRCS += video_common.h
simple_decoder.SRCS += video_reader.h video_reader.c simple_decoder.SRCS += video_reader.h video_reader.c
simple_decoder.SRCS += vpx_ports/mem_ops.h simple_decoder.SRCS += vpx_ports/mem_ops.h
simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h
simple_decoder.SRCS += vpx_ports/msvc.h
simple_decoder.DESCRIPTION = Simplified decoder loop simple_decoder.DESCRIPTION = Simplified decoder loop
EXAMPLES-$(CONFIG_DECODERS) += postproc.c EXAMPLES-$(CONFIG_DECODERS) += postproc.c
postproc.SRCS += ivfdec.h ivfdec.c postproc.SRCS += ivfdec.h ivfdec.c
@@ -139,7 +130,6 @@ postproc.SRCS += video_common.h
postproc.SRCS += video_reader.h video_reader.c postproc.SRCS += video_reader.h video_reader.c
postproc.SRCS += vpx_ports/mem_ops.h postproc.SRCS += vpx_ports/mem_ops.h
postproc.SRCS += vpx_ports/mem_ops_aligned.h postproc.SRCS += vpx_ports/mem_ops_aligned.h
postproc.SRCS += vpx_ports/msvc.h
postproc.GUID = 65E33355-F35E-4088-884D-3FD4905881D7 postproc.GUID = 65E33355-F35E-4088-884D-3FD4905881D7
postproc.DESCRIPTION = Decoder postprocessor control postproc.DESCRIPTION = Decoder postprocessor control
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
@@ -150,7 +140,6 @@ decode_to_md5.SRCS += video_common.h
decode_to_md5.SRCS += video_reader.h video_reader.c decode_to_md5.SRCS += video_reader.h video_reader.c
decode_to_md5.SRCS += vpx_ports/mem_ops.h decode_to_md5.SRCS += vpx_ports/mem_ops.h
decode_to_md5.SRCS += vpx_ports/mem_ops_aligned.h decode_to_md5.SRCS += vpx_ports/mem_ops_aligned.h
decode_to_md5.SRCS += vpx_ports/msvc.h
decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42 decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42
decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum
EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
@@ -158,7 +147,6 @@ simple_encoder.SRCS += ivfenc.h ivfenc.c
simple_encoder.SRCS += tools_common.h tools_common.c simple_encoder.SRCS += tools_common.h tools_common.c
simple_encoder.SRCS += video_common.h simple_encoder.SRCS += video_common.h
simple_encoder.SRCS += video_writer.h video_writer.c simple_encoder.SRCS += video_writer.h video_writer.c
simple_encoder.SRCS += vpx_ports/msvc.h
simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
simple_encoder.DESCRIPTION = Simplified encoder loop simple_encoder.DESCRIPTION = Simplified encoder loop
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
@@ -166,7 +154,6 @@ vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
vp9_lossless_encoder.SRCS += video_common.h vp9_lossless_encoder.SRCS += video_common.h
vp9_lossless_encoder.SRCS += video_writer.h video_writer.c vp9_lossless_encoder.SRCS += video_writer.h video_writer.c
vp9_lossless_encoder.SRCS += vpx_ports/msvc.h
vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366 vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
@@ -174,7 +161,6 @@ twopass_encoder.SRCS += ivfenc.h ivfenc.c
twopass_encoder.SRCS += tools_common.h tools_common.c twopass_encoder.SRCS += tools_common.h tools_common.c
twopass_encoder.SRCS += video_common.h twopass_encoder.SRCS += video_common.h
twopass_encoder.SRCS += video_writer.h video_writer.c twopass_encoder.SRCS += video_writer.h video_writer.c
twopass_encoder.SRCS += vpx_ports/msvc.h
twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8 twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8
twopass_encoder.DESCRIPTION = Two-pass encoder loop twopass_encoder.DESCRIPTION = Two-pass encoder loop
EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c
@@ -184,7 +170,6 @@ decode_with_drops.SRCS += video_common.h
decode_with_drops.SRCS += video_reader.h video_reader.c decode_with_drops.SRCS += video_reader.h video_reader.c
decode_with_drops.SRCS += vpx_ports/mem_ops.h decode_with_drops.SRCS += vpx_ports/mem_ops.h
decode_with_drops.SRCS += vpx_ports/mem_ops_aligned.h decode_with_drops.SRCS += vpx_ports/mem_ops_aligned.h
decode_with_drops.SRCS += vpx_ports/msvc.h
decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26 decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
decode_with_drops.DESCRIPTION = Drops frames while decoding decode_with_drops.DESCRIPTION = Drops frames while decoding
EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c
@@ -192,7 +177,6 @@ set_maps.SRCS += ivfenc.h ivfenc.c
set_maps.SRCS += tools_common.h tools_common.c set_maps.SRCS += tools_common.h tools_common.c
set_maps.SRCS += video_common.h set_maps.SRCS += video_common.h
set_maps.SRCS += video_writer.h video_writer.c set_maps.SRCS += video_writer.h video_writer.c
set_maps.SRCS += vpx_ports/msvc.h
set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
set_maps.DESCRIPTION = Set active and ROI maps set_maps.DESCRIPTION = Set active and ROI maps
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
@@ -200,7 +184,6 @@ vp8cx_set_ref.SRCS += ivfenc.h ivfenc.c
vp8cx_set_ref.SRCS += tools_common.h tools_common.c vp8cx_set_ref.SRCS += tools_common.h tools_common.c
vp8cx_set_ref.SRCS += video_common.h vp8cx_set_ref.SRCS += video_common.h
vp8cx_set_ref.SRCS += video_writer.h video_writer.c vp8cx_set_ref.SRCS += video_writer.h video_writer.c
vp8cx_set_ref.SRCS += vpx_ports/msvc.h
vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A vp8cx_set_ref.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame
@@ -211,7 +194,6 @@ EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.c
vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c
vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c
vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c
vp8_multi_resolution_encoder.SRCS += vpx_ports/msvc.h
vp8_multi_resolution_encoder.SRCS += $(LIBYUV_SRCS) vp8_multi_resolution_encoder.SRCS += $(LIBYUV_SRCS)
vp8_multi_resolution_encoder.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de vp8_multi_resolution_encoder.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de
vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding
@@ -272,6 +254,14 @@ CODEC_EXTRA_LIBS=$(sort $(call enabled,CODEC_EXTRA_LIBS))
$(foreach ex,$(ALL_EXAMPLES),$(eval $(notdir $(ex:.c=)).SRCS += $(ex) examples.mk)) $(foreach ex,$(ALL_EXAMPLES),$(eval $(notdir $(ex:.c=)).SRCS += $(ex) examples.mk))
# If this is a universal (fat) binary, then all the subarchitectures have
# already been built and our job is to stitch them together. The
# BUILD_OBJS variable indicates whether we should be building
# (compiling, linking) the library. The LIPO_OBJS variable indicates
# that we're stitching.
$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_OBJS,BUILD_OBJS):=yes)
# Create build/install dependencies for all examples. The common case # Create build/install dependencies for all examples. The common case
# is handled here. The MSVS case is handled below. # is handled here. The MSVS case is handled below.
NOT_MSVS = $(if $(CONFIG_MSVS),,yes) NOT_MSVS = $(if $(CONFIG_MSVS),,yes)
@@ -279,28 +269,24 @@ DIST-BINS-$(NOT_MSVS) += $(addprefix bin/,$(ALL_EXAMPLES:.c=$(EXE_SFX)))
INSTALL-BINS-$(NOT_MSVS) += $(addprefix bin/,$(UTILS:.c=$(EXE_SFX))) INSTALL-BINS-$(NOT_MSVS) += $(addprefix bin/,$(UTILS:.c=$(EXE_SFX)))
DIST-SRCS-yes += $(ALL_SRCS) DIST-SRCS-yes += $(ALL_SRCS)
INSTALL-SRCS-yes += $(UTIL_SRCS) INSTALL-SRCS-yes += $(UTIL_SRCS)
OBJS-$(NOT_MSVS) += $(call objs,$(ALL_SRCS)) OBJS-$(NOT_MSVS) += $(if $(BUILD_OBJS),$(call objs,$(ALL_SRCS)))
BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=$(EXE_SFX))) BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=$(EXE_SFX)))
# Instantiate linker template for all examples. # Instantiate linker template for all examples.
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx) CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
ifneq ($(filter darwin%,$(TGT_OS)),) SHARED_LIB_SUF=$(if $(filter darwin%,$(TGT_OS)),.dylib,.so)
SHARED_LIB_SUF=.dylib
else
ifneq ($(filter os2%,$(TGT_OS)),)
SHARED_LIB_SUF=_dll.a
else
SHARED_LIB_SUF=.so
endif
endif
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a) CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a)
$(foreach bin,$(BINS-yes),\ $(foreach bin,$(BINS-yes),\
$(eval $(bin):$(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF))\ $(if $(BUILD_OBJS),$(eval $(bin):\
$(eval $(call linker_template,$(bin),\ $(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF)))\
$(if $(BUILD_OBJS),$(eval $(call linker_template,$(bin),\
$(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) \ $(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) \
-l$(CODEC_LIB) $(addprefix -l,$(CODEC_EXTRA_LIBS))\ -l$(CODEC_LIB) $(addprefix -l,$(CODEC_EXTRA_LIBS))\
))) )))\
$(if $(LIPO_OBJS),$(eval $(call lipo_bin_template,$(bin))))\
)
# The following pairs define a mapping of locations in the distribution # The following pairs define a mapping of locations in the distribution
# tree to locations in the source/build trees. # tree to locations in the source/build trees.
@@ -328,8 +314,8 @@ endif
# the makefiles). We may want to revisit this. # the makefiles). We may want to revisit this.
define vcproj_template define vcproj_template
$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX) $(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX)
$(if $(quiet),@echo " [vcproj] $$@") @echo " [vcproj] $$@"
$(qexec)$$(GEN_VCPROJ)\ $$(GEN_VCPROJ)\
--exe\ --exe\
--target=$$(TOOLCHAIN)\ --target=$$(TOOLCHAIN)\
--name=$$(@:.$(VCPROJ_SFX)=)\ --name=$$(@:.$(VCPROJ_SFX)=)\
@@ -352,7 +338,6 @@ $(foreach proj,$(call enabled,PROJECTS),\
# #
%.dox: %.c %.dox: %.c
@echo " [DOXY] $@" @echo " [DOXY] $@"
@mkdir -p $(dir $@)
@echo "/*!\page example_$(@F:.dox=) $(@F:.dox=)" > $@ @echo "/*!\page example_$(@F:.dox=) $(@F:.dox=)" > $@
@echo " \includelineno $(<F)" >> $@ @echo " \includelineno $(<F)" >> $@
@echo "*/" >> $@ @echo "*/" >> $@

View File

@@ -36,9 +36,9 @@
#include "vpx/vp8dx.h" #include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h" #include "vpx/vpx_decoder.h"
#include "../md5_utils.h" #include "./md5_utils.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_reader.h" #include "./video_reader.h"
#include "./vpx_config.h" #include "./vpx_config.h"
static void get_image_md5(const vpx_image_t *img, unsigned char digest[16]) { static void get_image_md5(const vpx_image_t *img, unsigned char digest[16]) {
@@ -71,7 +71,7 @@ static void print_md5(FILE *stream, unsigned char digest[16]) {
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@@ -59,13 +59,13 @@
#include "vpx/vp8dx.h" #include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h" #include "vpx/vpx_decoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_reader.h" #include "./video_reader.h"
#include "./vpx_config.h" #include "./vpx_config.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <infile> <outfile> <N-M|N/M>\n", exec_name); fprintf(stderr, "Usage: %s <infile> <outfile> <N-M|N/M>\n", exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@@ -46,13 +46,13 @@
#include "vpx/vp8dx.h" #include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h" #include "vpx/vpx_decoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_reader.h" #include "./video_reader.h"
#include "./vpx_config.h" #include "./vpx_config.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@@ -15,23 +15,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../tools_common.h" #include "./vp9/encoder/vp9_resize.h"
#include "../vp9/encoder/vp9_resize.h"
static const char *exec_name = NULL; static void usage(char *progname) {
static void usage() {
printf("Usage:\n"); printf("Usage:\n");
printf("%s <input_yuv> <width>x<height> <target_width>x<target_height> ", printf("%s <input_yuv> <width>x<height> <target_width>x<target_height> ",
exec_name); progname);
printf("<output_yuv> [<frames>]\n"); printf("<output_yuv> [<frames>]\n");
} }
void usage_exit(void) {
usage();
exit(EXIT_FAILURE);
}
static int parse_dim(char *v, int *width, int *height) { static int parse_dim(char *v, int *width, int *height) {
char *x = strchr(v, 'x'); char *x = strchr(v, 'x');
if (x == NULL) if (x == NULL)
@@ -55,11 +47,9 @@ int main(int argc, char *argv[]) {
int f, frames; int f, frames;
int width, height, target_width, target_height; int width, height, target_width, target_height;
exec_name = argv[0];
if (argc < 5) { if (argc < 5) {
printf("Incorrect parameters:\n"); printf("Incorrect parameters:\n");
usage(); usage(argv[0]);
return 1; return 1;
} }
@@ -67,25 +57,25 @@ int main(int argc, char *argv[]) {
fout = argv[4]; fout = argv[4];
if (!parse_dim(argv[2], &width, &height)) { if (!parse_dim(argv[2], &width, &height)) {
printf("Incorrect parameters: %s\n", argv[2]); printf("Incorrect parameters: %s\n", argv[2]);
usage(); usage(argv[0]);
return 1; return 1;
} }
if (!parse_dim(argv[3], &target_width, &target_height)) { if (!parse_dim(argv[3], &target_width, &target_height)) {
printf("Incorrect parameters: %s\n", argv[3]); printf("Incorrect parameters: %s\n", argv[3]);
usage(); usage(argv[0]);
return 1; return 1;
} }
fpin = fopen(fin, "rb"); fpin = fopen(fin, "rb");
if (fpin == NULL) { if (fpin == NULL) {
printf("Can't open file %s to read\n", fin); printf("Can't open file %s to read\n", fin);
usage(); usage(argv[0]);
return 1; return 1;
} }
fpout = fopen(fout, "wb"); fpout = fopen(fout, "wb");
if (fpout == NULL) { if (fpout == NULL) {
printf("Can't open file %s to write\n", fout); printf("Can't open file %s to write\n", fout);
usage(); usage(argv[0]);
return 1; return 1;
} }
if (argc >= 6) if (argc >= 6)

View File

@@ -50,12 +50,12 @@
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_writer.h" #include "./video_writer.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n", fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
exec_name); exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@@ -82,13 +82,13 @@
#include "vpx/vpx_decoder.h" #include "vpx/vpx_decoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_reader.h" #include "./video_reader.h"
#include "./vpx_config.h" #include "./vpx_config.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@@ -101,12 +101,12 @@
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_writer.h" #include "./video_writer.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, fprintf(stderr,
"Usage: %s <codec> <width> <height> <infile> <outfile> " "Usage: %s <codec> <width> <height> <infile> <outfile> "
"<keyframe-interval> [<error-resilient>]\nSee comments in " "<keyframe-interval> [<error-resilient>]\nSee comments in "

View File

@@ -53,12 +53,12 @@
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_writer.h" #include "./video_writer.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n", fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
exec_name); exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@@ -8,729 +8,292 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
/*
* This is an example demonstrating multi-resolution encoding in VP8.
* High-resolution input video is down-sampled to lower-resolutions. The
* encoder then encodes the video and outputs multiple bitstreams with
* different resolutions.
*
* This test also allows for settings temporal layers for each spatial layer.
* Different number of temporal layers per spatial stream may be used.
* Currently up to 3 temporal layers per spatial stream (encoder) are supported
* in this test.
*/
#include "./vpx_config.h" // This is an example demonstrating multi-resolution encoding in VP8.
// High-resolution input video is down-sampled to lower-resolutions. The
// encoder then encodes the video and outputs multiple bitstreams with
// different resolutions.
//
// Configure with --enable-multi-res-encoding flag to enable this example.
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include <math.h>
#include <assert.h>
#include <sys/time.h>
#if USE_POSIX_MMAP
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include "vpx_ports/vpx_timer.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"
#include "vpx_ports/mem_ops.h"
#include "../tools_common.h"
#define interface (vpx_codec_vp8_cx())
#define fourcc 0x30385056
void usage_exit(void) {
exit(EXIT_FAILURE);
}
/*
* The input video frame is downsampled several times to generate a multi-level
* hierarchical structure. NUM_ENCODERS is defined as the number of encoding
* levels required. For example, if the size of input video is 1280x720,
* NUM_ENCODERS is 3, and down-sampling factor is 2, the encoder outputs 3
* bitstreams with resolution of 1280x720(level 0), 640x360(level 1), and
* 320x180(level 2) respectively.
*/
/* Number of encoders (spatial resolutions) used in this test. */
#define NUM_ENCODERS 3
/* Maximum number of temporal layers allowed for this test. */
#define MAX_NUM_TEMPORAL_LAYERS 3
/* This example uses the scaler function in libyuv. */
#include "third_party/libyuv/include/libyuv/basic_types.h" #include "third_party/libyuv/include/libyuv/basic_types.h"
#include "third_party/libyuv/include/libyuv/scale.h" #include "third_party/libyuv/include/libyuv/scale.h"
#include "third_party/libyuv/include/libyuv/cpu_id.h" #include "third_party/libyuv/include/libyuv/cpu_id.h"
int (*read_frame_p)(FILE *f, vpx_image_t *img); #include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"
static int read_frame(FILE *f, vpx_image_t *img) { #include "./tools_common.h"
size_t nbytes, to_read; #include "./video_writer.h"
int res = 1;
to_read = img->w*img->h*3/2; // The input video frame is downsampled several times to generate a
nbytes = fread(img->planes[0], 1, to_read, f); // multi-level hierarchical structure. kNumEncoders is defined as the number
if(nbytes != to_read) { // of encoding levels required. For example, if the size of input video is
res = 0; // 1280x720, kNumEncoders is 3, and down-sampling factor is 2, the encoder
if(nbytes > 0) // outputs 3 bitstreams with resolution of 1280x720(level 0),
printf("Warning: Read partial frame. Check your width & height!\n"); // 640x360(level 1), and 320x180(level 2) respectively.
} #define kNumEncoders 3
return res;
static const char *exec_name;
void usage_exit() {
fprintf(stderr,
"Usage: %s <width> <height> <infile> <outfile(s)> <output psnr?>\n",
exec_name);
exit(EXIT_FAILURE);
} }
static int read_frame_by_row(FILE *f, vpx_image_t *img) { int main(int argc, char *argv[]) {
size_t nbytes, to_read; int frame_cnt = 0;
int res = 1; FILE *infile = NULL;
int plane; VpxVideoWriter *writers[kNumEncoders];
vpx_codec_ctx_t codec[kNumEncoders];
vpx_codec_enc_cfg_t cfg[kNumEncoders];
vpx_image_t raw[kNumEncoders];
const VpxInterface *const encoder = get_vpx_encoder_by_name("vp8");
// Currently, only realtime mode is supported in multi-resolution encoding.
const int arg_deadline = VPX_DL_REALTIME;
int i;
int width = 0;
int height = 0;
int frame_avail = 0;
int got_data = 0;
for (plane = 0; plane < 3; plane++) // Set show_psnr to 1/0 to show/not show PSNR. Choose show_psnr=0 if you
// don't need to know PSNR, which will skip PSNR calculation and save
// encoding time.
int show_psnr = 0;
uint64_t psnr_sse_total[kNumEncoders] = {0};
uint64_t psnr_samples_total[kNumEncoders] = {0};
double psnr_totals[kNumEncoders][4] = {{0, 0}};
int psnr_count[kNumEncoders] = {0};
// Set the required target bitrates for each resolution level.
// If target bitrate for highest-resolution level is set to 0,
// (i.e. target_bitrate[0]=0), we skip encoding at that level.
unsigned int target_bitrate[kNumEncoders] = {1000, 500, 100};
// Enter the frame rate of the input video.
const int framerate = 30;
// Set down-sampling factor for each resolution level.
// dsf[0] controls down sampling from level 0 to level 1;
// dsf[1] controls down sampling from level 1 to level 2;
// dsf[2] is not used.
vpx_rational_t dsf[kNumEncoders] = {{2, 1}, {2, 1}, {1, 1}};
exec_name = argv[0];
if (!encoder)
die("Unsupported codec.");
// exe_name, input width, input height, input file,
// output file 1, output file 2, output file 3, psnr on/off
if (argc != (5 + kNumEncoders))
die("Invalid number of input options.");
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
width = strtol(argv[1], NULL, 0);
height = strtol(argv[2], NULL, 0);
if (width < 16 || width % 2 || height < 16 || height % 2)
die("Invalid resolution: %ldx%ld", width, height);
// Open input video file for encoding
if (!(infile = fopen(argv[3], "rb")))
die("Failed to open %s for reading", argv[3]);
show_psnr = strtol(argv[kNumEncoders + 4], NULL, 0);
// Populate default encoder configuration
for (i = 0; i < kNumEncoders; ++i) {
vpx_codec_err_t res =
vpx_codec_enc_config_default(encoder->codec_interface(), &cfg[i], 0);
if (res != VPX_CODEC_OK) {
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
return EXIT_FAILURE;
}
}
// Update the default configuration according to needs of the application.
// Highest-resolution encoder settings
cfg[0].g_w = width;
cfg[0].g_h = height;
cfg[0].g_threads = 1;
cfg[0].rc_dropframe_thresh = 30;
cfg[0].rc_end_usage = VPX_CBR;
cfg[0].rc_resize_allowed = 0;
cfg[0].rc_min_quantizer = 4;
cfg[0].rc_max_quantizer = 56;
cfg[0].rc_undershoot_pct = 98;
cfg[0].rc_overshoot_pct = 100;
cfg[0].rc_buf_initial_sz = 500;
cfg[0].rc_buf_optimal_sz = 600;
cfg[0].rc_buf_sz = 1000;
cfg[0].g_error_resilient = 1;
cfg[0].g_lag_in_frames = 0;
cfg[0].kf_mode = VPX_KF_AUTO; // VPX_KF_DISABLED
cfg[0].kf_min_dist = 3000;
cfg[0].kf_max_dist = 3000;
cfg[0].rc_target_bitrate = target_bitrate[0];
cfg[0].g_timebase.num = 1;
cfg[0].g_timebase.den = framerate;
// Other-resolution encoder settings
for (i = 1; i < kNumEncoders; ++i) {
cfg[i] = cfg[0];
cfg[i].g_threads = 1;
cfg[i].rc_target_bitrate = target_bitrate[i];
// Note: Width & height of other-resolution encoders are calculated
// from the highest-resolution encoder's size and the corresponding
// down_sampling_factor.
{ {
unsigned char *ptr; unsigned int iw = cfg[i - 1].g_w * dsf[i - 1].den + dsf[i - 1].num - 1;
int w = (plane ? (1 + img->d_w) / 2 : img->d_w); unsigned int ih = cfg[i - 1].g_h * dsf[i - 1].den + dsf[i - 1].num - 1;
int h = (plane ? (1 + img->d_h) / 2 : img->d_h); cfg[i].g_w = iw / dsf[i - 1].num;
int r; cfg[i].g_h = ih / dsf[i - 1].num;
}
/* Determine the correct plane based on the image format. The for-loop // Make width & height to be multiplier of 2.
* always counts in Y,U,V order, but this may not match the order of if ((cfg[i].g_w) % 2)
* the data on disk. cfg[i].g_w++;
*/
switch (plane) if ((cfg[i].g_h) % 2)
{ cfg[i].g_h++;
case 1: }
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12? VPX_PLANE_V : VPX_PLANE_U];
// Open output file for each encoder to output bitstreams
for (i = 0; i < kNumEncoders; ++i) {
VpxVideoInfo info = {
encoder->fourcc,
cfg[i].g_w,
cfg[i].g_h,
{cfg[i].g_timebase.num, cfg[i].g_timebase.den}
};
if (!(writers[i] = vpx_video_writer_open(argv[i+4], kContainerIVF, &info)))
die("Failed to open %s for writing", argv[i+4]);
}
// Allocate image for each encoder
for (i = 0; i < kNumEncoders; ++i)
if (!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32))
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
// Initialize multi-encoder
if (vpx_codec_enc_init_multi(&codec[0], encoder->codec_interface(), &cfg[0],
kNumEncoders,
show_psnr ? VPX_CODEC_USE_PSNR : 0, &dsf[0]))
die_codec(&codec[0], "Failed to initialize encoder");
// The extra encoding configuration parameters can be set as follows.
for (i = 0; i < kNumEncoders; i++) {
// Set encoding speed
if (vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, -6))
die_codec(&codec[i], "Failed to set cpu_used");
// Set static threshold.
if (vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1))
die_codec(&codec[i], "Failed to set static threshold");
// Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING
// Enable denoising for the highest-resolution encoder.
if (vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, i == 0))
die_codec(&codec[0], "Failed to set noise_sensitivity");
}
frame_avail = 1;
got_data = 0;
while (frame_avail || got_data) {
vpx_codec_iter_t iter[kNumEncoders] = {NULL};
const vpx_codec_cx_pkt_t *pkt[kNumEncoders];
frame_avail = vpx_img_read(&raw[0], infile);
if (frame_avail) {
for (i = 1; i < kNumEncoders; ++i) {
vpx_image_t *const prev = &raw[i - 1];
// Scale the image down a number of times by downsampling factor
// FilterMode 1 or 2 give better psnr than FilterMode 0.
I420Scale(prev->planes[VPX_PLANE_Y], prev->stride[VPX_PLANE_Y],
prev->planes[VPX_PLANE_U], prev->stride[VPX_PLANE_U],
prev->planes[VPX_PLANE_V], prev->stride[VPX_PLANE_V],
prev->d_w, prev->d_h,
raw[i].planes[VPX_PLANE_Y], raw[i].stride[VPX_PLANE_Y],
raw[i].planes[VPX_PLANE_U], raw[i].stride[VPX_PLANE_U],
raw[i].planes[VPX_PLANE_V], raw[i].stride[VPX_PLANE_V],
raw[i].d_w, raw[i].d_h, 1);
}
}
// Encode frame.
if (vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL,
frame_cnt, 1, 0, arg_deadline)) {
die_codec(&codec[0], "Failed to encode frame");
}
for (i = kNumEncoders - 1; i >= 0; i--) {
got_data = 0;
while ((pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i]))) {
got_data = 1;
switch (pkt[i]->kind) {
case VPX_CODEC_CX_FRAME_PKT:
vpx_video_writer_write_frame(writers[i], pkt[i]->data.frame.buf,
pkt[i]->data.frame.sz, frame_cnt - 1);
break;
case VPX_CODEC_PSNR_PKT:
if (show_psnr) {
int j;
psnr_sse_total[i] += pkt[i]->data.psnr.sse[0];
psnr_samples_total[i] += pkt[i]->data.psnr.samples[0];
for (j = 0; j < 4; j++)
psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j];
psnr_count[i]++;
}
break; break;
case 2: default:
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12?VPX_PLANE_U : VPX_PLANE_V];
break; break;
default:
ptr = img->planes[plane];
} }
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT &&
(pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
fflush(stdout);
}
}
frame_cnt++;
}
printf("\n");
for (r = 0; r < h; r++) fclose(infile);
{
to_read = w;
nbytes = fread(ptr, 1, to_read, f); printf("Processed %d frames.\n", frame_cnt - 1);
if(nbytes != to_read) { for (i = 0; i < kNumEncoders; ++i) {
res = 0; // Calculate PSNR and print it out
if(nbytes > 0) if (show_psnr && psnr_count[i] > 0) {
printf("Warning: Read partial frame. Check your width & height!\n"); int j;
break; double ovpsnr = sse_to_psnr(psnr_samples_total[i], 255.0,
} psnr_sse_total[i]);
ptr += img->stride[plane]; fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
} fprintf(stderr, " %.3lf", ovpsnr);
if (!res) for (j = 0; j < 4; j++)
break; fprintf(stderr, " %.3lf", psnr_totals[i][j]/psnr_count[i]);
} }
return res; if (vpx_codec_destroy(&codec[i]))
} die_codec(&codec[i], "Failed to destroy codec");
static void write_ivf_file_header(FILE *outfile, vpx_img_free(&raw[i]);
const vpx_codec_enc_cfg_t *cfg, vpx_video_writer_close(writers[i]);
int frame_cnt) { }
char header[32]; printf("\n");
if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS) return EXIT_SUCCESS;
return;
header[0] = 'D';
header[1] = 'K';
header[2] = 'I';
header[3] = 'F';
mem_put_le16(header+4, 0); /* version */
mem_put_le16(header+6, 32); /* headersize */
mem_put_le32(header+8, fourcc); /* headersize */
mem_put_le16(header+12, cfg->g_w); /* width */
mem_put_le16(header+14, cfg->g_h); /* height */
mem_put_le32(header+16, cfg->g_timebase.den); /* rate */
mem_put_le32(header+20, cfg->g_timebase.num); /* scale */
mem_put_le32(header+24, frame_cnt); /* length */
mem_put_le32(header+28, 0); /* unused */
(void) fwrite(header, 1, 32, outfile);
}
static void write_ivf_frame_header(FILE *outfile,
const vpx_codec_cx_pkt_t *pkt)
{
char header[12];
vpx_codec_pts_t pts;
if(pkt->kind != VPX_CODEC_CX_FRAME_PKT)
return;
pts = pkt->data.frame.pts;
mem_put_le32(header, pkt->data.frame.sz);
mem_put_le32(header+4, pts&0xFFFFFFFF);
mem_put_le32(header+8, pts >> 32);
(void) fwrite(header, 1, 12, outfile);
}
/* Temporal scaling parameters */
/* This sets all the temporal layer parameters given |num_temporal_layers|,
* including the target bit allocation across temporal layers. Bit allocation
* parameters will be passed in as user parameters in another version.
*/
static void set_temporal_layer_pattern(int num_temporal_layers,
vpx_codec_enc_cfg_t *cfg,
int bitrate,
int *layer_flags)
{
assert(num_temporal_layers <= MAX_NUM_TEMPORAL_LAYERS);
switch (num_temporal_layers)
{
case 1:
{
/* 1-layer */
cfg->ts_number_layers = 1;
cfg->ts_periodicity = 1;
cfg->ts_rate_decimator[0] = 1;
cfg->ts_layer_id[0] = 0;
cfg->ts_target_bitrate[0] = bitrate;
// Update L only.
layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
break;
}
case 2:
{
/* 2-layers, with sync point at first frame of layer 1. */
cfg->ts_number_layers = 2;
cfg->ts_periodicity = 2;
cfg->ts_rate_decimator[0] = 2;
cfg->ts_rate_decimator[1] = 1;
cfg->ts_layer_id[0] = 0;
cfg->ts_layer_id[1] = 1;
// Use 60/40 bit allocation as example.
cfg->ts_target_bitrate[0] = 0.6f * bitrate;
cfg->ts_target_bitrate[1] = bitrate;
/* 0=L, 1=GF */
// ARF is used as predictor for all frames, and is only updated on
// key frame. Sync point every 8 frames.
// Layer 0: predict from L and ARF, update L and G.
layer_flags[0] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_ARF;
// Layer 1: sync point: predict from L and ARF, and update G.
layer_flags[1] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
// Layer 0, predict from L and ARF, update L.
layer_flags[2] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
// Layer 1: predict from L, G and ARF, and update G.
layer_flags[3] = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 0
layer_flags[4] = layer_flags[2];
// Layer 1
layer_flags[5] = layer_flags[3];
// Layer 0
layer_flags[6] = layer_flags[4];
// Layer 1
layer_flags[7] = layer_flags[5];
break;
}
case 3:
default:
{
// 3-layers structure where ARF is used as predictor for all frames,
// and is only updated on key frame.
// Sync points for layer 1 and 2 every 8 frames.
cfg->ts_number_layers = 3;
cfg->ts_periodicity = 4;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
cfg->ts_layer_id[0] = 0;
cfg->ts_layer_id[1] = 2;
cfg->ts_layer_id[2] = 1;
cfg->ts_layer_id[3] = 2;
// Use 40/20/40 bit allocation as example.
cfg->ts_target_bitrate[0] = 0.4f * bitrate;
cfg->ts_target_bitrate[1] = 0.6f * bitrate;
cfg->ts_target_bitrate[2] = bitrate;
/* 0=L, 1=GF, 2=ARF */
// Layer 0: predict from L and ARF; update L and G.
layer_flags[0] = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
// Layer 2: sync point: predict from L and ARF; update none.
layer_flags[1] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 1: sync point: predict from L and ARF; update G.
layer_flags[2] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[3] = VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
// Layer 0: predict from L and ARF; update L.
layer_flags[4] = VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[5] = layer_flags[3];
// Layer 1: predict from L, G, ARF; update G.
layer_flags[6] = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
// Layer 2: predict from L, G, ARF; update none.
layer_flags[7] = layer_flags[3];
break;
}
}
}
/* The periodicity of the pattern given the number of temporal layers. */
static int periodicity_to_num_layers[MAX_NUM_TEMPORAL_LAYERS] = {1, 8, 8};
int main(int argc, char **argv)
{
FILE *infile, *outfile[NUM_ENCODERS];
FILE *downsampled_input[NUM_ENCODERS - 1];
char filename[50];
vpx_codec_ctx_t codec[NUM_ENCODERS];
vpx_codec_enc_cfg_t cfg[NUM_ENCODERS];
int frame_cnt = 0;
vpx_image_t raw[NUM_ENCODERS];
vpx_codec_err_t res[NUM_ENCODERS];
int i;
long width;
long height;
int length_frame;
int frame_avail;
int got_data;
int flags = 0;
int layer_id = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY * NUM_ENCODERS]
= {0};
int flag_periodicity;
/*Currently, only realtime mode is supported in multi-resolution encoding.*/
int arg_deadline = VPX_DL_REALTIME;
/* Set show_psnr to 1/0 to show/not show PSNR. Choose show_psnr=0 if you
don't need to know PSNR, which will skip PSNR calculation and save
encoding time. */
int show_psnr = 0;
int key_frame_insert = 0;
uint64_t psnr_sse_total[NUM_ENCODERS] = {0};
uint64_t psnr_samples_total[NUM_ENCODERS] = {0};
double psnr_totals[NUM_ENCODERS][4] = {{0,0}};
int psnr_count[NUM_ENCODERS] = {0};
double cx_time = 0;
struct timeval tv1, tv2, difftv;
/* Set the required target bitrates for each resolution level.
* If target bitrate for highest-resolution level is set to 0,
* (i.e. target_bitrate[0]=0), we skip encoding at that level.
*/
unsigned int target_bitrate[NUM_ENCODERS]={1000, 500, 100};
/* Enter the frame rate of the input video */
int framerate = 30;
/* Set down-sampling factor for each resolution level.
dsf[0] controls down sampling from level 0 to level 1;
dsf[1] controls down sampling from level 1 to level 2;
dsf[2] is not used. */
vpx_rational_t dsf[NUM_ENCODERS] = {{2, 1}, {2, 1}, {1, 1}};
/* Set the number of temporal layers for each encoder/resolution level,
* starting from highest resoln down to lowest resoln. */
unsigned int num_temporal_layers[NUM_ENCODERS] = {3, 3, 3};
if(argc!= (7 + 3 * NUM_ENCODERS))
die("Usage: %s <width> <height> <frame_rate> <infile> <outfile(s)> "
"<rate_encoder(s)> <temporal_layer(s)> <key_frame_insert> <output psnr?> \n",
argv[0]);
printf("Using %s\n",vpx_codec_iface_name(interface));
width = strtol(argv[1], NULL, 0);
height = strtol(argv[2], NULL, 0);
framerate = strtol(argv[3], NULL, 0);
if(width < 16 || width%2 || height <16 || height%2)
die("Invalid resolution: %ldx%ld", width, height);
/* Open input video file for encoding */
if(!(infile = fopen(argv[4], "rb")))
die("Failed to open %s for reading", argv[4]);
/* Open output file for each encoder to output bitstreams */
for (i=0; i< NUM_ENCODERS; i++)
{
if(!target_bitrate[i])
{
outfile[i] = NULL;
continue;
}
if(!(outfile[i] = fopen(argv[i+5], "wb")))
die("Failed to open %s for writing", argv[i+4]);
}
// Bitrates per spatial layer: overwrite default rates above.
for (i=0; i< NUM_ENCODERS; i++)
{
target_bitrate[i] = strtol(argv[NUM_ENCODERS + 5 + i], NULL, 0);
}
// Temporal layers per spatial layers: overwrite default settings above.
for (i=0; i< NUM_ENCODERS; i++)
{
num_temporal_layers[i] = strtol(argv[2 * NUM_ENCODERS + 5 + i], NULL, 0);
if (num_temporal_layers[i] < 1 || num_temporal_layers[i] > 3)
die("Invalid temporal layers: %d, Must be 1, 2, or 3. \n",
num_temporal_layers);
}
/* Open file to write out each spatially downsampled input stream. */
for (i=0; i< NUM_ENCODERS - 1; i++)
{
// Highest resoln is encoder 0.
if (sprintf(filename,"ds%d.yuv",NUM_ENCODERS - i) < 0)
{
return EXIT_FAILURE;
}
downsampled_input[i] = fopen(filename,"wb");
}
key_frame_insert = strtol(argv[3 * NUM_ENCODERS + 5], NULL, 0);
show_psnr = strtol(argv[3 * NUM_ENCODERS + 6], NULL, 0);
/* Populate default encoder configuration */
for (i=0; i< NUM_ENCODERS; i++)
{
res[i] = vpx_codec_enc_config_default(interface, &cfg[i], 0);
if(res[i]) {
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res[i]));
return EXIT_FAILURE;
}
}
/*
* Update the default configuration according to needs of the application.
*/
/* Highest-resolution encoder settings */
cfg[0].g_w = width;
cfg[0].g_h = height;
cfg[0].rc_dropframe_thresh = 0;
cfg[0].rc_end_usage = VPX_CBR;
cfg[0].rc_resize_allowed = 0;
cfg[0].rc_min_quantizer = 2;
cfg[0].rc_max_quantizer = 56;
cfg[0].rc_undershoot_pct = 100;
cfg[0].rc_overshoot_pct = 15;
cfg[0].rc_buf_initial_sz = 500;
cfg[0].rc_buf_optimal_sz = 600;
cfg[0].rc_buf_sz = 1000;
cfg[0].g_error_resilient = 1; /* Enable error resilient mode */
cfg[0].g_lag_in_frames = 0;
/* Disable automatic keyframe placement */
/* Note: These 3 settings are copied to all levels. But, except the lowest
* resolution level, all other levels are set to VPX_KF_DISABLED internally.
*/
cfg[0].kf_mode = VPX_KF_AUTO;
cfg[0].kf_min_dist = 3000;
cfg[0].kf_max_dist = 3000;
cfg[0].rc_target_bitrate = target_bitrate[0]; /* Set target bitrate */
cfg[0].g_timebase.num = 1; /* Set fps */
cfg[0].g_timebase.den = framerate;
/* Other-resolution encoder settings */
for (i=1; i< NUM_ENCODERS; i++)
{
memcpy(&cfg[i], &cfg[0], sizeof(vpx_codec_enc_cfg_t));
cfg[i].rc_target_bitrate = target_bitrate[i];
/* Note: Width & height of other-resolution encoders are calculated
* from the highest-resolution encoder's size and the corresponding
* down_sampling_factor.
*/
{
unsigned int iw = cfg[i-1].g_w*dsf[i-1].den + dsf[i-1].num - 1;
unsigned int ih = cfg[i-1].g_h*dsf[i-1].den + dsf[i-1].num - 1;
cfg[i].g_w = iw/dsf[i-1].num;
cfg[i].g_h = ih/dsf[i-1].num;
}
/* Make width & height to be multiplier of 2. */
// Should support odd size ???
if((cfg[i].g_w)%2)cfg[i].g_w++;
if((cfg[i].g_h)%2)cfg[i].g_h++;
}
// Set the number of threads per encode/spatial layer.
// (1, 1, 1) means no encoder threading.
cfg[0].g_threads = 2;
cfg[1].g_threads = 1;
cfg[2].g_threads = 1;
/* Allocate image for each encoder */
for (i=0; i< NUM_ENCODERS; i++)
if(!vpx_img_alloc(&raw[i], VPX_IMG_FMT_I420, cfg[i].g_w, cfg[i].g_h, 32))
die("Failed to allocate image", cfg[i].g_w, cfg[i].g_h);
if (raw[0].stride[VPX_PLANE_Y] == raw[0].d_w)
read_frame_p = read_frame;
else
read_frame_p = read_frame_by_row;
for (i=0; i< NUM_ENCODERS; i++)
if(outfile[i])
write_ivf_file_header(outfile[i], &cfg[i], 0);
/* Temporal layers settings */
for ( i=0; i<NUM_ENCODERS; i++)
{
set_temporal_layer_pattern(num_temporal_layers[i],
&cfg[i],
cfg[i].rc_target_bitrate,
&layer_flags[i * VPX_TS_MAX_PERIODICITY]);
}
/* Initialize multi-encoder */
if(vpx_codec_enc_init_multi(&codec[0], interface, &cfg[0], NUM_ENCODERS,
(show_psnr ? VPX_CODEC_USE_PSNR : 0), &dsf[0]))
die_codec(&codec[0], "Failed to initialize encoder");
/* The extra encoding configuration parameters can be set as follows. */
/* Set encoding speed */
for ( i=0; i<NUM_ENCODERS; i++)
{
int speed = -6;
/* Lower speed for the lowest resolution. */
if (i == NUM_ENCODERS - 1) speed = -4;
if(vpx_codec_control(&codec[i], VP8E_SET_CPUUSED, speed))
die_codec(&codec[i], "Failed to set cpu_used");
}
/* Set static threshold = 1 for all encoders */
for ( i=0; i<NUM_ENCODERS; i++)
{
if(vpx_codec_control(&codec[i], VP8E_SET_STATIC_THRESHOLD, 1))
die_codec(&codec[i], "Failed to set static threshold");
}
/* Set NOISE_SENSITIVITY to do TEMPORAL_DENOISING */
/* Enable denoising for the highest-resolution encoder. */
if(vpx_codec_control(&codec[0], VP8E_SET_NOISE_SENSITIVITY, 1))
die_codec(&codec[0], "Failed to set noise_sensitivity");
for ( i=1; i< NUM_ENCODERS; i++)
{
if(vpx_codec_control(&codec[i], VP8E_SET_NOISE_SENSITIVITY, 0))
die_codec(&codec[i], "Failed to set noise_sensitivity");
}
/* Set the number of token partitions */
for ( i=0; i<NUM_ENCODERS; i++)
{
if(vpx_codec_control(&codec[i], VP8E_SET_TOKEN_PARTITIONS, 1))
die_codec(&codec[i], "Failed to set static threshold");
}
/* Set the max intra target bitrate */
for ( i=0; i<NUM_ENCODERS; i++)
{
unsigned int max_intra_size_pct =
(int)(((double)cfg[0].rc_buf_optimal_sz * 0.5) * framerate / 10);
if(vpx_codec_control(&codec[i], VP8E_SET_MAX_INTRA_BITRATE_PCT,
max_intra_size_pct))
die_codec(&codec[i], "Failed to set static threshold");
//printf("%d %d \n",i,max_intra_size_pct);
}
frame_avail = 1;
got_data = 0;
while(frame_avail || got_data)
{
vpx_codec_iter_t iter[NUM_ENCODERS]={NULL};
const vpx_codec_cx_pkt_t *pkt[NUM_ENCODERS];
flags = 0;
frame_avail = read_frame_p(infile, &raw[0]);
if(frame_avail)
{
for ( i=1; i<NUM_ENCODERS; i++)
{
/*Scale the image down a number of times by downsampling factor*/
/* FilterMode 1 or 2 give better psnr than FilterMode 0. */
I420Scale(raw[i-1].planes[VPX_PLANE_Y], raw[i-1].stride[VPX_PLANE_Y],
raw[i-1].planes[VPX_PLANE_U], raw[i-1].stride[VPX_PLANE_U],
raw[i-1].planes[VPX_PLANE_V], raw[i-1].stride[VPX_PLANE_V],
raw[i-1].d_w, raw[i-1].d_h,
raw[i].planes[VPX_PLANE_Y], raw[i].stride[VPX_PLANE_Y],
raw[i].planes[VPX_PLANE_U], raw[i].stride[VPX_PLANE_U],
raw[i].planes[VPX_PLANE_V], raw[i].stride[VPX_PLANE_V],
raw[i].d_w, raw[i].d_h, 1);
/* Write out down-sampled input. */
length_frame = cfg[i].g_w * cfg[i].g_h *3/2;
if (fwrite(raw[i].planes[0], 1, length_frame,
downsampled_input[NUM_ENCODERS - i - 1]) !=
length_frame)
{
return EXIT_FAILURE;
}
}
}
/* Set the flags (reference and update) for all the encoders.*/
for ( i=0; i<NUM_ENCODERS; i++)
{
layer_id = cfg[i].ts_layer_id[frame_cnt % cfg[i].ts_periodicity];
flags = 0;
flag_periodicity = periodicity_to_num_layers
[num_temporal_layers[i] - 1];
flags = layer_flags[i * VPX_TS_MAX_PERIODICITY +
frame_cnt % flag_periodicity];
// Key frame flag for first frame.
if (frame_cnt == 0)
{
flags |= VPX_EFLAG_FORCE_KF;
}
if (frame_cnt > 0 && frame_cnt == key_frame_insert)
{
flags = VPX_EFLAG_FORCE_KF;
}
vpx_codec_control(&codec[i], VP8E_SET_FRAME_FLAGS, flags);
vpx_codec_control(&codec[i], VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
}
gettimeofday(&tv1, NULL);
/* Encode each frame at multi-levels */
/* Note the flags must be set to 0 in the encode call if they are set
for each frame with the vpx_codec_control(), as done above. */
if(vpx_codec_encode(&codec[0], frame_avail? &raw[0] : NULL,
frame_cnt, 1, 0, arg_deadline))
{
die_codec(&codec[0], "Failed to encode frame");
}
gettimeofday(&tv2, NULL);
timersub(&tv2, &tv1, &difftv);
cx_time += (double)(difftv.tv_sec * 1000000 + difftv.tv_usec);
for (i=NUM_ENCODERS-1; i>=0 ; i--)
{
got_data = 0;
while( (pkt[i] = vpx_codec_get_cx_data(&codec[i], &iter[i])) )
{
got_data = 1;
switch(pkt[i]->kind) {
case VPX_CODEC_CX_FRAME_PKT:
write_ivf_frame_header(outfile[i], pkt[i]);
(void) fwrite(pkt[i]->data.frame.buf, 1,
pkt[i]->data.frame.sz, outfile[i]);
break;
case VPX_CODEC_PSNR_PKT:
if (show_psnr)
{
int j;
psnr_sse_total[i] += pkt[i]->data.psnr.sse[0];
psnr_samples_total[i] += pkt[i]->data.psnr.samples[0];
for (j = 0; j < 4; j++)
{
psnr_totals[i][j] += pkt[i]->data.psnr.psnr[j];
}
psnr_count[i]++;
}
break;
default:
break;
}
printf(pkt[i]->kind == VPX_CODEC_CX_FRAME_PKT
&& (pkt[i]->data.frame.flags & VPX_FRAME_IS_KEY)? "K":"");
fflush(stdout);
}
}
frame_cnt++;
}
printf("\n");
printf("FPS for encoding %d %f %f \n", frame_cnt, (float)cx_time / 1000000,
1000000 * (double)frame_cnt / (double)cx_time);
fclose(infile);
printf("Processed %ld frames.\n",(long int)frame_cnt-1);
for (i=0; i< NUM_ENCODERS; i++)
{
/* Calculate PSNR and print it out */
if ( (show_psnr) && (psnr_count[i]>0) )
{
int j;
double ovpsnr = sse_to_psnr(psnr_samples_total[i], 255.0,
psnr_sse_total[i]);
fprintf(stderr, "\n ENC%d PSNR (Overall/Avg/Y/U/V)", i);
fprintf(stderr, " %.3lf", ovpsnr);
for (j = 0; j < 4; j++)
{
fprintf(stderr, " %.3lf", psnr_totals[i][j]/psnr_count[i]);
}
}
if(vpx_codec_destroy(&codec[i]))
die_codec(&codec[i], "Failed to destroy codec");
vpx_img_free(&raw[i]);
if(!outfile[i])
continue;
/* Try to rewrite the file header with the actual frame count */
if(!fseek(outfile[i], 0, SEEK_SET))
write_ivf_file_header(outfile[i], &cfg[i], frame_cnt-1);
fclose(outfile[i]);
}
printf("\n");
return EXIT_SUCCESS;
} }

View File

@@ -53,12 +53,12 @@
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_writer.h" #include "./video_writer.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile> <frame>\n", fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile> <frame>\n",
exec_name); exec_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@@ -15,12 +15,12 @@
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_writer.h" #include "./video_writer.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "vp9_lossless_encoder: Example demonstrating VP9 lossless " fprintf(stderr, "vp9_lossless_encoder: Example demonstrating VP9 lossless "
"encoding feature. Supports raw input only.\n"); "encoding feature. Supports raw input only.\n");
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name); fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);

View File

@@ -14,34 +14,24 @@
* that benefit from a scalable bitstream. * that benefit from a scalable bitstream.
*/ */
#include <math.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "./args.h"
#include "./tools_common.h"
#include "./video_writer.h"
#include "../args.h"
#include "../tools_common.h"
#include "../video_writer.h"
#include "../vpx_ports/vpx_timer.h"
#include "vpx/svc_context.h" #include "vpx/svc_context.h"
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "../vpxstats.h" #include "./vpxstats.h"
#define OUTPUT_RC_STATS 1
static const arg_def_t skip_frames_arg = static const arg_def_t skip_frames_arg =
ARG_DEF("s", "skip-frames", 1, "input frames to skip"); ARG_DEF("s", "skip-frames", 1, "input frames to skip");
static const arg_def_t frames_arg = static const arg_def_t frames_arg =
ARG_DEF("f", "frames", 1, "number of frames to encode"); ARG_DEF("f", "frames", 1, "number of frames to encode");
static const arg_def_t threads_arg =
ARG_DEF("th", "threads", 1, "number of threads to use");
#if OUTPUT_RC_STATS
static const arg_def_t output_rc_stats_arg =
ARG_DEF("rcstat", "output_rc_stats", 1, "output rc stats");
#endif
static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width"); static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width");
static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height"); static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height");
static const arg_def_t timebase_arg = static const arg_def_t timebase_arg =
@@ -52,9 +42,6 @@ static const arg_def_t spatial_layers_arg =
ARG_DEF("sl", "spatial-layers", 1, "number of spatial SVC layers"); ARG_DEF("sl", "spatial-layers", 1, "number of spatial SVC layers");
static const arg_def_t temporal_layers_arg = static const arg_def_t temporal_layers_arg =
ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers"); ARG_DEF("tl", "temporal-layers", 1, "number of temporal SVC layers");
static const arg_def_t temporal_layering_mode_arg =
ARG_DEF("tlm", "temporal-layering-mode", 1, "temporal layering scheme."
"VP9E_TEMPORAL_LAYERING_MODE");
static const arg_def_t kf_dist_arg = static const arg_def_t kf_dist_arg =
ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes"); ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
static const arg_def_t scale_factors_arg = static const arg_def_t scale_factors_arg =
@@ -73,15 +60,6 @@ static const arg_def_t min_bitrate_arg =
ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate"); ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate");
static const arg_def_t max_bitrate_arg = static const arg_def_t max_bitrate_arg =
ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate"); ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate");
static const arg_def_t lag_in_frame_arg =
ARG_DEF(NULL, "lag-in-frames", 1, "Number of frame to input before "
"generating any outputs");
static const arg_def_t rc_end_usage_arg =
ARG_DEF(NULL, "rc-end-usage", 1, "0 - 3: VBR, CBR, CQ, Q");
static const arg_def_t speed_arg =
ARG_DEF("sp", "speed", 1, "speed configuration");
static const arg_def_t aqmode_arg =
ARG_DEF("aq", "aqmode", 1, "aq-mode off/on");
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
static const struct arg_enum_list bitdepth_enum[] = { static const struct arg_enum_list bitdepth_enum[] = {
@@ -102,17 +80,11 @@ static const arg_def_t *svc_args[] = {
&timebase_arg, &bitrate_arg, &skip_frames_arg, &spatial_layers_arg, &timebase_arg, &bitrate_arg, &skip_frames_arg, &spatial_layers_arg,
&kf_dist_arg, &scale_factors_arg, &passes_arg, &pass_arg, &kf_dist_arg, &scale_factors_arg, &passes_arg, &pass_arg,
&fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg, &fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg,
&max_bitrate_arg, &temporal_layers_arg, &temporal_layering_mode_arg, &max_bitrate_arg, &temporal_layers_arg,
&lag_in_frame_arg, &threads_arg, &aqmode_arg,
#if OUTPUT_RC_STATS
&output_rc_stats_arg,
#endif
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
&bitdepth_arg, &bitdepth_arg,
#endif #endif
&speed_arg, NULL
&rc_end_usage_arg, NULL
}; };
static const uint32_t default_frames_to_skip = 0; static const uint32_t default_frames_to_skip = 0;
@@ -125,10 +97,6 @@ static const uint32_t default_bitrate = 1000;
static const uint32_t default_spatial_layers = 5; static const uint32_t default_spatial_layers = 5;
static const uint32_t default_temporal_layers = 1; static const uint32_t default_temporal_layers = 1;
static const uint32_t default_kf_dist = 100; static const uint32_t default_kf_dist = 100;
static const uint32_t default_temporal_layering_mode = 0;
static const uint32_t default_output_rc_stats = 0;
static const int32_t default_speed = -1; // -1 means use library default.
static const uint32_t default_threads = 0; // zero means use library default.
typedef struct { typedef struct {
const char *input_filename; const char *input_filename;
@@ -143,7 +111,7 @@ typedef struct {
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
fprintf(stderr, "Usage: %s <options> input_filename output_filename\n", fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
exec_name); exec_name);
fprintf(stderr, "Options:\n"); fprintf(stderr, "Options:\n");
@@ -170,12 +138,6 @@ static void parse_command_line(int argc, const char **argv_,
svc_ctx->log_level = SVC_LOG_DEBUG; svc_ctx->log_level = SVC_LOG_DEBUG;
svc_ctx->spatial_layers = default_spatial_layers; svc_ctx->spatial_layers = default_spatial_layers;
svc_ctx->temporal_layers = default_temporal_layers; svc_ctx->temporal_layers = default_temporal_layers;
svc_ctx->temporal_layering_mode = default_temporal_layering_mode;
#if OUTPUT_RC_STATS
svc_ctx->output_rc_stat = default_output_rc_stats;
#endif
svc_ctx->speed = default_speed;
svc_ctx->threads = default_threads;
// start with default encoder configuration // start with default encoder configuration
res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0); res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
@@ -217,22 +179,6 @@ static void parse_command_line(int argc, const char **argv_,
svc_ctx->spatial_layers = arg_parse_uint(&arg); svc_ctx->spatial_layers = arg_parse_uint(&arg);
} else if (arg_match(&arg, &temporal_layers_arg, argi)) { } else if (arg_match(&arg, &temporal_layers_arg, argi)) {
svc_ctx->temporal_layers = arg_parse_uint(&arg); svc_ctx->temporal_layers = arg_parse_uint(&arg);
#if OUTPUT_RC_STATS
} else if (arg_match(&arg, &output_rc_stats_arg, argi)) {
svc_ctx->output_rc_stat = arg_parse_uint(&arg);
#endif
} else if (arg_match(&arg, &speed_arg, argi)) {
svc_ctx->speed = arg_parse_uint(&arg);
} else if (arg_match(&arg, &aqmode_arg, argi)) {
svc_ctx->aqmode = arg_parse_uint(&arg);
} else if (arg_match(&arg, &threads_arg, argi)) {
svc_ctx->threads = arg_parse_uint(&arg);
} else if (arg_match(&arg, &temporal_layering_mode_arg, argi)) {
svc_ctx->temporal_layering_mode =
enc_cfg->temporal_layering_mode = arg_parse_int(&arg);
if (svc_ctx->temporal_layering_mode) {
enc_cfg->g_error_resilient = 1;
}
} else if (arg_match(&arg, &kf_dist_arg, argi)) { } else if (arg_match(&arg, &kf_dist_arg, argi)) {
enc_cfg->kf_min_dist = arg_parse_uint(&arg); enc_cfg->kf_min_dist = arg_parse_uint(&arg);
enc_cfg->kf_max_dist = enc_cfg->kf_min_dist; enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
@@ -261,10 +207,6 @@ static void parse_command_line(int argc, const char **argv_,
min_bitrate = arg_parse_uint(&arg); min_bitrate = arg_parse_uint(&arg);
} else if (arg_match(&arg, &max_bitrate_arg, argi)) { } else if (arg_match(&arg, &max_bitrate_arg, argi)) {
max_bitrate = arg_parse_uint(&arg); max_bitrate = arg_parse_uint(&arg);
} else if (arg_match(&arg, &lag_in_frame_arg, argi)) {
enc_cfg->g_lag_in_frames = arg_parse_uint(&arg);
} else if (arg_match(&arg, &rc_end_usage_arg, argi)) {
enc_cfg->rc_end_usage = arg_parse_uint(&arg);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
} else if (arg_match(&arg, &bitdepth_arg, argi)) { } else if (arg_match(&arg, &bitdepth_arg, argi)) {
enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg); enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg);
@@ -365,238 +307,6 @@ static void parse_command_line(int argc, const char **argv_,
enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist); enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
} }
#if OUTPUT_RC_STATS
// For rate control encoding stats.
struct RateControlStats {
// Number of input frames per layer.
int layer_input_frames[VPX_MAX_LAYERS];
// Total (cumulative) number of encoded frames per layer.
int layer_tot_enc_frames[VPX_MAX_LAYERS];
// Number of encoded non-key frames per layer.
int layer_enc_frames[VPX_MAX_LAYERS];
// Framerate per layer (cumulative).
double layer_framerate[VPX_MAX_LAYERS];
// Target average frame size per layer (per-frame-bandwidth per layer).
double layer_pfb[VPX_MAX_LAYERS];
// Actual average frame size per layer.
double layer_avg_frame_size[VPX_MAX_LAYERS];
// Average rate mismatch per layer (|target - actual| / target).
double layer_avg_rate_mismatch[VPX_MAX_LAYERS];
// Actual encoding bitrate per layer (cumulative).
double layer_encoding_bitrate[VPX_MAX_LAYERS];
// Average of the short-time encoder actual bitrate.
// TODO(marpan): Should we add these short-time stats for each layer?
double avg_st_encoding_bitrate;
// Variance of the short-time encoder actual bitrate.
double variance_st_encoding_bitrate;
// Window (number of frames) for computing short-time encoding bitrate.
int window_size;
// Number of window measurements.
int window_count;
};
// Note: these rate control stats assume only 1 key frame in the
// sequence (i.e., first frame only).
static void set_rate_control_stats(struct RateControlStats *rc,
vpx_codec_enc_cfg_t *cfg) {
unsigned int sl, tl;
// Set the layer (cumulative) framerate and the target layer (non-cumulative)
// per-frame-bandwidth, for the rate control encoding stats below.
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
const int layer = sl * cfg->ts_number_layers + tl;
const int tlayer0 = sl * cfg->ts_number_layers;
rc->layer_framerate[layer] =
framerate / cfg->ts_rate_decimator[tl];
if (tl > 0) {
rc->layer_pfb[layer] = 1000.0 *
(cfg->layer_target_bitrate[layer] -
cfg->layer_target_bitrate[layer - 1]) /
(rc->layer_framerate[layer] -
rc->layer_framerate[layer - 1]);
} else {
rc->layer_pfb[tlayer0] = 1000.0 *
cfg->layer_target_bitrate[tlayer0] /
rc->layer_framerate[tlayer0];
}
rc->layer_input_frames[layer] = 0;
rc->layer_enc_frames[layer] = 0;
rc->layer_tot_enc_frames[layer] = 0;
rc->layer_encoding_bitrate[layer] = 0.0;
rc->layer_avg_frame_size[layer] = 0.0;
rc->layer_avg_rate_mismatch[layer] = 0.0;
}
}
rc->window_count = 0;
rc->window_size = 15;
rc->avg_st_encoding_bitrate = 0.0;
rc->variance_st_encoding_bitrate = 0.0;
}
static void printout_rate_control_summary(struct RateControlStats *rc,
vpx_codec_enc_cfg_t *cfg,
int frame_cnt) {
unsigned int sl, tl;
int tot_num_frames = 0;
double perc_fluctuation = 0.0;
printf("Total number of processed frames: %d\n\n", frame_cnt - 1);
printf("Rate control layer stats for sl%d tl%d layer(s):\n\n",
cfg->ss_number_layers, cfg->ts_number_layers);
for (sl = 0; sl < cfg->ss_number_layers; ++sl) {
for (tl = 0; tl < cfg->ts_number_layers; ++tl) {
const int layer = sl * cfg->ts_number_layers + tl;
const int num_dropped = (tl > 0) ?
(rc->layer_input_frames[layer] - rc->layer_enc_frames[layer]) :
(rc->layer_input_frames[layer] - rc->layer_enc_frames[layer] - 1);
if (!sl)
tot_num_frames += rc->layer_input_frames[layer];
rc->layer_encoding_bitrate[layer] = 0.001 * rc->layer_framerate[layer] *
rc->layer_encoding_bitrate[layer] / tot_num_frames;
rc->layer_avg_frame_size[layer] = rc->layer_avg_frame_size[layer] /
rc->layer_enc_frames[layer];
rc->layer_avg_rate_mismatch[layer] =
100.0 * rc->layer_avg_rate_mismatch[layer] /
rc->layer_enc_frames[layer];
printf("For layer#: sl%d tl%d \n", sl, tl);
printf("Bitrate (target vs actual): %d %f.0 kbps\n",
cfg->layer_target_bitrate[layer],
rc->layer_encoding_bitrate[layer]);
printf("Average frame size (target vs actual): %f %f bits\n",
rc->layer_pfb[layer], rc->layer_avg_frame_size[layer]);
printf("Average rate_mismatch: %f\n",
rc->layer_avg_rate_mismatch[layer]);
printf("Number of input frames, encoded (non-key) frames, "
"and percent dropped frames: %d %d %f.0 \n",
rc->layer_input_frames[layer], rc->layer_enc_frames[layer],
100.0 * num_dropped / rc->layer_input_frames[layer]);
printf("\n");
}
}
rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count;
rc->variance_st_encoding_bitrate =
rc->variance_st_encoding_bitrate / rc->window_count -
(rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate);
perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) /
rc->avg_st_encoding_bitrate;
printf("Short-time stats, for window of %d frames: \n", rc->window_size);
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
rc->avg_st_encoding_bitrate,
sqrt(rc->variance_st_encoding_bitrate),
perc_fluctuation);
if (frame_cnt != tot_num_frames)
die("Error: Number of input frames not equal to output encoded frames != "
"%d tot_num_frames = %d\n", frame_cnt, tot_num_frames);
}
vpx_codec_err_t parse_superframe_index(const uint8_t *data,
size_t data_sz,
uint32_t sizes[8], int *count) {
// A chunk ending with a byte matching 0xc0 is an invalid chunk unless
// it is a super frame index. If the last byte of real video compression
// data is 0xc0 the encoder must add a 0 byte. If we have the marker but
// not the associated matching marker byte at the front of the index we have
// an invalid bitstream and need to return an error.
uint8_t marker;
marker = *(data + data_sz - 1);
*count = 0;
if ((marker & 0xe0) == 0xc0) {
const uint32_t frames = (marker & 0x7) + 1;
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
const size_t index_sz = 2 + mag * frames;
// This chunk is marked as having a superframe index but doesn't have
// enough data for it, thus it's an invalid superframe index.
if (data_sz < index_sz)
return VPX_CODEC_CORRUPT_FRAME;
{
const uint8_t marker2 = *(data + data_sz - index_sz);
// This chunk is marked as having a superframe index but doesn't have
// the matching marker byte at the front of the index therefore it's an
// invalid chunk.
if (marker != marker2)
return VPX_CODEC_CORRUPT_FRAME;
}
{
// Found a valid superframe index.
uint32_t i, j;
const uint8_t *x = &data[data_sz - index_sz + 1];
for (i = 0; i < frames; ++i) {
uint32_t this_sz = 0;
for (j = 0; j < mag; ++j)
this_sz |= (*x++) << (j * 8);
sizes[i] = this_sz;
}
*count = frames;
}
}
return VPX_CODEC_OK;
}
#endif
// Example pattern for spatial layers and 2 temporal layers used in the
// bypass/flexible mode. The pattern corresponds to the pattern
// VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
// non-flexible mode.
void set_frame_flags_bypass_mode(int sl, int tl, int num_spatial_layers,
int is_key_frame,
vpx_svc_ref_frame_config_t *ref_frame_config) {
for (sl = 0; sl < num_spatial_layers; ++sl) {
if (!tl) {
if (!sl) {
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
if (is_key_frame) {
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_LAST |
VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
}
}
} else if (tl == 1) {
if (!sl) {
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF;
} else {
ref_frame_config->frame_flags[sl] = VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF;
}
}
if (tl == 0) {
ref_frame_config->lst_fb_idx[sl] = sl;
if (sl)
ref_frame_config->gld_fb_idx[sl] = sl - 1;
else
ref_frame_config->gld_fb_idx[sl] = 0;
ref_frame_config->alt_fb_idx[sl] = 0;
} else if (tl == 1) {
ref_frame_config->lst_fb_idx[sl] = sl;
ref_frame_config->gld_fb_idx[sl] = num_spatial_layers + sl - 1;
ref_frame_config->alt_fb_idx[sl] = num_spatial_layers + sl;
}
}
}
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
AppInput app_input = {0}; AppInput app_input = {0};
VpxVideoWriter *writer = NULL; VpxVideoWriter *writer = NULL;
@@ -613,18 +323,7 @@ int main(int argc, const char **argv) {
FILE *infile = NULL; FILE *infile = NULL;
int end_of_stream = 0; int end_of_stream = 0;
int frames_received = 0; int frames_received = 0;
#if OUTPUT_RC_STATS
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = {NULL};
struct RateControlStats rc;
vpx_svc_layer_id_t layer_id;
vpx_svc_ref_frame_config_t ref_frame_config;
int sl, tl;
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
double framerate = 30.0;
#endif
struct vpx_usec_timer timer;
int64_t cx_time = 0;
memset(&svc_ctx, 0, sizeof(svc_ctx)); memset(&svc_ctx, 0, sizeof(svc_ctx));
svc_ctx.log_print = 1; svc_ctx.log_print = 1;
exec_name = argv[0]; exec_name = argv[0];
@@ -651,13 +350,6 @@ int main(int argc, const char **argv) {
VPX_CODEC_OK) VPX_CODEC_OK)
die("Failed to initialize encoder\n"); die("Failed to initialize encoder\n");
#if OUTPUT_RC_STATS
if (svc_ctx.output_rc_stat) {
set_rate_control_stats(&rc, &enc_cfg);
framerate = enc_cfg.g_timebase.den / enc_cfg.g_timebase.num;
}
#endif
info.codec_fourcc = VP9_FOURCC; info.codec_fourcc = VP9_FOURCC;
info.time_base.numerator = enc_cfg.g_timebase.num; info.time_base.numerator = enc_cfg.g_timebase.num;
info.time_base.denominator = enc_cfg.g_timebase.den; info.time_base.denominator = enc_cfg.g_timebase.den;
@@ -669,34 +361,11 @@ int main(int argc, const char **argv) {
if (!writer) if (!writer)
die("Failed to open %s for writing\n", app_input.output_filename); die("Failed to open %s for writing\n", app_input.output_filename);
} }
#if OUTPUT_RC_STATS
// For now, just write temporal layer streams.
// TODO(wonkap): do spatial by re-writing superframe.
if (svc_ctx.output_rc_stat) {
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
char file_name[PATH_MAX];
snprintf(file_name, sizeof(file_name), "%s_t%d.ivf",
app_input.output_filename, tl);
outfile[tl] = vpx_video_writer_open(file_name, kContainerIVF, &info);
if (!outfile[tl])
die("Failed to open %s for writing", file_name);
}
}
#endif
// skip initial frames // skip initial frames
for (i = 0; i < app_input.frames_to_skip; ++i) for (i = 0; i < app_input.frames_to_skip; ++i)
vpx_img_read(&raw, infile); vpx_img_read(&raw, infile);
if (svc_ctx.speed != -1)
vpx_codec_control(&codec, VP8E_SET_CPUUSED, svc_ctx.speed);
if (svc_ctx.threads)
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (svc_ctx.threads >> 1));
if (svc_ctx.speed >= 5 && svc_ctx.aqmode == 1)
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
// Encode frames // Encode frames
while (!end_of_stream) { while (!end_of_stream) {
vpx_codec_iter_t iter = NULL; vpx_codec_iter_t iter = NULL;
@@ -707,37 +376,8 @@ int main(int argc, const char **argv) {
end_of_stream = 1; end_of_stream = 1;
} }
// For BYPASS/FLEXIBLE mode, set the frame flags (reference and updates)
// and the buffer indices for each spatial layer of the current
// (super)frame to be encoded. The temporal layer_id for the current frame
// also needs to be set.
// TODO(marpan): Should rename the "VP9E_TEMPORAL_LAYERING_MODE_BYPASS"
// mode to "VP9E_LAYERING_MODE_BYPASS".
if (svc_ctx.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
// Example for 2 temporal layers.
if (frame_cnt % 2 == 0)
layer_id.temporal_layer_id = 0;
else
layer_id.temporal_layer_id = 1;
// Note that we only set the temporal layer_id, since we are calling
// the encode for the whole superframe. The encoder will internally loop
// over all the spatial layers for the current superframe.
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
set_frame_flags_bypass_mode(sl, layer_id.temporal_layer_id,
svc_ctx.spatial_layers,
frame_cnt == 0,
&ref_frame_config);
vpx_codec_control(&codec, VP9E_SET_SVC_REF_FRAME_CONFIG,
&ref_frame_config);
}
vpx_usec_timer_start(&timer);
res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw), res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw),
pts, frame_duration, svc_ctx.speed >= 5 ? pts, frame_duration, VPX_DL_GOOD_QUALITY);
VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
printf("%s", vpx_svc_get_message(&svc_ctx)); printf("%s", vpx_svc_get_message(&svc_ctx));
if (res != VPX_CODEC_OK) { if (res != VPX_CODEC_OK) {
die_codec(&codec, "Failed to encode frame"); die_codec(&codec, "Failed to encode frame");
@@ -746,90 +386,11 @@ int main(int argc, const char **argv) {
while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) { while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
switch (cx_pkt->kind) { switch (cx_pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT: { case VPX_CODEC_CX_FRAME_PKT: {
if (cx_pkt->data.frame.sz > 0) { if (cx_pkt->data.frame.sz > 0)
#if OUTPUT_RC_STATS
uint32_t sizes[8];
int count = 0;
#endif
vpx_video_writer_write_frame(writer, vpx_video_writer_write_frame(writer,
cx_pkt->data.frame.buf, cx_pkt->data.frame.buf,
cx_pkt->data.frame.sz, cx_pkt->data.frame.sz,
cx_pkt->data.frame.pts); cx_pkt->data.frame.pts);
#if OUTPUT_RC_STATS
// TODO(marpan/wonkap): Put this (to line728) in separate function.
if (svc_ctx.output_rc_stat) {
vpx_codec_control(&codec, VP9E_GET_SVC_LAYER_ID, &layer_id);
parse_superframe_index(cx_pkt->data.frame.buf,
cx_pkt->data.frame.sz, sizes, &count);
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
++rc.layer_input_frames[sl * enc_cfg.ts_number_layers +
layer_id.temporal_layer_id];
}
for (tl = layer_id.temporal_layer_id;
tl < enc_cfg.ts_number_layers; ++tl) {
vpx_video_writer_write_frame(outfile[tl],
cx_pkt->data.frame.buf,
cx_pkt->data.frame.sz,
cx_pkt->data.frame.pts);
}
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
for (tl = layer_id.temporal_layer_id;
tl < enc_cfg.ts_number_layers; ++tl) {
const int layer = sl * enc_cfg.ts_number_layers + tl;
++rc.layer_tot_enc_frames[layer];
rc.layer_encoding_bitrate[layer] += 8.0 * sizes[sl];
// Keep count of rate control stats per layer, for non-key
// frames.
if (tl == layer_id.temporal_layer_id &&
!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
rc.layer_avg_frame_size[layer] += 8.0 * sizes[sl];
rc.layer_avg_rate_mismatch[layer] +=
fabs(8.0 * sizes[sl] - rc.layer_pfb[layer]) /
rc.layer_pfb[layer];
++rc.layer_enc_frames[layer];
}
}
}
// Update for short-time encoding bitrate states, for moving
// window of size rc->window, shifted by rc->window / 2.
// Ignore first window segment, due to key frame.
if (frame_cnt > rc.window_size) {
tl = layer_id.temporal_layer_id;
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
sum_bitrate += 0.001 * 8.0 * sizes[sl] * framerate;
}
if (frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate / rc.window_size) *
(sum_bitrate / rc.window_size);
sum_bitrate = 0.0;
}
}
// Second shifted window.
if (frame_cnt > rc.window_size + rc.window_size / 2) {
tl = layer_id.temporal_layer_id;
for (sl = 0; sl < enc_cfg.ss_number_layers; ++sl) {
sum_bitrate2 += 0.001 * 8.0 * sizes[sl] * framerate;
}
if (frame_cnt > 2 * rc.window_size &&
frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate2 / rc.window_size) *
(sum_bitrate2 / rc.window_size);
sum_bitrate2 = 0.0;
}
}
}
#endif
}
printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received, printf("SVC frame: %d, kf: %d, size: %d, pts: %d\n", frames_received,
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY), !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
@@ -854,34 +415,25 @@ int main(int argc, const char **argv) {
pts += frame_duration; pts += frame_duration;
} }
} }
printf("Processed %d frames\n", frame_cnt); printf("Processed %d frames\n", frame_cnt);
fclose(infile); fclose(infile);
#if OUTPUT_RC_STATS
if (svc_ctx.output_rc_stat) {
printout_rate_control_summary(&rc, &enc_cfg, frame_cnt);
printf("\n");
}
#endif
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
if (app_input.passes == 2) if (app_input.passes == 2)
stats_close(&app_input.rc_stats, 1); stats_close(&app_input.rc_stats, 1);
if (writer) { if (writer) {
vpx_video_writer_close(writer); vpx_video_writer_close(writer);
} }
#if OUTPUT_RC_STATS
if (svc_ctx.output_rc_stat) {
for (tl = 0; tl < enc_cfg.ts_number_layers; ++tl) {
vpx_video_writer_close(outfile[tl]);
}
}
#endif
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
frame_cnt,
1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1000000 * (double)frame_cnt / (double)cx_time);
vpx_img_free(&raw); vpx_img_free(&raw);
// display average size, psnr // display average size, psnr
printf("%s", vpx_svc_dump_statistics(&svc_ctx)); printf("%s", vpx_svc_dump_statistics(&svc_ctx));
vpx_svc_release(&svc_ctx); vpx_svc_release(&svc_ctx);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@@ -19,16 +19,16 @@
#include <string.h> #include <string.h>
#include "./vpx_config.h" #include "./vpx_config.h"
#include "../vpx_ports/vpx_timer.h" #include "vpx_ports/vpx_timer.h"
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#include "../tools_common.h" #include "./tools_common.h"
#include "../video_writer.h" #include "./video_writer.h"
static const char *exec_name; static const char *exec_name;
void usage_exit(void) { void usage_exit() {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -61,16 +61,6 @@ struct RateControlMetrics {
double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS]; double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS];
// Actual encoding bitrate per layer (cumulative). // Actual encoding bitrate per layer (cumulative).
double layer_encoding_bitrate[VPX_TS_MAX_LAYERS]; double layer_encoding_bitrate[VPX_TS_MAX_LAYERS];
// Average of the short-time encoder actual bitrate.
// TODO(marpan): Should we add these short-time stats for each layer?
double avg_st_encoding_bitrate;
// Variance of the short-time encoder actual bitrate.
double variance_st_encoding_bitrate;
// Window (number of frames) for computing short-timee encoding bitrate.
int window_size;
// Number of window measurements.
int window_count;
int layer_target_bitrate[VPX_MAX_LAYERS];
}; };
// Note: these rate control metrics assume only 1 key frame in the // Note: these rate control metrics assume only 1 key frame in the
@@ -86,13 +76,13 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
// per-frame-bandwidth, for the rate control encoding stats below. // per-frame-bandwidth, for the rate control encoding stats below.
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num; const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0]; rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] / rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] /
rc->layer_framerate[0]; rc->layer_framerate[0];
for (i = 0; i < cfg->ts_number_layers; ++i) { for (i = 0; i < cfg->ts_number_layers; ++i) {
if (i > 0) { if (i > 0) {
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i]; rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
rc->layer_pfb[i] = 1000.0 * rc->layer_pfb[i] = 1000.0 *
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) / (cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) /
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]); (rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
} }
rc->layer_input_frames[i] = 0; rc->layer_input_frames[i] = 0;
@@ -102,10 +92,6 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
rc->layer_avg_frame_size[i] = 0.0; rc->layer_avg_frame_size[i] = 0.0;
rc->layer_avg_rate_mismatch[i] = 0.0; rc->layer_avg_rate_mismatch[i] = 0.0;
} }
rc->window_count = 0;
rc->window_size = 15;
rc->avg_st_encoding_bitrate = 0.0;
rc->variance_st_encoding_bitrate = 0.0;
} }
static void printout_rate_control_summary(struct RateControlMetrics *rc, static void printout_rate_control_summary(struct RateControlMetrics *rc,
@@ -113,7 +99,6 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
int frame_cnt) { int frame_cnt) {
unsigned int i = 0; unsigned int i = 0;
int tot_num_frames = 0; int tot_num_frames = 0;
double perc_fluctuation = 0.0;
printf("Total number of processed frames: %d\n\n", frame_cnt -1); printf("Total number of processed frames: %d\n\n", frame_cnt -1);
printf("Rate control layer stats for %d layer(s):\n\n", printf("Rate control layer stats for %d layer(s):\n\n",
cfg->ts_number_layers); cfg->ts_number_layers);
@@ -129,7 +114,7 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] / rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
rc->layer_enc_frames[i]; rc->layer_enc_frames[i];
printf("For layer#: %d \n", i); printf("For layer#: %d \n", i);
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i], printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i],
rc->layer_encoding_bitrate[i]); rc->layer_encoding_bitrate[i]);
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i], printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
rc->layer_avg_frame_size[i]); rc->layer_avg_frame_size[i]);
@@ -140,17 +125,6 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
100.0 * num_dropped / rc->layer_input_frames[i]); 100.0 * num_dropped / rc->layer_input_frames[i]);
printf("\n"); printf("\n");
} }
rc->avg_st_encoding_bitrate = rc->avg_st_encoding_bitrate / rc->window_count;
rc->variance_st_encoding_bitrate =
rc->variance_st_encoding_bitrate / rc->window_count -
(rc->avg_st_encoding_bitrate * rc->avg_st_encoding_bitrate);
perc_fluctuation = 100.0 * sqrt(rc->variance_st_encoding_bitrate) /
rc->avg_st_encoding_bitrate;
printf("Short-time stats, for window of %d frames: \n",rc->window_size);
printf("Average, rms-variance, and percent-fluct: %f %f %f \n",
rc->avg_st_encoding_bitrate,
sqrt(rc->variance_st_encoding_bitrate),
perc_fluctuation);
if ((frame_cnt - 1) != tot_num_frames) if ((frame_cnt - 1) != tot_num_frames)
die("Error: Number of input frames not equal to output! \n"); die("Error: Number of input frames not equal to output! \n");
} }
@@ -482,11 +456,7 @@ int main(int argc, char **argv) {
int layering_mode = 0; int layering_mode = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY] = {0}; int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
int flag_periodicity = 1; int flag_periodicity = 1;
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
vpx_svc_layer_id_t layer_id = {0, 0}; vpx_svc_layer_id_t layer_id = {0, 0};
#else
vpx_svc_layer_id_t layer_id = {0};
#endif
const VpxInterface *encoder = NULL; const VpxInterface *encoder = NULL;
FILE *infile = NULL; FILE *infile = NULL;
struct RateControlMetrics rc; struct RateControlMetrics rc;
@@ -499,9 +469,6 @@ int main(int argc, char **argv) {
#else #else
const int min_args = min_args_base; const int min_args = min_args_base;
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
double framerate = 30.0;
exec_name = argv[0]; exec_name = argv[0];
// Check usage and arguments. // Check usage and arguments.
@@ -598,32 +565,21 @@ int main(int argc, char **argv) {
for (i = min_args_base; for (i = min_args_base;
(int)i < min_args_base + mode_to_num_layers[layering_mode]; (int)i < min_args_base + mode_to_num_layers[layering_mode];
++i) { ++i) {
rc.layer_target_bitrate[i - 11] = strtol(argv[i], NULL, 0); cfg.ts_target_bitrate[i - 11] = strtol(argv[i], NULL, 0);
if (strncmp(encoder->name, "vp8", 3) == 0)
cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
else if (strncmp(encoder->name, "vp9", 3) == 0)
cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
} }
// Real time parameters. // Real time parameters.
cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0); cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
cfg.rc_end_usage = VPX_CBR; cfg.rc_end_usage = VPX_CBR;
cfg.rc_resize_allowed = 0;
cfg.rc_min_quantizer = 2; cfg.rc_min_quantizer = 2;
cfg.rc_max_quantizer = 56; cfg.rc_max_quantizer = 56;
if (strncmp(encoder->name, "vp9", 3) == 0)
cfg.rc_max_quantizer = 52;
cfg.rc_undershoot_pct = 50; cfg.rc_undershoot_pct = 50;
cfg.rc_overshoot_pct = 50; cfg.rc_overshoot_pct = 50;
cfg.rc_buf_initial_sz = 500; cfg.rc_buf_initial_sz = 500;
cfg.rc_buf_optimal_sz = 600; cfg.rc_buf_optimal_sz = 600;
cfg.rc_buf_sz = 1000; cfg.rc_buf_sz = 1000;
// Disable dynamic resizing by default.
cfg.rc_resize_allowed = 0;
// Use 1 thread as default.
cfg.g_threads = 1;
// Enable error resilient mode. // Enable error resilient mode.
cfg.g_error_resilient = 1; cfg.g_error_resilient = 1;
cfg.g_lag_in_frames = 0; cfg.g_lag_in_frames = 0;
@@ -632,8 +588,6 @@ int main(int argc, char **argv) {
// Disable automatic keyframe placement. // Disable automatic keyframe placement.
cfg.kf_min_dist = cfg.kf_max_dist = 3000; cfg.kf_min_dist = cfg.kf_max_dist = 3000;
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
set_temporal_layer_pattern(layering_mode, set_temporal_layer_pattern(layering_mode,
&cfg, &cfg,
layer_flags, layer_flags,
@@ -642,15 +596,14 @@ int main(int argc, char **argv) {
set_rate_control_metrics(&rc, &cfg); set_rate_control_metrics(&rc, &cfg);
// Target bandwidth for the whole stream. // Target bandwidth for the whole stream.
// Set to layer_target_bitrate for highest layer (total bitrate). // Set to ts_target_bitrate for highest layer (total bitrate).
cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1]; cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1];
// Open input file. // Open input file.
if (!(infile = fopen(argv[1], "rb"))) { if (!(infile = fopen(argv[1], "rb"))) {
die("Failed to open %s for reading", argv[1]); die("Failed to open %s for reading", argv[1]);
} }
framerate = cfg.g_timebase.den / cfg.g_timebase.num;
// Open an output file for each stream. // Open an output file for each stream.
for (i = 0; i < cfg.ts_number_layers; ++i) { for (i = 0; i < cfg.ts_number_layers; ++i) {
char file_name[PATH_MAX]; char file_name[PATH_MAX];
@@ -683,36 +636,23 @@ int main(int argc, char **argv) {
if (strncmp(encoder->name, "vp8", 3) == 0) { if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed); vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff); vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYOnly);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
} else if (strncmp(encoder->name, "vp9", 3) == 0) { } else if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_svc_extra_cfg_t svc_params; vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed); vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3); vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0); vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0); if (vpx_codec_control(&codec, VP9E_SET_SVC, 1)) {
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1); die_codec(&codec, "Failed to set SVC");
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0))
die_codec(&codec, "Failed to set SVC");
for (i = 0; i < cfg.ts_number_layers; ++i) {
svc_params.max_quantizers[i] = cfg.rc_max_quantizer;
svc_params.min_quantizers[i] = cfg.rc_min_quantizer;
} }
svc_params.scaling_factor_num[0] = cfg.g_h;
svc_params.scaling_factor_den[0] = cfg.g_h;
vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params);
}
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0);
} }
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1); vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1);
// This controls the maximum target size of the key frame. // This controls the maximum target size of the key frame.
// For generating smaller key frames, use a smaller max_intra_size_pct // For generating smaller key frames, use a smaller max_intra_size_pct
// value, like 100 or 200. // value, like 100 or 200.
{ {
const int max_intra_size_pct = 900; const int max_intra_size_pct = 200;
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
max_intra_size_pct); max_intra_size_pct);
} }
@@ -722,21 +662,14 @@ int main(int argc, char **argv) {
struct vpx_usec_timer timer; struct vpx_usec_timer timer;
vpx_codec_iter_t iter = NULL; vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt; const vpx_codec_cx_pkt_t *pkt;
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
// Update the temporal layer_id. No spatial layers in this test. // Update the temporal layer_id. No spatial layers in this test.
layer_id.spatial_layer_id = 0; layer_id.spatial_layer_id = 0;
#endif
layer_id.temporal_layer_id = layer_id.temporal_layer_id =
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity]; cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
if (strncmp(encoder->name, "vp9", 3) == 0) { if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id); vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
} else if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_TEMPORAL_LAYER_ID,
layer_id.temporal_layer_id);
} }
flags = layer_flags[frame_cnt % flag_periodicity]; flags = layer_flags[frame_cnt % flag_periodicity];
if (layering_mode == 0)
flags = 0;
frame_avail = vpx_img_read(&raw, infile); frame_avail = vpx_img_read(&raw, infile);
if (frame_avail) if (frame_avail)
++rc.layer_input_frames[layer_id.temporal_layer_id]; ++rc.layer_input_frames[layer_id.temporal_layer_id];
@@ -772,33 +705,6 @@ int main(int argc, char **argv) {
++rc.layer_enc_frames[i]; ++rc.layer_enc_frames[i];
} }
} }
// Update for short-time encoding bitrate states, for moving window
// of size rc->window, shifted by rc->window / 2.
// Ignore first window segment, due to key frame.
if (frame_cnt > rc.window_size) {
sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
if (frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate / rc.window_size) *
(sum_bitrate / rc.window_size);
sum_bitrate = 0.0;
}
}
// Second shifted window.
if (frame_cnt > rc.window_size + rc.window_size / 2) {
sum_bitrate2 += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
if (frame_cnt > 2 * rc.window_size &&
frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate2 / rc.window_size) *
(sum_bitrate2 / rc.window_size);
sum_bitrate2 = 0.0;
}
}
break; break;
default: default:
break; break;

View File

@@ -36,7 +36,7 @@ DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project. # by quotes) that should identify the project.
PROJECT_NAME = "WebM Codec SDK" PROJECT_NAME = "WebM VP8 Codec SDK"
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.
@@ -415,6 +415,12 @@ MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES SHOW_USED_FILES = YES
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES = NO
# The FILE_VERSION_FILTER tag can be used to specify a program or script that # The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from the # doxygen should invoke to get the current version for each file (typically from the
# version control system). Doxygen will invoke the program by executing (via # version control system). Doxygen will invoke the program by executing (via
@@ -709,6 +715,12 @@ HTML_FOOTER =
HTML_STYLESHEET = HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files # If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the # will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # Microsoft HTML help workshop to generate a compressed HTML help file (.chm)

281
libs.mk
View File

@@ -17,6 +17,32 @@ else
ASM:=.asm ASM:=.asm
endif endif
#
# Calculate platform- and compiler-specific offsets for hand coded assembly
#
ifeq ($(filter icc gcc,$(TGT_CC)), $(TGT_CC))
OFFSET_PATTERN:='^[a-zA-Z0-9_]* EQU'
define asm_offsets_template
$$(BUILD_PFX)$(1): $$(BUILD_PFX)$(2).S
@echo " [CREATE] $$@"
$$(qexec)LC_ALL=C grep $$(OFFSET_PATTERN) $$< | tr -d '$$$$\#' $$(ADS2GAS) > $$@
$$(BUILD_PFX)$(2).S: $(2)
CLEAN-OBJS += $$(BUILD_PFX)$(1) $(2).S
endef
else
ifeq ($(filter rvct,$(TGT_CC)), $(TGT_CC))
define asm_offsets_template
$$(BUILD_PFX)$(1): obj_int_extract
$$(BUILD_PFX)$(1): $$(BUILD_PFX)$(2).o
@echo " [CREATE] $$@"
$$(qexec)./obj_int_extract rvds $$< $$(ADS2GAS) > $$@
OBJS-yes += $$(BUILD_PFX)$(2).o
CLEAN-OBJS += $$(BUILD_PFX)$(1)
$$(filter %$$(ASM).o,$$(OBJS-yes)): $$(BUILD_PFX)$(1)
endef
endif # rvct
endif # !gcc
# #
# Rule to generate runtime cpu detection files # Rule to generate runtime cpu detection files
# #
@@ -25,7 +51,7 @@ $$(BUILD_PFX)$(1).h: $$(SRC_PATH_BARE)/$(2)
@echo " [CREATE] $$@" @echo " [CREATE] $$@"
$$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \ $$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \
--sym=$(1) \ --sym=$(1) \
--config=$$(CONFIG_DIR)$$(target)-$$(TOOLCHAIN).mk \ --config=$$(CONFIG_DIR)$$(target)$$(if $$(FAT_ARCHS),,-$$(TOOLCHAIN)).mk \
$$(RTCD_OPTIONS) $$^ > $$@ $$(RTCD_OPTIONS) $$^ > $$@
CLEAN-OBJS += $$(BUILD_PFX)$(1).h CLEAN-OBJS += $$(BUILD_PFX)$(1).h
RTCD += $$(BUILD_PFX)$(1).h RTCD += $$(BUILD_PFX)$(1).h
@@ -34,6 +60,13 @@ endef
CODEC_SRCS-yes += CHANGELOG CODEC_SRCS-yes += CHANGELOG
CODEC_SRCS-yes += libs.mk CODEC_SRCS-yes += libs.mk
# If this is a universal (fat) binary, then all the subarchitectures have
# already been built and our job is to stitch them together. The
# BUILD_LIBVPX variable indicates whether we should be building
# (compiling, linking) the library. The LIPO_LIBVPX variable indicates
# that we're stitching.
$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_LIBVPX,BUILD_LIBVPX):=yes)
include $(SRC_PATH_BARE)/vpx/vpx_codec.mk include $(SRC_PATH_BARE)/vpx/vpx_codec.mk
CODEC_SRCS-yes += $(addprefix vpx/,$(call enabled,API_SRCS)) CODEC_SRCS-yes += $(addprefix vpx/,$(call enabled,API_SRCS))
CODEC_DOC_SRCS += $(addprefix vpx/,$(call enabled,API_DOC_SRCS)) CODEC_DOC_SRCS += $(addprefix vpx/,$(call enabled,API_DOC_SRCS))
@@ -47,13 +80,7 @@ CODEC_SRCS-yes += $(addprefix vpx_scale/,$(call enabled,SCALE_SRCS))
include $(SRC_PATH_BARE)/vpx_ports/vpx_ports.mk include $(SRC_PATH_BARE)/vpx_ports/vpx_ports.mk
CODEC_SRCS-yes += $(addprefix vpx_ports/,$(call enabled,PORTS_SRCS)) CODEC_SRCS-yes += $(addprefix vpx_ports/,$(call enabled,PORTS_SRCS))
include $(SRC_PATH_BARE)/vpx_dsp/vpx_dsp.mk ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),)
CODEC_SRCS-yes += $(addprefix vpx_dsp/,$(call enabled,DSP_SRCS))
include $(SRC_PATH_BARE)/vpx_util/vpx_util.mk
CODEC_SRCS-yes += $(addprefix vpx_util/,$(call enabled,UTIL_SRCS))
ifeq ($(CONFIG_VP8),yes)
VP8_PREFIX=vp8/ VP8_PREFIX=vp8/
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk
endif endif
@@ -76,7 +103,7 @@ ifeq ($(CONFIG_VP8_DECODER),yes)
CODEC_DOC_SECTIONS += vp8 vp8_decoder CODEC_DOC_SECTIONS += vp8 vp8_decoder
endif endif
ifeq ($(CONFIG_VP9),yes) ifneq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_DECODER),)
VP9_PREFIX=vp9/ VP9_PREFIX=vp9/
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9_common.mk include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9_common.mk
endif endif
@@ -109,40 +136,6 @@ endif
VP9_PREFIX=vp9/ VP9_PREFIX=vp9/
$(BUILD_PFX)$(VP9_PREFIX)%.c.o: CFLAGS += -Wextra $(BUILD_PFX)$(VP9_PREFIX)%.c.o: CFLAGS += -Wextra
# VP10 make file
ifeq ($(CONFIG_VP10),yes)
VP10_PREFIX=vp10/
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10_common.mk
endif
ifeq ($(CONFIG_VP10_ENCODER),yes)
VP10_PREFIX=vp10/
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10cx.mk
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_CX_SRCS))
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_CX_EXPORTS))
CODEC_SRCS-yes += $(VP10_PREFIX)vp10cx.mk vpx/vp8.h vpx/vp8cx.h
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
CODEC_DOC_SECTIONS += vp9 vp9_encoder
endif
ifeq ($(CONFIG_VP10_DECODER),yes)
VP10_PREFIX=vp10/
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10dx.mk
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_DX_SRCS))
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_DX_EXPORTS))
CODEC_SRCS-yes += $(VP10_PREFIX)vp10dx.mk vpx/vp8.h vpx/vp8dx.h
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
CODEC_DOC_SECTIONS += vp9 vp9_decoder
endif
VP10_PREFIX=vp10/
$(BUILD_PFX)$(VP10_PREFIX)%.c.o: CFLAGS += -Wextra
ifeq ($(CONFIG_ENCODERS),yes) ifeq ($(CONFIG_ENCODERS),yes)
CODEC_DOC_SECTIONS += encoder CODEC_DOC_SECTIONS += encoder
endif endif
@@ -170,18 +163,18 @@ INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Release/%)
INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%) INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%)
endif endif
CODEC_SRCS-yes += build/make/version.sh CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh
CODEC_SRCS-yes += build/make/rtcd.pl CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.pl
CODEC_SRCS-yes += vpx_ports/emmintrin_compat.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/emmintrin_compat.h
CODEC_SRCS-yes += vpx_ports/mem_ops.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops.h
CODEC_SRCS-yes += vpx_ports/mem_ops_aligned.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops_aligned.h
CODEC_SRCS-yes += vpx_ports/vpx_once.h CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_once.h
CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c CODEC_SRCS-$(BUILD_LIBVPX) += $(BUILD_PFX)vpx_config.c
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes) ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
endif endif
CODEC_EXPORTS-yes += vpx/exports_com CODEC_EXPORTS-$(BUILD_LIBVPX) += vpx/exports_com
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
@@ -212,13 +205,33 @@ INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(call enabled,CODEC_EXPORTS)
# based build systems. # based build systems.
libvpx_srcs.txt: libvpx_srcs.txt:
@echo " [CREATE] $@" @echo " [CREATE] $@"
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@ @echo $(CODEC_SRCS) | xargs -n1 echo | sort -u > $@
CLEAN-OBJS += libvpx_srcs.txt CLEAN-OBJS += libvpx_srcs.txt
ifeq ($(CONFIG_EXTERNAL_BUILD),yes) ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
ifeq ($(CONFIG_MSVS),yes) ifeq ($(CONFIG_MSVS),yes)
obj_int_extract.bat: $(SRC_PATH_BARE)/build/$(MSVS_ARCH_DIR)/obj_int_extract.bat
@cp $^ $@
obj_int_extract.$(VCPROJ_SFX): obj_int_extract.bat
obj_int_extract.$(VCPROJ_SFX): $(SRC_PATH_BARE)/build/make/obj_int_extract.c
@echo " [CREATE] $@"
$(qexec)$(GEN_VCPROJ) \
--exe \
--target=$(TOOLCHAIN) \
--name=obj_int_extract \
--ver=$(CONFIG_VS_VERSION) \
--proj-guid=E1360C65-D375-4335-8057-7ED99CC3F9B2 \
--src-path-bare="$(SRC_PATH_BARE)" \
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
--out=$@ $^ \
-I. \
-I"$(SRC_PATH_BARE)" \
PROJECTS-$(BUILD_LIBVPX) += obj_int_extract.$(VCPROJ_SFX)
vpx.def: $(call enabled,CODEC_EXPORTS) vpx.def: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@" @echo " [CREATE] $@"
$(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_def.sh\ $(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_def.sh\
@@ -233,7 +246,7 @@ ASM_INCLUDES := \
vpx_config.asm \ vpx_config.asm \
vpx_ports/x86_abi_support.asm \ vpx_ports/x86_abi_support.asm \
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def obj_int_extract.$(VCPROJ_SFX)
@echo " [CREATE] $@" @echo " [CREATE] $@"
$(qexec)$(GEN_VCPROJ) \ $(qexec)$(GEN_VCPROJ) \
$(if $(CONFIG_SHARED),--dll,--lib) \ $(if $(CONFIG_SHARED),--dll,--lib) \
@@ -248,7 +261,7 @@ vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \ $(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
--src-path-bare="$(SRC_PATH_BARE)" \ --src-path-bare="$(SRC_PATH_BARE)" \
PROJECTS-yes += vpx.$(VCPROJ_SFX) PROJECTS-$(BUILD_LIBVPX) += vpx.$(VCPROJ_SFX)
vpx.$(VCPROJ_SFX): vpx_config.asm vpx.$(VCPROJ_SFX): vpx_config.asm
vpx.$(VCPROJ_SFX): $(RTCD) vpx.$(VCPROJ_SFX): $(RTCD)
@@ -256,42 +269,32 @@ vpx.$(VCPROJ_SFX): $(RTCD)
endif endif
else else
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS)) LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
OBJS-yes += $(LIBVPX_OBJS) OBJS-$(BUILD_LIBVPX) += $(LIBVPX_OBJS)
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a LIBS-$(if $(BUILD_LIBVPX),$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS) $(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
SO_VERSION_MAJOR := 3
SO_VERSION_MINOR := 0 BUILD_LIBVPX_SO := $(if $(BUILD_LIBVPX),$(CONFIG_SHARED))
SO_VERSION_PATCH := 0
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS)) ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib LIBVPX_SO := libvpx.$(VERSION_MAJOR).dylib
SHARED_LIB_SUF := .dylib
EXPORT_FILE := libvpx.syms EXPORT_FILE := libvpx.syms
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \ LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
libvpx.dylib ) libvpx.dylib )
else else
ifeq ($(filter os2%,$(TGT_OS)),$(TGT_OS)) LIBVPX_SO := libvpx.so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
LIBVPX_SO := libvpx$(SO_VERSION_MAJOR).dll
SHARED_LIB_SUF := _dll.a
EXPORT_FILE := libvpx.def
LIBVPX_SO_SYMLINKS :=
LIBVPX_SO_IMPLIB := libvpx_dll.a
else
LIBVPX_SO := libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR).$(SO_VERSION_PATCH)
SHARED_LIB_SUF := .so
EXPORT_FILE := libvpx.ver EXPORT_FILE := libvpx.ver
SYM_LINK := libvpx.so
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \ LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
libvpx.so libvpx.so.$(SO_VERSION_MAJOR) \ libvpx.so libvpx.so.$(VERSION_MAJOR) \
libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR)) libvpx.so.$(VERSION_MAJOR).$(VERSION_MINOR))
endif
endif endif
LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\ LIBS-$(BUILD_LIBVPX_SO) += $(BUILD_PFX)$(LIBVPX_SO)\
$(notdir $(LIBVPX_SO_SYMLINKS)) \ $(notdir $(LIBVPX_SO_SYMLINKS))
$(if $(LIBVPX_SO_IMPLIB), $(BUILD_PFX)$(LIBVPX_SO_IMPLIB))
$(BUILD_PFX)$(LIBVPX_SO): $(LIBVPX_OBJS) $(EXPORT_FILE) $(BUILD_PFX)$(LIBVPX_SO): $(LIBVPX_OBJS) $(EXPORT_FILE)
$(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm $(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(SO_VERSION_MAJOR) $(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(VERSION_MAJOR)
$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE) $(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE)
libvpx.ver: $(call enabled,CODEC_EXPORTS) libvpx.ver: $(call enabled,CODEC_EXPORTS)
@@ -306,19 +309,6 @@ libvpx.syms: $(call enabled,CODEC_EXPORTS)
$(qexec)awk '{print "_"$$2}' $^ >$@ $(qexec)awk '{print "_"$$2}' $^ >$@
CLEAN-OBJS += libvpx.syms CLEAN-OBJS += libvpx.syms
libvpx.def: $(call enabled,CODEC_EXPORTS)
@echo " [CREATE] $@"
$(qexec)echo LIBRARY $(LIBVPX_SO:.dll=) INITINSTANCE TERMINSTANCE > $@
$(qexec)echo "DATA MULTIPLE NONSHARED" >> $@
$(qexec)echo "EXPORTS" >> $@
$(qexec)awk '!/vpx_svc_*/ {print "_"$$2}' $^ >>$@
CLEAN-OBJS += libvpx.def
libvpx_dll.a: $(LIBVPX_SO)
@echo " [IMPLIB] $@"
$(qexec)emximp -o $@ $<
CLEAN-OBJS += libvpx_dll.a
define libvpx_symlink_template define libvpx_symlink_template
$(1): $(2) $(1): $(2)
@echo " [LN] $(2) $$@" @echo " [LN] $(2) $$@"
@@ -334,12 +324,11 @@ $(eval $(call libvpx_symlink_template,\
$(LIBVPX_SO))) $(LIBVPX_SO)))
INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBVPX_SO_SYMLINKS) INSTALL-LIBS-$(BUILD_LIBVPX_SO) += $(LIBVPX_SO_SYMLINKS)
INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBSUBDIR)/$(LIBVPX_SO) INSTALL-LIBS-$(BUILD_LIBVPX_SO) += $(LIBSUBDIR)/$(LIBVPX_SO)
INSTALL-LIBS-$(CONFIG_SHARED) += $(if $(LIBVPX_SO_IMPLIB),$(LIBSUBDIR)/$(LIBVPX_SO_IMPLIB))
LIBS-yes += vpx.pc LIBS-$(BUILD_LIBVPX) += vpx.pc
vpx.pc: config.mk libs.mk vpx.pc: config.mk libs.mk
@echo " [CREATE] $@" @echo " [CREATE] $@"
$(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@ $(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@
@@ -365,6 +354,9 @@ INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc
CLEAN-OBJS += vpx.pc CLEAN-OBJS += vpx.pc
endif endif
LIBS-$(LIPO_LIBVPX) += libvpx.a
$(eval $(if $(LIPO_LIBVPX),$(call lipo_lib_template,libvpx.a)))
# #
# Rule to make assembler configuration file from C configuration file # Rule to make assembler configuration file from C configuration file
# #
@@ -385,7 +377,7 @@ CLEAN-OBJS += $(BUILD_PFX)vpx_config.asm
endif endif
# #
# Add assembler dependencies for configuration. # Add assembler dependencies for configuration and offsets
# #
$(filter %.s.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm $(filter %.s.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
@@ -403,18 +395,14 @@ LIBVPX_TEST_DATA_PATH ?= .
include $(SRC_PATH_BARE)/test/test.mk include $(SRC_PATH_BARE)/test/test.mk
LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS)) LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX) LIBVPX_TEST_BINS=./test_libvpx$(EXE_SFX)
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\ LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
$(call enabled,LIBVPX_TEST_DATA)) $(call enabled,LIBVPX_TEST_DATA))
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1) libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
TEST_INTRA_PRED_SPEED_OBJS := $(sort $(call objs,$(TEST_INTRA_PRED_SPEED_SRCS)))
libvpx_test_srcs.txt: libvpx_test_srcs.txt:
@echo " [CREATE] $@" @echo " [CREATE] $@"
@echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@ @echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | sort -u > $@
CLEAN-OBJS += libvpx_test_srcs.txt CLEAN-OBJS += libvpx_test_srcs.txt
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1 $(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
@@ -475,25 +463,7 @@ test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_
PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX) PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX)
LIBVPX_TEST_BIN := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BIN))) LIBVPX_TEST_BINS := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BINS)))
ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),)
PROJECTS-$(CONFIG_MSVS) += test_intra_pred_speed.$(VCPROJ_SFX)
test_intra_pred_speed.$(VCPROJ_SFX): $(TEST_INTRA_PRED_SPEED_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX)
@echo " [CREATE] $@"
$(qexec)$(GEN_VCPROJ) \
--exe \
--target=$(TOOLCHAIN) \
--name=test_intra_pred_speed \
-D_VARIADIC_MAX=10 \
--proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \
--ver=$(CONFIG_VS_VERSION) \
--src-path-bare="$(SRC_PATH_BARE)" \
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
--out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
-I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
-L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^
endif # TEST_INTRA_PRED_SPEED
endif endif
else else
@@ -504,54 +474,45 @@ ifeq ($(filter win%,$(TGT_OS)),$(TGT_OS))
# Disabling pthreads globally will cause issues on darwin and possibly elsewhere # Disabling pthreads globally will cause issues on darwin and possibly elsewhere
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0 $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0
endif endif
GTEST_INCLUDES := -I$(SRC_PATH_BARE)/third_party/googletest/src $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
GTEST_INCLUDES += -I$(SRC_PATH_BARE)/third_party/googletest/src/include $(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES) OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS)
OBJS-yes += $(GTEST_OBJS) LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
LIBS-yes += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
$(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS) $(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS)
LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS))) LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS)))
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES) $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
OBJS-yes += $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
BINS-yes += $(LIBVPX_TEST_BIN) OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS)
BINS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_BINS)
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx) CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a) CODEC_LIB_SUF=$(if $(CONFIG_SHARED),.so,.a)
TEST_LIBS := lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a $(foreach bin,$(LIBVPX_TEST_BINS),\
$(LIBVPX_TEST_BIN): $(TEST_LIBS) $(if $(BUILD_LIBVPX),$(eval $(bin): \
$(eval $(call linkerxx_template,$(LIBVPX_TEST_BIN), \ lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a ))\
$(LIBVPX_TEST_OBJS) \ $(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\
-L. -lvpx -lgtest $(extralibs) -lm)) $(LIBVPX_TEST_OBJS) \
-L. -lvpx -lgtest $(extralibs) -lm)\
)))\
$(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\
ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),) endif
$(TEST_INTRA_PRED_SPEED_OBJS) $(TEST_INTRA_PRED_SPEED_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES)
OBJS-yes += $(TEST_INTRA_PRED_SPEED_OBJS)
BINS-yes += $(TEST_INTRA_PRED_SPEED_BIN)
$(TEST_INTRA_PRED_SPEED_BIN): $(TEST_LIBS)
$(eval $(call linkerxx_template,$(TEST_INTRA_PRED_SPEED_BIN), \
$(TEST_INTRA_PRED_SPEED_OBJS) \
-L. -lvpx -lgtest $(extralibs) -lm))
endif # TEST_INTRA_PRED_SPEED
endif # CONFIG_UNIT_TESTS
# Install test sources only if codec source is included # Install test sources only if codec source is included
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\ INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\
$(shell find $(SRC_PATH_BARE)/third_party/googletest -type f)) $(shell find $(SRC_PATH_BARE)/third_party/googletest -type f))
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS) INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS)
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(TEST_INTRA_PRED_SPEED_SRCS)
define test_shard_template define test_shard_template
test:: test_shard.$(1) test:: test_shard.$(1)
test-no-data-check:: test_shard_ndc.$(1) test_shard.$(1): $(LIBVPX_TEST_BINS) testdata
test_shard.$(1) test_shard_ndc.$(1): $(LIBVPX_TEST_BIN)
@set -e; \ @set -e; \
export GTEST_SHARD_INDEX=$(1); \ for t in $(LIBVPX_TEST_BINS); do \
export GTEST_TOTAL_SHARDS=$(2); \ export GTEST_SHARD_INDEX=$(1); \
$(LIBVPX_TEST_BIN) export GTEST_TOTAL_SHARDS=$(2); \
test_shard.$(1): testdata $$$$t; \
done
.PHONY: test_shard.$(1) .PHONY: test_shard.$(1)
endef endef
@@ -574,11 +535,7 @@ libs.doxy: $(CODEC_DOC_SRCS)
@echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@ @echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@
## Generate rtcd.h for all objects ## Generate rtcd.h for all objects
ifeq ($(CONFIG_DEPENDENCY_TRACKING),yes)
$(OBJS-yes:.o=.d): $(RTCD) $(OBJS-yes:.o=.d): $(RTCD)
else
$(OBJS-yes): $(RTCD)
endif
## Update the global src list ## Update the global src list
SRCS += $(CODEC_SRCS) $(LIBVPX_TEST_SRCS) $(GTEST_SRCS) SRCS += $(CODEC_SRCS) $(LIBVPX_TEST_SRCS) $(GTEST_SRCS)
@@ -596,16 +553,15 @@ ifeq ($(CONFIG_MSVS),yes)
# TODO(tomfinegan): Support running the debug versions of tools? # TODO(tomfinegan): Support running the debug versions of tools?
TEST_BIN_PATH := $(addsuffix /$(TGT_OS:win64=x64)/Release, $(TEST_BIN_PATH)) TEST_BIN_PATH := $(addsuffix /$(TGT_OS:win64=x64)/Release, $(TEST_BIN_PATH))
endif endif
utiltest utiltest-no-data-check: utiltest: testdata
$(qexec)$(SRC_PATH_BARE)/test/vpxdec.sh \ $(qexec)$(SRC_PATH_BARE)/test/vpxdec.sh \
--test-data-path $(LIBVPX_TEST_DATA_PATH) \ --test-data-path $(LIBVPX_TEST_DATA_PATH) \
--bin-path $(TEST_BIN_PATH) --bin-path $(TEST_BIN_PATH)
$(qexec)$(SRC_PATH_BARE)/test/vpxenc.sh \ $(qexec)$(SRC_PATH_BARE)/test/vpxenc.sh \
--test-data-path $(LIBVPX_TEST_DATA_PATH) \ --test-data-path $(LIBVPX_TEST_DATA_PATH) \
--bin-path $(TEST_BIN_PATH) --bin-path $(TEST_BIN_PATH)
utiltest: testdata
else else
utiltest utiltest-no-data-check: utiltest:
@echo Unit tests must be enabled to make the utiltest target. @echo Unit tests must be enabled to make the utiltest target.
endif endif
@@ -623,12 +579,11 @@ ifeq ($(CONFIG_MSVS),yes)
# TODO(tomfinegan): Support running the debug versions of tools? # TODO(tomfinegan): Support running the debug versions of tools?
EXAMPLES_BIN_PATH := $(TGT_OS:win64=x64)/Release EXAMPLES_BIN_PATH := $(TGT_OS:win64=x64)/Release
endif endif
exampletest exampletest-no-data-check: examples exampletest: examples testdata
$(qexec)$(SRC_PATH_BARE)/test/examples.sh \ $(qexec)$(SRC_PATH_BARE)/test/examples.sh \
--test-data-path $(LIBVPX_TEST_DATA_PATH) \ --test-data-path $(LIBVPX_TEST_DATA_PATH) \
--bin-path $(EXAMPLES_BIN_PATH) --bin-path $(EXAMPLES_BIN_PATH)
exampletest: testdata
else else
exampletest exampletest-no-data-check: exampletest:
@echo Unit tests must be enabled to make the exampletest target. @echo Unit tests must be enabled to make the exampletest target.
endif endif

View File

@@ -1,4 +1,4 @@
/*!\mainpage WebM Codec SDK /*!\mainpage WebM VP8 Codec SDK
\section main_contents Page Contents \section main_contents Page Contents
- \ref main_intro - \ref main_intro
@@ -6,11 +6,11 @@
- \ref main_support - \ref main_support
\section main_intro Introduction \section main_intro Introduction
Welcome to the WebM Codec SDK. This SDK allows you to integrate your Welcome to the WebM VP8 Codec SDK. This SDK allows you to integrate your
applications with the VP8 and VP9 video codecs, high quality, royalty free, applications with the VP8 video codec, a high quality, royalty free, open
open source codecs deployed on billions of computers and devices worldwide. source codec deployed on millions of computers and devices worldwide.
This distribution of the WebM Codec SDK includes the following support: This distribution of the WebM VP8 Codec SDK includes the following support:
\if vp8_encoder \if vp8_encoder
- \ref vp8_encoder - \ref vp8_encoder
@@ -28,12 +28,12 @@
- Read the \ref samples "sample code" for examples of how to interact with the - Read the \ref samples "sample code" for examples of how to interact with the
codec. codec.
- \ref codec reference - \ref codec reference
\if encoder \if encoder
- \ref encoder reference - \ref encoder reference
\endif \endif
\if decoder \if decoder
- \ref decoder reference - \ref decoder reference
\endif \endif
\section main_support Support Options & FAQ \section main_support Support Options & FAQ
The WebM project is an open source project supported by its community. For The WebM project is an open source project supported by its community. For

View File

@@ -24,7 +24,7 @@
#include "md5_utils.h" #include "md5_utils.h"
static void void
byteSwap(UWORD32 *buf, unsigned words) { byteSwap(UWORD32 *buf, unsigned words) {
md5byte *p; md5byte *p;

View File

@@ -88,9 +88,6 @@ void update_rate_histogram(struct rate_hist *hist,
if (now < cfg->rc_buf_initial_sz) if (now < cfg->rc_buf_initial_sz)
return; return;
if (!cfg->rc_target_bitrate)
return;
then = now; then = now;
/* Sum the size over the past rc_buf_sz ms */ /* Sum the size over the past rc_buf_sz ms */

View File

@@ -9,7 +9,7 @@
## ##
# libvpx reverse dependencies (targets that depend on libvpx) # libvpx reverse dependencies (targets that depend on libvpx)
VPX_NONDEPS=$(addsuffix .$(VCPROJ_SFX),vpx gtest) VPX_NONDEPS=$(addsuffix .$(VCPROJ_SFX),vpx gtest obj_int_extract)
VPX_RDEPS=$(foreach vcp,\ VPX_RDEPS=$(foreach vcp,\
$(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.$(VCPROJ_SFX)=):vpx) $(filter-out $(VPX_NONDEPS),$^), --dep=$(vcp:.$(VCPROJ_SFX)=):vpx)
@@ -17,6 +17,7 @@ vpx.sln: $(wildcard *.$(VCPROJ_SFX))
@echo " [CREATE] $@" @echo " [CREATE] $@"
$(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \ $(SRC_PATH_BARE)/build/make/gen_msvs_sln.sh \
$(if $(filter vpx.$(VCPROJ_SFX),$^),$(VPX_RDEPS)) \ $(if $(filter vpx.$(VCPROJ_SFX),$^),$(VPX_RDEPS)) \
--dep=vpx:obj_int_extract \
--dep=test_libvpx:gtest \ --dep=test_libvpx:gtest \
--ver=$(CONFIG_VS_VERSION)\ --ver=$(CONFIG_VS_VERSION)\
--out=$@ $^ --out=$@ $^

View File

@@ -29,14 +29,14 @@ class ACMRandom {
uint16_t Rand16(void) { uint16_t Rand16(void) {
const uint32_t value = const uint32_t value =
random_.Generate(testing::internal::Random::kMaxRange); random_.Generate(testing::internal::Random::kMaxRange);
return (value >> 15) & 0xffff; return (value >> 16) & 0xffff;
} }
uint8_t Rand8(void) { uint8_t Rand8(void) {
const uint32_t value = const uint32_t value =
random_.Generate(testing::internal::Random::kMaxRange); random_.Generate(testing::internal::Random::kMaxRange);
// There's a bit more entropy in the upper bits of this implementation. // There's a bit more entropy in the upper bits of this implementation.
return (value >> 23) & 0xff; return (value >> 24) & 0xff;
} }
uint8_t Rand8Extremes(void) { uint8_t Rand8Extremes(void) {

View File

@@ -1,127 +0,0 @@
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <algorithm>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
namespace {
// Check if any pixel in a 16x16 macroblock varies between frames.
int CheckMb(const vpx_image_t &current, const vpx_image_t &previous,
int mb_r, int mb_c) {
for (int plane = 0; plane < 3; plane++) {
int r = 16 * mb_r;
int c0 = 16 * mb_c;
int r_top = std::min(r + 16, static_cast<int>(current.d_h));
int c_top = std::min(c0 + 16, static_cast<int>(current.d_w));
r = std::max(r, 0);
c0 = std::max(c0, 0);
if (plane > 0 && current.x_chroma_shift) {
c_top = (c_top + 1) >> 1;
c0 >>= 1;
}
if (plane > 0 && current.y_chroma_shift) {
r_top = (r_top + 1) >> 1;
r >>= 1;
}
for (; r < r_top; ++r) {
for (int c = c0; c < c_top; ++c) {
if (current.planes[plane][current.stride[plane] * r + c] !=
previous.planes[plane][previous.stride[plane] * r + c])
return 1;
}
}
}
return 0;
}
void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t &current,
const vpx_image_t &previous, uint8_t *map) {
for (int mb_r = 0; mb_r < mb_rows; ++mb_r) {
for (int mb_c = 0; mb_c < mb_cols; ++mb_c) {
map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c);
}
}
}
const int kAqModeCyclicRefresh = 3;
class ActiveMapRefreshTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~ActiveMapRefreshTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
cpu_used_ = GET_PARAM(2);
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
::libvpx_test::Y4mVideoSource *y4m_video =
static_cast<libvpx_test::Y4mVideoSource *>(video);
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
} else if (video->frame() >= 2 && video->img()) {
vpx_image_t *current = video->img();
vpx_image_t *previous = y4m_holder_->img();
ASSERT_TRUE(previous != NULL);
vpx_active_map_t map = vpx_active_map_t();
const int width = static_cast<int>(current->d_w);
const int height = static_cast<int>(current->d_h);
const int mb_width = (width + 15) / 16;
const int mb_height = (height + 15) / 16;
uint8_t *active_map = new uint8_t[mb_width * mb_height];
GenerateMap(mb_height, mb_width, *current, *previous, active_map);
map.cols = mb_width;
map.rows = mb_height;
map.active_map = active_map;
encoder->Control(VP8E_SET_ACTIVEMAP, &map);
delete[] active_map;
}
if (video->img()) {
y4m_video->SwapBuffers(y4m_holder_);
}
}
int cpu_used_;
::libvpx_test::Y4mVideoSource *y4m_holder_;
};
TEST_P(ActiveMapRefreshTest, Test) {
cfg_.g_lag_in_frames = 0;
cfg_.g_profile = 1;
cfg_.rc_target_bitrate = 600;
cfg_.rc_resize_allowed = 0;
cfg_.rc_min_quantizer = 8;
cfg_.rc_max_quantizer = 30;
cfg_.g_pass = VPX_RC_ONE_PASS;
cfg_.rc_end_usage = VPX_CBR;
cfg_.kf_max_dist = 90000;
::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, 30);
::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, 30);
video_holder.Begin();
y4m_holder_ = &video_holder;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP9_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 6));
} // namespace

View File

@@ -40,17 +40,9 @@ include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm
LOCAL_MODULE := libvpx_test LOCAL_MODULE := libvpx_test
LOCAL_STATIC_LIBRARIES := gtest libwebm LOCAL_STATIC_LIBRARIES := gtest libwebm
LOCAL_SHARED_LIBRARIES := vpx
ifeq ($(ENABLE_SHARED),1)
LOCAL_SHARED_LIBRARIES := vpx
else
LOCAL_STATIC_LIBRARIES += vpx
endif
include $(LOCAL_PATH)/test/test.mk include $(LOCAL_PATH)/test/test.mk
LOCAL_C_INCLUDES := $(BINDINGS_DIR) LOCAL_C_INCLUDES := $(BINDINGS_DIR)
FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes))) FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes)))
LOCAL_SRC_FILES := $(addprefix ./test/, $(FILTERED_SRC)) LOCAL_SRC_FILES := $(addprefix ./test/, $(FILTERED_SRC))
# some test files depend on *_rtcd.h, ensure they're generated first.
$(eval $(call rtcd_dep_template))
include $(BUILD_EXECUTABLE) include $(BUILD_EXECUTABLE)

View File

@@ -1,229 +0,0 @@
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#if CONFIG_VP9_ENCODER
#include "./vp9_rtcd.h"
#endif
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx_mem/vpx_mem.h"
extern "C"
double vp9_get_blockiness(const unsigned char *img1, int img1_pitch,
const unsigned char *img2, int img2_pitch,
int width, int height);
using libvpx_test::ACMRandom;
namespace {
class BlockinessTestBase : public ::testing::Test {
public:
BlockinessTestBase(int width, int height) : width_(width), height_(height) {}
static void SetUpTestCase() {
source_data_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
reference_data_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
}
static void TearDownTestCase() {
vpx_free(source_data_);
source_data_ = NULL;
vpx_free(reference_data_);
reference_data_ = NULL;
}
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
protected:
// Handle frames up to 640x480
static const int kDataAlignment = 16;
static const int kDataBufferSize = 640*480;
virtual void SetUp() {
source_stride_ = (width_ + 31) & ~31;
reference_stride_ = width_ * 2;
rnd_.Reset(ACMRandom::DeterministicSeed());
}
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant,
int width, int height) {
for (int h = 0; h < height; ++h) {
for (int w = 0; w < width; ++w) {
data[h * stride + w] = fill_constant;
}
}
}
void FillConstant(uint8_t *data, int stride, uint8_t fill_constant) {
FillConstant(data, stride, fill_constant, width_, height_);
}
void FillRandom(uint8_t *data, int stride, int width, int height) {
for (int h = 0; h < height; ++h) {
for (int w = 0; w < width; ++w) {
data[h * stride + w] = rnd_.Rand8();
}
}
}
void FillRandom(uint8_t *data, int stride) {
FillRandom(data, stride, width_, height_);
}
void FillRandomBlocky(uint8_t *data, int stride) {
for (int h = 0; h < height_; h += 4) {
for (int w = 0; w < width_; w += 4) {
FillRandom(data + h * stride + w, stride, 4, 4);
}
}
}
void FillCheckerboard(uint8_t *data, int stride) {
for (int h = 0; h < height_; h += 4) {
for (int w = 0; w < width_; w += 4) {
if (((h/4) ^ (w/4)) & 1)
FillConstant(data + h * stride + w, stride, 255, 4, 4);
else
FillConstant(data + h * stride + w, stride, 0, 4, 4);
}
}
}
void Blur(uint8_t *data, int stride, int taps) {
int sum = 0;
int half_taps = taps / 2;
for (int h = 0; h < height_; ++h) {
for (int w = 0; w < taps; ++w) {
sum += data[w + h * stride];
}
for (int w = taps; w < width_; ++w) {
sum += data[w + h * stride] - data[w - taps + h * stride];
data[w - half_taps + h * stride] = (sum + half_taps) / taps;
}
}
for (int w = 0; w < width_; ++w) {
for (int h = 0; h < taps; ++h) {
sum += data[h + w * stride];
}
for (int h = taps; h < height_; ++h) {
sum += data[w + h * stride] - data[(h - taps) * stride + w];
data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
}
}
}
int width_, height_;
static uint8_t* source_data_;
int source_stride_;
static uint8_t* reference_data_;
int reference_stride_;
ACMRandom rnd_;
};
#if CONFIG_VP9_ENCODER
typedef std::tr1::tuple<int, int> BlockinessParam;
class BlockinessVP9Test
: public BlockinessTestBase,
public ::testing::WithParamInterface<BlockinessParam> {
public:
BlockinessVP9Test() : BlockinessTestBase(GET_PARAM(0), GET_PARAM(1)) {}
protected:
int CheckBlockiness() {
return vp9_get_blockiness(source_data_, source_stride_,
reference_data_, reference_stride_,
width_, height_);
}
};
#endif // CONFIG_VP9_ENCODER
uint8_t* BlockinessTestBase::source_data_ = NULL;
uint8_t* BlockinessTestBase::reference_data_ = NULL;
#if CONFIG_VP9_ENCODER
TEST_P(BlockinessVP9Test, SourceBlockierThanReference) {
// Source is blockier than reference.
FillRandomBlocky(source_data_, source_stride_);
FillConstant(reference_data_, reference_stride_, 128);
int super_blocky = CheckBlockiness();
EXPECT_EQ(0, super_blocky) << "Blocky source should produce 0 blockiness.";
}
TEST_P(BlockinessVP9Test, ReferenceBlockierThanSource) {
// Source is blockier than reference.
FillConstant(source_data_, source_stride_, 128);
FillRandomBlocky(reference_data_, reference_stride_);
int super_blocky = CheckBlockiness();
EXPECT_GT(super_blocky, 0.0)
<< "Blocky reference should score high for blockiness.";
}
TEST_P(BlockinessVP9Test, BlurringDecreasesBlockiness) {
// Source is blockier than reference.
FillConstant(source_data_, source_stride_, 128);
FillRandomBlocky(reference_data_, reference_stride_);
int super_blocky = CheckBlockiness();
Blur(reference_data_, reference_stride_, 4);
int less_blocky = CheckBlockiness();
EXPECT_GT(super_blocky, less_blocky)
<< "A straight blur should decrease blockiness.";
}
TEST_P(BlockinessVP9Test, WorstCaseBlockiness) {
// Source is blockier than reference.
FillConstant(source_data_, source_stride_, 128);
FillCheckerboard(reference_data_, reference_stride_);
int super_blocky = CheckBlockiness();
Blur(reference_data_, reference_stride_, 4);
int less_blocky = CheckBlockiness();
EXPECT_GT(super_blocky, less_blocky)
<< "A straight blur should decrease blockiness.";
}
#endif // CONFIG_VP9_ENCODER
using std::tr1::make_tuple;
//------------------------------------------------------------------------------
// C functions
#if CONFIG_VP9_ENCODER
const BlockinessParam c_vp9_tests[] = {
make_tuple(320, 240),
make_tuple(318, 242),
make_tuple(318, 238),
};
INSTANTIATE_TEST_CASE_P(C, BlockinessVP9Test, ::testing::ValuesIn(c_vp9_tests));
#endif
} // namespace

View File

@@ -80,7 +80,4 @@ TEST_P(BordersTest, TestLowBitrate) {
VP9_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values( VP9_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
::libvpx_test::kTwoPassGood)); ::libvpx_test::kTwoPassGood));
VP10_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
::libvpx_test::kTwoPassGood));
} // namespace } // namespace

View File

@@ -1,189 +0,0 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string>
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/md5_helper.h"
#include "test/util.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
namespace {
const int kLegacyByteAlignment = 0;
const int kLegacyYPlaneByteAlignment = 32;
const int kNumPlanesToCheck = 3;
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
const char kVP9Md5File[] = "vp90-2-02-size-lf-1920x1080.webm.md5";
#if CONFIG_WEBM_IO
struct ByteAlignmentTestParam {
int byte_alignment;
vpx_codec_err_t expected_value;
bool decode_remaining;
};
const ByteAlignmentTestParam kBaTestParams[] = {
{kLegacyByteAlignment, VPX_CODEC_OK, true},
{32, VPX_CODEC_OK, true},
{64, VPX_CODEC_OK, true},
{128, VPX_CODEC_OK, true},
{256, VPX_CODEC_OK, true},
{512, VPX_CODEC_OK, true},
{1024, VPX_CODEC_OK, true},
{1, VPX_CODEC_INVALID_PARAM, false},
{-2, VPX_CODEC_INVALID_PARAM, false},
{4, VPX_CODEC_INVALID_PARAM, false},
{16, VPX_CODEC_INVALID_PARAM, false},
{255, VPX_CODEC_INVALID_PARAM, false},
{2048, VPX_CODEC_INVALID_PARAM, false},
};
// Class for testing byte alignment of reference buffers.
class ByteAlignmentTest
: public ::testing::TestWithParam<ByteAlignmentTestParam> {
protected:
ByteAlignmentTest()
: video_(NULL),
decoder_(NULL),
md5_file_(NULL) {}
virtual void SetUp() {
video_ = new libvpx_test::WebMVideoSource(kVP9TestFile);
ASSERT_TRUE(video_ != NULL);
video_->Init();
video_->Begin();
const vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
ASSERT_TRUE(decoder_ != NULL);
OpenMd5File(kVP9Md5File);
}
virtual void TearDown() {
if (md5_file_ != NULL)
fclose(md5_file_);
delete decoder_;
delete video_;
}
void SetByteAlignment(int byte_alignment, vpx_codec_err_t expected_value) {
decoder_->Control(VP9_SET_BYTE_ALIGNMENT, byte_alignment, expected_value);
}
vpx_codec_err_t DecodeOneFrame(int byte_alignment_to_check) {
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
CheckDecodedFrames(byte_alignment_to_check);
if (res == VPX_CODEC_OK)
video_->Next();
return res;
}
vpx_codec_err_t DecodeRemainingFrames(int byte_alignment_to_check) {
for (; video_->cxdata() != NULL; video_->Next()) {
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
if (res != VPX_CODEC_OK)
return res;
CheckDecodedFrames(byte_alignment_to_check);
}
return VPX_CODEC_OK;
}
private:
// Check if |data| is aligned to |byte_alignment_to_check|.
// |byte_alignment_to_check| must be a power of 2.
void CheckByteAlignment(const uint8_t *data, int byte_alignment_to_check) {
ASSERT_EQ(0u, reinterpret_cast<size_t>(data) % byte_alignment_to_check);
}
// Iterate through the planes of the decoded frames and check for
// alignment based off |byte_alignment_to_check|.
void CheckDecodedFrames(int byte_alignment_to_check) {
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
const vpx_image_t *img;
// Get decompressed data
while ((img = dec_iter.Next()) != NULL) {
if (byte_alignment_to_check == kLegacyByteAlignment) {
CheckByteAlignment(img->planes[0], kLegacyYPlaneByteAlignment);
} else {
for (int i = 0; i < kNumPlanesToCheck; ++i) {
CheckByteAlignment(img->planes[i], byte_alignment_to_check);
}
}
CheckMd5(*img);
}
}
// TODO(fgalligan): Move the MD5 testing code into another class.
void OpenMd5File(const std::string &md5_file_name_) {
md5_file_ = libvpx_test::OpenTestDataFile(md5_file_name_);
ASSERT_TRUE(md5_file_ != NULL) << "MD5 file open failed. Filename: "
<< md5_file_name_;
}
void CheckMd5(const vpx_image_t &img) {
ASSERT_TRUE(md5_file_ != NULL);
char expected_md5[33];
char junk[128];
// Read correct md5 checksums.
const int res = fscanf(md5_file_, "%s %s", expected_md5, junk);
ASSERT_NE(EOF, res) << "Read md5 data failed";
expected_md5[32] = '\0';
::libvpx_test::MD5 md5_res;
md5_res.Add(&img);
const char *const actual_md5 = md5_res.Get();
// Check md5 match.
ASSERT_STREQ(expected_md5, actual_md5) << "MD5 checksums don't match";
}
libvpx_test::WebMVideoSource *video_;
libvpx_test::VP9Decoder *decoder_;
FILE *md5_file_;
};
TEST_F(ByteAlignmentTest, SwitchByteAlignment) {
const int num_elements = 14;
const int byte_alignments[] = { 0, 32, 64, 128, 256, 512, 1024,
0, 1024, 32, 512, 64, 256, 128 };
for (int i = 0; i < num_elements; ++i) {
SetByteAlignment(byte_alignments[i], VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame(byte_alignments[i]));
}
SetByteAlignment(byte_alignments[0], VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(byte_alignments[0]));
}
TEST_P(ByteAlignmentTest, TestAlignment) {
const ByteAlignmentTestParam t = GetParam();
SetByteAlignment(t.byte_alignment, t.expected_value);
if (t.decode_remaining)
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames(t.byte_alignment));
}
INSTANTIATE_TEST_CASE_P(Alignments, ByteAlignmentTest,
::testing::ValuesIn(kBaTestParams));
#endif // CONFIG_WEBM_IO
} // namespace

View File

@@ -13,10 +13,10 @@
#include "./vpx_config.h" #include "./vpx_config.h"
#include "vpx/vpx_decoder.h" #include "vpx/vpx_decoder.h"
#include "vpx/vpx_encoder.h" #include "vpx/vpx_encoder.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#endif #endif
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER || CONFIG_VP10_DECODER #if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
#include "vpx/vp8dx.h" #include "vpx/vp8dx.h"
#endif #endif
@@ -35,11 +35,6 @@ class CodecFactory {
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg, virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const = 0; unsigned long deadline) const = 0;
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags,
unsigned long deadline) // NOLINT(runtime/int)
const = 0;
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg, virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline, unsigned long deadline,
const unsigned long init_flags, const unsigned long init_flags,
@@ -77,10 +72,6 @@ class VP8Decoder : public Decoder {
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline) VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {} : Decoder(cfg, deadline) {}
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: Decoder(cfg, flag, deadline) {}
protected: protected:
virtual vpx_codec_iface_t* CodecInterface() const { virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP8_DECODER #if CONFIG_VP8_DECODER
@@ -113,14 +104,8 @@ class VP8CodecFactory : public CodecFactory {
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg, virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const { unsigned long deadline) const {
return CreateDecoder(cfg, 0, deadline);
}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags,
unsigned long deadline) const { // NOLINT
#if CONFIG_VP8_DECODER #if CONFIG_VP8_DECODER
return new VP8Decoder(cfg, flags, deadline); return new VP8Decoder(cfg, deadline);
#else #else
return NULL; return NULL;
#endif #endif
@@ -169,10 +154,6 @@ class VP9Decoder : public Decoder {
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline) VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {} : Decoder(cfg, deadline) {}
VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: Decoder(cfg, flag, deadline) {}
protected: protected:
virtual vpx_codec_iface_t* CodecInterface() const { virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP9_DECODER #if CONFIG_VP9_DECODER
@@ -205,14 +186,8 @@ class VP9CodecFactory : public CodecFactory {
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg, virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const { unsigned long deadline) const {
return CreateDecoder(cfg, 0, deadline);
}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags,
unsigned long deadline) const { // NOLINT
#if CONFIG_VP9_DECODER #if CONFIG_VP9_DECODER
return new VP9Decoder(cfg, flags, deadline); return new VP9Decoder(cfg, deadline);
#else #else
return NULL; return NULL;
#endif #endif
@@ -233,8 +208,6 @@ class VP9CodecFactory : public CodecFactory {
int usage) const { int usage) const {
#if CONFIG_VP9_ENCODER #if CONFIG_VP9_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage); return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
#elif CONFIG_VP10_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
#else #else
return VPX_CODEC_INCAPABLE; return VPX_CODEC_INCAPABLE;
#endif #endif
@@ -253,96 +226,7 @@ const libvpx_test::VP9CodecFactory kVP9;
#define VP9_INSTANTIATE_TEST_CASE(test, ...) #define VP9_INSTANTIATE_TEST_CASE(test, ...)
#endif // CONFIG_VP9 #endif // CONFIG_VP9
/*
* VP10 Codec Definitions
*/
#if CONFIG_VP10
class VP10Decoder : public Decoder {
public:
VP10Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
VP10Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: Decoder(cfg, flag, deadline) {}
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP10_DECODER
return &vpx_codec_vp10_dx_algo;
#else
return NULL;
#endif
}
};
class VP10Encoder : public Encoder {
public:
VP10Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
const unsigned long init_flags, TwopassStatsStore *stats)
: Encoder(cfg, deadline, init_flags, stats) {}
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP10_ENCODER
return &vpx_codec_vp10_cx_algo;
#else
return NULL;
#endif
}
};
class VP10CodecFactory : public CodecFactory {
public:
VP10CodecFactory() : CodecFactory() {}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
return CreateDecoder(cfg, 0, deadline);
}
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
const vpx_codec_flags_t flags,
unsigned long deadline) const { // NOLINT
#if CONFIG_VP10_DECODER
return new VP10Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
}
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
const unsigned long init_flags,
TwopassStatsStore *stats) const {
#if CONFIG_VP10_ENCODER
return new VP10Encoder(cfg, deadline, init_flags, stats);
#else
return NULL;
#endif
}
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
int usage) const {
#if CONFIG_VP10_ENCODER
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
#else
return VPX_CODEC_INCAPABLE;
#endif
}
};
const libvpx_test::VP10CodecFactory kVP10;
#define VP10_INSTANTIATE_TEST_CASE(test, ...)\
INSTANTIATE_TEST_CASE_P(VP10, test, \
::testing::Combine( \
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
&libvpx_test::kVP10)), \
__VA_ARGS__))
#else
#define VP10_INSTANTIATE_TEST_CASE(test, ...)
#endif // CONFIG_VP10
} // namespace libvpx_test } // namespace libvpx_test
#endif // TEST_CODEC_FACTORY_H_ #endif // TEST_CODEC_FACTORY_H_

View File

@@ -1,224 +0,0 @@
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#if CONFIG_VP9_ENCODER
#include "./vp9_rtcd.h"
#endif
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vpx_dsp/ssim.h"
#include "vpx_mem/vpx_mem.h"
extern "C"
double vpx_get_ssim_metrics(uint8_t *img1, int img1_pitch,
uint8_t *img2, int img2_pitch,
int width, int height,
Ssimv *sv2, Metrics *m,
int do_inconsistency);
using libvpx_test::ACMRandom;
namespace {
class ConsistencyTestBase : public ::testing::Test {
public:
ConsistencyTestBase(int width, int height) : width_(width), height_(height) {}
static void SetUpTestCase() {
source_data_[0] = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
reference_data_[0] = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
source_data_[1] = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
reference_data_[1] = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
ssim_array_ = new Ssimv[kDataBufferSize / 16];
}
static void ClearSsim() {
memset(ssim_array_, 0, kDataBufferSize / 16);
}
static void TearDownTestCase() {
vpx_free(source_data_[0]);
source_data_[0] = NULL;
vpx_free(reference_data_[0]);
reference_data_[0] = NULL;
vpx_free(source_data_[1]);
source_data_[1] = NULL;
vpx_free(reference_data_[1]);
reference_data_[1] = NULL;
delete[] ssim_array_;
}
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
protected:
// Handle frames up to 640x480
static const int kDataAlignment = 16;
static const int kDataBufferSize = 640*480;
virtual void SetUp() {
source_stride_ = (width_ + 31) & ~31;
reference_stride_ = width_ * 2;
rnd_.Reset(ACMRandom::DeterministicSeed());
}
void FillRandom(uint8_t *data, int stride, int width, int height) {
for (int h = 0; h < height; ++h) {
for (int w = 0; w < width; ++w) {
data[h * stride + w] = rnd_.Rand8();
}
}
}
void FillRandom(uint8_t *data, int stride) {
FillRandom(data, stride, width_, height_);
}
void Copy(uint8_t *reference, uint8_t *source) {
memcpy(reference, source, kDataBufferSize);
}
void Blur(uint8_t *data, int stride, int taps) {
int sum = 0;
int half_taps = taps / 2;
for (int h = 0; h < height_; ++h) {
for (int w = 0; w < taps; ++w) {
sum += data[w + h * stride];
}
for (int w = taps; w < width_; ++w) {
sum += data[w + h * stride] - data[w - taps + h * stride];
data[w - half_taps + h * stride] = (sum + half_taps) / taps;
}
}
for (int w = 0; w < width_; ++w) {
for (int h = 0; h < taps; ++h) {
sum += data[h + w * stride];
}
for (int h = taps; h < height_; ++h) {
sum += data[w + h * stride] - data[(h - taps) * stride + w];
data[(h - half_taps) * stride + w] = (sum + half_taps) / taps;
}
}
}
int width_, height_;
static uint8_t* source_data_[2];
int source_stride_;
static uint8_t* reference_data_[2];
int reference_stride_;
static Ssimv *ssim_array_;
Metrics metrics_;
ACMRandom rnd_;
};
#if CONFIG_VP9_ENCODER
typedef std::tr1::tuple<int, int> ConsistencyParam;
class ConsistencyVP9Test
: public ConsistencyTestBase,
public ::testing::WithParamInterface<ConsistencyParam> {
public:
ConsistencyVP9Test() : ConsistencyTestBase(GET_PARAM(0), GET_PARAM(1)) {}
protected:
double CheckConsistency(int frame) {
EXPECT_LT(frame, 2)<< "Frame to check has to be less than 2.";
return
vpx_get_ssim_metrics(source_data_[frame], source_stride_,
reference_data_[frame], reference_stride_,
width_, height_, ssim_array_, &metrics_, 1);
}
};
#endif // CONFIG_VP9_ENCODER
uint8_t* ConsistencyTestBase::source_data_[2] = {NULL, NULL};
uint8_t* ConsistencyTestBase::reference_data_[2] = {NULL, NULL};
Ssimv* ConsistencyTestBase::ssim_array_ = NULL;
#if CONFIG_VP9_ENCODER
TEST_P(ConsistencyVP9Test, ConsistencyIsZero) {
FillRandom(source_data_[0], source_stride_);
Copy(source_data_[1], source_data_[0]);
Copy(reference_data_[0], source_data_[0]);
Blur(reference_data_[0], reference_stride_, 3);
Copy(reference_data_[1], source_data_[0]);
Blur(reference_data_[1], reference_stride_, 3);
double inconsistency = CheckConsistency(1);
inconsistency = CheckConsistency(0);
EXPECT_EQ(inconsistency, 0.0)
<< "Should have 0 inconsistency if they are exactly the same.";
// If sources are not consistent reference frames inconsistency should
// be less than if the source is consistent.
FillRandom(source_data_[0], source_stride_);
FillRandom(source_data_[1], source_stride_);
FillRandom(reference_data_[0], reference_stride_);
FillRandom(reference_data_[1], reference_stride_);
CheckConsistency(0);
inconsistency = CheckConsistency(1);
Copy(source_data_[1], source_data_[0]);
CheckConsistency(0);
double inconsistency2 = CheckConsistency(1);
EXPECT_LT(inconsistency, inconsistency2)
<< "Should have less inconsistency if source itself is inconsistent.";
// Less of a blur should be less inconsistent than more blur coming off a
// a frame with no blur.
ClearSsim();
FillRandom(source_data_[0], source_stride_);
Copy(source_data_[1], source_data_[0]);
Copy(reference_data_[0], source_data_[0]);
Copy(reference_data_[1], source_data_[0]);
Blur(reference_data_[1], reference_stride_, 4);
CheckConsistency(0);
inconsistency = CheckConsistency(1);
ClearSsim();
Copy(reference_data_[1], source_data_[0]);
Blur(reference_data_[1], reference_stride_, 8);
CheckConsistency(0);
inconsistency2 = CheckConsistency(1);
EXPECT_LT(inconsistency, inconsistency2)
<< "Stronger Blur should produce more inconsistency.";
}
#endif // CONFIG_VP9_ENCODER
using std::tr1::make_tuple;
//------------------------------------------------------------------------------
// C functions
#if CONFIG_VP9_ENCODER
const ConsistencyParam c_vp9_tests[] = {
make_tuple(320, 240),
make_tuple(318, 242),
make_tuple(318, 238),
};
INSTANTIATE_TEST_CASE_P(C, ConsistencyVP9Test,
::testing::ValuesIn(c_vp9_tests));
#endif
} // namespace

File diff suppressed because it is too large Load Diff

View File

@@ -140,9 +140,4 @@ VP9_INSTANTIATE_TEST_CASE(
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood, ::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime), ::libvpx_test::kRealTime),
::testing::Range(0, 9)); ::testing::Range(0, 9));
VP10_INSTANTIATE_TEST_CASE(
CpuSpeedTest,
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
::testing::Range(0, 3));
} // namespace } // namespace

View File

@@ -14,7 +14,6 @@
#include "test/i420_video_source.h" #include "test/i420_video_source.h"
#include "test/util.h" #include "test/util.h"
#include "test/y4m_video_source.h" #include "test/y4m_video_source.h"
#include "vpx/vpx_codec.h"
namespace { namespace {
@@ -39,25 +38,13 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
first_drop_ = 0; first_drop_ = 0;
bits_total_ = 0; bits_total_ = 0;
duration_ = 0.0; duration_ = 0.0;
denoiser_offon_test_ = 0;
denoiser_offon_period_ = -1;
} }
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) { ::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) if (video->frame() == 1) {
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
if (denoiser_offon_test_) {
ASSERT_GT(denoiser_offon_period_, 0)
<< "denoiser_offon_period_ is not positive.";
if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
// Flip denoiser_on_ periodically
denoiser_on_ ^= 1;
}
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_); encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
} }
const vpx_rational_t tb = video->timebase(); const vpx_rational_t tb = video->timebase();
timebase_ = static_cast<double>(tb.num) / tb.den; timebase_ = static_cast<double>(tb.num) / tb.den;
duration_ = 0; duration_ = 0;
@@ -137,8 +124,6 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
double effective_datarate_; double effective_datarate_;
size_t bits_in_last_frame_; size_t bits_in_last_frame_;
int denoiser_on_; int denoiser_on_;
int denoiser_offon_test_;
int denoiser_offon_period_;
}; };
#if CONFIG_TEMPORAL_DENOISING #if CONFIG_TEMPORAL_DENOISING
@@ -170,29 +155,6 @@ TEST_P(DatarateTestLarge, DenoiserLevels) {
<< " The datarate for the file missed the target!"; << " The datarate for the file missed the target!";
} }
} }
// Check basic datarate targeting, for a single bitrate, when denoiser is off
// and on.
TEST_P(DatarateTestLarge, DenoiserOffOn) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_dropframe_thresh = 1;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_CBR;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 299);
cfg_.rc_target_bitrate = 300;
ResetModel();
// The denoiser is off by default.
denoiser_on_ = 0;
// Set the offon test flag.
denoiser_offon_test_ = 1;
denoiser_offon_period_ = 100;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
<< " The datarate for the file exceeds the target!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.3)
<< " The datarate for the file missed the target!";
}
#endif // CONFIG_TEMPORAL_DENOISING #endif // CONFIG_TEMPORAL_DENOISING
TEST_P(DatarateTestLarge, BasicBufferModel) { TEST_P(DatarateTestLarge, BasicBufferModel) {
@@ -284,8 +246,6 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
bits_total_[i] = 0; bits_total_[i] = 0;
} }
denoiser_offon_test_ = 0;
denoiser_offon_period_ = -1;
} }
// //
@@ -353,30 +313,22 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) { ::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_); encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
if (denoiser_offon_test_) {
ASSERT_GT(denoiser_offon_period_, 0)
<< "denoiser_offon_period_ is not positive.";
if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
// Flip denoiser_on_ periodically
denoiser_on_ ^= 1;
}
} }
encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
if (cfg_.ts_number_layers > 1) { if (cfg_.ts_number_layers > 1) {
if (video->frame() == 0) { if (video->frame() == 1) {
encoder->Control(VP9E_SET_SVC, 1); encoder->Control(VP9E_SET_SVC, 1);
} }
vpx_svc_layer_id_t layer_id; vpx_svc_layer_id_t layer_id = {0, 0};
layer_id.spatial_layer_id = 0; layer_id.spatial_layer_id = 0;
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers); frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
layer_id.temporal_layer_id = SetLayerId(video->frame(), layer_id.temporal_layer_id = SetLayerId(video->frame(),
cfg_.ts_number_layers); cfg_.ts_number_layers);
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id); if (video->frame() > 0) {
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
}
} }
const vpx_rational_t tb = video->timebase(); const vpx_rational_t tb = video->timebase();
timebase_ = static_cast<double>(tb.num) / tb.den; timebase_ = static_cast<double>(tb.num) / tb.den;
@@ -446,8 +398,6 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
vpx_codec_pts_t first_drop_; vpx_codec_pts_t first_drop_;
int num_drops_; int num_drops_;
int denoiser_on_; int denoiser_on_;
int denoiser_offon_test_;
int denoiser_offon_period_;
}; };
// Check basic rate targeting, // Check basic rate targeting,
@@ -538,7 +488,7 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
<< " The first dropped frame for drop_thresh " << i << " The first dropped frame for drop_thresh " << i
<< " > first dropped frame for drop_thresh " << " > first dropped frame for drop_thresh "
<< i - kDropFrameThreshTestStep; << i - kDropFrameThreshTestStep;
ASSERT_GE(num_drops_, last_num_drops * 0.90) ASSERT_GE(num_drops_, last_num_drops)
<< " The number of dropped frames for drop_thresh " << i << " The number of dropped frames for drop_thresh " << i
<< " < number of dropped frames for drop_thresh " << " < number of dropped frames for drop_thresh "
<< i - kDropFrameThreshTestStep; << i - kDropFrameThreshTestStep;
@@ -564,25 +514,20 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
cfg_.ts_rate_decimator[0] = 2; cfg_.ts_rate_decimator[0] = 2;
cfg_.ts_rate_decimator[1] = 1; cfg_.ts_rate_decimator[1] = 1;
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
if (deadline_ == VPX_DL_REALTIME)
cfg_.g_error_resilient = 1;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200); 30, 1, 0, 200);
for (int i = 200; i <= 800; i += 200) { for (int i = 200; i <= 800; i += 200) {
cfg_.rc_target_bitrate = i; cfg_.rc_target_bitrate = i;
ResetModel(); ResetModel();
// 60-40 bitrate allocation for 2 temporal layers. // 60-40 bitrate allocation for 2 temporal layers.
cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100; cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate; cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85) ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85)
<< " The datarate for the file is lower than target by too much, " << " The datarate for the file is lower than target by too much, "
"for layer: " << j; "for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15) ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15)
<< " The datarate for the file is greater than target by too much, " << " The datarate for the file is greater than target by too much, "
"for layer: " << j; "for layer: " << j;
} }
@@ -607,27 +552,25 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
cfg_.ts_rate_decimator[1] = 2; cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1; cfg_.ts_rate_decimator[2] = 1;
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200); 30, 1, 0, 200);
for (int i = 200; i <= 800; i += 200) { for (int i = 200; i <= 800; i += 200) {
cfg_.rc_target_bitrate = i; cfg_.rc_target_bitrate = i;
ResetModel(); ResetModel();
// 40-20-40 bitrate allocation for 3 temporal layers. // 40-20-40 bitrate allocation for 3 temporal layers.
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate; cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
// TODO(yaowu): Work out more stable rc control strategy and // TODO(yaowu): Work out more stable rc control strategy and
// Adjust the thresholds to be tighter than .75. // Adjust the thresholds to be tighter than .75.
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75) ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
<< " The datarate for the file is lower than target by too much, " << " The datarate for the file is lower than target by too much, "
"for layer: " << j; "for layer: " << j;
// TODO(yaowu): Work out more stable rc control strategy and // TODO(yaowu): Work out more stable rc control strategy and
// Adjust the thresholds to be tighter than 1.25. // Adjust the thresholds to be tighter than 1.25.
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25) ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
<< " The datarate for the file is greater than target by too much, " << " The datarate for the file is greater than target by too much, "
"for layer: " << j; "for layer: " << j;
} }
@@ -655,22 +598,20 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
cfg_.ts_rate_decimator[1] = 2; cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1; cfg_.ts_rate_decimator[2] = 1;
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200); 30, 1, 0, 200);
cfg_.rc_target_bitrate = 200; cfg_.rc_target_bitrate = 200;
ResetModel(); ResetModel();
// 40-20-40 bitrate allocation for 3 temporal layers. // 40-20-40 bitrate allocation for 3 temporal layers.
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100; cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100; cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate; cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) { for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85) ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85)
<< " The datarate for the file is lower than target by too much, " << " The datarate for the file is lower than target by too much, "
"for layer: " << j; "for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15) ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15)
<< " The datarate for the file is greater than target by too much, " << " The datarate for the file is greater than target by too much, "
"for layer: " << j; "for layer: " << j;
// Expect some frame drops in this test: for this 200 frames test, // Expect some frame drops in this test: for this 200 frames test,
@@ -708,271 +649,11 @@ TEST_P(DatarateTestVP9Large, DenoiserLevels) {
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15) ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
<< " The datarate for the file is greater than target by too much!"; << " The datarate for the file is greater than target by too much!";
} }
// Check basic datarate targeting, for a single bitrate, when denoiser is off
// and on.
TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_dropframe_thresh = 1;
cfg_.rc_min_quantizer = 2;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 299);
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
// there is only one denoiser mode: denoiserYonly(which is 1),
// but may add more modes in the future.
cfg_.rc_target_bitrate = 300;
ResetModel();
// The denoiser is off by default.
denoiser_on_ = 0;
// Set the offon test flag.
denoiser_offon_test_ = 1;
denoiser_offon_period_ = 100;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
<< " The datarate for the file is greater than target by too much!";
}
#endif // CONFIG_VP9_TEMPORAL_DENOISING #endif // CONFIG_VP9_TEMPORAL_DENOISING
class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
public:
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {}
virtual ~DatarateOnePassCbrSvc() {}
protected:
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
speed_setting_ = GET_PARAM(2);
ResetModel();
}
virtual void ResetModel() {
last_pts_ = 0;
bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
frame_number_ = 0;
first_drop_ = 0;
bits_total_ = 0;
duration_ = 0.0;
mismatch_psnr_ = 0.0;
mismatch_nframes_ = 0;
}
virtual void BeginPassHook(unsigned int /*pass*/) {
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
int i;
for (i = 0; i < 2; ++i) {
svc_params_.max_quantizers[i] = 63;
svc_params_.min_quantizers[i] = 0;
}
svc_params_.scaling_factor_num[0] = 144;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
encoder->Control(VP9E_SET_SVC, 1);
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
}
const vpx_rational_t tb = video->timebase();
timebase_ = static_cast<double>(tb.num) / tb.den;
duration_ = 0;
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
if (last_pts_ == 0)
duration = 1;
bits_in_buffer_model_ += static_cast<int64_t>(
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
? true: false;
if (!key_frame) {
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
<< pkt->data.frame.pts;
}
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
bits_in_buffer_model_ -= frame_size_in_bits;
bits_total_ += frame_size_in_bits;
if (!first_drop_ && duration > 1)
first_drop_ = last_pts_ + 1;
last_pts_ = pkt->data.frame.pts;
bits_in_last_frame_ = frame_size_in_bits;
++frame_number_;
}
virtual void EndPassHook(void) {
if (bits_total_) {
const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
duration_ = (last_pts_ + 1) * timebase_;
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0
/ (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
file_datarate_ = file_size_in_kb / duration_;
}
}
virtual void MismatchHook(const vpx_image_t *img1,
const vpx_image_t *img2) {
double mismatch_psnr = compute_psnr(img1, img2);
mismatch_psnr_ += mismatch_psnr;
++mismatch_nframes_;
}
unsigned int GetMismatchFrames() {
return mismatch_nframes_;
}
vpx_codec_pts_t last_pts_;
int64_t bits_in_buffer_model_;
double timebase_;
int frame_number_;
vpx_codec_pts_t first_drop_;
int64_t bits_total_;
double duration_;
double file_datarate_;
double effective_datarate_;
size_t bits_in_last_frame_;
vpx_svc_extra_cfg_t svc_params_;
int speed_setting_;
double mismatch_psnr_;
int mismatch_nframes_;
};
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
const vpx_svc_extra_cfg_t *svc_params,
int spatial_layers,
int temporal_layers,
int temporal_layering_mode,
unsigned int total_rate) {
int sl, spatial_layer_target;
float total = 0;
float alloc_ratio[VPX_MAX_LAYERS] = {0};
for (sl = 0; sl < spatial_layers; ++sl) {
if (svc_params->scaling_factor_den[sl] > 0) {
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] *
1.0 / svc_params->scaling_factor_den[sl]);
total += alloc_ratio[sl];
}
}
for (sl = 0; sl < spatial_layers; ++sl) {
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
(unsigned int)(enc_cfg->rc_target_bitrate *
alloc_ratio[sl] / total);
const int index = sl * temporal_layers;
if (temporal_layering_mode == 3) {
enc_cfg->layer_target_bitrate[index] =
spatial_layer_target >> 1;
enc_cfg->layer_target_bitrate[index + 1] =
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
enc_cfg->layer_target_bitrate[index + 2] =
spatial_layer_target;
} else if (temporal_layering_mode == 2) {
enc_cfg->layer_target_bitrate[index] =
spatial_layer_target * 2 / 3;
enc_cfg->layer_target_bitrate[index + 1] =
spatial_layer_target;
}
}
}
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
// 3 temporal layers. Run CIF clip with 1 thread.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.ss_number_layers = 2;
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 1;
cfg_.temporal_layering_mode = 3;
svc_params_.scaling_factor_num[0] = 144;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
// TODO(wonkap/marpan): No frame drop for now, we need to implement correct
// frame dropping for SVC.
cfg_.rc_dropframe_thresh = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
// layer target_bitrate. Also check if test can pass at lower bitrate (~200k).
for (int i = 400; i <= 800; i += 200) {
cfg_.rc_target_bitrate = i;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode,
cfg_.rc_target_bitrate);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
}
}
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
// 3 temporal layers. Run HD clip with 4 threads.
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc4threads) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
cfg_.ss_number_layers = 2;
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.g_error_resilient = 1;
cfg_.g_threads = 4;
cfg_.temporal_layering_mode = 3;
svc_params_.scaling_factor_num[0] = 144;
svc_params_.scaling_factor_den[0] = 288;
svc_params_.scaling_factor_num[1] = 288;
svc_params_.scaling_factor_den[1] = 288;
// TODO(wonkap/marpan): No frame drop for now, we need to implement correct
// frame dropping for SVC.
cfg_.rc_dropframe_thresh = 0;
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
30, 1, 0, 300);
cfg_.rc_target_bitrate = 800;
ResetModel();
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
cfg_.ts_number_layers, cfg_.temporal_layering_mode,
cfg_.rc_target_bitrate);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
<< " The datarate for the file is lower than the target by too much!";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
}
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES); VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large, VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
::testing::Values(::libvpx_test::kOnePassGood, ::testing::Values(::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime), ::libvpx_test::kRealTime),
::testing::Range(2, 7)); ::testing::Range(2, 7));
VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 8));
} // namespace } // namespace

View File

@@ -13,18 +13,15 @@
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_scan.h"
#include "vpx/vpx_codec.h" #include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom; using libvpx_test::ACMRandom;
@@ -40,6 +37,30 @@ static int round(double x) {
#endif #endif
const int kNumCoeffs = 256; const int kNumCoeffs = 256;
const double PI = 3.1415926535898;
void reference2_16x16_idct_2d(double *input, double *output) {
double x;
for (int l = 0; l < 16; ++l) {
for (int k = 0; k < 16; ++k) {
double s = 0;
for (int i = 0; i < 16; ++i) {
for (int j = 0; j < 16; ++j) {
x = cos(PI * j * (l + 0.5) / 16.0) *
cos(PI * i * (k + 0.5) / 16.0) *
input[i * 16 + j] / 256;
if (i != 0)
x *= sqrt(2.0);
if (j != 0)
x *= sqrt(2.0);
s += x;
}
}
output[k*16+l] = s;
}
}
}
const double C1 = 0.995184726672197; const double C1 = 0.995184726672197;
const double C2 = 0.98078528040323; const double C2 = 0.98078528040323;
const double C3 = 0.956940335732209; const double C3 = 0.956940335732209;
@@ -248,12 +269,12 @@ typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t>
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride, void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
int /*tx_type*/) { int /*tx_type*/) {
vpx_fdct16x16_c(in, out, stride); vp9_fdct16x16_c(in, out, stride);
} }
void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride, void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
int /*tx_type*/) { int /*tx_type*/) {
vpx_idct16x16_256_add_c(in, dest, stride); vp9_idct16x16_256_add_c(in, dest, stride);
} }
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride,
@@ -268,11 +289,11 @@ void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_256_add_c(in, out, stride, 10); vp9_highbd_idct16x16_256_add_c(in, out, stride, 10);
} }
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_256_add_c(in, out, stride, 12); vp9_highbd_idct16x16_256_add_c(in, out, stride, 12);
} }
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride, void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
@@ -294,31 +315,31 @@ void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
} }
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10); vp9_highbd_idct16x16_10_add_c(in, out, stride, 10);
} }
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_10_add_c(in, out, stride, 12); vp9_highbd_idct16x16_10_add_c(in, out, stride, 12);
} }
#if HAVE_SSE2 #if HAVE_SSE2
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10); vp9_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
} }
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12); vp9_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
} }
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10); vp9_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
} }
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12); vp9_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
} }
#endif // HAVE_SSE2 #endif
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
class Trans16x16TestBase { class Trans16x16TestBase {
public: public:
@@ -335,13 +356,13 @@ class Trans16x16TestBase {
int64_t total_error = 0; int64_t total_error = 0;
const int count_test_block = 10000; const int count_test_block = 10000;
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif #endif
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
@@ -395,9 +416,9 @@ class Trans16x16TestBase {
void RunCoeffCheck() { void RunCoeffCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
@@ -416,13 +437,15 @@ class Trans16x16TestBase {
void RunMemCheck() { void RunMemCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
} }
if (i == 0) { if (i == 0) {
@@ -449,19 +472,24 @@ class Trans16x16TestBase {
void RunQuantCheck(int dc_thred, int ac_thred) { void RunQuantCheck(int dc_thred, int ac_thred) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 100000; const int count_test_block = 100000;
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
if (bit_depth_ == VPX_BITS_8)
input_block[j] = rnd.Rand8() - rnd.Rand8();
else
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
} }
if (i == 0) if (i == 0)
@@ -474,11 +502,11 @@ class Trans16x16TestBase {
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
// clear reconstructed pixel buffers // clear reconstructed pixel buffers
memset(dst, 0, kNumCoeffs * sizeof(uint8_t)); vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
memset(ref, 0, kNumCoeffs * sizeof(uint8_t)); vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
memset(dst16, 0, kNumCoeffs * sizeof(uint16_t)); vpx_memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
memset(ref16, 0, kNumCoeffs * sizeof(uint16_t)); vpx_memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
#endif #endif
// quantization with maximum allowed step sizes // quantization with maximum allowed step sizes
@@ -511,14 +539,14 @@ class Trans16x16TestBase {
void RunInvAccuracyCheck() { void RunInvAccuracyCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
double out_r[kNumCoeffs]; double out_r[kNumCoeffs];
@@ -534,7 +562,7 @@ class Trans16x16TestBase {
src16[j] = rnd.Rand16() & mask_; src16[j] = rnd.Rand16() & mask_;
dst16[j] = rnd.Rand16() & mask_; dst16[j] = rnd.Rand16() & mask_;
in[j] = src16[j] - dst16[j]; in[j] = src16[j] - dst16[j];
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
} }
} }
@@ -548,7 +576,7 @@ class Trans16x16TestBase {
} else { } else {
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
16)); 16));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
} }
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
@@ -557,7 +585,7 @@ class Trans16x16TestBase {
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else #else
const uint32_t diff = dst[j] - src[j]; const uint32_t diff = dst[j] - src[j];
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
const uint32_t error = diff * diff; const uint32_t error = diff * diff;
EXPECT_GE(1u, error) EXPECT_GE(1u, error)
<< "Error: 16x16 IDCT has error " << error << "Error: 16x16 IDCT has error " << error
@@ -565,25 +593,24 @@ class Trans16x16TestBase {
} }
} }
} }
void CompareInvReference(IdctFunc ref_txfm, int thresh) { void CompareInvReference(IdctFunc ref_txfm, int thresh) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 10000; const int count_test_block = 10000;
const int eob = 10; const int eob = 10;
const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan; const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan;
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
if (j < eob) { if (j < eob) {
// Random values less than the threshold, either positive or negative // Random values less than the threshold, either positive or negative
coeff[scan[j]] = rnd(thresh) * (1 - 2 * (i % 2)); coeff[scan[j]] = rnd(thresh) * (1-2*(i%2));
} else { } else {
coeff[scan[j]] = 0; coeff[scan[j]] = 0;
} }
@@ -594,7 +621,7 @@ class Trans16x16TestBase {
} else { } else {
dst16[j] = 0; dst16[j] = 0;
ref16[j] = 0; ref16[j] = 0;
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
} }
} }
if (bit_depth_ == VPX_BITS_8) { if (bit_depth_ == VPX_BITS_8) {
@@ -605,7 +632,7 @@ class Trans16x16TestBase {
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_); ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
pitch_)); pitch_));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
} }
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
@@ -614,7 +641,7 @@ class Trans16x16TestBase {
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j]; bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
#else #else
const uint32_t diff = dst[j] - ref[j]; const uint32_t diff = dst[j] - ref[j];
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
const uint32_t error = diff * diff; const uint32_t error = diff * diff;
EXPECT_EQ(0u, error) EXPECT_EQ(0u, error)
<< "Error: 16x16 IDCT Comparison has error " << error << "Error: 16x16 IDCT Comparison has error " << error
@@ -622,7 +649,6 @@ class Trans16x16TestBase {
} }
} }
} }
int pitch_; int pitch_;
int tx_type_; int tx_type_;
vpx_bit_depth_t bit_depth_; vpx_bit_depth_t bit_depth_;
@@ -770,9 +796,9 @@ class InvTrans16x16DCT
virtual void SetUp() { virtual void SetUp() {
ref_txfm_ = GET_PARAM(0); ref_txfm_ = GET_PARAM(0);
inv_txfm_ = GET_PARAM(1); inv_txfm_ = GET_PARAM(1);
thresh_ = GET_PARAM(2); thresh_ = GET_PARAM(2);
bit_depth_ = GET_PARAM(3); bit_depth_ = GET_PARAM(3);
pitch_ = 16; pitch_ = 16;
mask_ = (1 << bit_depth_) - 1; mask_ = (1 << bit_depth_) - 1;
} }
virtual void TearDown() { libvpx_test::ClearSystemState(); } virtual void TearDown() { libvpx_test::ClearSystemState(); }
@@ -798,15 +824,15 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans16x16DCT, C, Trans16x16DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12), make_tuple(&vp9_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans16x16DCT, C, Trans16x16DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
@@ -832,22 +858,22 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8))); make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, Trans16x16DCT, NEON, Trans16x16DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8))); &vp9_idct16x16_256_add_neon, 0, VPX_BITS_8)));
#endif #endif
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16DCT, SSE2, Trans16x16DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct16x16_sse2, make_tuple(&vp9_fdct16x16_sse2,
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8))); &vp9_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16HT, SSE2, Trans16x16HT,
::testing::Values( ::testing::Values(
@@ -859,25 +885,33 @@ INSTANTIATE_TEST_CASE_P(
VPX_BITS_8), VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3, make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3,
VPX_BITS_8))); VPX_BITS_8)));
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16DCT, SSE2, Trans16x16DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_fdct16x16_sse2, make_tuple(&vp9_highbd_fdct16x16_sse2,
&idct16x16_10, 0, VPX_BITS_10), &idct16x16_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_c, make_tuple(&vp9_highbd_fdct16x16_c,
&idct16x16_256_add_10_sse2, 0, VPX_BITS_10), &idct16x16_256_add_10_sse2, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct16x16_sse2, make_tuple(&vp9_highbd_fdct16x16_sse2,
&idct16x16_12, 0, VPX_BITS_12), &idct16x16_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct16x16_c, make_tuple(&vp9_highbd_fdct16x16_c,
&idct16x16_256_add_12_sse2, 0, VPX_BITS_12), &idct16x16_256_add_12_sse2, 0, VPX_BITS_12),
make_tuple(&vpx_fdct16x16_sse2, make_tuple(&vp9_fdct16x16_sse2,
&vpx_idct16x16_256_add_c, 0, VPX_BITS_8))); &vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans16x16HT, SSE2, Trans16x16HT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 0, VPX_BITS_10),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 1, VPX_BITS_10),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 2, VPX_BITS_10),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 3, VPX_BITS_10),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 0, VPX_BITS_12),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 1, VPX_BITS_12),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 2, VPX_BITS_12),
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 3, VPX_BITS_12),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8), make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8), make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8), make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
@@ -896,21 +930,13 @@ INSTANTIATE_TEST_CASE_P(
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12), &idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
make_tuple(&idct16x16_12, make_tuple(&idct16x16_12,
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12))); &idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
MSA, Trans16x16DCT, SSSE3, Trans16x16DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct16x16_msa, make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0,
&vpx_idct16x16_256_add_msa, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, Trans16x16HT,
::testing::Values(
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 0, VPX_BITS_8),
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 1, VPX_BITS_8),
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_msa, &vp9_iht16x16_256_add_msa, 3,
VPX_BITS_8))); VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
} // namespace } // namespace

View File

@@ -13,18 +13,16 @@
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_rtcd.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropy.h"
#include "vpx/vpx_codec.h" #include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom; using libvpx_test::ACMRandom;
@@ -82,17 +80,17 @@ typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
void idct32x32_8(const tran_low_t *in, uint8_t *out, int stride) { void idct32x32_8(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 8); vp9_highbd_idct32x32_1024_add_c(in, out, stride, 8);
} }
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) { void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10); vp9_highbd_idct32x32_1024_add_c(in, out, stride, 10);
} }
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) { void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 12); vp9_highbd_idct32x32_1024_add_c(in, out, stride, 12);
} }
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> { class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
public: public:
@@ -121,13 +119,13 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
uint32_t max_error = 0; uint32_t max_error = 0;
int64_t total_error = 0; int64_t total_error = 0;
const int count_test_block = 10000; const int count_test_block = 10000;
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -186,16 +184,16 @@ TEST_P(Trans32x32Test, CoeffCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
for (int j = 0; j < kNumCoeffs; ++j) for (int j = 0; j < kNumCoeffs; ++j)
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
const int stride = 32; const int stride = 32;
vpx_fdct32x32_c(input_block, output_ref_block, stride); vp9_fdct32x32_c(input_block, output_ref_block, stride);
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride)); ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
if (version_ == 0) { if (version_ == 0) {
@@ -214,13 +212,15 @@ TEST_P(Trans32x32Test, MemCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 2000; const int count_test_block = 2000;
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_; input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
} }
if (i == 0) { if (i == 0) {
@@ -232,7 +232,7 @@ TEST_P(Trans32x32Test, MemCheck) {
} }
const int stride = 32; const int stride = 32;
vpx_fdct32x32_c(input_extreme_block, output_ref_block, stride); vp9_fdct32x32_c(input_extreme_block, output_ref_block, stride);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
fwd_txfm_(input_extreme_block, output_block, stride)); fwd_txfm_(input_extreme_block, output_block, stride));
@@ -257,13 +257,13 @@ TEST_P(Trans32x32Test, MemCheck) {
TEST_P(Trans32x32Test, InverseAccuracy) { TEST_P(Trans32x32Test, InverseAccuracy) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -315,81 +315,71 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans32x32Test, C, Trans32x32Test,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_fdct32x32_c, make_tuple(&vp9_highbd_fdct32x32_c,
&idct32x32_10, 0, VPX_BITS_10), &idct32x32_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_rd_c, make_tuple(&vp9_highbd_fdct32x32_rd_c,
&idct32x32_10, 1, VPX_BITS_10), &idct32x32_10, 1, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_c, make_tuple(&vp9_highbd_fdct32x32_c,
&idct32x32_12, 0, VPX_BITS_12), &idct32x32_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct32x32_rd_c, make_tuple(&vp9_highbd_fdct32x32_rd_c,
&idct32x32_12, 1, VPX_BITS_12), &idct32x32_12, 1, VPX_BITS_12),
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8), &vp9_idct32x32_1024_add_c, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c, make_tuple(&vp9_fdct32x32_rd_c,
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8))); &vp9_idct32x32_1024_add_c, 1, VPX_BITS_8)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans32x32Test, C, Trans32x32Test,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8), &vp9_idct32x32_1024_add_c, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c, make_tuple(&vp9_fdct32x32_rd_c,
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8))); &vp9_idct32x32_1024_add_c, 1, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, Trans32x32Test, NEON, Trans32x32Test,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8), &vp9_idct32x32_1024_add_neon, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_c, make_tuple(&vp9_fdct32x32_rd_c,
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8))); &vp9_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans32x32Test, SSE2, Trans32x32Test,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_sse2, make_tuple(&vp9_fdct32x32_sse2,
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8), &vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_sse2, make_tuple(&vp9_fdct32x32_rd_sse2,
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8))); &vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans32x32Test, SSE2, Trans32x32Test,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fdct32x32_sse2, &idct32x32_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_10, 1, make_tuple(&vp9_highbd_fdct32x32_rd_sse2, &idct32x32_10, 1,
VPX_BITS_10), VPX_BITS_10),
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 0, VPX_BITS_12), make_tuple(&vp9_highbd_fdct32x32_sse2, &idct32x32_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_12, 1, make_tuple(&vp9_highbd_fdct32x32_rd_sse2, &idct32x32_12, 1,
VPX_BITS_12), VPX_BITS_12),
make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_c, 0, make_tuple(&vp9_fdct32x32_sse2, &vp9_idct32x32_1024_add_c, 0,
VPX_BITS_8), VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1, make_tuple(&vp9_fdct32x32_rd_sse2, &vp9_idct32x32_1024_add_c, 1,
VPX_BITS_8))); VPX_BITS_8)));
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
AVX2, Trans32x32Test, AVX2, Trans32x32Test,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_avx2, make_tuple(&vp9_fdct32x32_avx2,
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8), &vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_avx2, make_tuple(&vp9_fdct32x32_rd_avx2,
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8))); &vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, Trans32x32Test,
::testing::Values(
make_tuple(&vpx_fdct32x32_msa,
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
make_tuple(&vpx_fdct32x32_rd_msa,
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace } // namespace

View File

@@ -7,11 +7,10 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "test/ivf_video_source.h" #include "test/ivf_video_source.h"
#include "./vpx_config.h"
#include "vpx/vp8dx.h" #include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h" #include "vpx/vpx_decoder.h"
@@ -26,9 +25,6 @@ TEST(DecodeAPI, InvalidParams) {
#endif #endif
#if CONFIG_VP9_DECODER #if CONFIG_VP9_DECODER
&vpx_codec_vp9_dx_algo, &vpx_codec_vp9_dx_algo,
#endif
#if CONFIG_VP10_DECODER
&vpx_codec_vp10_dx_algo,
#endif #endif
}; };
uint8_t buf[1] = {0}; uint8_t buf[1] = {0};
@@ -61,21 +57,6 @@ TEST(DecodeAPI, InvalidParams) {
} }
} }
#if CONFIG_VP8_DECODER
TEST(DecodeAPI, OptionalParams) {
vpx_codec_ctx_t dec;
#if CONFIG_ERROR_CONCEALMENT
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
VPX_CODEC_USE_ERROR_CONCEALMENT));
#else
EXPECT_EQ(VPX_CODEC_INCAPABLE,
vpx_codec_dec_init(&dec, &vpx_codec_vp8_dx_algo, NULL,
VPX_CODEC_USE_ERROR_CONCEALMENT));
#endif // CONFIG_ERROR_CONCEALMENT
}
#endif // CONFIG_VP8_DECODER
#if CONFIG_VP9_DECODER #if CONFIG_VP9_DECODER
// Test VP9 codec controls after a decode error to ensure the code doesn't // Test VP9 codec controls after a decode error to ensure the code doesn't
// misbehave. // misbehave.
@@ -84,7 +65,6 @@ void TestVp9Controls(vpx_codec_ctx_t *dec) {
VP8D_GET_LAST_REF_UPDATES, VP8D_GET_LAST_REF_UPDATES,
VP8D_GET_FRAME_CORRUPTED, VP8D_GET_FRAME_CORRUPTED,
VP9D_GET_DISPLAY_SIZE, VP9D_GET_DISPLAY_SIZE,
VP9D_GET_FRAME_SIZE
}; };
int val[2]; int val[2];
@@ -133,13 +113,8 @@ TEST(DecodeAPI, Vp9InvalidDecode) {
vpx_codec_ctx_t dec; vpx_codec_ctx_t dec;
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0)); EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
const uint32_t frame_size = static_cast<uint32_t>(video.frame_size()); const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
#if CONFIG_VP9_HIGHBITDEPTH
EXPECT_EQ(VPX_CODEC_MEM_ERROR, EXPECT_EQ(VPX_CODEC_MEM_ERROR,
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0)); vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
#else
EXPECT_EQ(VPX_CODEC_UNSUP_BITSTREAM,
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
#endif
vpx_codec_iter_t iter = NULL; vpx_codec_iter_t iter = NULL;
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter)); EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));

View File

@@ -8,17 +8,13 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include <string>
#include "test/codec_factory.h" #include "test/codec_factory.h"
#include "test/decode_test_driver.h" #include "test/decode_test_driver.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/ivf_video_source.h" #include "test/ivf_video_source.h"
#include "test/md5_helper.h" #include "test/md5_helper.h"
#include "test/util.h" #include "test/util.h"
#include "test/webm_video_source.h" #include "test/webm_video_source.h"
#include "vpx_ports/vpx_timer.h" #include "vpx_ports/vpx_timer.h"
#include "./ivfenc.h"
#include "./vpx_version.h" #include "./vpx_version.h"
using std::tr1::make_tuple; using std::tr1::make_tuple;
@@ -28,9 +24,7 @@ namespace {
#define VIDEO_NAME 0 #define VIDEO_NAME 0
#define THREADS 1 #define THREADS 1
const int kMaxPsnr = 100;
const double kUsecsInSec = 1000000.0; const double kUsecsInSec = 1000000.0;
const char kNewEncodeOutputFile[] = "new_encode.ivf";
/* /*
DecodePerfTest takes a tuple of filename + number of threads to decode with DecodePerfTest takes a tuple of filename + number of threads to decode with
@@ -111,163 +105,4 @@ TEST_P(DecodePerfTest, PerfTest) {
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest, INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
::testing::ValuesIn(kVP9DecodePerfVectors)); ::testing::ValuesIn(kVP9DecodePerfVectors));
class VP9NewEncodeDecodePerfTest :
public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
VP9NewEncodeDecodePerfTest()
: EncoderTest(GET_PARAM(0)),
encoding_mode_(GET_PARAM(1)),
speed_(0),
outfile_(0),
out_frames_(0) {
}
virtual ~VP9NewEncodeDecodePerfTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
cfg_.g_lag_in_frames = 25;
cfg_.rc_min_quantizer = 2;
cfg_.rc_max_quantizer = 56;
cfg_.rc_dropframe_thresh = 0;
cfg_.rc_undershoot_pct = 50;
cfg_.rc_overshoot_pct = 50;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
cfg_.rc_resize_allowed = 0;
cfg_.rc_end_usage = VPX_VBR;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, speed_);
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(VP9E_SET_TILE_COLUMNS, 2);
}
}
virtual void BeginPassHook(unsigned int /*pass*/) {
const std::string data_path = getenv("LIBVPX_TEST_DATA_PATH");
const std::string path_to_source = data_path + "/" + kNewEncodeOutputFile;
outfile_ = fopen(path_to_source.c_str(), "wb");
ASSERT_TRUE(outfile_ != NULL);
}
virtual void EndPassHook() {
if (outfile_ != NULL) {
if (!fseek(outfile_, 0, SEEK_SET))
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
fclose(outfile_);
outfile_ = NULL;
}
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
++out_frames_;
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0)
ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
// Write frame header and data.
ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
ASSERT_EQ(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_),
pkt->data.frame.sz);
}
virtual bool DoDecode() { return false; }
void set_speed(unsigned int speed) {
speed_ = speed;
}
private:
libvpx_test::TestMode encoding_mode_;
uint32_t speed_;
FILE *outfile_;
uint32_t out_frames_;
};
struct EncodePerfTestVideo {
EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
uint32_t bitrate_, int frames_)
: name(name_),
width(width_),
height(height_),
bitrate(bitrate_),
frames(frames_) {}
const char *name;
uint32_t width;
uint32_t height;
uint32_t bitrate;
int frames;
};
const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
};
TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
SetUp();
// TODO(JBB): Make this work by going through the set of given files.
const int i = 0;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
init_flags_ = VPX_CODEC_USE_PSNR;
const char *video_name = kVP9EncodePerfTestVectors[i].name;
libvpx_test::I420VideoSource video(
video_name,
kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height,
timebase.den, timebase.num, 0,
kVP9EncodePerfTestVectors[i].frames);
set_speed(2);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
const uint32_t threads = 4;
libvpx_test::IVFVideoSource decode_video(kNewEncodeOutputFile);
decode_video.Init();
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
cfg.threads = threads;
libvpx_test::VP9Decoder decoder(cfg, 0);
vpx_usec_timer t;
vpx_usec_timer_start(&t);
for (decode_video.Begin(); decode_video.cxdata() != NULL;
decode_video.Next()) {
decoder.DecodeFrame(decode_video.cxdata(), decode_video.frame_size());
}
vpx_usec_timer_mark(&t);
const double elapsed_secs =
static_cast<double>(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
const unsigned decode_frames = decode_video.frame_number();
const double fps = static_cast<double>(decode_frames) / elapsed_secs;
printf("{\n");
printf("\t\"type\" : \"decode_perf_test\",\n");
printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
printf("\t\"videoName\" : \"%s\",\n", kNewEncodeOutputFile);
printf("\t\"threadCount\" : %u,\n", threads);
printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
printf("\t\"totalFrames\" : %u,\n", decode_frames);
printf("\t\"framesPerSecond\" : %f\n", fps);
printf("}\n");
}
VP9_INSTANTIATE_TEST_CASE(
VP9NewEncodeDecodePerfTest, ::testing::Values(::libvpx_test::kTwoPassGood));
} // namespace } // namespace

View File

@@ -7,11 +7,9 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h" #include "test/codec_factory.h"
#include "test/decode_test_driver.h" #include "test/decode_test_driver.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/video_source.h" #include "test/video_source.h"
@@ -67,7 +65,7 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
void DecoderTest::RunLoop(CompressedVideoSource *video, void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_codec_dec_cfg_t &dec_cfg) { const vpx_codec_dec_cfg_t &dec_cfg) {
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, flags_, 0); Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
ASSERT_TRUE(decoder != NULL); ASSERT_TRUE(decoder != NULL);
bool end_of_file = false; bool end_of_file = false;
@@ -112,12 +110,4 @@ void DecoderTest::RunLoop(CompressedVideoSource *video) {
RunLoop(video, dec_cfg); RunLoop(video, dec_cfg);
} }
void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) {
memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
}
void DecoderTest::set_flags(const vpx_codec_flags_t flags) {
flags_ = flags;
}
} // namespace libvpx_test } // namespace libvpx_test

View File

@@ -41,13 +41,7 @@ class DxDataIterator {
class Decoder { class Decoder {
public: public:
Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline) Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: cfg_(cfg), flags_(0), deadline_(deadline), init_done_(false) { : cfg_(cfg), deadline_(deadline), init_done_(false) {
memset(&decoder_, 0, sizeof(decoder_));
}
Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
unsigned long deadline) // NOLINT
: cfg_(cfg), flags_(flag), deadline_(deadline), init_done_(false) {
memset(&decoder_, 0, sizeof(decoder_)); memset(&decoder_, 0, sizeof(decoder_));
} }
@@ -72,7 +66,9 @@ class Decoder {
} }
void Control(int ctrl_id, int arg) { void Control(int ctrl_id, int arg) {
Control(ctrl_id, arg, VPX_CODEC_OK); InitOnce();
const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
} }
void Control(int ctrl_id, const void *arg) { void Control(int ctrl_id, const void *arg) {
@@ -81,12 +77,6 @@ class Decoder {
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
} }
void Control(int ctrl_id, int arg, vpx_codec_err_t expected_value) {
InitOnce();
const vpx_codec_err_t res = vpx_codec_control_(&decoder_, ctrl_id, arg);
ASSERT_EQ(expected_value, res) << DecodeError();
}
const char* DecodeError() { const char* DecodeError() {
const char *detail = vpx_codec_error_detail(&decoder_); const char *detail = vpx_codec_error_detail(&decoder_);
return detail ? detail : vpx_codec_error(&decoder_); return detail ? detail : vpx_codec_error(&decoder_);
@@ -107,10 +97,6 @@ class Decoder {
bool IsVP8() const; bool IsVP8() const;
vpx_codec_ctx_t * GetDecoder() {
return &decoder_;
}
protected: protected:
virtual vpx_codec_iface_t* CodecInterface() const = 0; virtual vpx_codec_iface_t* CodecInterface() const = 0;
@@ -118,7 +104,7 @@ class Decoder {
if (!init_done_) { if (!init_done_) {
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_, const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
CodecInterface(), CodecInterface(),
&cfg_, flags_); &cfg_, 0);
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError(); ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
init_done_ = true; init_done_ = true;
} }
@@ -126,7 +112,6 @@ class Decoder {
vpx_codec_ctx_t decoder_; vpx_codec_ctx_t decoder_;
vpx_codec_dec_cfg_t cfg_; vpx_codec_dec_cfg_t cfg_;
vpx_codec_flags_t flags_;
unsigned int deadline_; unsigned int deadline_;
bool init_done_; bool init_done_;
}; };
@@ -139,9 +124,6 @@ class DecoderTest {
virtual void RunLoop(CompressedVideoSource *video, virtual void RunLoop(CompressedVideoSource *video,
const vpx_codec_dec_cfg_t &dec_cfg); const vpx_codec_dec_cfg_t &dec_cfg);
virtual void set_cfg(const vpx_codec_dec_cfg_t &dec_cfg);
virtual void set_flags(const vpx_codec_flags_t flags);
// Hook to be called before decompressing every frame. // Hook to be called before decompressing every frame.
virtual void PreDecodeFrameHook(const CompressedVideoSource& /*video*/, virtual void PreDecodeFrameHook(const CompressedVideoSource& /*video*/,
Decoder* /*decoder*/) {} Decoder* /*decoder*/) {}
@@ -164,16 +146,11 @@ class DecoderTest {
const vpx_codec_err_t res_peek); const vpx_codec_err_t res_peek);
protected: protected:
explicit DecoderTest(const CodecFactory *codec) explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {}
: codec_(codec),
cfg_(),
flags_(0) {}
virtual ~DecoderTest() {} virtual ~DecoderTest() {}
const CodecFactory *codec_; const CodecFactory *codec_;
vpx_codec_dec_cfg_t cfg_;
vpx_codec_flags_t flags_;
}; };
} // namespace libvpx_test } // namespace libvpx_test

View File

@@ -7,7 +7,6 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h" #include "./vpx_config.h"
#include "./vpx_version.h" #include "./vpx_version.h"
@@ -51,8 +50,7 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470), EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
}; };
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8 }; const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 12 };
const int kEncodePerfTestThreads[] = { 1, 2, 4 };
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0])) #define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
@@ -65,8 +63,7 @@ class VP9EncodePerfTest
min_psnr_(kMaxPsnr), min_psnr_(kMaxPsnr),
nframes_(0), nframes_(0),
encoding_mode_(GET_PARAM(1)), encoding_mode_(GET_PARAM(1)),
speed_(0), speed_(0) {}
threads_(1) {}
virtual ~VP9EncodePerfTest() {} virtual ~VP9EncodePerfTest() {}
@@ -85,18 +82,12 @@ class VP9EncodePerfTest
cfg_.rc_buf_optimal_sz = 600; cfg_.rc_buf_optimal_sz = 600;
cfg_.rc_resize_allowed = 0; cfg_.rc_resize_allowed = 0;
cfg_.rc_end_usage = VPX_CBR; cfg_.rc_end_usage = VPX_CBR;
cfg_.g_error_resilient = 1;
cfg_.g_threads = threads_;
} }
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) { ::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) { if (video->frame() == 1) {
const int log2_tile_columns = 3;
encoder->Control(VP8E_SET_CPUUSED, speed_); encoder->Control(VP8E_SET_CPUUSED, speed_);
encoder->Control(VP9E_SET_TILE_COLUMNS, log2_tile_columns);
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
} }
} }
@@ -122,77 +113,54 @@ class VP9EncodePerfTest
speed_ = speed; speed_ = speed;
} }
void set_threads(unsigned int threads) {
threads_ = threads;
}
private: private:
double min_psnr_; double min_psnr_;
unsigned int nframes_; unsigned int nframes_;
libvpx_test::TestMode encoding_mode_; libvpx_test::TestMode encoding_mode_;
unsigned speed_; unsigned speed_;
unsigned int threads_;
}; };
TEST_P(VP9EncodePerfTest, PerfTest) { TEST_P(VP9EncodePerfTest, PerfTest) {
for (size_t i = 0; i < NELEMENTS(kVP9EncodePerfTestVectors); ++i) { for (size_t i = 0; i < NELEMENTS(kVP9EncodePerfTestVectors); ++i) {
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) { for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) { SetUp();
if (kVP9EncodePerfTestVectors[i].width < 512 &&
kEncodePerfTestThreads[k] > 1)
continue;
else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
kEncodePerfTestThreads[k] > 2)
continue;
set_threads(kEncodePerfTestThreads[k]); const vpx_rational timebase = { 33333333, 1000000000 };
SetUp(); cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
const vpx_rational timebase = { 33333333, 1000000000 }; init_flags_ = VPX_CODEC_USE_PSNR;
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
init_flags_ = VPX_CODEC_USE_PSNR; const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
const char *video_name = kVP9EncodePerfTestVectors[i].name;
libvpx_test::I420VideoSource video(
video_name,
kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height,
timebase.den, timebase.num, 0,
kVP9EncodePerfTestVectors[i].frames);
set_speed(kEncodePerfTestSpeeds[j]);
const unsigned frames = kVP9EncodePerfTestVectors[i].frames; vpx_usec_timer t;
const char *video_name = kVP9EncodePerfTestVectors[i].name; vpx_usec_timer_start(&t);
libvpx_test::I420VideoSource video(
video_name,
kVP9EncodePerfTestVectors[i].width,
kVP9EncodePerfTestVectors[i].height,
timebase.den, timebase.num, 0,
kVP9EncodePerfTestVectors[i].frames);
set_speed(kEncodePerfTestSpeeds[j]);
vpx_usec_timer t; ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
vpx_usec_timer_start(&t);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); vpx_usec_timer_mark(&t);
const double elapsed_secs = vpx_usec_timer_elapsed(&t) / kUsecsInSec;
const double fps = frames / elapsed_secs;
const double minimum_psnr = min_psnr();
vpx_usec_timer_mark(&t); printf("{\n");
const double elapsed_secs = vpx_usec_timer_elapsed(&t) / kUsecsInSec; printf("\t\"type\" : \"encode_perf_test\",\n");
const double fps = frames / elapsed_secs; printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
const double minimum_psnr = min_psnr(); printf("\t\"videoName\" : \"%s\",\n", video_name);
std::string display_name(video_name); printf("\t\"encodeTimeSecs\" : %f,\n", elapsed_secs);
if (kEncodePerfTestThreads[k] > 1) { printf("\t\"totalFrames\" : %u,\n", frames);
char thread_count[32]; printf("\t\"framesPerSecond\" : %f,\n", fps);
snprintf(thread_count, sizeof(thread_count), "_t-%d", printf("\t\"minPsnr\" : %f,\n", minimum_psnr);
kEncodePerfTestThreads[k]); printf("\t\"speed\" : %d\n", kEncodePerfTestSpeeds[j]);
display_name += thread_count; printf("}\n");
}
printf("{\n");
printf("\t\"type\" : \"encode_perf_test\",\n");
printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
printf("\t\"videoName\" : \"%s\",\n", display_name.c_str());
printf("\t\"encodeTimeSecs\" : %f,\n", elapsed_secs);
printf("\t\"totalFrames\" : %u,\n", frames);
printf("\t\"framesPerSecond\" : %f,\n", fps);
printf("\t\"minPsnr\" : %f,\n", minimum_psnr);
printf("\t\"speed\" : %d,\n", kEncodePerfTestSpeeds[j]);
printf("\t\"threads\" : %d\n", kEncodePerfTestThreads[k]);
printf("}\n");
}
} }
} }
} }

View File

@@ -8,59 +8,15 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h" #include "./vpx_config.h"
#include "test/codec_factory.h" #include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/encode_test_driver.h" #include "test/encode_test_driver.h"
#include "test/decode_test_driver.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/video_source.h" #include "test/video_source.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
namespace libvpx_test { namespace libvpx_test {
void Encoder::InitEncoder(VideoSource *video) {
vpx_codec_err_t res;
const vpx_image_t *img = video->img();
if (video->img() && !encoder_.priv) {
cfg_.g_w = img->d_w;
cfg_.g_h = img->d_h;
cfg_.g_timebase = video->timebase();
cfg_.rc_twopass_stats_in = stats_->buf();
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
init_flags_);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
#if CONFIG_VP9_ENCODER
if (CodecInterface() == &vpx_codec_vp9_cx_algo) {
// Default to 1 tile column for VP9.
const int log2_tile_columns = 0;
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
log2_tile_columns);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} else
#endif
#if CONFIG_VP10_ENCODER
if (CodecInterface() == &vpx_codec_vp10_cx_algo) {
// Default to 1 tile column for VP10.
const int log2_tile_columns = 0;
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
log2_tile_columns);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} else
#endif
{
#if CONFIG_VP8_ENCODER
ASSERT_EQ(&vpx_codec_vp8_cx_algo, CodecInterface())
<< "Unknown Codec Interface";
#endif
}
}
}
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) { void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
if (video->img()) if (video->img())
EncodeFrameInternal(*video, frame_flags); EncodeFrameInternal(*video, frame_flags);
@@ -83,6 +39,17 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
vpx_codec_err_t res; vpx_codec_err_t res;
const vpx_image_t *img = video.img(); const vpx_image_t *img = video.img();
// Handle first frame initialization
if (!encoder_.priv) {
cfg_.g_w = img->d_w;
cfg_.g_h = img->d_h;
cfg_.g_timebase = video.timebase();
cfg_.rc_twopass_stats_in = stats_->buf();
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
init_flags_);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
// Handle frame resizing // Handle frame resizing
if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) { if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) {
cfg_.g_w = img->d_w; cfg_.g_w = img->d_w;
@@ -93,7 +60,8 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
// Encode the frame // Encode the frame
API_REGISTER_STATE_CHECK( API_REGISTER_STATE_CHECK(
res = vpx_codec_encode(&encoder_, img, video.pts(), video.duration(), res = vpx_codec_encode(&encoder_,
video.img(), video.pts(), video.duration(),
frame_flags, deadline_)); frame_flags, deadline_));
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} }
@@ -109,7 +77,6 @@ void Encoder::Flush() {
void EncoderTest::InitializeConfig() { void EncoderTest::InitializeConfig() {
const vpx_codec_err_t res = codec_->DefaultEncoderConfig(&cfg_, 0); const vpx_codec_err_t res = codec_->DefaultEncoderConfig(&cfg_, 0);
dec_cfg_ = vpx_codec_dec_cfg_t();
ASSERT_EQ(VPX_CODEC_OK, res); ASSERT_EQ(VPX_CODEC_OK, res);
} }
@@ -143,7 +110,6 @@ void EncoderTest::SetMode(TestMode mode) {
static bool compare_img(const vpx_image_t *img1, static bool compare_img(const vpx_image_t *img1,
const vpx_image_t *img2) { const vpx_image_t *img2) {
bool match = (img1->fmt == img2->fmt) && bool match = (img1->fmt == img2->fmt) &&
(img1->cs == img2->cs) &&
(img1->d_w == img2->d_w) && (img1->d_w == img2->d_w) &&
(img1->d_h == img2->d_h); (img1->d_h == img2->d_h);
@@ -192,19 +158,9 @@ void EncoderTest::RunLoop(VideoSource *video) {
Encoder* const encoder = codec_->CreateEncoder(cfg_, deadline_, init_flags_, Encoder* const encoder = codec_->CreateEncoder(cfg_, deadline_, init_flags_,
&stats_); &stats_);
ASSERT_TRUE(encoder != NULL); ASSERT_TRUE(encoder != NULL);
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
video->Begin();
encoder->InitEncoder(video);
ASSERT_FALSE(::testing::Test::HasFatalFailure());
unsigned long dec_init_flags = 0; // NOLINT
// Use fragment decoder if encoder outputs partitions.
// NOTE: fragment decoder and partition encoder are only supported by VP8.
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION)
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, dec_init_flags, 0);
bool again; bool again;
for (again = true; again; video->Next()) { for (again = true, video->Begin(); again; video->Next()) {
again = (video->img() != NULL); again = (video->img() != NULL);
PreEncodeFrameHook(video); PreEncodeFrameHook(video);
@@ -244,13 +200,6 @@ void EncoderTest::RunLoop(VideoSource *video) {
} }
} }
// Flush the decoder when there are no more fragments.
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
if (!HandleDecodeResult(res_dec, *video, decoder))
break;
}
if (has_dxdata && has_cxdata) { if (has_dxdata && has_cxdata) {
const vpx_image_t *img_enc = encoder->GetPreviewFrame(); const vpx_image_t *img_enc = encoder->GetPreviewFrame();
DxDataIterator dec_iter = decoder->GetDxData(); DxDataIterator dec_iter = decoder->GetDxData();

View File

@@ -13,13 +13,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h" #include "./vpx_config.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER #include "third_party/googletest/src/include/gtest/gtest.h"
#include "vpx/vpx_encoder.h"
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
#include "vpx/vp8cx.h" #include "vpx/vp8cx.h"
#endif #endif
#include "vpx/vpx_encoder.h"
namespace libvpx_test { namespace libvpx_test {
@@ -105,8 +104,6 @@ class Encoder {
return CxDataIterator(&encoder_); return CxDataIterator(&encoder_);
} }
void InitEncoder(VideoSource *video);
const vpx_image_t *GetPreviewFrame() { const vpx_image_t *GetPreviewFrame() {
return vpx_codec_get_preview_frame(&encoder_); return vpx_codec_get_preview_frame(&encoder_);
} }
@@ -124,11 +121,6 @@ class Encoder {
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} }
void Control(int ctrl_id, int *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Control(int ctrl_id, struct vpx_scaling_mode *arg) { void Control(int ctrl_id, struct vpx_scaling_mode *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
@@ -139,23 +131,13 @@ class Encoder {
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} }
void Control(int ctrl_id, struct vpx_svc_parameters *arg) { #if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER || CONFIG_VP10_ENCODER
void Control(int ctrl_id, vpx_active_map_t *arg) { void Control(int ctrl_id, vpx_active_map_t *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg); const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError(); ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
} }
#endif #endif
void Config(const vpx_codec_enc_cfg_t *cfg) {
const vpx_codec_err_t res = vpx_codec_enc_config_set(&encoder_, cfg);
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
cfg_ = *cfg;
}
void set_deadline(unsigned long deadline) { void set_deadline(unsigned long deadline) {
deadline_ = deadline; deadline_ = deadline;
} }
@@ -193,10 +175,7 @@ class EncoderTest {
protected: protected:
explicit EncoderTest(const CodecFactory *codec) explicit EncoderTest(const CodecFactory *codec)
: codec_(codec), abort_(false), init_flags_(0), frame_flags_(0), : codec_(codec), abort_(false), init_flags_(0), frame_flags_(0),
last_pts_(0) { last_pts_(0) {}
// Default to 1 thread.
cfg_.g_threads = 1;
}
virtual ~EncoderTest() {} virtual ~EncoderTest() {}
@@ -206,11 +185,6 @@ class EncoderTest {
// Map the TestMode enum to the deadline_ and passes_ variables. // Map the TestMode enum to the deadline_ and passes_ variables.
void SetMode(TestMode mode); void SetMode(TestMode mode);
// Set encoder flag.
void set_init_flags(unsigned long flag) { // NOLINT(runtime/int)
init_flags_ = flag;
}
// Main loop // Main loop
virtual void RunLoop(VideoSource *video); virtual void RunLoop(VideoSource *video);
@@ -264,7 +238,6 @@ class EncoderTest {
bool abort_; bool abort_;
vpx_codec_enc_cfg_t cfg_; vpx_codec_enc_cfg_t cfg_;
vpx_codec_dec_cfg_t dec_cfg_;
unsigned int passes_; unsigned int passes_;
unsigned long deadline_; unsigned long deadline_;
TwopassStatsStore stats_; TwopassStatsStore stats_;

146
test/error_block_test.cc Normal file
View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <cmath>
#include <cstdlib>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h"
#include "vpx/vpx_integer.h"
using libvpx_test::ACMRandom;
namespace {
#if CONFIG_VP9_HIGHBITDEPTH
const int number_of_iterations = 1000;
typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
const tran_low_t *dqcoeff, intptr_t block_size,
int64_t *ssz, int bps);
typedef std::tr1::tuple<ErrorBlockFunc, ErrorBlockFunc, vpx_bit_depth_t>
ErrorBlockParam;
class ErrorBlockTest
: public ::testing::TestWithParam<ErrorBlockParam> {
public:
virtual ~ErrorBlockTest() {}
virtual void SetUp() {
error_block_op_ = GET_PARAM(0);
ref_error_block_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
vpx_bit_depth_t bit_depth_;
ErrorBlockFunc error_block_op_;
ErrorBlockFunc ref_error_block_op_;
};
TEST_P(ErrorBlockTest, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, 4096);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff, 4096);
int err_count_total = 0;
int first_failure = -1;
intptr_t block_size;
int64_t ssz;
int64_t ret;
int64_t ref_ssz;
int64_t ref_ret;
for (int i = 0; i < number_of_iterations; ++i) {
int err_count = 0;
block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64
for (int j = 0; j < block_size; j++) {
coeff[j] = rnd(2<<20)-(1<<20);
dqcoeff[j] = rnd(2<<20)-(1<<20);
}
ref_ret = ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz,
bit_depth_);
ASM_REGISTER_STATE_CHECK(ret = error_block_op_(coeff, dqcoeff, block_size,
&ssz, bit_depth_));
err_count += (ref_ret != ret) | (ref_ssz != ssz);
if (err_count && !err_count_total) {
first_failure = i;
}
err_count_total += err_count;
}
EXPECT_EQ(0, err_count_total)
<< "Error: Error Block Test, C output doesn't match SSE2 output. "
<< "First failed at test case " << first_failure;
}
TEST_P(ErrorBlockTest, ExtremeValues) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, 4096);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff, 4096);
int err_count_total = 0;
int first_failure = -1;
intptr_t block_size;
int64_t ssz;
int64_t ret;
int64_t ref_ssz;
int64_t ref_ret;
int max_val = ((1<<20)-1);
for (int i = 0; i < number_of_iterations; ++i) {
int err_count = 0;
int k = (i / 9) % 5;
// Change the maximum coeff value, to test different bit boundaries
if ( k == 4 && (i % 9) == 0 ) {
max_val >>= 1;
}
block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64
for (int j = 0; j < block_size; j++) {
if (k < 4) { // Test at maximum values
coeff[j] = k % 2 ? max_val : -max_val;
dqcoeff[j] = (k >> 1) % 2 ? max_val : -max_val;
} else {
coeff[j] = rnd(2 << 14) - (1 << 14);
dqcoeff[j] = rnd(2 << 14) - (1 << 14);
}
}
ref_ret = ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz,
bit_depth_);
ASM_REGISTER_STATE_CHECK(ret = error_block_op_(coeff, dqcoeff, block_size,
&ssz, bit_depth_));
err_count += (ref_ret != ret) | (ref_ssz != ssz);
if (err_count && !err_count_total) {
first_failure = i;
}
err_count_total += err_count;
}
EXPECT_EQ(0, err_count_total)
<< "Error: Error Block Test, C output doesn't match SSE2 output. "
<< "First failed at test case " << first_failure;
}
using std::tr1::make_tuple;
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE, ErrorBlockTest,
::testing::Values(
make_tuple(&vp9_highbd_block_error_sse2,
&vp9_highbd_block_error_c, VPX_BITS_10),
make_tuple(&vp9_highbd_block_error_sse2,
&vp9_highbd_block_error_c, VPX_BITS_12),
make_tuple(&vp9_highbd_block_error_sse2,
&vp9_highbd_block_error_c, VPX_BITS_8)));
#endif // HAVE_SSE2
#endif // CONFIG_VP9_HIGHBITDEPTH
} // namespace

View File

@@ -20,11 +20,10 @@ const int kMaxErrorFrames = 12;
const int kMaxDroppableFrames = 12; const int kMaxDroppableFrames = 12;
class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest, class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> { public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected: protected:
ErrorResilienceTestLarge() ErrorResilienceTestLarge()
: EncoderTest(GET_PARAM(0)), : EncoderTest(GET_PARAM(0)),
svc_support_(GET_PARAM(2)),
psnr_(0.0), psnr_(0.0),
nframes_(0), nframes_(0),
mismatch_psnr_(0.0), mismatch_psnr_(0.0),
@@ -38,7 +37,6 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
void Reset() { void Reset() {
error_nframes_ = 0; error_nframes_ = 0;
droppable_nframes_ = 0; droppable_nframes_ = 0;
pattern_switch_ = 0;
} }
virtual void SetUp() { virtual void SetUp() {
@@ -58,77 +56,22 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
nframes_++; nframes_++;
} }
// virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video) {
// Frame flags and layer id for temporal layers.
// For two layers, test pattern is:
// 1 3
// 0 2 .....
// LAST is updated on base/layer 0, GOLDEN updated on layer 1.
// Non-zero pattern_switch parameter means pattern will switch to
// not using LAST for frame_num >= pattern_switch.
int SetFrameFlags(int frame_num,
int num_temp_layers,
int pattern_switch) {
int frame_flags = 0;
if (num_temp_layers == 2) {
if (frame_num % 2 == 0) {
if (frame_num < pattern_switch || pattern_switch == 0) {
// Layer 0: predict from LAST and ARF, update LAST.
frame_flags = VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
// Layer 0: predict from GF and ARF, update GF.
frame_flags = VP8_EFLAG_NO_REF_LAST |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
}
} else {
if (frame_num < pattern_switch || pattern_switch == 0) {
// Layer 1: predict from L, GF, and ARF, update GF.
frame_flags = VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
} else {
// Layer 1: predict from GF and ARF, update GF.
frame_flags = VP8_EFLAG_NO_REF_LAST |
VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
}
}
}
return frame_flags;
}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST | frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF); VP8_EFLAG_NO_UPD_ARF);
// For temporal layer case. if (droppable_nframes_ > 0 &&
if (cfg_.ts_number_layers > 1) { (cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
frame_flags_ = SetFrameFlags(video->frame(),
cfg_.ts_number_layers,
pattern_switch_);
for (unsigned int i = 0; i < droppable_nframes_; ++i) { for (unsigned int i = 0; i < droppable_nframes_; ++i) {
if (droppable_frames_[i] == video->frame()) { if (droppable_frames_[i] == video->frame()) {
std::cout << "Encoding droppable frame: " std::cout << " Encoding droppable frame: "
<< droppable_frames_[i] << "\n"; << droppable_frames_[i] << "\n";
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF);
return;
} }
} }
} else {
if (droppable_nframes_ > 0 &&
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
if (droppable_frames_[i] == video->frame()) {
std::cout << "Encoding droppable frame: "
<< droppable_frames_[i] << "\n";
frame_flags_ |= (VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF);
return;
}
}
}
} }
} }
@@ -190,18 +133,11 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
return mismatch_nframes_; return mismatch_nframes_;
} }
void SetPatternSwitch(int frame_switch) {
pattern_switch_ = frame_switch;
}
bool svc_support_;
private: private:
double psnr_; double psnr_;
unsigned int nframes_; unsigned int nframes_;
unsigned int error_nframes_; unsigned int error_nframes_;
unsigned int droppable_nframes_; unsigned int droppable_nframes_;
unsigned int pattern_switch_;
double mismatch_psnr_; double mismatch_psnr_;
unsigned int mismatch_nframes_; unsigned int mismatch_nframes_;
unsigned int error_frames_[kMaxErrorFrames]; unsigned int error_frames_[kMaxErrorFrames];
@@ -300,303 +236,7 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
#endif #endif
} }
// Check for successful decoding and no encoder/decoder mismatch VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
// if we lose (i.e., drop before decoding) the enhancement layer frames for a VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
// two layer temporal pattern. The base layer does not predict from the top
// layer, so successful decoding is expected.
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
// This test doesn't run if SVC is not supported.
if (!svc_support_)
return;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = 500;
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
// 2 Temporal layers, no spatial layers, CBR mode.
cfg_.ss_number_layers = 1;
cfg_.ts_number_layers = 2;
cfg_.ts_rate_decimator[0] = 2;
cfg_.ts_rate_decimator[1] = 1;
cfg_.ts_periodicity = 2;
cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
init_flags_ = VPX_CODEC_USE_PSNR;
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
timebase.den, timebase.num, 0, 40);
// Error resilient mode ON.
cfg_.g_error_resilient = 1;
cfg_.kf_mode = VPX_KF_DISABLED;
SetPatternSwitch(0);
// The odd frames are the enhancement layer for 2 layer pattern, so set
// those frames as droppable. Drop the last 7 frames.
unsigned int num_droppable_frames = 7;
unsigned int droppable_frame_list[] = {27, 29, 31, 33, 35, 37, 39};
SetDroppableFrames(num_droppable_frames, droppable_frame_list);
SetErrorFrames(num_droppable_frames, droppable_frame_list);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// Test that no mismatches have been found
std::cout << " Mismatch frames: "
<< GetMismatchFrames() << "\n";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
// Reset previously set of error/droppable frames.
Reset();
}
// Check for successful decoding and no encoder/decoder mismatch
// for a two layer temporal pattern, where at some point in the
// sequence, the LAST ref is not used anymore.
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
// This test doesn't run if SVC is not supported.
if (!svc_support_)
return;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = 500;
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
// 2 Temporal layers, no spatial layers, CBR mode.
cfg_.ss_number_layers = 1;
cfg_.ts_number_layers = 2;
cfg_.ts_rate_decimator[0] = 2;
cfg_.ts_rate_decimator[1] = 1;
cfg_.ts_periodicity = 2;
cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
init_flags_ = VPX_CODEC_USE_PSNR;
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
timebase.den, timebase.num, 0, 100);
// Error resilient mode ON.
cfg_.g_error_resilient = 1;
cfg_.kf_mode = VPX_KF_DISABLED;
SetPatternSwitch(60);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
// Test that no mismatches have been found
std::cout << " Mismatch frames: "
<< GetMismatchFrames() << "\n";
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
// Reset previously set of error/droppable frames.
Reset();
}
class ErrorResilienceTestLargeCodecControls : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected:
ErrorResilienceTestLargeCodecControls()
: EncoderTest(GET_PARAM(0)),
encoding_mode_(GET_PARAM(1)) {
Reset();
}
virtual ~ErrorResilienceTestLargeCodecControls() {}
void Reset() {
last_pts_ = 0;
tot_frame_number_ = 0;
// For testing up to 3 layers.
for (int i = 0; i < 3; ++i) {
bits_total_[i] = 0;
}
duration_ = 0.0;
}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
}
//
// Frame flags and layer id for temporal layers.
//
// For two layers, test pattern is:
// 1 3
// 0 2 .....
// For three layers, test pattern is:
// 1 3 5 7
// 2 6
// 0 4 ....
// LAST is always update on base/layer 0, GOLDEN is updated on layer 1,
// and ALTREF is updated on top layer for 3 layer pattern.
int SetFrameFlags(int frame_num, int num_temp_layers) {
int frame_flags = 0;
if (num_temp_layers == 2) {
if (frame_num % 2 == 0) {
// Layer 0: predict from L and ARF, update L.
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
} else {
// Layer 1: predict from L, G and ARF, and update G.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ENTROPY;
}
} else if (num_temp_layers == 3) {
if (frame_num % 4 == 0) {
// Layer 0: predict from L, update L.
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
} else if ((frame_num - 2) % 4 == 0) {
// Layer 1: predict from L, G, update G.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_REF_ARF;
} else if ((frame_num - 1) % 2 == 0) {
// Layer 2: predict from L, G, ARF; update ARG.
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
}
}
return frame_flags;
}
int SetLayerId(int frame_num, int num_temp_layers) {
int layer_id = 0;
if (num_temp_layers == 2) {
if (frame_num % 2 == 0) {
layer_id = 0;
} else {
layer_id = 1;
}
} else if (num_temp_layers == 3) {
if (frame_num % 4 == 0) {
layer_id = 0;
} else if ((frame_num - 2) % 4 == 0) {
layer_id = 1;
} else if ((frame_num - 1) % 2 == 0) {
layer_id = 2;
}
}
return layer_id;
}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (cfg_.ts_number_layers > 1) {
int layer_id = SetLayerId(video->frame(), cfg_.ts_number_layers);
int frame_flags = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
if (video->frame() > 0) {
encoder->Control(VP8E_SET_TEMPORAL_LAYER_ID, layer_id);
encoder->Control(VP8E_SET_FRAME_FLAGS, frame_flags);
}
const vpx_rational_t tb = video->timebase();
timebase_ = static_cast<double>(tb.num) / tb.den;
duration_ = 0;
return;
}
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
// Time since last timestamp = duration.
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
if (duration > 1) {
// Update counter for total number of frames (#frames input to encoder).
// Needed for setting the proper layer_id below.
tot_frame_number_ += static_cast<int>(duration - 1);
}
int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
// Update the total encoded bits. For temporal layers, update the cumulative
// encoded bits per layer.
for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
bits_total_[i] += frame_size_in_bits;
}
// Update the most recent pts.
last_pts_ = pkt->data.frame.pts;
++tot_frame_number_;
}
virtual void EndPassHook(void) {
duration_ = (last_pts_ + 1) * timebase_;
if (cfg_.ts_number_layers > 1) {
for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
++layer) {
if (bits_total_[layer]) {
// Effective file datarate:
effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
}
}
}
}
double effective_datarate_[3];
private:
libvpx_test::TestMode encoding_mode_;
vpx_codec_pts_t last_pts_;
double timebase_;
int64_t bits_total_[3];
double duration_;
int tot_frame_number_;
};
// Check two codec controls used for:
// (1) for setting temporal layer id, and (2) for settings encoder flags.
// This test invokes those controls for each frame, and verifies encoder/decoder
// mismatch and basic rate control response.
// TODO(marpan): Maybe move this test to datarate_test.cc.
TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_dropframe_thresh = 1;
cfg_.rc_min_quantizer = 2;
cfg_.rc_max_quantizer = 56;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_dropframe_thresh = 1;
cfg_.g_lag_in_frames = 0;
cfg_.kf_mode = VPX_KF_DISABLED;
cfg_.g_error_resilient = 1;
// 3 Temporal layers. Framerate decimation (4, 2, 1).
cfg_.ts_number_layers = 3;
cfg_.ts_rate_decimator[0] = 4;
cfg_.ts_rate_decimator[1] = 2;
cfg_.ts_rate_decimator[2] = 1;
cfg_.ts_periodicity = 4;
cfg_.ts_layer_id[0] = 0;
cfg_.ts_layer_id[1] = 2;
cfg_.ts_layer_id[2] = 1;
cfg_.ts_layer_id[3] = 2;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
for (int i = 200; i <= 800; i += 200) {
cfg_.rc_target_bitrate = i;
Reset();
// 40-20-40 bitrate allocation for 3 temporal layers.
cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
<< " The datarate for the file is lower than target by too much, "
"for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
<< " The datarate for the file is greater than target by too much, "
"for layer: " << j;
}
}
}
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
::testing::Values(true));
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
ONE_PASS_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
::testing::Values(true));
// SVC-related tests don't run for VP10 since SVC is not supported.
VP10_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
::testing::Values(false));
} // namespace } // namespace

View File

@@ -97,19 +97,13 @@ class ExternalFrameBufferList {
return 0; return 0;
} }
// Marks the external frame buffer that |fb| is pointing to as free. // Marks the external frame buffer that |fb| is pointing too as free.
// Returns < 0 on an error. // Returns < 0 on an error.
int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) { int ReturnFrameBuffer(vpx_codec_frame_buffer_t *fb) {
if (fb == NULL) { EXPECT_TRUE(fb != NULL);
EXPECT_TRUE(fb != NULL);
return -1;
}
ExternalFrameBuffer *const ext_fb = ExternalFrameBuffer *const ext_fb =
reinterpret_cast<ExternalFrameBuffer*>(fb->priv); reinterpret_cast<ExternalFrameBuffer*>(fb->priv);
if (ext_fb == NULL) { EXPECT_TRUE(ext_fb != NULL);
EXPECT_TRUE(ext_fb != NULL);
return -1;
}
EXPECT_EQ(1, ext_fb->in_use); EXPECT_EQ(1, ext_fb->in_use);
ext_fb->in_use = 0; ext_fb->in_use = 0;
return 0; return 0;

View File

@@ -13,17 +13,15 @@
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropy.h"
#include "vpx/vpx_codec.h" #include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom; using libvpx_test::ACMRandom;
@@ -41,7 +39,7 @@ typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht4x4Param;
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride, void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
int tx_type) { int tx_type) {
vpx_fdct4x4_c(in, out, stride); vp9_fdct4x4_c(in, out, stride);
} }
void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
@@ -55,11 +53,11 @@ void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) { void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct4x4_16_add_c(in, out, stride, 10); vp9_highbd_idct4x4_16_add_c(in, out, stride, 10);
} }
void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) { void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct4x4_16_add_c(in, out, stride, 12); vp9_highbd_idct4x4_16_add_c(in, out, stride, 12);
} }
void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
@@ -71,23 +69,23 @@ void iht4x4_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
} }
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) { void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 10); vp9_highbd_iwht4x4_16_add_c(in, out, stride, 10);
} }
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) { void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 12); vp9_highbd_iwht4x4_16_add_c(in, out, stride, 12);
} }
#if HAVE_SSE2 #if HAVE_SSE2
void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 10); vp9_highbd_idct4x4_16_add_sse2(in, out, stride, 10);
} }
void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 12); vp9_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
} }
#endif // HAVE_SSE2 #endif
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
class Trans4x4TestBase { class Trans4x4TestBase {
public: public:
@@ -104,13 +102,13 @@ class Trans4x4TestBase {
int64_t total_error = 0; int64_t total_error = 0;
const int count_test_block = 10000; const int count_test_block = 10000;
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif #endif
// Initialize a test block with input range [-255, 255]. // Initialize a test block with input range [-255, 255].
@@ -144,7 +142,6 @@ class Trans4x4TestBase {
const uint32_t diff = const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else #else
ASSERT_EQ(VPX_BITS_8, bit_depth_);
const uint32_t diff = dst[j] - src[j]; const uint32_t diff = dst[j] - src[j];
#endif #endif
const uint32_t error = diff * diff; const uint32_t error = diff * diff;
@@ -166,9 +163,9 @@ class Trans4x4TestBase {
void RunCoeffCheck() { void RunCoeffCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 5000; const int count_test_block = 5000;
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
@@ -187,13 +184,15 @@ class Trans4x4TestBase {
void RunMemCheck() { void RunMemCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 5000; const int count_test_block = 5000;
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_]. // Initialize a test block with input range [-mask_, mask_].
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_; input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
} }
if (i == 0) { if (i == 0) {
@@ -220,13 +219,13 @@ class Trans4x4TestBase {
void RunInvAccuracyCheck(int limit) { void RunInvAccuracyCheck(int limit) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -419,15 +418,15 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans4x4DCT, C, Trans4x4DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12), make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12),
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fdct4x4_c, &vp9_idct4x4_16_add_c, 0, VPX_BITS_8)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans4x4DCT, C, Trans4x4DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fdct4x4_c, &vp9_idct4x4_16_add_c, 0, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
@@ -453,7 +452,7 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8))); make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
@@ -461,54 +460,43 @@ INSTANTIATE_TEST_CASE_P(
::testing::Values( ::testing::Values(
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10),
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12), make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12),
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fwht4x4_c, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, Trans4x4WHT, C, Trans4x4WHT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fwht4x4_c, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, Trans4x4DCT, NEON, Trans4x4DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct4x4_c, make_tuple(&vp9_fdct4x4_c,
&vpx_idct4x4_16_add_neon, 0, VPX_BITS_8))); &vp9_idct4x4_16_add_neon, 0, VPX_BITS_8)));
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, Trans4x4HT, DISABLED_NEON, Trans4x4HT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 0, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 0, VPX_BITS_8),
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, VPX_BITS_8),
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 2, VPX_BITS_8), make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, VPX_BITS_8))); make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, VPX_BITS_8)));
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \ #if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
MMX, Trans4x4WHT, MMX, Trans4x4WHT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_fwht4x4_mmx, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fwht4x4_mmx, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
#endif
#if CONFIG_USE_X86INC && HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSE2, Trans4x4WHT,
::testing::Values(
make_tuple(&vp9_fwht4x4_c, &vpx_iwht4x4_16_add_sse2, 0, VPX_BITS_8)));
#endif #endif
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans4x4DCT, SSE2, Trans4x4DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct4x4_sse2, make_tuple(&vp9_fdct4x4_sse2,
&vpx_idct4x4_16_add_sse2, 0, VPX_BITS_8))); &vp9_idct4x4_16_add_sse2, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans4x4HT, SSE2, Trans4x4HT,
::testing::Values( ::testing::Values(
@@ -516,39 +504,33 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 1, VPX_BITS_8), make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 1, VPX_BITS_8),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 2, VPX_BITS_8), make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 3, VPX_BITS_8))); make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 3, VPX_BITS_8)));
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans4x4DCT, SSE2, Trans4x4DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10_sse2, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_10_sse2, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12_sse2, 0, VPX_BITS_12), make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_12_sse2, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0, VPX_BITS_12), make_tuple(&vp9_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0, VPX_BITS_12),
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0, make_tuple(&vp9_fdct4x4_sse2, &vp9_idct4x4_16_add_c, 0,
VPX_BITS_8))); VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Trans4x4HT, SSE2, Trans4x4HT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 0, VPX_BITS_10),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 1, VPX_BITS_10),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 2, VPX_BITS_10),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 3, VPX_BITS_10),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 0, VPX_BITS_12),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 1, VPX_BITS_12),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 2, VPX_BITS_12),
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 3, VPX_BITS_12),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8), make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8), make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8), make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8))); make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, Trans4x4DCT,
::testing::Values(
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, Trans4x4HT,
::testing::Values(
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 0, VPX_BITS_8),
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 1, VPX_BITS_8),
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_msa, &vp9_iht4x4_16_add_msa, 3, VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace } // namespace

View File

@@ -13,40 +13,18 @@
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_scan.h"
#include "vpx/vpx_codec.h" #include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom;
namespace {
const int kNumCoeffs = 64; const int kNumCoeffs = 64;
const double kPi = 3.141592653589793238462643383279502884; const double kPi = 3.141592653589793238462643383279502884;
const int kSignBiasMaxDiff255 = 1500;
const int kSignBiasMaxDiff15 = 10000;
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
int tx_type);
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
int tx_type);
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
void reference_8x8_dct_1d(const double in[8], double out[8], int stride) { void reference_8x8_dct_1d(const double in[8], double out[8], int stride) {
const double kInvSqrt2 = 0.707106781186547524400844362104; const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < 8; k++) { for (int k = 0; k < 8; k++) {
@@ -81,9 +59,22 @@ void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
} }
} }
using libvpx_test::ACMRandom;
namespace {
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
int tx_type);
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
int tx_type);
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct8x8Param;
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht8x8Param;
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t> Idct8x8Param;
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
vpx_fdct8x8_c(in, out, stride); vp9_fdct8x8_c(in, out, stride);
} }
void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) { void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
@@ -92,11 +83,11 @@ void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_64_add_c(in, out, stride, 10); vp9_highbd_idct8x8_64_add_c(in, out, stride, 10);
} }
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_64_add_c(in, out, stride, 12); vp9_highbd_idct8x8_64_add_c(in, out, stride, 12);
} }
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) { void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
@@ -108,31 +99,31 @@ void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
} }
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_c(in, out, stride, 10); vp9_highbd_idct8x8_10_add_c(in, out, stride, 10);
} }
void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_c(in, out, stride, 12); vp9_highbd_idct8x8_10_add_c(in, out, stride, 12);
} }
#if HAVE_SSE2 #if HAVE_SSE2
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 10); vp9_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
} }
void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 12); vp9_highbd_idct8x8_10_add_sse2(in, out, stride, 12);
} }
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 10); vp9_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
} }
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) { void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 12); vp9_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
} }
#endif // HAVE_SSE2 #endif
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
class FwdTrans8x8TestBase { class FwdTrans8x8TestBase {
public: public:
@@ -144,8 +135,8 @@ class FwdTrans8x8TestBase {
void RunSignBiasCheck() { void RunSignBiasCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, int16_t, test_input_block[64]); DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
DECLARE_ALIGNED(16, tran_low_t, test_output_block[64]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_output_block, 64);
int count_sign_block[64][2]; int count_sign_block[64][2];
const int count_test_block = 100000; const int count_test_block = 100000;
@@ -169,7 +160,7 @@ class FwdTrans8x8TestBase {
for (int j = 0; j < 64; ++j) { for (int j = 0; j < 64; ++j) {
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]); const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
const int max_diff = kSignBiasMaxDiff255; const int max_diff = 1125;
EXPECT_LT(diff, max_diff << (bit_depth_ - 8)) EXPECT_LT(diff, max_diff << (bit_depth_ - 8))
<< "Error: 8x8 FDCT/FHT has a sign bias > " << "Error: 8x8 FDCT/FHT has a sign bias > "
<< 1. * max_diff / count_test_block * 100 << "%" << 1. * max_diff / count_test_block * 100 << "%"
@@ -182,7 +173,7 @@ class FwdTrans8x8TestBase {
memset(count_sign_block, 0, sizeof(count_sign_block)); memset(count_sign_block, 0, sizeof(count_sign_block));
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_ / 16, mask_ / 16]. // Initialize a test block with input range [-mask_/16, mask_/16].
for (int j = 0; j < 64; ++j) for (int j = 0; j < 64; ++j)
test_input_block[j] = ((rnd.Rand16() & mask_) >> 4) - test_input_block[j] = ((rnd.Rand16() & mask_) >> 4) -
((rnd.Rand16() & mask_) >> 4); ((rnd.Rand16() & mask_) >> 4);
@@ -199,9 +190,9 @@ class FwdTrans8x8TestBase {
for (int j = 0; j < 64; ++j) { for (int j = 0; j < 64; ++j) {
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]); const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
const int max_diff = kSignBiasMaxDiff15; const int max_diff = 10000;
EXPECT_LT(diff, max_diff << (bit_depth_ - 8)) EXPECT_LT(diff, max_diff << (bit_depth_ - 8))
<< "Error: 8x8 FDCT/FHT has a sign bias > " << "Error: 4x4 FDCT/FHT has a sign bias > "
<< 1. * max_diff / count_test_block * 100 << "%" << 1. * max_diff / count_test_block * 100 << "%"
<< " for input range [-15, 15] at index " << j << " for input range [-15, 15] at index " << j
<< " count0: " << count_sign_block[j][0] << " count0: " << count_sign_block[j][0]
@@ -215,13 +206,13 @@ class FwdTrans8x8TestBase {
int max_error = 0; int max_error = 0;
int total_error = 0; int total_error = 0;
const int count_test_block = 100000; const int count_test_block = 100000;
DECLARE_ALIGNED(16, int16_t, test_input_block[64]); DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64);
DECLARE_ALIGNED(16, uint8_t, dst[64]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
DECLARE_ALIGNED(16, uint8_t, src[64]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[64]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64);
DECLARE_ALIGNED(16, uint16_t, src16[64]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -292,14 +283,14 @@ class FwdTrans8x8TestBase {
int total_error = 0; int total_error = 0;
int total_coeff_error = 0; int total_coeff_error = 0;
const int count_test_block = 100000; const int count_test_block = 100000;
DECLARE_ALIGNED(16, int16_t, test_input_block[64]); DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64);
DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_temp_block, 64);
DECLARE_ALIGNED(16, uint8_t, dst[64]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
DECLARE_ALIGNED(16, uint8_t, src[64]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[64]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64);
DECLARE_ALIGNED(16, uint16_t, src16[64]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -381,13 +372,13 @@ class FwdTrans8x8TestBase {
void RunInvAccuracyCheck() { void RunInvAccuracyCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
#endif #endif
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -439,9 +430,9 @@ class FwdTrans8x8TestBase {
void RunFwdAccuracyCheck() { void RunFwdAccuracyCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000; const int count_test_block = 1000;
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff_r[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_r, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
double out_r[kNumCoeffs]; double out_r[kNumCoeffs];
@@ -469,12 +460,12 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 10000; const int count_test_block = 10000;
const int eob = 12; const int eob = 12;
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
#endif #endif
const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan; const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan;
@@ -629,8 +620,8 @@ class InvTrans8x8DCT
virtual void SetUp() { virtual void SetUp() {
ref_txfm_ = GET_PARAM(0); ref_txfm_ = GET_PARAM(0);
inv_txfm_ = GET_PARAM(1); inv_txfm_ = GET_PARAM(1);
thresh_ = GET_PARAM(2); thresh_ = GET_PARAM(2);
pitch_ = 8; pitch_ = 8;
bit_depth_ = GET_PARAM(3); bit_depth_ = GET_PARAM(3);
mask_ = (1 << bit_depth_) - 1; mask_ = (1 << bit_depth_) - 1;
} }
@@ -658,21 +649,20 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8DCT, C, FwdTrans8x8DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8), make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12))); make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8DCT, C, FwdTrans8x8DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8))); make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8HT, C, FwdTrans8x8HT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10), make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10),
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10), make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10),
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10), make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
@@ -681,6 +671,7 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12), make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12),
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12), make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12),
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12), make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
@@ -692,31 +683,28 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8))); make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, FwdTrans8x8DCT, NEON, FwdTrans8x8DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 0, make_tuple(&vp9_fdct8x8_neon, &vp9_idct8x8_64_add_neon, 0,
VPX_BITS_8))); VPX_BITS_8)));
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, FwdTrans8x8HT, DISABLED_NEON, FwdTrans8x8HT,
::testing::Values( ::testing::Values(
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8), make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8))); make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8DCT, SSE2, FwdTrans8x8DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 0, make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_sse2, 0,
VPX_BITS_8))); VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8HT, SSE2, FwdTrans8x8HT,
@@ -725,21 +713,22 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8), make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8),
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8), make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8))); make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8)));
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8DCT, SSE2, FwdTrans8x8DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8), make_tuple(&vp9_highbd_fdct8x8_c,
make_tuple(&vpx_highbd_fdct8x8_c,
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10), &idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct8x8_sse2, make_tuple(&vp9_highbd_fdct8x8_sse2,
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10), &idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
make_tuple(&vpx_highbd_fdct8x8_c, make_tuple(&vp9_highbd_fdct8x8_c,
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12), &idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
make_tuple(&vpx_highbd_fdct8x8_sse2, make_tuple(&vp9_highbd_fdct8x8_sse2,
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12))); &idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8HT, SSE2, FwdTrans8x8HT,
@@ -762,28 +751,15 @@ INSTANTIATE_TEST_CASE_P(
&idct8x8_10_add_12_sse2, 6225, VPX_BITS_12), &idct8x8_10_add_12_sse2, 6225, VPX_BITS_12),
make_tuple(&idct8x8_12, make_tuple(&idct8x8_12,
&idct8x8_64_add_12_sse2, 6225, VPX_BITS_12))); &idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64 && \
!CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSSE3, FwdTrans8x8DCT, SSSE3, FwdTrans8x8DCT,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_ssse3, 0, make_tuple(&vp9_fdct8x8_ssse3, &vp9_idct8x8_64_add_ssse3, 0,
VPX_BITS_8))); VPX_BITS_8)));
#endif #endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 0, VPX_BITS_8)));
INSTANTIATE_TEST_CASE_P(
MSA, FwdTrans8x8HT,
::testing::Values(
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 0, VPX_BITS_8),
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 1, VPX_BITS_8),
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_msa, &vp9_iht8x8_64_add_msa, 3, VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace } // namespace

View File

@@ -74,7 +74,7 @@ TEST_F(VP9FrameSizeTestsLarge, ValidSizes) {
// size or almost 1 gig of memory. // size or almost 1 gig of memory.
// In total the allocations will exceed 2GiB which may cause a failure with // In total the allocations will exceed 2GiB which may cause a failure with
// mingw + wine, use a smaller size in that case. // mingw + wine, use a smaller size in that case.
#if defined(_WIN32) && !defined(_WIN64) || defined(__OS2__) #if defined(_WIN32) && !defined(_WIN64)
video.SetSize(4096, 3072); video.SetSize(4096, 3072);
#else #else
video.SetSize(4096, 4096); video.SetSize(4096, 4096);

View File

@@ -13,22 +13,104 @@
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include "test/yuv_video_source.h" #include "test/video_source.h"
namespace libvpx_test { namespace libvpx_test {
// This class extends VideoSource to allow parsing of raw yv12 // This class extends VideoSource to allow parsing of raw yv12
// so that we can do actual file encodes. // so that we can do actual file encodes.
class I420VideoSource : public YUVVideoSource { class I420VideoSource : public VideoSource {
public: public:
I420VideoSource(const std::string &file_name, I420VideoSource(const std::string &file_name,
unsigned int width, unsigned int height, unsigned int width, unsigned int height,
int rate_numerator, int rate_denominator, int rate_numerator, int rate_denominator,
unsigned int start, int limit) unsigned int start, int limit)
: YUVVideoSource(file_name, VPX_IMG_FMT_I420, : file_name_(file_name),
width, height, input_file_(NULL),
rate_numerator, rate_denominator, img_(NULL),
start, limit) {} start_(start),
limit_(limit),
frame_(0),
width_(0),
height_(0),
framerate_numerator_(rate_numerator),
framerate_denominator_(rate_denominator) {
// This initializes raw_sz_, width_, height_ and allocates an img.
SetSize(width, height);
}
virtual ~I420VideoSource() {
vpx_img_free(img_);
if (input_file_)
fclose(input_file_);
}
virtual void Begin() {
if (input_file_)
fclose(input_file_);
input_file_ = OpenTestDataFile(file_name_);
ASSERT_TRUE(input_file_ != NULL) << "Input file open failed. Filename: "
<< file_name_;
if (start_) {
fseek(input_file_, static_cast<unsigned>(raw_sz_) * start_, SEEK_SET);
}
frame_ = start_;
FillFrame();
}
virtual void Next() {
++frame_;
FillFrame();
}
virtual vpx_image_t *img() const { return (frame_ < limit_) ? img_ : NULL; }
// Models a stream where Timebase = 1/FPS, so pts == frame.
virtual vpx_codec_pts_t pts() const { return frame_; }
virtual unsigned long duration() const { return 1; }
virtual vpx_rational_t timebase() const {
const vpx_rational_t t = { framerate_denominator_, framerate_numerator_ };
return t;
}
virtual unsigned int frame() const { return frame_; }
virtual unsigned int limit() const { return limit_; }
void SetSize(unsigned int width, unsigned int height) {
if (width != width_ || height != height_) {
vpx_img_free(img_);
img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, width, height, 1);
ASSERT_TRUE(img_ != NULL);
width_ = width;
height_ = height;
raw_sz_ = width * height * 3 / 2;
}
}
virtual void FillFrame() {
ASSERT_TRUE(input_file_ != NULL);
// Read a frame from input_file.
if (fread(img_->img_data, raw_sz_, 1, input_file_) == 0) {
limit_ = frame_;
}
}
protected:
std::string file_name_;
FILE *input_file_;
vpx_image_t *img_;
size_t raw_sz_;
unsigned int start_;
unsigned int limit_;
unsigned int frame_;
unsigned int width_;
unsigned int height_;
int framerate_numerator_;
int framerate_denominator_;
}; };
} // namespace libvpx_test } // namespace libvpx_test

View File

@@ -14,7 +14,8 @@
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h" #include "./vp9_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
@@ -67,6 +68,43 @@ void reference_dct_2d(int16_t input[64], double output[64]) {
output[i] *= 2; output[i] *= 2;
} }
void reference_idct_1d(double input[8], double output[8]) {
const double kPi = 3.141592653589793238462643383279502884;
const double kSqrt2 = 1.414213562373095048801688724209698;
for (int k = 0; k < 8; k++) {
output[k] = 0.0;
for (int n = 0; n < 8; n++) {
output[k] += input[n]*cos(kPi*(2*k+1)*n/16.0);
if (n == 0)
output[k] = output[k]/kSqrt2;
}
}
}
void reference_idct_2d(double input[64], int16_t output[64]) {
double out[64], out2[64];
// First transform rows
for (int i = 0; i < 8; ++i) {
double temp_in[8], temp_out[8];
for (int j = 0; j < 8; ++j)
temp_in[j] = input[j + i*8];
reference_idct_1d(temp_in, temp_out);
for (int j = 0; j < 8; ++j)
out[j + i*8] = temp_out[j];
}
// Then transform columns
for (int i = 0; i < 8; ++i) {
double temp_in[8], temp_out[8];
for (int j = 0; j < 8; ++j)
temp_in[j] = out[j*8 + i];
reference_idct_1d(temp_in, temp_out);
for (int j = 0; j < 8; ++j)
out2[j*8 + i] = temp_out[j];
}
for (int i = 0; i < 64; ++i)
output[i] = round(out2[i]/32);
}
TEST(VP9Idct8x8Test, AccuracyCheck) { TEST(VP9Idct8x8Test, AccuracyCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 10000; const int count_test_block = 10000;
@@ -87,7 +125,7 @@ TEST(VP9Idct8x8Test, AccuracyCheck) {
reference_dct_2d(input, output_r); reference_dct_2d(input, output_r);
for (int j = 0; j < 64; ++j) for (int j = 0; j < 64; ++j)
coeff[j] = round(output_r[j]); coeff[j] = round(output_r[j]);
vpx_idct8x8_64_add_c(coeff, dst, 8); vp9_idct8x8_64_add_c(coeff, dst, 8);
for (int j = 0; j < 64; ++j) { for (int j = 0; j < 64; ++j) {
const int diff = dst[j] - src[j]; const int diff = dst[j] - src[j];
const int error = diff * diff; const int error = diff * diff;

View File

@@ -10,11 +10,10 @@
#include "./vpx_config.h" #include "./vpx_config.h"
#include "./vp8_rtcd.h" #include "./vp8_rtcd.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr, typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
@@ -114,8 +113,4 @@ INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest, INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
::testing::Values(vp8_short_idct4x4llm_mmx)); ::testing::Values(vp8_short_idct4x4llm_mmx));
#endif #endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
::testing::Values(vp8_short_idct4x4llm_msa));
#endif
} }

396
test/intrapred_test.cc Normal file
View File

@@ -0,0 +1,396 @@
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string.h>
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "vp8/common/blockd.h"
#include "vpx_mem/vpx_mem.h"
namespace {
using libvpx_test::ACMRandom;
class IntraPredBase {
public:
virtual ~IntraPredBase() { libvpx_test::ClearSystemState(); }
protected:
void SetupMacroblock(MACROBLOCKD *mbptr,
MODE_INFO *miptr,
uint8_t *data,
int block_size,
int stride,
int num_planes) {
mbptr_ = mbptr;
miptr_ = miptr;
mbptr_->up_available = 1;
mbptr_->left_available = 1;
mbptr_->mode_info_context = miptr_;
stride_ = stride;
block_size_ = block_size;
num_planes_ = num_planes;
for (int p = 0; p < num_planes; p++)
data_ptr_[p] = data + stride * (block_size + 1) * p +
stride + block_size;
}
void FillRandom() {
// Fill edges with random data
ACMRandom rnd(ACMRandom::DeterministicSeed());
for (int p = 0; p < num_planes_; p++) {
for (int x = -1 ; x <= block_size_; x++)
data_ptr_[p][x - stride_] = rnd.Rand8();
for (int y = 0; y < block_size_; y++)
data_ptr_[p][y * stride_ - 1] = rnd.Rand8();
}
}
virtual void Predict(MB_PREDICTION_MODE mode) = 0;
void SetLeftUnavailable() {
mbptr_->left_available = 0;
for (int p = 0; p < num_planes_; p++)
for (int i = -1; i < block_size_; ++i)
data_ptr_[p][stride_ * i - 1] = 129;
}
void SetTopUnavailable() {
mbptr_->up_available = 0;
for (int p = 0; p < num_planes_; p++)
memset(&data_ptr_[p][-1 - stride_], 127, block_size_ + 2);
}
void SetTopLeftUnavailable() {
SetLeftUnavailable();
SetTopUnavailable();
}
int BlockSizeLog2Min1() const {
switch (block_size_) {
case 16:
return 3;
case 8:
return 2;
default:
return 0;
}
}
// check DC prediction output against a reference
void CheckDCPrediction() const {
for (int p = 0; p < num_planes_; p++) {
// calculate expected DC
int expected;
if (mbptr_->up_available || mbptr_->left_available) {
int sum = 0, shift = BlockSizeLog2Min1() + mbptr_->up_available +
mbptr_->left_available;
if (mbptr_->up_available)
for (int x = 0; x < block_size_; x++)
sum += data_ptr_[p][x - stride_];
if (mbptr_->left_available)
for (int y = 0; y < block_size_; y++)
sum += data_ptr_[p][y * stride_ - 1];
expected = (sum + (1 << (shift - 1))) >> shift;
} else {
expected = 0x80;
}
// check that all subsequent lines are equal to the first
for (int y = 1; y < block_size_; ++y)
ASSERT_EQ(0, memcmp(data_ptr_[p], &data_ptr_[p][y * stride_],
block_size_));
// within the first line, ensure that each pixel has the same value
for (int x = 1; x < block_size_; ++x)
ASSERT_EQ(data_ptr_[p][0], data_ptr_[p][x]);
// now ensure that that pixel has the expected (DC) value
ASSERT_EQ(expected, data_ptr_[p][0]);
}
}
// check V prediction output against a reference
void CheckVPrediction() const {
// check that all lines equal the top border
for (int p = 0; p < num_planes_; p++)
for (int y = 0; y < block_size_; y++)
ASSERT_EQ(0, memcmp(&data_ptr_[p][-stride_],
&data_ptr_[p][y * stride_], block_size_));
}
// check H prediction output against a reference
void CheckHPrediction() const {
// for each line, ensure that each pixel is equal to the left border
for (int p = 0; p < num_planes_; p++)
for (int y = 0; y < block_size_; y++)
for (int x = 0; x < block_size_; x++)
ASSERT_EQ(data_ptr_[p][-1 + y * stride_],
data_ptr_[p][x + y * stride_]);
}
static int ClipByte(int value) {
if (value > 255)
return 255;
else if (value < 0)
return 0;
return value;
}
// check TM prediction output against a reference
void CheckTMPrediction() const {
for (int p = 0; p < num_planes_; p++)
for (int y = 0; y < block_size_; y++)
for (int x = 0; x < block_size_; x++) {
const int expected = ClipByte(data_ptr_[p][x - stride_]
+ data_ptr_[p][stride_ * y - 1]
- data_ptr_[p][-1 - stride_]);
ASSERT_EQ(expected, data_ptr_[p][y * stride_ + x]);
}
}
// Actual test
void RunTest() {
{
SCOPED_TRACE("DC_PRED");
FillRandom();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("DC_PRED LEFT");
FillRandom();
SetLeftUnavailable();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("DC_PRED TOP");
FillRandom();
SetTopUnavailable();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("DC_PRED TOP_LEFT");
FillRandom();
SetTopLeftUnavailable();
Predict(DC_PRED);
CheckDCPrediction();
}
{
SCOPED_TRACE("H_PRED");
FillRandom();
Predict(H_PRED);
CheckHPrediction();
}
{
SCOPED_TRACE("V_PRED");
FillRandom();
Predict(V_PRED);
CheckVPrediction();
}
{
SCOPED_TRACE("TM_PRED");
FillRandom();
Predict(TM_PRED);
CheckTMPrediction();
}
}
MACROBLOCKD *mbptr_;
MODE_INFO *miptr_;
uint8_t *data_ptr_[2]; // in the case of Y, only [0] is used
int stride_;
int block_size_;
int num_planes_;
};
typedef void (*IntraPredYFunc)(MACROBLOCKD *x,
uint8_t *yabove_row,
uint8_t *yleft,
int left_stride,
uint8_t *ypred_ptr,
int y_stride);
class IntraPredYTest
: public IntraPredBase,
public ::testing::TestWithParam<IntraPredYFunc> {
public:
static void SetUpTestCase() {
mb_ = reinterpret_cast<MACROBLOCKD*>(
vpx_memalign(32, sizeof(MACROBLOCKD)));
mi_ = reinterpret_cast<MODE_INFO*>(
vpx_memalign(32, sizeof(MODE_INFO)));
data_array_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
}
static void TearDownTestCase() {
vpx_free(data_array_);
vpx_free(mi_);
vpx_free(mb_);
data_array_ = NULL;
}
protected:
static const int kBlockSize = 16;
static const int kDataAlignment = 16;
static const int kStride = kBlockSize * 3;
// We use 48 so that the data pointer of the first pixel in each row of
// each macroblock is 16-byte aligned, and this gives us access to the
// top-left and top-right corner pixels belonging to the top-left/right
// macroblocks.
// We use 17 lines so we have one line above us for top-prediction.
static const int kDataBufferSize = kStride * (kBlockSize + 1);
virtual void SetUp() {
pred_fn_ = GetParam();
SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 1);
}
virtual void Predict(MB_PREDICTION_MODE mode) {
mbptr_->mode_info_context->mbmi.mode = mode;
ASM_REGISTER_STATE_CHECK(pred_fn_(mbptr_,
data_ptr_[0] - kStride,
data_ptr_[0] - 1, kStride,
data_ptr_[0], kStride));
}
IntraPredYFunc pred_fn_;
static uint8_t* data_array_;
static MACROBLOCKD * mb_;
static MODE_INFO *mi_;
};
MACROBLOCKD* IntraPredYTest::mb_ = NULL;
MODE_INFO* IntraPredYTest::mi_ = NULL;
uint8_t* IntraPredYTest::data_array_ = NULL;
TEST_P(IntraPredYTest, IntraPredTests) {
RunTest();
}
INSTANTIATE_TEST_CASE_P(C, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_sse2));
#endif
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_ssse3));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, IntraPredYTest,
::testing::Values(
vp8_build_intra_predictors_mby_s_neon));
#endif
typedef void (*IntraPredUvFunc)(MACROBLOCKD *x,
uint8_t *uabove_row,
uint8_t *vabove_row,
uint8_t *uleft,
uint8_t *vleft,
int left_stride,
uint8_t *upred_ptr,
uint8_t *vpred_ptr,
int pred_stride);
class IntraPredUVTest
: public IntraPredBase,
public ::testing::TestWithParam<IntraPredUvFunc> {
public:
static void SetUpTestCase() {
mb_ = reinterpret_cast<MACROBLOCKD*>(
vpx_memalign(32, sizeof(MACROBLOCKD)));
mi_ = reinterpret_cast<MODE_INFO*>(
vpx_memalign(32, sizeof(MODE_INFO)));
data_array_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kDataBufferSize));
}
static void TearDownTestCase() {
vpx_free(data_array_);
vpx_free(mi_);
vpx_free(mb_);
data_array_ = NULL;
}
protected:
static const int kBlockSize = 8;
static const int kDataAlignment = 8;
static const int kStride = kBlockSize * 3;
// We use 24 so that the data pointer of the first pixel in each row of
// each macroblock is 8-byte aligned, and this gives us access to the
// top-left and top-right corner pixels belonging to the top-left/right
// macroblocks.
// We use 9 lines so we have one line above us for top-prediction.
// [0] = U, [1] = V
static const int kDataBufferSize = 2 * kStride * (kBlockSize + 1);
virtual void SetUp() {
pred_fn_ = GetParam();
SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 2);
}
virtual void Predict(MB_PREDICTION_MODE mode) {
mbptr_->mode_info_context->mbmi.uv_mode = mode;
pred_fn_(mbptr_, data_ptr_[0] - kStride, data_ptr_[1] - kStride,
data_ptr_[0] - 1, data_ptr_[1] - 1, kStride,
data_ptr_[0], data_ptr_[1], kStride);
}
IntraPredUvFunc pred_fn_;
// We use 24 so that the data pointer of the first pixel in each row of
// each macroblock is 8-byte aligned, and this gives us access to the
// top-left and top-right corner pixels belonging to the top-left/right
// macroblocks.
// We use 9 lines so we have one line above us for top-prediction.
// [0] = U, [1] = V
static uint8_t* data_array_;
static MACROBLOCKD* mb_;
static MODE_INFO* mi_;
};
MACROBLOCKD* IntraPredUVTest::mb_ = NULL;
MODE_INFO* IntraPredUVTest::mi_ = NULL;
uint8_t* IntraPredUVTest::data_array_ = NULL;
TEST_P(IntraPredUVTest, IntraPredTests) {
RunTest();
}
INSTANTIATE_TEST_CASE_P(C, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_c));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_sse2));
#endif
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_ssse3));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, IntraPredUVTest,
::testing::Values(
vp8_build_intra_predictors_mbuv_s_neon));
#endif
} // namespace

View File

@@ -63,22 +63,9 @@ class InvalidFileTest
EXPECT_NE(res, EOF) << "Read result data failed"; EXPECT_NE(res, EOF) << "Read result data failed";
// Check results match. // Check results match.
const DecodeParam input = GET_PARAM(1); EXPECT_EQ(expected_res_dec, res_dec)
if (input.threads > 1) { << "Results don't match: frame number = " << video.frame_number()
// The serial decode check is too strict for tile-threaded decoding as << ". (" << decoder->DecodeError() << ")";
// there is no guarantee on the decode order nor which specific error
// will take precedence. Currently a tile-level error is not forwarded so
// the frame will simply be marked corrupt.
EXPECT_TRUE(res_dec == expected_res_dec ||
res_dec == VPX_CODEC_CORRUPT_FRAME)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError() << "). Expected: "
<< expected_res_dec << " or " << VPX_CODEC_CORRUPT_FRAME;
} else {
EXPECT_EQ(expected_res_dec, res_dec)
<< "Results don't match: frame number = " << video.frame_number()
<< ". (" << decoder->DecodeError() << ")";
}
return !HasFailure(); return !HasFailure();
} }
@@ -125,9 +112,7 @@ TEST_P(InvalidFileTest, ReturnCode) {
const DecodeParam kVP9InvalidFileTests[] = { const DecodeParam kVP9InvalidFileTests[] = {
{1, "invalid-vp90-02-v2.webm"}, {1, "invalid-vp90-02-v2.webm"},
#if CONFIG_VP9_HIGHBITDEPTH
{1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"}, {1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"},
#endif
{1, "invalid-vp90-03-v3.webm"}, {1, "invalid-vp90-03-v3.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-.ivf"},
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"}, {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"},
@@ -136,8 +121,6 @@ const DecodeParam kVP9InvalidFileTests[] = {
{1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf"}, {1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.ivf"},
{1, "invalid-vp91-2-mixedrefcsp-444to420.ivf"}, {1, "invalid-vp91-2-mixedrefcsp-444to420.ivf"},
{1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf"}, {1, "invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf"},
{1, "invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf"},
{1, "invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf"},
}; };
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest, VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
@@ -158,7 +141,7 @@ TEST_P(InvalidFileInvalidPeekTest, ReturnCode) {
} }
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = { const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
{1, "invalid-vp90-01-v3.webm"}, {1, "invalid-vp90-01-v2.webm"},
}; };
VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest, VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
@@ -168,7 +151,6 @@ const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
{4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"}, {4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
{4, "invalid-" {4, "invalid-"
"vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf"}, "vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf"},
{4, "invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf"},
{2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf"}, {2, "invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf"},
{4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf"}, {4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf"},
}; };

View File

@@ -13,17 +13,18 @@
#include <string> #include <string>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_loopfilter.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#define MAX_LOOP_FILTER 63
using libvpx_test::ACMRandom; using libvpx_test::ACMRandom;
namespace { namespace {
@@ -52,105 +53,62 @@ typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
const uint8_t *thresh1); const uint8_t *thresh1);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
typedef std::tr1::tuple<loop_op_t, loop_op_t, int, int> loop8_param_t; typedef std::tr1::tuple<loop_op_t, loop_op_t, vpx_bit_depth_t> loop8_param_t;
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t; typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t,
vpx_bit_depth_t> dualloop8_param_t;
#if HAVE_SSE2 #if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
void wrapper_vertical_16_sse2(uint16_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_sse2(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count, int bd) { int count, int bd) {
vpx_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd); vp9_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd);
} }
void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count, int bd) { int count, int bd) {
vpx_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd); vp9_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd);
} }
void wrapper_vertical_16_dual_sse2(uint16_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_dual_sse2(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count, int bd) { int count, int bd) {
vpx_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd); vp9_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd);
} }
void wrapper_vertical_16_dual_c(uint16_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_dual_c(uint16_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count, int bd) { int count, int bd) {
vpx_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd); vp9_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd);
} }
#else #else
void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count) { int count) {
vpx_lpf_vertical_16_sse2(s, p, blimit, limit, thresh); vp9_lpf_vertical_16_sse2(s, p, blimit, limit, thresh);
} }
void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count) { int count) {
vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh); vp9_lpf_vertical_16_c(s, p, blimit, limit, thresh);
} }
void wrapper_vertical_16_dual_sse2(uint8_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_dual_sse2(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count) { int count) {
vpx_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh); vp9_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh);
} }
void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit, void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh, const uint8_t *limit, const uint8_t *thresh,
int count) { int count) {
vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh); vp9_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
} }
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_SSE2 #endif // HAVE_SSE2
#if HAVE_NEON_ASM
#if CONFIG_VP9_HIGHBITDEPTH
// No neon high bitdepth functions.
#else
void wrapper_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_neon(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_dual_neon(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_NEON_ASM
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
void wrapper_vertical_16_msa(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_msa(s, p, blimit, limit, thresh);
}
void wrapper_vertical_16_c(uint8_t *s, int p, const uint8_t *blimit,
const uint8_t *limit, const uint8_t *thresh,
int count) {
vpx_lpf_vertical_16_c(s, p, blimit, limit, thresh);
}
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> { class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
public: public:
virtual ~Loop8Test6Param() {} virtual ~Loop8Test6Param() {}
@@ -158,15 +116,13 @@ class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
loopfilter_op_ = GET_PARAM(0); loopfilter_op_ = GET_PARAM(0);
ref_loopfilter_op_ = GET_PARAM(1); ref_loopfilter_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2); bit_depth_ = GET_PARAM(2);
count_ = GET_PARAM(3);
mask_ = (1 << bit_depth_) - 1; mask_ = (1 << bit_depth_) - 1;
} }
virtual void TearDown() { libvpx_test::ClearSystemState(); } virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected: protected:
int bit_depth_; vpx_bit_depth_t bit_depth_;
int count_;
int mask_; int mask_;
loop_op_t loopfilter_op_; loop_op_t loopfilter_op_;
loop_op_t ref_loopfilter_op_; loop_op_t ref_loopfilter_op_;
@@ -185,7 +141,7 @@ class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
virtual void TearDown() { libvpx_test::ClearSystemState(); } virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected: protected:
int bit_depth_; vpx_bit_depth_t bit_depth_;
int mask_; int mask_;
dual_loop_op_t loopfilter_op_; dual_loop_op_t loopfilter_op_;
dual_loop_op_t ref_loopfilter_op_; dual_loop_op_t ref_loopfilter_op_;
@@ -195,23 +151,30 @@ TEST_P(Loop8Test6Param, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations; const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
int32_t bd = bit_depth_; vpx_bit_depth_t bd = bit_depth_;
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
#else #else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0; int err_count_total = 0;
int first_failure = -1; int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
int err_count = 0; int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4)); uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = { DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER)); tmp = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = { DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -222,6 +185,7 @@ TEST_P(Loop8Test6Param, OperationCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
int32_t p = kNumCoeffs/32; int32_t p = kNumCoeffs/32;
int count = 1;
uint16_t tmp_s[kNumCoeffs]; uint16_t tmp_s[kNumCoeffs];
int j = 0; int j = 0;
@@ -253,13 +217,13 @@ TEST_P(Loop8Test6Param, OperationCheck) {
ref_s[j] = s[j]; ref_s[j] = s[j];
} }
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count_, bd); ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count, bd);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_, bd)); loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count, bd));
#else #else
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count_); ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_)); loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
@@ -280,36 +244,29 @@ TEST_P(Loop8Test6Param, ValueCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations; const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_; vpx_bit_depth_t bd = bit_depth_;
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
#else #else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0; int err_count_total = 0;
int first_failure = -1; int first_failure = -1;
// NOTE: The code in vp9_loopfilter.c:update_sharpness computes mblim as a
// function of sharpness_lvl and the loopfilter lvl as:
// block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
// ...
// memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
// SIMD_WIDTH);
// This means that the largest value for mblim will occur when sharpness_lvl
// is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER).
// In this case block_inside_limit will be equal to MAX_LOOP_FILTER and
// therefore mblim will be equal to (2 * (lvl + 2) + block_inside_limit) =
// 2 * (MAX_LOOP_FILTER + 2) + MAX_LOOP_FILTER = 3 * MAX_LOOP_FILTER + 4
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
int err_count = 0; int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4)); uint8_t tmp = rnd.Rand8();
while (tmp > 3*MAX_LOOP_FILTER + 4) { // mblim <= 3*MAX_LOOP_FILTER + 4
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = { DECLARE_ALIGNED(16, const uint8_t, blimit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER)); tmp = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = { DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -320,18 +277,19 @@ TEST_P(Loop8Test6Param, ValueCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
int32_t p = kNumCoeffs / 32; int32_t p = kNumCoeffs / 32;
int count = 1;
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
s[j] = rnd.Rand16() & mask_; s[j] = rnd.Rand16() & mask_;
ref_s[j] = s[j]; ref_s[j] = s[j];
} }
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count_, bd); ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count, bd);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_, bd)); loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count, bd));
#else #else
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count_); ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count_)); loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
for (int j = 0; j < kNumCoeffs; ++j) { for (int j = 0; j < kNumCoeffs; ++j) {
err_count += ref_s[j] != s[j]; err_count += ref_s[j] != s[j];
@@ -351,23 +309,31 @@ TEST_P(Loop8Test9Param, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations; const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_; vpx_bit_depth_t bd = bit_depth_;
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
#else #else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0; int err_count_total = 0;
int first_failure = -1; int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
int err_count = 0; int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4)); uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = { DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER)); tmp = rnd.Rand8();
// lim <= MAX_LOOP_FILTER
while (tmp > MAX_LOOP_FILTER) {
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = { DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -377,12 +343,19 @@ TEST_P(Loop8Test9Param, OperationCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4)); tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = { DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER)); tmp = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = { DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -454,22 +427,29 @@ TEST_P(Loop8Test9Param, ValueCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed()); ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations; const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
#else #else
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]); DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0; int err_count_total = 0;
int first_failure = -1; int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
int err_count = 0; int err_count = 0;
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4)); uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = { DECLARE_ALIGNED(16, const uint8_t, blimit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER)); tmp = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = { DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -479,12 +459,18 @@ TEST_P(Loop8Test9Param, ValueCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4)); tmp = rnd.Rand8();
while (tmp > 3 * MAX_LOOP_FILTER + 4) { // mblim <= 3*MAX_LOOP_FILTER + 4
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = { DECLARE_ALIGNED(16, const uint8_t, blimit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
}; };
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER)); tmp = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = { DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -500,7 +486,7 @@ TEST_P(Loop8Test9Param, ValueCheck) {
ref_s[j] = s[j]; ref_s[j] = s[j];
} }
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_; vpx_bit_depth_t bd = bit_depth_;
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0, ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
blimit1, limit1, thresh1, bd); blimit1, limit1, thresh1, bd);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
@@ -532,187 +518,118 @@ using std::tr1::make_tuple;
#if HAVE_SSE2 #if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test6Param, SSE2_C_COMPARE_SINGLE, Loop8Test6Param,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2, make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 8, 1), &vp9_highbd_lpf_horizontal_4_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2, make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 8, 1), &vp9_highbd_lpf_vertical_4_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2, make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 8, 1), &vp9_highbd_lpf_horizontal_8_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 8, 1), &vp9_highbd_lpf_horizontal_16_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_horizontal_16_c, 8, 2), &vp9_highbd_lpf_vertical_8_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_sse2, make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 8, 1), &wrapper_vertical_16_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2, make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 10, 1), &vp9_highbd_lpf_horizontal_4_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2, make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 10, 1), &vp9_highbd_lpf_vertical_4_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2, make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 10, 1), &vp9_highbd_lpf_horizontal_8_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 10, 1), &vp9_highbd_lpf_horizontal_16_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_horizontal_16_c, 10, 2), &vp9_highbd_lpf_vertical_8_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 10, 1),
make_tuple(&wrapper_vertical_16_sse2, make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 10, 1), &wrapper_vertical_16_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2, make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
&vpx_highbd_lpf_horizontal_4_c, 12, 1), &vp9_highbd_lpf_horizontal_4_c, VPX_BITS_12),
make_tuple(&vpx_highbd_lpf_vertical_4_sse2, make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
&vpx_highbd_lpf_vertical_4_c, 12, 1), &vp9_highbd_lpf_vertical_4_c, VPX_BITS_12),
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2, make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
&vpx_highbd_lpf_horizontal_8_c, 12, 1), &vp9_highbd_lpf_horizontal_8_c, VPX_BITS_12),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vpx_highbd_lpf_horizontal_16_c, 12, 1), &vp9_highbd_lpf_horizontal_16_c, VPX_BITS_12),
make_tuple(&vpx_highbd_lpf_horizontal_16_sse2, make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_horizontal_16_c, 12, 2), &vp9_highbd_lpf_vertical_8_c, VPX_BITS_12),
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
&vpx_highbd_lpf_vertical_8_c, 12, 1),
make_tuple(&wrapper_vertical_16_sse2, make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 12, 1), &wrapper_vertical_16_c, VPX_BITS_12)));
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 8, 1),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 10, 1),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 12, 1)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test6Param, SSE2_C_COMPARE_SINGLE, Loop8Test6Param,
::testing::Values( ::testing::Values(
make_tuple(&vpx_lpf_horizontal_8_sse2, &vpx_lpf_horizontal_8_c, 8, 1), make_tuple(&vp9_lpf_horizontal_8_sse2, &vp9_lpf_horizontal_8_c,
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8, 1), VPX_BITS_8),
make_tuple(&vpx_lpf_horizontal_16_sse2, &vpx_lpf_horizontal_16_c, 8, 2), make_tuple(&vp9_lpf_horizontal_16_sse2, &vp9_lpf_horizontal_16_c,
make_tuple(&vpx_lpf_vertical_8_sse2, &vpx_lpf_vertical_8_c, 8, 1), VPX_BITS_8),
make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8, 1), make_tuple(&vp9_lpf_vertical_8_sse2, &vp9_lpf_vertical_8_c,
make_tuple(&wrapper_vertical_16_dual_sse2, VPX_BITS_8)));
&wrapper_vertical_16_dual_c, 8, 1)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
#endif #endif
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
INSTANTIATE_TEST_CASE_P(
AVX2, Loop8Test6Param,
::testing::Values(
make_tuple(&vpx_lpf_horizontal_16_avx2, &vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_avx2, &vpx_lpf_horizontal_16_c, 8,
2)));
#endif
#if HAVE_SSE2 #if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test9Param, SSE2_C_COMPARE_DUAL, Loop8Test6Param,
::testing::Values( ::testing::Values(
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2, make_tuple(&wrapper_vertical_16_dual_sse2,
&vpx_highbd_lpf_horizontal_4_dual_c, 8), &wrapper_vertical_16_dual_c, VPX_BITS_8),
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2, make_tuple(&wrapper_vertical_16_dual_sse2,
&vpx_highbd_lpf_horizontal_8_dual_c, 8), &wrapper_vertical_16_dual_c, VPX_BITS_10),
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2, make_tuple(&wrapper_vertical_16_dual_sse2,
&vpx_highbd_lpf_vertical_4_dual_c, 8), &wrapper_vertical_16_dual_c, VPX_BITS_12)));
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
&vpx_highbd_lpf_vertical_8_dual_c, 8),
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
&vpx_highbd_lpf_vertical_4_dual_c, 10),
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
&vpx_highbd_lpf_vertical_8_dual_c, 10),
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
&vpx_highbd_lpf_vertical_4_dual_c, 12),
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
#else #else
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, Loop8Test9Param, SSE2_C_COMPARE_DUAL, Loop8Test6Param,
::testing::Values( ::testing::Values(
make_tuple(&vpx_lpf_horizontal_4_dual_sse2, make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c,
&vpx_lpf_horizontal_4_dual_c, 8), VPX_BITS_8)));
make_tuple(&vpx_lpf_horizontal_8_dual_sse2, #endif // CONFIG_VP9_HIGHBITDEPTH
&vpx_lpf_horizontal_8_dual_c, 8), #endif // HAVE_SSE2
make_tuple(&vpx_lpf_vertical_4_dual_sse2,
&vpx_lpf_vertical_4_dual_c, 8), #if HAVE_SSE2
make_tuple(&vpx_lpf_vertical_8_dual_sse2, #if CONFIG_VP9_HIGHBITDEPTH
&vpx_lpf_vertical_8_dual_c, 8))); INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE_DUAL, Loop8Test9Param,
::testing::Values(
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
&vp9_highbd_lpf_horizontal_4_dual_c, VPX_BITS_8),
make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2,
&vp9_highbd_lpf_horizontal_8_dual_c, VPX_BITS_8),
make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2,
&vp9_highbd_lpf_vertical_4_dual_c, VPX_BITS_8),
make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2,
&vp9_highbd_lpf_vertical_8_dual_c, VPX_BITS_8),
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
&vp9_highbd_lpf_horizontal_4_dual_c, VPX_BITS_10),
make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2,
&vp9_highbd_lpf_horizontal_8_dual_c, VPX_BITS_10),
make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2,
&vp9_highbd_lpf_vertical_4_dual_c, VPX_BITS_10),
make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2,
&vp9_highbd_lpf_vertical_8_dual_c, VPX_BITS_10),
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
&vp9_highbd_lpf_horizontal_4_dual_c, VPX_BITS_12),
make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2,
&vp9_highbd_lpf_horizontal_8_dual_c, VPX_BITS_12),
make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2,
&vp9_highbd_lpf_vertical_4_dual_c, VPX_BITS_12),
make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2,
&vp9_highbd_lpf_vertical_8_dual_c, VPX_BITS_12)));
#else
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE_DUAL, Loop8Test9Param,
::testing::Values(
make_tuple(&vp9_lpf_horizontal_4_dual_sse2,
&vp9_lpf_horizontal_4_dual_c, VPX_BITS_8),
make_tuple(&vp9_lpf_horizontal_8_dual_sse2,
&vp9_lpf_horizontal_8_dual_c, VPX_BITS_8),
make_tuple(&vp9_lpf_vertical_4_dual_sse2,
&vp9_lpf_vertical_4_dual_c, VPX_BITS_8),
make_tuple(&vp9_lpf_vertical_8_dual_sse2,
&vp9_lpf_vertical_8_dual_c, VPX_BITS_8)));
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
#endif #endif
#if HAVE_NEON
#if CONFIG_VP9_HIGHBITDEPTH
// No neon high bitdepth functions.
#else
INSTANTIATE_TEST_CASE_P(
NEON, Loop8Test6Param,
::testing::Values(
#if HAVE_NEON_ASM
// Using #if inside the macro is unsupported on MSVS but the tests are not
// currently built for MSVS with ARM and NEON.
make_tuple(&vpx_lpf_horizontal_16_neon,
&vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_neon,
&vpx_lpf_horizontal_16_c, 8, 2),
make_tuple(&wrapper_vertical_16_neon,
&wrapper_vertical_16_c, 8, 1),
make_tuple(&wrapper_vertical_16_dual_neon,
&wrapper_vertical_16_dual_c, 8, 1),
#endif // HAVE_NEON_ASM
make_tuple(&vpx_lpf_horizontal_8_neon,
&vpx_lpf_horizontal_8_c, 8, 1),
make_tuple(&vpx_lpf_vertical_8_neon,
&vpx_lpf_vertical_8_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_4_neon,
&vpx_lpf_horizontal_4_c, 8, 1),
make_tuple(&vpx_lpf_vertical_4_neon,
&vpx_lpf_vertical_4_c, 8, 1)));
INSTANTIATE_TEST_CASE_P(
NEON, Loop8Test9Param,
::testing::Values(
#if HAVE_NEON_ASM
make_tuple(&vpx_lpf_horizontal_8_dual_neon,
&vpx_lpf_horizontal_8_dual_c, 8),
make_tuple(&vpx_lpf_vertical_8_dual_neon,
&vpx_lpf_vertical_8_dual_c, 8),
#endif // HAVE_NEON_ASM
make_tuple(&vpx_lpf_horizontal_4_dual_neon,
&vpx_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_lpf_vertical_4_dual_neon,
&vpx_lpf_vertical_4_dual_c, 8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_NEON
#if HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
INSTANTIATE_TEST_CASE_P(
MSA, Loop8Test6Param,
::testing::Values(
make_tuple(&vpx_lpf_horizontal_8_msa, &vpx_lpf_horizontal_8_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8, 1),
make_tuple(&vpx_lpf_horizontal_16_msa, &vpx_lpf_horizontal_16_c, 8, 2),
make_tuple(&vpx_lpf_vertical_8_msa, &vpx_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_msa, &wrapper_vertical_16_c, 8, 1)));
INSTANTIATE_TEST_CASE_P(
MSA, Loop8Test9Param,
::testing::Values(
make_tuple(&vpx_lpf_horizontal_4_dual_msa,
&vpx_lpf_horizontal_4_dual_c, 8),
make_tuple(&vpx_lpf_horizontal_8_dual_msa,
&vpx_lpf_horizontal_8_dual_c, 8),
make_tuple(&vpx_lpf_vertical_4_dual_msa,
&vpx_lpf_vertical_4_dual_c, 8),
make_tuple(&vpx_lpf_vertical_8_dual_msa,
&vpx_lpf_vertical_8_dual_c, 8)));
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
} // namespace } // namespace

View File

@@ -42,10 +42,6 @@ class MD5 {
} }
} }
void Add(const uint8_t *data, size_t size) {
MD5Update(&md5_, data, static_cast<uint32_t>(size));
}
const char *Get(void) { const char *Get(void) {
static const char hex[16] = { static const char hex[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '0', '1', '2', '3', '4', '5', '6', '7',

View File

@@ -13,13 +13,12 @@
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_blockd.h" #include "vp9/common/vp9_blockd.h"
#include "vp9/common/vp9_scan.h" #include "vp9/common/vp9_scan.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
@@ -75,16 +74,16 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
FAIL() << "Wrong Size!"; FAIL() << "Wrong Size!";
break; break;
} }
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block1, kMaxNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block2, kMaxNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
const int count_test_block = 1000; const int count_test_block = 1000;
const int block_size = size * size; const int block_size = size * size;
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kMaxNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kMaxNumCoeffs);
int max_error = 0; int max_error = 0;
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
@@ -154,10 +153,10 @@ TEST_P(PartialIDctTest, ResultsMatch) {
FAIL() << "Wrong Size!"; FAIL() << "Wrong Size!";
break; break;
} }
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block1, kMaxNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block2, kMaxNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]); DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
const int count_test_block = 1000; const int count_test_block = 1000;
const int max_coeff = 32766 / 4; const int max_coeff = 32766 / 4;
const int block_size = size * size; const int block_size = size * size;
@@ -202,142 +201,117 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
C, PartialIDctTest, C, PartialIDctTest,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, &vp9_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_c, &vp9_idct32x32_34_add_c,
TX_32X32, 34), TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, &vp9_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_c, &vp9_idct32x32_1_add_c,
TX_32X32, 1), TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct16x16_10_add_c, &vp9_idct16x16_10_add_c,
TX_16X16, 10), TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct16x16_1_add_c, &vp9_idct16x16_1_add_c,
TX_16X16, 1), TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_12_add_c, &vp9_idct8x8_12_add_c,
TX_8X8, 12), TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_1_add_c, &vp9_idct8x8_1_add_c,
TX_8X8, 1), TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, make_tuple(&vp9_fdct4x4_c,
&vpx_idct4x4_16_add_c, &vp9_idct4x4_16_add_c,
&vpx_idct4x4_1_add_c, &vp9_idct4x4_1_add_c,
TX_4X4, 1))); TX_4X4, 1)));
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_NEON_ASM
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, PartialIDctTest, NEON, PartialIDctTest,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, &vp9_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_neon, &vp9_idct32x32_1_add_neon,
TX_32X32, 1), TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct16x16_10_add_neon, &vp9_idct16x16_10_add_neon,
TX_16X16, 10), TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct16x16_1_add_neon, &vp9_idct16x16_1_add_neon,
TX_16X16, 1), TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_12_add_neon, &vp9_idct8x8_12_add_neon,
TX_8X8, 12), TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_1_add_neon, &vp9_idct8x8_1_add_neon,
TX_8X8, 1), TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, make_tuple(&vp9_fdct4x4_c,
&vpx_idct4x4_16_add_c, &vp9_idct4x4_16_add_c,
&vpx_idct4x4_1_add_neon, &vp9_idct4x4_1_add_neon,
TX_4X4, 1))); TX_4X4, 1)));
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #endif
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, PartialIDctTest, SSE2, PartialIDctTest,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, &vp9_idct32x32_1024_add_c,
&vpx_idct32x32_34_add_sse2, &vp9_idct32x32_34_add_sse2,
TX_32X32, 34), TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct32x32_c,
&vpx_idct32x32_1024_add_c, &vp9_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_sse2, &vp9_idct32x32_1_add_sse2,
TX_32X32, 1), TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct16x16_10_add_sse2, &vp9_idct16x16_10_add_sse2,
TX_16X16, 10), TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct16x16_256_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct16x16_1_add_sse2, &vp9_idct16x16_1_add_sse2,
TX_16X16, 1), TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_12_add_sse2, &vp9_idct8x8_12_add_sse2,
TX_8X8, 12), TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_1_add_sse2, &vp9_idct8x8_1_add_sse2,
TX_8X8, 1), TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c, make_tuple(&vp9_fdct4x4_c,
&vpx_idct4x4_16_add_c, &vp9_idct4x4_16_add_c,
&vpx_idct4x4_1_add_sse2, &vp9_idct4x4_1_add_sse2,
TX_4X4, 1))); TX_4X4, 1)));
#endif #endif
#if HAVE_SSSE3 && CONFIG_USE_X86INC && ARCH_X86_64 && \ #if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSSE3_64, PartialIDctTest, SSSE3_64, PartialIDctTest,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct8x8_c, make_tuple(&vp9_fdct8x8_c,
&vpx_idct8x8_64_add_c, &vp9_idct8x8_64_add_c,
&vpx_idct8x8_12_add_ssse3, &vp9_idct8x8_12_add_ssse3,
TX_8X8, 12))); TX_8X8, 12)));
#endif #endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE #if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
MSA, PartialIDctTest, SSSE3, PartialIDctTest,
::testing::Values( ::testing::Values(
make_tuple(&vpx_fdct32x32_c, make_tuple(&vp9_fdct16x16_c,
&vpx_idct32x32_1024_add_c, &vp9_idct16x16_256_add_c,
&vpx_idct32x32_34_add_msa, &vp9_idct16x16_10_add_ssse3,
TX_32X32, 34), TX_16X16, 10)));
make_tuple(&vpx_fdct32x32_c, #endif
&vpx_idct32x32_1024_add_c,
&vpx_idct32x32_1_add_msa,
TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_10_add_msa,
TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c,
&vpx_idct16x16_256_add_c,
&vpx_idct16x16_1_add_msa,
TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_12_add_msa,
TX_8X8, 10),
make_tuple(&vpx_fdct8x8_c,
&vpx_idct8x8_64_add_c,
&vpx_idct8x8_1_add_msa,
TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c,
&vpx_idct4x4_16_add_c,
&vpx_idct4x4_1_add_msa,
TX_4X4, 1)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace } // namespace

View File

@@ -63,12 +63,12 @@ TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
uint8_t *const dst_image_ptr = dst_image + 8; uint8_t *const dst_image_ptr = dst_image + 8;
uint8_t *const flimits = uint8_t *const flimits =
reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width)); reinterpret_cast<uint8_t *>(vpx_memalign(16, block_width));
(void)memset(flimits, 255, block_width); (void)vpx_memset(flimits, 255, block_width);
// Initialize pixels in the input: // Initialize pixels in the input:
// block pixels to value 1, // block pixels to value 1,
// border pixels to value 10. // border pixels to value 10.
(void)memset(src_image, 10, input_size); (void)vpx_memset(src_image, 10, input_size);
uint8_t *pixel_ptr = src_image_ptr; uint8_t *pixel_ptr = src_image_ptr;
for (int i = 0; i < block_height; ++i) { for (int i = 0; i < block_height; ++i) {
for (int j = 0; j < block_width; ++j) { for (int j = 0; j < block_width; ++j) {
@@ -78,7 +78,7 @@ TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
} }
// Initialize pixels in the output to 99. // Initialize pixels in the output to 99.
(void)memset(dst_image, 99, output_size); (void)vpx_memset(dst_image, 99, output_size);
ASM_REGISTER_STATE_CHECK( ASM_REGISTER_STATE_CHECK(
GetParam()(src_image_ptr, dst_image_ptr, input_stride, GetParam()(src_image_ptr, dst_image_ptr, input_stride,
@@ -110,9 +110,4 @@ INSTANTIATE_TEST_CASE_P(SSE2, VP8PostProcessingFilterTest,
::testing::Values(vp8_post_proc_down_and_across_mb_row_sse2)); ::testing::Values(vp8_post_proc_down_and_across_mb_row_sse2));
#endif #endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(MSA, VP8PostProcessingFilterTest,
::testing::Values(vp8_post_proc_down_and_across_mb_row_msa));
#endif
} // namespace } // namespace

View File

@@ -8,196 +8,346 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include <math.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "vp8/common/blockd.h"
#include "vp8/common/onyx.h" #include "./vpx_config.h"
#include "vp8/encoder/block.h" #include "./vp9_rtcd.h"
#include "vp8/encoder/onyx_int.h" #include "vp9/common/vp9_entropy.h"
#include "vp8/encoder/quantize.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h"
namespace {
const int kNumBlocks = 25;
const int kNumBlockEntries = 16;
typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d);
typedef std::tr1::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
using libvpx_test::ACMRandom; using libvpx_test::ACMRandom;
using std::tr1::make_tuple;
// Create and populate a VP8_COMP instance which has a complete set of namespace {
// quantization inputs as well as a second MACROBLOCKD for output. #if CONFIG_VP9_HIGHBITDEPTH
class QuantizeTestBase { const int number_of_iterations = 100;
typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
int skip_block, const int16_t *zbin,
const int16_t *round, const int16_t *quant,
const int16_t *quant_shift,
tran_low_t *qcoeff, tran_low_t *dqcoeff,
const int16_t *dequant, int zbin_oq_value,
uint16_t *eob, const int16_t *scan,
const int16_t *iscan);
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
QuantizeParam;
class QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
public: public:
virtual ~QuantizeTestBase() { virtual ~QuantizeTest() {}
vp8_remove_compressor(&vp8_comp_);
vp8_comp_ = NULL;
vpx_free(macroblockd_dst_);
macroblockd_dst_ = NULL;
libvpx_test::ClearSystemState();
}
protected:
void SetupCompressor() {
rnd_.Reset(ACMRandom::DeterministicSeed());
// The full configuration is necessary to generate the quantization tables.
VP8_CONFIG vp8_config;
memset(&vp8_config, 0, sizeof(vp8_config));
vp8_comp_ = vp8_create_compressor(&vp8_config);
// Set the tables based on a quantizer of 0.
vp8_set_quantizer(vp8_comp_, 0);
// Set up all the block/blockd pointers for the mb in vp8_comp_.
vp8cx_frame_init_quantizer(vp8_comp_);
// Copy macroblockd from the reference to get pre-set-up dequant values.
macroblockd_dst_ = reinterpret_cast<MACROBLOCKD *>(
vpx_memalign(32, sizeof(*macroblockd_dst_)));
memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_));
// Fix block pointers - currently they point to the blocks in the reference
// structure.
vp8_setup_block_dptrs(macroblockd_dst_);
}
void UpdateQuantizer(int q) {
vp8_set_quantizer(vp8_comp_, q);
memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_));
vp8_setup_block_dptrs(macroblockd_dst_);
}
void FillCoeffConstant(int16_t c) {
for (int i = 0; i < kNumBlocks * kNumBlockEntries; ++i) {
vp8_comp_->mb.coeff[i] = c;
}
}
void FillCoeffRandom() {
for (int i = 0; i < kNumBlocks * kNumBlockEntries; ++i) {
vp8_comp_->mb.coeff[i] = rnd_.Rand8();
}
}
void CheckOutput() {
EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.qcoeff, macroblockd_dst_->qcoeff,
sizeof(*macroblockd_dst_->qcoeff) * kNumBlocks *
kNumBlockEntries))
<< "qcoeff mismatch";
EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.dqcoeff, macroblockd_dst_->dqcoeff,
sizeof(*macroblockd_dst_->dqcoeff) * kNumBlocks *
kNumBlockEntries))
<< "dqcoeff mismatch";
EXPECT_EQ(0, memcmp(vp8_comp_->mb.e_mbd.eobs, macroblockd_dst_->eobs,
sizeof(*macroblockd_dst_->eobs) * kNumBlocks))
<< "eobs mismatch";
}
VP8_COMP *vp8_comp_;
MACROBLOCKD *macroblockd_dst_;
private:
ACMRandom rnd_;
};
class QuantizeTest : public QuantizeTestBase,
public ::testing::TestWithParam<VP8QuantizeParam> {
protected:
virtual void SetUp() { virtual void SetUp() {
SetupCompressor(); quantize_op_ = GET_PARAM(0);
asm_quant_ = GET_PARAM(0); ref_quantize_op_ = GET_PARAM(1);
c_quant_ = GET_PARAM(1); bit_depth_ = GET_PARAM(2);
mask_ = (1 << bit_depth_) - 1;
} }
void RunComparison() { virtual void TearDown() { libvpx_test::ClearSystemState(); }
for (int i = 0; i < kNumBlocks; ++i) {
ASM_REGISTER_STATE_CHECK(
c_quant_(&vp8_comp_->mb.block[i], &vp8_comp_->mb.e_mbd.block[i]));
ASM_REGISTER_STATE_CHECK(
asm_quant_(&vp8_comp_->mb.block[i], &macroblockd_dst_->block[i]));
}
CheckOutput(); protected:
vpx_bit_depth_t bit_depth_;
int mask_;
QuantizeFunc quantize_op_;
QuantizeFunc ref_quantize_op_;
};
class Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
public:
virtual ~Quantize32Test() {}
virtual void SetUp() {
quantize_op_ = GET_PARAM(0);
ref_quantize_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
mask_ = (1 << bit_depth_) - 1;
} }
private: virtual void TearDown() { libvpx_test::ClearSystemState(); }
VP8Quantize asm_quant_;
VP8Quantize c_quant_; protected:
vpx_bit_depth_t bit_depth_;
int mask_;
QuantizeFunc quantize_op_;
QuantizeFunc ref_quantize_op_;
}; };
TEST_P(QuantizeTest, TestZeroInput) { TEST_P(QuantizeTest, OperationCheck) {
FillCoeffConstant(0); ACMRandom rnd(ACMRandom::DeterministicSeed());
RunComparison(); int zbin_oq_value = 0;
} DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
TEST_P(QuantizeTest, TestLargeNegativeInput) { DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
FillCoeffConstant(0); DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
// Generate a qcoeff which contains 512/-512 (0x0100/0xFE00) to catch issues DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
// like BUG=883 where the constant being compared was incorrectly initialized. DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 256);
vp8_comp_->mb.coeff[0] = -8191; DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 256);
RunComparison(); DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 256);
} DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
TEST_P(QuantizeTest, TestRandomInput) { DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
FillCoeffRandom(); DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
RunComparison(); int err_count_total = 0;
} int first_failure = -1;
for (int i = 0; i < number_of_iterations; ++i) {
TEST_P(QuantizeTest, TestMultipleQ) { int skip_block = i == 0;
for (int q = 0; q < QINDEX_RANGE; ++q) { TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
UpdateQuantizer(q); TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
FillCoeffRandom(); const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
RunComparison(); int count = (4 << sz) * (4 << sz); // 16, 64, 256
int err_count = 0;
*eob_ptr = rnd.Rand16();
*ref_eob_ptr = *eob_ptr;
for (int j = 0; j < count; j++) {
coeff_ptr[j] = rnd.Rand16()&mask_;
}
for (int j = 0; j < 2; j++) {
zbin_ptr[j] = rnd.Rand16()&mask_;
round_ptr[j] = rnd.Rand16();
quant_ptr[j] = rnd.Rand16();
quant_shift_ptr[j] = rnd.Rand16();
dequant_ptr[j] = rnd.Rand16();
}
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
ref_eob_ptr, scan_order->scan, scan_order->iscan);
ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
zbin_ptr, round_ptr, quant_ptr,
quant_shift_ptr, qcoeff_ptr,
dqcoeff_ptr, dequant_ptr,
zbin_oq_value, eob_ptr,
scan_order->scan, scan_order->iscan));
for (int j = 0; j < sz; ++j) {
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
}
err_count += (*ref_eob_ptr != *eob_ptr);
if (err_count && !err_count_total) {
first_failure = i;
}
err_count_total += err_count;
} }
EXPECT_EQ(0, err_count_total)
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
<< "First failed at test case " << first_failure;
} }
TEST_P(Quantize32Test, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int zbin_oq_value = 0;
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < number_of_iterations; ++i) {
int skip_block = i == 0;
TX_SIZE sz = TX_32X32;
TX_TYPE tx_type = (TX_TYPE)(i % 4);
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
int count = (4 << sz) * (4 << sz); // 1024
int err_count = 0;
*eob_ptr = rnd.Rand16();
*ref_eob_ptr = *eob_ptr;
for (int j = 0; j < count; j++) {
coeff_ptr[j] = rnd.Rand16()&mask_;
}
for (int j = 0; j < 2; j++) {
zbin_ptr[j] = rnd.Rand16()&mask_;
round_ptr[j] = rnd.Rand16();
quant_ptr[j] = rnd.Rand16();
quant_shift_ptr[j] = rnd.Rand16();
dequant_ptr[j] = rnd.Rand16();
}
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
ref_eob_ptr, scan_order->scan, scan_order->iscan);
ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
zbin_ptr, round_ptr, quant_ptr,
quant_shift_ptr, qcoeff_ptr,
dqcoeff_ptr, dequant_ptr,
zbin_oq_value, eob_ptr,
scan_order->scan, scan_order->iscan));
for (int j = 0; j < sz; ++j) {
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
}
err_count += (*ref_eob_ptr != *eob_ptr);
if (err_count && !err_count_total) {
first_failure = i;
}
err_count_total += err_count;
}
EXPECT_EQ(0, err_count_total)
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
<< "First failed at test case " << first_failure;
}
TEST_P(QuantizeTest, EOBCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int zbin_oq_value = 0;
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 256);
DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < number_of_iterations; ++i) {
int skip_block = i == 0;
TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
int count = (4 << sz) * (4 << sz); // 16, 64, 256
int err_count = 0;
*eob_ptr = rnd.Rand16();
*ref_eob_ptr = *eob_ptr;
// Two random entries
for (int j = 0; j < count; j++) {
coeff_ptr[j] = 0;
}
coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
for (int j = 0; j < 2; j++) {
zbin_ptr[j] = rnd.Rand16()&mask_;
round_ptr[j] = rnd.Rand16();
quant_ptr[j] = rnd.Rand16();
quant_shift_ptr[j] = rnd.Rand16();
dequant_ptr[j] = rnd.Rand16();
}
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
ref_eob_ptr, scan_order->scan, scan_order->iscan);
ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
zbin_ptr, round_ptr, quant_ptr,
quant_shift_ptr, qcoeff_ptr,
dqcoeff_ptr, dequant_ptr,
zbin_oq_value, eob_ptr,
scan_order->scan, scan_order->iscan));
for (int j = 0; j < sz; ++j) {
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
}
err_count += (*ref_eob_ptr != *eob_ptr);
if (err_count && !err_count_total) {
first_failure = i;
}
err_count_total += err_count;
}
EXPECT_EQ(0, err_count_total)
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
<< "First failed at test case " << first_failure;
}
TEST_P(Quantize32Test, EOBCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int zbin_oq_value = 0;
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 1024);
DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < number_of_iterations; ++i) {
int skip_block = i == 0;
TX_SIZE sz = TX_32X32;
TX_TYPE tx_type = (TX_TYPE)(i % 4);
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
int count = (4 << sz) * (4 << sz); // 1024
int err_count = 0;
*eob_ptr = rnd.Rand16();
*ref_eob_ptr = *eob_ptr;
for (int j = 0; j < count; j++) {
coeff_ptr[j] = 0;
}
// Two random entries
coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
for (int j = 0; j < 2; j++) {
zbin_ptr[j] = rnd.Rand16()&mask_;
round_ptr[j] = rnd.Rand16();
quant_ptr[j] = rnd.Rand16();
quant_shift_ptr[j] = rnd.Rand16();
dequant_ptr[j] = rnd.Rand16();
}
ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
ref_eob_ptr, scan_order->scan, scan_order->iscan);
ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
zbin_ptr, round_ptr, quant_ptr,
quant_shift_ptr, qcoeff_ptr,
dqcoeff_ptr, dequant_ptr,
zbin_oq_value, eob_ptr,
scan_order->scan, scan_order->iscan));
for (int j = 0; j < sz; ++j) {
err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
(ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
}
err_count += (*ref_eob_ptr != *eob_ptr);
if (err_count && !err_count_total) {
first_failure = i;
}
err_count_total += err_count;
}
EXPECT_EQ(0, err_count_total)
<< "Error: Quantization Test, C output doesn't match SSE2 output. "
<< "First failed at test case " << first_failure;
}
using std::tr1::make_tuple;
#if HAVE_SSE2 #if HAVE_SSE2
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
SSE2, QuantizeTest, SSE2_C_COMPARE, QuantizeTest,
::testing::Values( ::testing::Values(
make_tuple(&vp8_fast_quantize_b_sse2, &vp8_fast_quantize_b_c), make_tuple(&vp9_highbd_quantize_b_sse2,
make_tuple(&vp8_regular_quantize_b_sse2, &vp8_regular_quantize_b_c))); &vp9_highbd_quantize_b_c, VPX_BITS_8),
make_tuple(&vp9_highbd_quantize_b_sse2,
&vp9_highbd_quantize_b_c, VPX_BITS_10),
make_tuple(&vp9_highbd_quantize_b_sse2,
&vp9_highbd_quantize_b_c, VPX_BITS_12)));
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE, Quantize32Test,
::testing::Values(
make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
&vp9_highbd_quantize_b_32x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
&vp9_highbd_quantize_b_32x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
&vp9_highbd_quantize_b_32x32_c, VPX_BITS_12)));
#endif // HAVE_SSE2 #endif // HAVE_SSE2
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(SSSE3, QuantizeTest,
::testing::Values(make_tuple(&vp8_fast_quantize_b_ssse3,
&vp8_fast_quantize_b_c)));
#endif // HAVE_SSSE3
#if HAVE_SSE4_1
INSTANTIATE_TEST_CASE_P(
SSE4_1, QuantizeTest,
::testing::Values(make_tuple(&vp8_regular_quantize_b_sse4_1,
&vp8_regular_quantize_b_c)));
#endif // HAVE_SSE4_1
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, QuantizeTest,
::testing::Values(make_tuple(&vp8_fast_quantize_b_neon,
&vp8_fast_quantize_b_c)));
#endif // HAVE_NEON
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(
MSA, QuantizeTest,
::testing::Values(
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
#endif // HAVE_MSA
} // namespace } // namespace

View File

@@ -30,9 +30,7 @@
#if defined(_WIN64) #if defined(_WIN64)
#undef NOMINMAX #define _WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <winnt.h> #include <winnt.h>
@@ -98,7 +96,7 @@ class RegisterStateCheck {
extern "C" { extern "C" {
// Save the d8-d15 registers into store. // Save the d8-d15 registers into store.
void vpx_push_neon(int64_t *store); void vp9_push_neon(int64_t *store);
} }
namespace libvpx_test { namespace libvpx_test {
@@ -113,7 +111,7 @@ class RegisterStateCheck {
private: private:
static bool StoreRegisters(int64_t store[8]) { static bool StoreRegisters(int64_t store[8]) {
vpx_push_neon(store); vp9_push_neon(store);
return true; return true;
} }
@@ -121,7 +119,7 @@ class RegisterStateCheck {
bool Check() const { bool Check() const {
if (!initialized_) return false; if (!initialized_) return false;
int64_t post_store[8]; int64_t post_store[8];
vpx_push_neon(post_store); vp9_push_neon(post_store);
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
EXPECT_EQ(pre_store_[i], post_store[i]) << "d" EXPECT_EQ(pre_store_[i], post_store[i]) << "d"
<< i + 8 << " has been modified"; << i + 8 << " has been modified";

View File

@@ -81,15 +81,6 @@ static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt,
const unsigned int kInitialWidth = 320; const unsigned int kInitialWidth = 320;
const unsigned int kInitialHeight = 240; const unsigned int kInitialHeight = 240;
struct FrameInfo {
FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
: pts(_pts), w(_w), h(_h) {}
vpx_codec_pts_t pts;
unsigned int w;
unsigned int h;
};
unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) { unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) {
if (frame < 10) if (frame < 10)
return val; return val;
@@ -129,6 +120,15 @@ class ResizeTest : public ::libvpx_test::EncoderTest,
virtual ~ResizeTest() {} virtual ~ResizeTest() {}
struct FrameInfo {
FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
: pts(_pts), w(_w), h(_h) {}
vpx_codec_pts_t pts;
unsigned int w;
unsigned int h;
};
virtual void SetUp() { virtual void SetUp() {
InitializeConfig(); InitializeConfig();
SetMode(GET_PARAM(1)); SetMode(GET_PARAM(1));
@@ -144,7 +144,6 @@ class ResizeTest : public ::libvpx_test::EncoderTest,
TEST_P(ResizeTest, TestExternalResizeWorks) { TEST_P(ResizeTest, TestExternalResizeWorks) {
ResizingVideoSource video; ResizingVideoSource video;
cfg_.g_lag_in_frames = 0;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin(); for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
@@ -154,9 +153,9 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight); const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight);
EXPECT_EQ(expected_w, info->w) EXPECT_EQ(expected_w, info->w)
<< "Frame " << frame << " had unexpected width"; << "Frame " << frame << "had unexpected width";
EXPECT_EQ(expected_h, info->h) EXPECT_EQ(expected_h, info->h)
<< "Frame " << frame << " had unexpected height"; << "Frame " << frame << "had unexpected height";
} }
} }
@@ -196,27 +195,13 @@ class ResizeInternalTest : public ResizeTest {
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video, virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) { libvpx_test::Encoder *encoder) {
if (change_config_) { if (video->frame() == kStepDownFrame) {
int new_q = 60; struct vpx_scaling_mode mode = {VP8E_FOURFIVE, VP8E_THREEFIVE};
if (video->frame() == 0) { encoder->Control(VP8E_SET_SCALEMODE, &mode);
struct vpx_scaling_mode mode = {VP8E_ONETWO, VP8E_ONETWO}; }
encoder->Control(VP8E_SET_SCALEMODE, &mode); if (video->frame() == kStepUpFrame) {
} struct vpx_scaling_mode mode = {VP8E_NORMAL, VP8E_NORMAL};
if (video->frame() == 1) { encoder->Control(VP8E_SET_SCALEMODE, &mode);
struct vpx_scaling_mode mode = {VP8E_NORMAL, VP8E_NORMAL};
encoder->Control(VP8E_SET_SCALEMODE, &mode);
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = new_q;
encoder->Config(&cfg_);
}
} else {
if (video->frame() == kStepDownFrame) {
struct vpx_scaling_mode mode = {VP8E_FOURFIVE, VP8E_THREEFIVE};
encoder->Control(VP8E_SET_SCALEMODE, &mode);
}
if (video->frame() == kStepUpFrame) {
struct vpx_scaling_mode mode = {VP8E_NORMAL, VP8E_NORMAL};
encoder->Control(VP8E_SET_SCALEMODE, &mode);
}
} }
} }
@@ -241,7 +226,6 @@ class ResizeInternalTest : public ResizeTest {
#endif #endif
double frame0_psnr_; double frame0_psnr_;
bool change_config_;
#if WRITE_COMPRESSED_STREAM #if WRITE_COMPRESSED_STREAM
FILE *outfile_; FILE *outfile_;
unsigned int out_frames_; unsigned int out_frames_;
@@ -252,7 +236,6 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 10); 30, 1, 0, 10);
init_flags_ = VPX_CODEC_USE_PSNR; init_flags_ = VPX_CODEC_USE_PSNR;
change_config_ = false;
// q picked such that initial keyframe on this clip is ~30dB PSNR // q picked such that initial keyframe on this clip is ~30dB PSNR
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48; cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
@@ -277,256 +260,7 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
} }
} }
TEST_P(ResizeInternalTest, TestInternalResizeChangeConfig) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 10);
cfg_.g_w = 352;
cfg_.g_h = 288;
change_config_ = true;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
class ResizeInternalRealtimeTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
ResizeInternalRealtimeTest() : EncoderTest(GET_PARAM(0)) {}
virtual ~ResizeInternalRealtimeTest() {}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(VP9E_SET_AQ_MODE, 3);
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
}
if (change_bitrate_ && video->frame() == 120) {
change_bitrate_ = false;
cfg_.rc_target_bitrate = 500;
encoder->Config(&cfg_);
}
}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
set_cpu_used_ = GET_PARAM(2);
}
virtual void DecompressedFrameHook(const vpx_image_t &img,
vpx_codec_pts_t pts) {
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
}
void DefaultConfig() {
cfg_.g_w = 352;
cfg_.g_h = 288;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
cfg_.rc_buf_sz = 1000;
cfg_.rc_min_quantizer = 2;
cfg_.rc_max_quantizer = 56;
cfg_.rc_undershoot_pct = 50;
cfg_.rc_overshoot_pct = 50;
cfg_.rc_end_usage = VPX_CBR;
cfg_.kf_mode = VPX_KF_AUTO;
cfg_.g_lag_in_frames = 0;
cfg_.kf_min_dist = cfg_.kf_max_dist = 3000;
// Enable dropped frames.
cfg_.rc_dropframe_thresh = 1;
// Enable error_resilience mode.
cfg_.g_error_resilient = 1;
// Enable dynamic resizing.
cfg_.rc_resize_allowed = 1;
// Run at low bitrate.
cfg_.rc_target_bitrate = 200;
}
std::vector< FrameInfo > frame_info_list_;
int set_cpu_used_;
bool change_bitrate_;
};
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
// Run at low bitrate, with resize_allowed = 1, and verify that we get
// one resize down event.
TEST_P(ResizeInternalRealtimeTest, TestInternalResizeDown) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 299);
DefaultConfig();
change_bitrate_ = false;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
unsigned int last_w = cfg_.g_w;
unsigned int last_h = cfg_.g_h;
int resize_count = 0;
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
if (info->w != last_w || info->h != last_h) {
// Verify that resize down occurs.
ASSERT_LT(info->w, last_w);
ASSERT_LT(info->h, last_h);
last_w = info->w;
last_h = info->h;
resize_count++;
}
}
// Verify that we get 1 resize down event in this test.
ASSERT_EQ(1, resize_count) << "Resizing should occur.";
}
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
// Start at low target bitrate, raise the bitrate in the middle of the clip,
// scaling-up should occur after bitrate changed.
TEST_P(ResizeInternalRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 299);
DefaultConfig();
change_bitrate_ = true;
// Disable dropped frames.
cfg_.rc_dropframe_thresh = 0;
// Starting bitrate low.
cfg_.rc_target_bitrate = 100;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
unsigned int last_w = cfg_.g_w;
unsigned int last_h = cfg_.g_h;
int resize_count = 0;
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
info != frame_info_list_.end(); ++info) {
if (info->w != last_w || info->h != last_h) {
resize_count++;
if (resize_count == 1) {
// Verify that resize down occurs.
ASSERT_LT(info->w, last_w);
ASSERT_LT(info->h, last_h);
} else if (resize_count == 2) {
// Verify that resize up occurs.
ASSERT_GT(info->w, last_w);
ASSERT_GT(info->h, last_h);
}
last_w = info->w;
last_h = info->h;
}
}
// Verify that we get 2 resize events in this test.
ASSERT_EQ(2, resize_count) << "Resizing should occur twice.";
}
vpx_img_fmt_t CspForFrameNumber(int frame) {
if (frame < 10)
return VPX_IMG_FMT_I420;
if (frame < 20)
return VPX_IMG_FMT_I444;
return VPX_IMG_FMT_I420;
}
class ResizeCspTest : public ResizeTest {
protected:
#if WRITE_COMPRESSED_STREAM
ResizeCspTest()
: ResizeTest(),
frame0_psnr_(0.0),
outfile_(NULL),
out_frames_(0) {}
#else
ResizeCspTest() : ResizeTest(), frame0_psnr_(0.0) {}
#endif
virtual ~ResizeCspTest() {}
virtual void BeginPassHook(unsigned int /*pass*/) {
#if WRITE_COMPRESSED_STREAM
outfile_ = fopen("vp91-2-05-cspchape.ivf", "wb");
#endif
}
virtual void EndPassHook() {
#if WRITE_COMPRESSED_STREAM
if (outfile_) {
if (!fseek(outfile_, 0, SEEK_SET))
write_ivf_file_header(&cfg_, out_frames_, outfile_);
fclose(outfile_);
outfile_ = NULL;
}
#endif
}
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
libvpx_test::Encoder *encoder) {
if (CspForFrameNumber(video->frame()) != VPX_IMG_FMT_I420 &&
cfg_.g_profile != 1) {
cfg_.g_profile = 1;
encoder->Config(&cfg_);
}
if (CspForFrameNumber(video->frame()) == VPX_IMG_FMT_I420 &&
cfg_.g_profile != 0) {
cfg_.g_profile = 0;
encoder->Config(&cfg_);
}
}
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
if (!frame0_psnr_)
frame0_psnr_ = pkt->data.psnr.psnr[0];
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
}
#if WRITE_COMPRESSED_STREAM
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
++out_frames_;
// Write initial file header if first frame.
if (pkt->data.frame.pts == 0)
write_ivf_file_header(&cfg_, 0, outfile_);
// Write frame header and data.
write_ivf_frame_header(pkt, outfile_);
(void)fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_);
}
#endif
double frame0_psnr_;
#if WRITE_COMPRESSED_STREAM
FILE *outfile_;
unsigned int out_frames_;
#endif
};
class ResizingCspVideoSource : public ::libvpx_test::DummyVideoSource {
public:
ResizingCspVideoSource() {
SetSize(kInitialWidth, kInitialHeight);
limit_ = 30;
}
virtual ~ResizingCspVideoSource() {}
protected:
virtual void Next() {
++frame_;
SetImageFormat(CspForFrameNumber(frame_));
FillFrame();
}
};
TEST_P(ResizeCspTest, TestResizeCspWorks) {
ResizingCspVideoSource video;
init_flags_ = VPX_CODEC_USE_PSNR;
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
cfg_.g_lag_in_frames = 0;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
VP8_INSTANTIATE_TEST_CASE(ResizeTest, ONE_PASS_TEST_MODES); VP8_INSTANTIATE_TEST_CASE(ResizeTest, ONE_PASS_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(ResizeTest,
::testing::Values(::libvpx_test::kRealTime));
VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest, VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest,
::testing::Values(::libvpx_test::kOnePassBest)); ::testing::Values(::libvpx_test::kOnePassBest));
VP9_INSTANTIATE_TEST_CASE(ResizeInternalRealtimeTest,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 9));
VP9_INSTANTIATE_TEST_CASE(ResizeCspTest,
::testing::Values(::libvpx_test::kRealTime));
} // namespace } // namespace

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,7 @@ TEST(VP8RoiMapTest, ParameterCheck) {
cpi.common.mb_rows = 240 >> 4; cpi.common.mb_rows = 240 >> 4;
cpi.common.mb_cols = 320 >> 4; cpi.common.mb_cols = 320 >> 4;
const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols); const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols);
memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data)); vpx_memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));
// Segment map // Segment map
cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1)); cpi.segmentation_map = reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
@@ -61,9 +61,9 @@ TEST(VP8RoiMapTest, ParameterCheck) {
// Allocate memory for the source memory map. // Allocate memory for the source memory map.
unsigned char *roi_map = unsigned char *roi_map =
reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1)); reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
memset(&roi_map[mbs >> 2], 1, (mbs >> 2)); vpx_memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
memset(&roi_map[mbs >> 1], 2, (mbs >> 2)); vpx_memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2)); vpx_memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2));
// Do a test call with valid parameters. // Do a test call with valid parameters.
int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows, int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,

View File

@@ -11,15 +11,13 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "test/clear_system_state.h" #include "test/clear_system_state.h"
#include "test/register_state_check.h" #include "test/register_state_check.h"
#include "test/util.h" #include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vpx_mem/vpx_mem.h" #include "vpx_mem/vpx_mem.h"
@@ -201,7 +199,7 @@ const SixtapPredictFunc sixtap_16x16_neon = vp8_sixtap_predict16x16_neon;
const SixtapPredictFunc sixtap_8x8_neon = vp8_sixtap_predict8x8_neon; const SixtapPredictFunc sixtap_8x8_neon = vp8_sixtap_predict8x8_neon;
const SixtapPredictFunc sixtap_8x4_neon = vp8_sixtap_predict8x4_neon; const SixtapPredictFunc sixtap_8x4_neon = vp8_sixtap_predict8x4_neon;
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
NEON, SixtapPredictTest, ::testing::Values( DISABLED_NEON, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_neon), make_tuple(16, 16, sixtap_16x16_neon),
make_tuple(8, 8, sixtap_8x8_neon), make_tuple(8, 8, sixtap_8x8_neon),
make_tuple(8, 4, sixtap_8x4_neon))); make_tuple(8, 4, sixtap_8x4_neon)));
@@ -240,16 +238,4 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(8, 4, sixtap_8x4_ssse3), make_tuple(8, 4, sixtap_8x4_ssse3),
make_tuple(4, 4, sixtap_4x4_ssse3))); make_tuple(4, 4, sixtap_4x4_ssse3)));
#endif #endif
#if HAVE_MSA
const SixtapPredictFunc sixtap_16x16_msa = vp8_sixtap_predict16x16_msa;
const SixtapPredictFunc sixtap_8x8_msa = vp8_sixtap_predict8x8_msa;
const SixtapPredictFunc sixtap_8x4_msa = vp8_sixtap_predict8x4_msa;
const SixtapPredictFunc sixtap_4x4_msa = vp8_sixtap_predict4x4_msa;
INSTANTIATE_TEST_CASE_P(
MSA, SixtapPredictTest, ::testing::Values(
make_tuple(16, 16, sixtap_16x16_msa),
make_tuple(8, 8, sixtap_8x8_msa),
make_tuple(8, 4, sixtap_8x4_msa),
make_tuple(4, 4, sixtap_4x4_msa)));
#endif
} // namespace } // namespace

123
test/subtract_test.cc Normal file
View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "./vpx_config.h"
#include "./vp8_rtcd.h"
#include "vp8/common/blockd.h"
#include "vp8/encoder/block.h"
#include "vpx_mem/vpx_mem.h"
typedef void (*SubtractBlockFunc)(BLOCK *be, BLOCKD *bd, int pitch);
namespace {
class SubtractBlockTest : public ::testing::TestWithParam<SubtractBlockFunc> {
public:
virtual void TearDown() {
libvpx_test::ClearSystemState();
}
};
using libvpx_test::ACMRandom;
TEST_P(SubtractBlockTest, SimpleSubtract) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
BLOCK be;
BLOCKD bd;
// in libvpx, this stride is always 16
const int kDiffPredStride = 16;
const int kSrcStride[] = {32, 16, 8, 4, 0};
const int kBlockWidth = 4;
const int kBlockHeight = 4;
// Allocate... align to 16 for mmx/sse tests
uint8_t *source = reinterpret_cast<uint8_t*>(
vpx_memalign(16, kBlockHeight * kSrcStride[0] * sizeof(*source)));
be.src_diff = reinterpret_cast<int16_t*>(
vpx_memalign(16, kBlockHeight * kDiffPredStride * sizeof(*be.src_diff)));
bd.predictor = reinterpret_cast<unsigned char*>(
vpx_memalign(16, kBlockHeight * kDiffPredStride * sizeof(*bd.predictor)));
for (int i = 0; kSrcStride[i] > 0; ++i) {
// start at block0
be.src = 0;
be.base_src = &source;
be.src_stride = kSrcStride[i];
// set difference
int16_t *src_diff = be.src_diff;
for (int r = 0; r < kBlockHeight; ++r) {
for (int c = 0; c < kBlockWidth; ++c) {
src_diff[c] = static_cast<int16_t>(0xa5a5u);
}
src_diff += kDiffPredStride;
}
// set destination
uint8_t *base_src = *be.base_src;
for (int r = 0; r < kBlockHeight; ++r) {
for (int c = 0; c < kBlockWidth; ++c) {
base_src[c] = rnd.Rand8();
}
base_src += be.src_stride;
}
// set predictor
uint8_t *predictor = bd.predictor;
for (int r = 0; r < kBlockHeight; ++r) {
for (int c = 0; c < kBlockWidth; ++c) {
predictor[c] = rnd.Rand8();
}
predictor += kDiffPredStride;
}
ASM_REGISTER_STATE_CHECK(GetParam()(&be, &bd, kDiffPredStride));
base_src = *be.base_src;
src_diff = be.src_diff;
predictor = bd.predictor;
for (int r = 0; r < kBlockHeight; ++r) {
for (int c = 0; c < kBlockWidth; ++c) {
EXPECT_EQ(base_src[c], (src_diff[c] + predictor[c])) << "r = " << r
<< ", c = " << c;
}
src_diff += kDiffPredStride;
predictor += kDiffPredStride;
base_src += be.src_stride;
}
}
vpx_free(be.src_diff);
vpx_free(source);
vpx_free(bd.predictor);
}
INSTANTIATE_TEST_CASE_P(C, SubtractBlockTest,
::testing::Values(vp8_subtract_b_c));
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(NEON, SubtractBlockTest,
::testing::Values(vp8_subtract_b_neon));
#endif
#if HAVE_MMX
INSTANTIATE_TEST_CASE_P(MMX, SubtractBlockTest,
::testing::Values(vp8_subtract_b_mmx));
#endif
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(SSE2, SubtractBlockTest,
::testing::Values(vp8_subtract_b_sse2));
#endif
} // namespace

View File

@@ -16,13 +16,8 @@
namespace { namespace {
const int kTestMode = 0;
const int kSuperframeSyntax = 1;
typedef std::tr1::tuple<libvpx_test::TestMode,int> SuperframeTestParam;
class SuperframeTest : public ::libvpx_test::EncoderTest, class SuperframeTest : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWithParam<SuperframeTestParam> { public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
protected: protected:
SuperframeTest() : EncoderTest(GET_PARAM(0)), modified_buf_(NULL), SuperframeTest() : EncoderTest(GET_PARAM(0)), modified_buf_(NULL),
last_sf_pts_(0) {} last_sf_pts_(0) {}
@@ -30,13 +25,9 @@ class SuperframeTest : public ::libvpx_test::EncoderTest,
virtual void SetUp() { virtual void SetUp() {
InitializeConfig(); InitializeConfig();
const SuperframeTestParam input = GET_PARAM(1); SetMode(GET_PARAM(1));
const libvpx_test::TestMode mode = std::tr1::get<kTestMode>(input);
const int syntax = std::tr1::get<kSuperframeSyntax>(input);
SetMode(mode);
sf_count_ = 0; sf_count_ = 0;
sf_count_max_ = INT_MAX; sf_count_max_ = INT_MAX;
is_vp10_style_superframe_ = syntax;
} }
virtual void TearDown() { virtual void TearDown() {
@@ -59,8 +50,7 @@ class SuperframeTest : public ::libvpx_test::EncoderTest,
const uint8_t marker = buffer[pkt->data.frame.sz - 1]; const uint8_t marker = buffer[pkt->data.frame.sz - 1];
const int frames = (marker & 0x7) + 1; const int frames = (marker & 0x7) + 1;
const int mag = ((marker >> 3) & 3) + 1; const int mag = ((marker >> 3) & 3) + 1;
const unsigned int index_sz = const unsigned int index_sz = 2 + mag * frames;
2 + mag * (frames - is_vp10_style_superframe_);
if ((marker & 0xe0) == 0xc0 && if ((marker & 0xe0) == 0xc0 &&
pkt->data.frame.sz >= index_sz && pkt->data.frame.sz >= index_sz &&
buffer[pkt->data.frame.sz - index_sz] == marker) { buffer[pkt->data.frame.sz - index_sz] == marker) {
@@ -85,7 +75,6 @@ class SuperframeTest : public ::libvpx_test::EncoderTest,
return pkt; return pkt;
} }
int is_vp10_style_superframe_;
int sf_count_; int sf_count_;
int sf_count_max_; int sf_count_max_;
vpx_codec_cx_pkt_t modified_pkt_; vpx_codec_cx_pkt_t modified_pkt_;
@@ -103,11 +92,6 @@ TEST_P(SuperframeTest, TestSuperframeIndexIsOptional) {
EXPECT_EQ(sf_count_, 1); EXPECT_EQ(sf_count_, 1);
} }
VP9_INSTANTIATE_TEST_CASE(SuperframeTest, ::testing::Combine( VP9_INSTANTIATE_TEST_CASE(SuperframeTest, ::testing::Values(
::testing::Values(::libvpx_test::kTwoPassGood), ::libvpx_test::kTwoPassGood));
::testing::Values(0)));
VP10_INSTANTIATE_TEST_CASE(SuperframeTest, ::testing::Combine(
::testing::Values(::libvpx_test::kTwoPassGood),
::testing::Values(CONFIG_MISC_FIXES)));
} // namespace } // namespace

View File

@@ -63,9 +63,6 @@ class SvcTest : public ::testing::Test {
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t(); vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
VP9CodecFactory codec_factory; VP9CodecFactory codec_factory;
decoder_ = codec_factory.CreateDecoder(dec_cfg, 0); decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
tile_columns_ = 0;
tile_rows_ = 0;
} }
virtual void TearDown() { virtual void TearDown() {
@@ -78,8 +75,6 @@ class SvcTest : public ::testing::Test {
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_OK, res); EXPECT_EQ(VPX_CODEC_OK, res);
vpx_codec_control(&codec_, VP8E_SET_CPUUSED, 4); // Make the test faster vpx_codec_control(&codec_, VP8E_SET_CPUUSED, 4); // Make the test faster
vpx_codec_control(&codec_, VP9E_SET_TILE_COLUMNS, tile_columns_);
vpx_codec_control(&codec_, VP9E_SET_TILE_ROWS, tile_rows_);
codec_initialized_ = true; codec_initialized_ = true;
} }
@@ -113,8 +108,7 @@ class SvcTest : public ::testing::Test {
codec_enc_.g_pass = VPX_RC_FIRST_PASS; codec_enc_.g_pass = VPX_RC_FIRST_PASS;
InitializeEncoder(); InitializeEncoder();
libvpx_test::I420VideoSource video(test_file_name_, libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den, codec_enc_.g_timebase.den,
codec_enc_.g_timebase.num, 0, 30); codec_enc_.g_timebase.num, 0, 30);
video.Begin(); video.Begin();
@@ -182,8 +176,7 @@ class SvcTest : public ::testing::Test {
} }
InitializeEncoder(); InitializeEncoder();
libvpx_test::I420VideoSource video(test_file_name_, libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den, codec_enc_.g_timebase.den,
codec_enc_.g_timebase.num, 0, 30); codec_enc_.g_timebase.num, 0, 30);
video.Begin(); video.Begin();
@@ -232,9 +225,10 @@ class SvcTest : public ::testing::Test {
EXPECT_EQ(received_frames, n); EXPECT_EQ(received_frames, n);
} }
void DropEnhancementLayers(struct vpx_fixed_buf *const inputs, void DropLayersAndMakeItVP9Comaptible(struct vpx_fixed_buf *const inputs,
const int num_super_frames, const int num_super_frames,
const int remained_spatial_layers) { const int remained_spatial_layers,
const bool is_multiple_frame_contexts) {
ASSERT_TRUE(inputs != NULL); ASSERT_TRUE(inputs != NULL);
ASSERT_GT(num_super_frames, 0); ASSERT_GT(num_super_frames, 0);
ASSERT_GT(remained_spatial_layers, 0); ASSERT_GT(remained_spatial_layers, 0);
@@ -256,6 +250,45 @@ class SvcTest : public ::testing::Test {
if (frame_count == 0) { if (frame_count == 0) {
// There's no super frame but only a single frame. // There's no super frame but only a single frame.
ASSERT_EQ(1, remained_spatial_layers); ASSERT_EQ(1, remained_spatial_layers);
if (is_multiple_frame_contexts) {
// Make a new super frame.
uint8_t marker = 0xc1;
unsigned int mask;
int mag;
// Choose the magnitude.
for (mag = 0, mask = 0xff; mag < 4; ++mag) {
if (inputs[i].sz < mask)
break;
mask <<= 8;
mask |= 0xff;
}
marker |= mag << 3;
int index_sz = 2 + (mag + 1) * 2;
inputs[i].buf = realloc(inputs[i].buf, inputs[i].sz + index_sz + 16);
ASSERT_TRUE(inputs[i].buf != NULL);
uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf);
frame_data[0] &= ~2; // Set the show_frame flag to 0.
frame_data += inputs[i].sz;
// Add an one byte frame with show_existing_frame.
*frame_data++ = 0x88;
// Write the super frame index.
*frame_data++ = marker;
frame_sizes[0] = inputs[i].sz;
frame_sizes[1] = 1;
for (int j = 0; j < 2; ++j) {
unsigned int this_sz = frame_sizes[j];
for (int k = 0; k <= mag; k++) {
*frame_data++ = this_sz & 0xff;
this_sz >>= 8;
}
}
*frame_data++ = marker;
inputs[i].sz += index_sz + 1;
}
} else { } else {
// Found a super frame. // Found a super frame.
uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf); uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf);
@@ -271,13 +304,16 @@ class SvcTest : public ::testing::Test {
} }
ASSERT_LT(frame, frame_count) << "Couldn't find a visible frame. " ASSERT_LT(frame, frame_count) << "Couldn't find a visible frame. "
<< "remained_spatial_layers: " << remained_spatial_layers << "remained_spatial_layers: " << remained_spatial_layers
<< " super_frame: " << i; << " super_frame: " << i
if (frame == frame_count - 1) << " is_multiple_frame_context: " << is_multiple_frame_contexts;
if (frame == frame_count - 1 && !is_multiple_frame_contexts)
continue; continue;
frame_data += frame_sizes[frame]; frame_data += frame_sizes[frame];
// We need to add one more frame for multiple frame contexts. // We need to add one more frame for multiple frame contexts.
if (is_multiple_frame_contexts)
++frame;
uint8_t marker = uint8_t marker =
static_cast<const uint8_t*>(inputs[i].buf)[inputs[i].sz - 1]; static_cast<const uint8_t*>(inputs[i].buf)[inputs[i].sz - 1];
const uint32_t mag = ((marker >> 3) & 0x3) + 1; const uint32_t mag = ((marker >> 3) & 0x3) + 1;
@@ -287,14 +323,35 @@ class SvcTest : public ::testing::Test {
marker |= frame; marker |= frame;
// Copy existing frame sizes. // Copy existing frame sizes.
memmove(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1, memmove(frame_data + (is_multiple_frame_contexts ? 2 : 1),
new_index_sz - 2); frame_start + inputs[i].sz - index_sz + 1, new_index_sz - 2);
if (is_multiple_frame_contexts) {
// Add a one byte frame with flag show_existing_frame.
*frame_data++ = 0x88 | (remained_spatial_layers - 1);
}
// New marker. // New marker.
frame_data[0] = marker; frame_data[0] = marker;
frame_data += (mag * (frame + 1) + 1); frame_data += (mag * (frame + 1) + 1);
if (is_multiple_frame_contexts) {
// Write the frame size for the one byte frame.
frame_data -= mag;
*frame_data++ = 1;
for (uint32_t j = 1; j < mag; ++j) {
*frame_data++ = 0;
}
}
*frame_data++ = marker; *frame_data++ = marker;
inputs[i].sz = frame_data - frame_start; inputs[i].sz = frame_data - frame_start;
if (is_multiple_frame_contexts) {
// Change the show frame flag to 0 for all frames.
for (int j = 0; j < frame; ++j) {
frame_start[0] &= ~2;
frame_start += frame_sizes[j];
}
}
} }
} }
} }
@@ -317,8 +374,6 @@ class SvcTest : public ::testing::Test {
std::string test_file_name_; std::string test_file_name_;
bool codec_initialized_; bool codec_initialized_;
Decoder *decoder_; Decoder *decoder_;
int tile_columns_;
int tile_rows_;
}; };
TEST_F(SvcTest, SvcInit) { TEST_F(SvcTest, SvcInit) {
@@ -453,7 +508,6 @@ TEST_F(SvcTest, OnePassEncodeOneFrame) {
TEST_F(SvcTest, OnePassEncodeThreeFrames) { TEST_F(SvcTest, OnePassEncodeThreeFrames) {
codec_enc_.g_pass = VPX_RC_ONE_PASS; codec_enc_.g_pass = VPX_RC_ONE_PASS;
codec_enc_.g_lag_in_frames = 0;
vpx_fixed_buf outputs[3]; vpx_fixed_buf outputs[3];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]); Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]);
@@ -501,7 +555,7 @@ TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
vpx_fixed_buf outputs[10]; vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropEnhancementLayers(&outputs[0], 10, 1); DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, false);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
} }
@@ -519,13 +573,13 @@ TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 4); DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 4, false);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 3); DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 3, false);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 2); DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, false);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 1); DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, false);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
@@ -562,9 +616,9 @@ TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
DecodeNFrames(&outputs[0], 20); DecodeNFrames(&outputs[0], 20);
DropEnhancementLayers(&outputs[0], 20, 2); DropLayersAndMakeItVP9Comaptible(&outputs[0], 20, 2, false);
DecodeNFrames(&outputs[0], 20); DecodeNFrames(&outputs[0], 20);
DropEnhancementLayers(&outputs[0], 20, 1); DropLayersAndMakeItVP9Comaptible(&outputs[0], 20, 1, false);
DecodeNFrames(&outputs[0], 20); DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20); FreeBitstreamBuffers(&outputs[0], 20);
@@ -595,6 +649,7 @@ TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
vpx_fixed_buf outputs[10]; vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, true);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
} }
@@ -612,7 +667,7 @@ TEST_F(SvcTest,
vpx_fixed_buf outputs[10]; vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropEnhancementLayers(&outputs[0], 10, 1); DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
} }
@@ -631,6 +686,7 @@ TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
vpx_fixed_buf outputs[10]; vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, true);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
} }
@@ -651,13 +707,32 @@ TEST_F(SvcTest,
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]);
DecodeNFrames(&outputs[0], 10); vpx_fixed_buf outputs_new[10];
DropEnhancementLayers(&outputs[0], 10, 2); for (int i = 0; i < 10; ++i) {
DecodeNFrames(&outputs[0], 10); outputs_new[i].buf = malloc(outputs[i].sz + 16);
DropEnhancementLayers(&outputs[0], 10, 1); ASSERT_TRUE(outputs_new[i].buf != NULL);
DecodeNFrames(&outputs[0], 10); memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz);
outputs_new[i].sz = outputs[i].sz;
}
DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 3, true);
DecodeNFrames(&outputs_new[0], 10);
for (int i = 0; i < 10; ++i) {
memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz);
outputs_new[i].sz = outputs[i].sz;
}
DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 2, true);
DecodeNFrames(&outputs_new[0], 10);
for (int i = 0; i < 10; ++i) {
memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz);
outputs_new[i].sz = outputs[i].sz;
}
DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 1, true);
DecodeNFrames(&outputs_new[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
FreeBitstreamBuffers(&outputs_new[0], 10);
} }
TEST_F(SvcTest, TwoPassEncode2TemporalLayers) { TEST_F(SvcTest, TwoPassEncode2TemporalLayers) {
@@ -694,6 +769,7 @@ TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
vpx_fixed_buf outputs[10]; vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true);
DecodeNFrames(&outputs[0], 10); DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
} }
@@ -738,6 +814,7 @@ TEST_F(SvcTest,
vpx_fixed_buf outputs[10]; vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs)); memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]); Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true);
vpx_fixed_buf base_layer[5]; vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
@@ -747,51 +824,4 @@ TEST_F(SvcTest,
FreeBitstreamBuffers(&outputs[0], 10); FreeBitstreamBuffers(&outputs[0], 10);
} }
TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithTiles) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
codec_enc_.g_w = 704;
codec_enc_.g_h = 144;
tile_columns_ = 1;
tile_rows_ = 1;
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode2TemporalLayersWithMultipleFrameContextsAndTiles) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1");
svc_.temporal_layers = 2;
Pass1EncodeNFrames(10, 1, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
svc_.temporal_layers = 2;
codec_enc_.g_error_resilient = 0;
codec_enc_.g_w = 704;
codec_enc_.g_h = 144;
tile_columns_ = 1;
tile_rows_ = 1;
vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
} // namespace } // namespace

View File

@@ -7,19 +7,13 @@ LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += hantro_odd.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_420.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_422.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_10_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_420.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_422.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_12_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420_a10-1.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_420.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_422.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_422.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_444.y4m LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_ENCODERS) += park_joy_90p_8_440.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += desktop_credits.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
@@ -556,8 +550,6 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-06-bilinear.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel-1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-07-frame_parallel-1.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x1.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm
@@ -658,38 +650,12 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-01.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-19-skip-02.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv422.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv422.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv440.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv440.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm.md5 LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp91-2-04-yuv444.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-01.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-01.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-02.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-20-big_superframe-02.webm.md5
ifeq ($(CONFIG_VP9_HIGHBITDEPTH),yes)
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-10bit-yuv420.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-10bit-yuv420.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-12bit-yuv420.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp92-2-20-12bit-yuv420.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv422.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv422.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv422.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv422.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv440.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv440.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv440.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv440.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv444.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-10bit-yuv444.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp93-2-20-12bit-yuv444.webm.md5
endif # CONFIG_VP9_HIGHBITDEPTH
# Invalid files for testing libvpx error checking. # Invalid files for testing libvpx error checking.
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v3.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v2.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm
@@ -700,16 +666,10 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.iv
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-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-202x210.webm.ivf.s113306_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-03-size-224x196.webm.ivf.s44156_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x8_frame_parallel.webm.ivf.s288_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf
@@ -724,13 +684,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s738
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s73804_r01-05_b6-.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp91-2-mixedrefcsp-444to420.ivf.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-1.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-2.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-07-frame_parallel-3.webm
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes) ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
# Encode / Decode test
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
# BBB VP9 streams # BBB VP9 streams
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_426x240_tile_1x1_180kbps.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_426x240_tile_1x1_180kbps.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_640x360_tile_1x2_337kbps.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-bbb_640x360_tile_1x2_337kbps.webm
@@ -766,6 +721,3 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomanarrows_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += tacomasmallcameramovement_640_480_30.yuv
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += thaloundeskmtg_640_480_30.yuv
endif # CONFIG_ENCODE_PERF_TESTS endif # CONFIG_ENCODE_PERF_TESTS
# sort and remove duplicates
LIBVPX_TEST_DATA-yes := $(sort $(LIBVPX_TEST_DATA-yes))

File diff suppressed because it is too large Load Diff

View File

@@ -22,37 +22,28 @@ LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += aq_segment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += datarate_test.cc LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += datarate_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += error_resilience_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += i420_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += resize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_video_source.h LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += yuv_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += altref_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += altref_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += keyframe_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += byte_alignment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += external_frame_buffer_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += invalid_file_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += invalid_file_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += user_priv_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_frame_parallel_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_refresh_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += active_map_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += borders_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += cpu_speed_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += cpu_speed_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += frame_size_tests.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += resize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_lossless_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_end_to_end_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_ethread_test.cc
LIBVPX_TEST_SRCS-yes += decode_test_driver.cc LIBVPX_TEST_SRCS-yes += decode_test_driver.cc
LIBVPX_TEST_SRCS-yes += decode_test_driver.h LIBVPX_TEST_SRCS-yes += decode_test_driver.h
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_test_driver.cc LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
LIBVPX_TEST_SRCS-yes += encode_test_driver.h LIBVPX_TEST_SRCS-yes += encode_test_driver.h
## IVF writing.
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../ivfenc.c ../ivfenc.h
## Y4m parsing. ## Y4m parsing.
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_test.cc ../y4menc.c ../y4menc.h LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_test.cc ../y4menc.c ../y4menc.h
@@ -67,7 +58,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../tools_common.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.h LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_skip_loopfilter_test.cc
endif endif
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += decode_api_test.cc LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += decode_api_test.cc
@@ -92,7 +82,6 @@ endif
## shared library builds don't make these functions accessible. ## shared library builds don't make these functions accessible.
## ##
ifeq ($(CONFIG_SHARED),) ifeq ($(CONFIG_SHARED),)
LIBVPX_TEST_SRCS-$(CONFIG_VP9) += lpf_8_test.cc
## VP8 ## VP8
ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),) ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),)
@@ -100,17 +89,17 @@ ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),)
# These tests require both the encoder and decoder to be built. # These tests require both the encoder and decoder to be built.
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),yesyes) ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),yesyes)
LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc
LIBVPX_TEST_SRCS-yes += vp8_fragments_test.cc
endif endif
LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += vp8_decrypt_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_DECODER) += vp8_decrypt_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += set_roi.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += set_roi.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += subtract_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += variance_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += vp8_fdct4x4_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += quantize_test.cc
LIBVPX_TEST_SRCS-yes += idct_test.cc LIBVPX_TEST_SRCS-yes += idct_test.cc
LIBVPX_TEST_SRCS-yes += intrapred_test.cc
LIBVPX_TEST_SRCS-yes += sixtap_predict_test.cc LIBVPX_TEST_SRCS-yes += sixtap_predict_test.cc
LIBVPX_TEST_SRCS-yes += vpx_scale_test.cc LIBVPX_TEST_SRCS-yes += vpx_scale_test.cc
@@ -131,7 +120,7 @@ LIBVPX_TEST_SRCS-yes += partial_idct_test.cc
LIBVPX_TEST_SRCS-yes += superframe_test.cc LIBVPX_TEST_SRCS-yes += superframe_test.cc
LIBVPX_TEST_SRCS-yes += tile_independence_test.cc LIBVPX_TEST_SRCS-yes += tile_independence_test.cc
LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc
LIBVPX_TEST_SRCS-yes += vp9_encoder_parms_get_to_decoder.cc
endif endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9) += convolve_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9) += convolve_test.cc
@@ -143,34 +132,24 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct4x4_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_subtract_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += lpf_8_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_avg_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_avg_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_error_block_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += quantize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += error_block_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9) += vp9_intrapred_test.cc LIBVPX_TEST_SRCS-$(CONFIG_VP9) += vp9_intrapred_test.cc
ifeq ($(CONFIG_VP9_ENCODER),yes) ifeq ($(CONFIG_VP9_ENCODER),yes)
LIBVPX_TEST_SRCS-$(CONFIG_SPATIAL_SVC) += svc_test.cc LIBVPX_TEST_SRCS-$(CONFIG_SPATIAL_SVC) += svc_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += blockiness_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_INTERNAL_STATS) += consistency_test.cc
endif endif
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes) ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp9_denoiser_sse2_test.cc LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp9_denoiser_sse2_test.cc
endif endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
endif # VP9 endif # VP9
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc
TEST_INTRA_PRED_SPEED_SRCS-$(CONFIG_VP9) := test_intra_pred_speed.cc
TEST_INTRA_PRED_SPEED_SRCS-$(CONFIG_VP9) += ../md5_utils.h ../md5_utils.c
## VP10
LIBVPX_TEST_SRCS-$(CONFIG_VP10_ENCODER) += vp10_dct_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP10) += vp10_inv_txfm_test.cc
endif # CONFIG_SHARED endif # CONFIG_SHARED
include $(SRC_PATH_BARE)/test/test-data.mk include $(SRC_PATH_BARE)/test/test-data.mk

View File

@@ -1,384 +0,0 @@
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Test and time VPX intra-predictor functions
#include <stdio.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/md5_helper.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
#include "vpx_ports/vpx_timer.h"
// -----------------------------------------------------------------------------
namespace {
typedef void (*VpxPredFunc)(uint8_t *dst, ptrdiff_t y_stride,
const uint8_t *above, const uint8_t *left);
const int kNumVp9IntraPredFuncs = 13;
const char *kVp9IntraPredNames[kNumVp9IntraPredFuncs] = {
"DC_PRED", "DC_LEFT_PRED", "DC_TOP_PRED", "DC_128_PRED", "V_PRED", "H_PRED",
"D45_PRED", "D135_PRED", "D117_PRED", "D153_PRED", "D207_PRED", "D63_PRED",
"TM_PRED"
};
void TestIntraPred(const char name[], VpxPredFunc const *pred_funcs,
const char *const pred_func_names[], int num_funcs,
const char *const signatures[], int block_size,
int num_pixels_per_test) {
libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
const int kBPS = 32;
const int kTotalPixels = 32 * kBPS;
DECLARE_ALIGNED(16, uint8_t, src[kTotalPixels]);
DECLARE_ALIGNED(16, uint8_t, ref_src[kTotalPixels]);
DECLARE_ALIGNED(16, uint8_t, left[kBPS]);
DECLARE_ALIGNED(16, uint8_t, above_mem[2 * kBPS + 16]);
uint8_t *const above = above_mem + 16;
for (int i = 0; i < kTotalPixels; ++i) ref_src[i] = rnd.Rand8();
for (int i = 0; i < kBPS; ++i) left[i] = rnd.Rand8();
for (int i = -1; i < kBPS; ++i) above[i] = rnd.Rand8();
const int kNumTests = static_cast<int>(2.e10 / num_pixels_per_test);
// some code assumes the top row has been extended:
// d45/d63 C-code, for instance, but not the assembly.
// TODO(jzern): this style of extension isn't strictly necessary.
ASSERT_LE(block_size, kBPS);
memset(above + block_size, above[block_size - 1], 2 * kBPS - block_size);
for (int k = 0; k < num_funcs; ++k) {
if (pred_funcs[k] == NULL) continue;
memcpy(src, ref_src, sizeof(src));
vpx_usec_timer timer;
vpx_usec_timer_start(&timer);
for (int num_tests = 0; num_tests < kNumTests; ++num_tests) {
pred_funcs[k](src, kBPS, above, left);
}
libvpx_test::ClearSystemState();
vpx_usec_timer_mark(&timer);
const int elapsed_time =
static_cast<int>(vpx_usec_timer_elapsed(&timer) / 1000);
libvpx_test::MD5 md5;
md5.Add(src, sizeof(src));
printf("Mode %s[%12s]: %5d ms MD5: %s\n", name, pred_func_names[k],
elapsed_time, md5.Get());
EXPECT_STREQ(signatures[k], md5.Get());
}
}
void TestIntraPred4(VpxPredFunc const *pred_funcs) {
static const int kNumVp9IntraFuncs = 13;
static const char *const kSignatures[kNumVp9IntraFuncs] = {
"4334156168b34ab599d9b5b30f522fe9",
"bc4649d5ba47c7ff178d92e475960fb0",
"8d316e5933326dcac24e1064794b5d12",
"a27270fed024eafd762c95de85f4da51",
"c33dff000d4256c2b8f3bf9e9bab14d2",
"44d8cddc2ad8f79b8ed3306051722b4f",
"eb54839b2bad6699d8946f01ec041cd0",
"ecb0d56ae5f677ea45127ce9d5c058e4",
"0b7936841f6813da818275944895b574",
"9117972ef64f91a58ff73e1731c81db2",
"c56d5e8c729e46825f46dd5d3b5d508a",
"c0889e2039bcf7bcb5d2f33cdca69adc",
"309a618577b27c648f9c5ee45252bc8f",
};
TestIntraPred("Intra4", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
kSignatures, 4, 4 * 4 * kNumVp9IntraFuncs);
}
void TestIntraPred8(VpxPredFunc const *pred_funcs) {
static const int kNumVp9IntraFuncs = 13;
static const char *const kSignatures[kNumVp9IntraFuncs] = {
"7694ddeeefed887faf9d339d18850928",
"7d726b1213591b99f736be6dec65065b",
"19c5711281357a485591aaf9c96c0a67",
"ba6b66877a089e71cd938e3b8c40caac",
"802440c93317e0f8ba93fab02ef74265",
"9e09a47a15deb0b9d8372824f9805080",
"b7c2d8c662268c0c427da412d7b0311d",
"78339c1c60bb1d67d248ab8c4da08b7f",
"5c97d70f7d47de1882a6cd86c165c8a9",
"8182bf60688b42205acd95e59e967157",
"08323400005a297f16d7e57e7fe1eaac",
"95f7bfc262329a5849eda66d8f7c68ce",
"815b75c8e0d91cc1ae766dc5d3e445a3",
};
TestIntraPred("Intra8", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
kSignatures, 8, 8 * 8 * kNumVp9IntraFuncs);
}
void TestIntraPred16(VpxPredFunc const *pred_funcs) {
static const int kNumVp9IntraFuncs = 13;
static const char *const kSignatures[kNumVp9IntraFuncs] = {
"b40dbb555d5d16a043dc361e6694fe53",
"fb08118cee3b6405d64c1fd68be878c6",
"6c190f341475c837cc38c2e566b64875",
"db5c34ccbe2c7f595d9b08b0dc2c698c",
"a62cbfd153a1f0b9fed13e62b8408a7a",
"143df5b4c89335e281103f610f5052e4",
"d87feb124107cdf2cfb147655aa0bb3c",
"7841fae7d4d47b519322e6a03eeed9dc",
"f6ebed3f71cbcf8d6d0516ce87e11093",
"3cc480297dbfeed01a1c2d78dd03d0c5",
"b9f69fa6532b372c545397dcb78ef311",
"a8fe1c70432f09d0c20c67bdb6432c4d",
"b8a41aa968ec108af447af4217cba91b",
};
TestIntraPred("Intra16", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
kSignatures, 16, 16 * 16 * kNumVp9IntraFuncs);
}
void TestIntraPred32(VpxPredFunc const *pred_funcs) {
static const int kNumVp9IntraFuncs = 13;
static const char *const kSignatures[kNumVp9IntraFuncs] = {
"558541656d84f9ae7896db655826febe",
"b3587a1f9a01495fa38c8cd3c8e2a1bf",
"4c6501e64f25aacc55a2a16c7e8f0255",
"b3b01379ba08916ef6b1b35f7d9ad51c",
"0f1eb38b6cbddb3d496199ef9f329071",
"911c06efb9ed1c3b4c104b232b55812f",
"9225beb0ddfa7a1d24eaa1be430a6654",
"0a6d584a44f8db9aa7ade2e2fdb9fc9e",
"b01c9076525216925f3456f034fb6eee",
"d267e20ad9e5cd2915d1a47254d3d149",
"ed012a4a5da71f36c2393023184a0e59",
"f162b51ed618d28b936974cff4391da5",
"9e1370c6d42e08d357d9612c93a71cfc",
};
TestIntraPred("Intra32", pred_funcs, kVp9IntraPredNames, kNumVp9IntraFuncs,
kSignatures, 32, 32 * 32 * kNumVp9IntraFuncs);
}
} // namespace
// Defines a test case for |arch| (e.g., C, SSE2, ...) passing the predictors
// to |test_func|. The test name is 'arch.test_func', e.g., C.TestIntraPred4.
#define INTRA_PRED_TEST(arch, test_func, dc, dc_left, dc_top, dc_128, v, h, \
d45, d135, d117, d153, d207, d63, tm) \
TEST(arch, test_func) { \
static const VpxPredFunc vpx_intra_pred[] = { \
dc, dc_left, dc_top, dc_128, v, h, d45, \
d135, d117, d153, d207, d63, tm}; \
test_func(vpx_intra_pred); \
}
// -----------------------------------------------------------------------------
// 4x4
INTRA_PRED_TEST(C, TestIntraPred4, vpx_dc_predictor_4x4_c,
vpx_dc_left_predictor_4x4_c, vpx_dc_top_predictor_4x4_c,
vpx_dc_128_predictor_4x4_c, vpx_v_predictor_4x4_c,
vpx_h_predictor_4x4_c, vpx_d45_predictor_4x4_c,
vpx_d135_predictor_4x4_c, vpx_d117_predictor_4x4_c,
vpx_d153_predictor_4x4_c, vpx_d207_predictor_4x4_c,
vpx_d63_predictor_4x4_c, vpx_tm_predictor_4x4_c)
#if HAVE_SSE && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSE, TestIntraPred4, vpx_dc_predictor_4x4_sse,
vpx_dc_left_predictor_4x4_sse, vpx_dc_top_predictor_4x4_sse,
vpx_dc_128_predictor_4x4_sse, vpx_v_predictor_4x4_sse, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, vpx_tm_predictor_4x4_sse)
#endif // HAVE_SSE && CONFIG_USE_X86INC
#if HAVE_SSSE3 && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL,
vpx_h_predictor_4x4_ssse3, vpx_d45_predictor_4x4_ssse3, NULL,
NULL, vpx_d153_predictor_4x4_ssse3,
vpx_d207_predictor_4x4_ssse3, vpx_d63_predictor_4x4_ssse3, NULL)
#endif // HAVE_SSSE3 && CONFIG_USE_X86INC
#if HAVE_DSPR2
INTRA_PRED_TEST(DSPR2, TestIntraPred4, vpx_dc_predictor_4x4_dspr2, NULL, NULL,
NULL, NULL, vpx_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL,
NULL, NULL, vpx_tm_predictor_4x4_dspr2)
#endif // HAVE_DSPR2
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred4, vpx_dc_predictor_4x4_neon,
vpx_dc_left_predictor_4x4_neon, vpx_dc_top_predictor_4x4_neon,
vpx_dc_128_predictor_4x4_neon, vpx_v_predictor_4x4_neon,
vpx_h_predictor_4x4_neon, vpx_d45_predictor_4x4_neon,
vpx_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
vpx_tm_predictor_4x4_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred4, vpx_dc_predictor_4x4_msa,
vpx_dc_left_predictor_4x4_msa, vpx_dc_top_predictor_4x4_msa,
vpx_dc_128_predictor_4x4_msa, vpx_v_predictor_4x4_msa,
vpx_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vpx_tm_predictor_4x4_msa)
#endif // HAVE_MSA
// -----------------------------------------------------------------------------
// 8x8
INTRA_PRED_TEST(C, TestIntraPred8, vpx_dc_predictor_8x8_c,
vpx_dc_left_predictor_8x8_c, vpx_dc_top_predictor_8x8_c,
vpx_dc_128_predictor_8x8_c, vpx_v_predictor_8x8_c,
vpx_h_predictor_8x8_c, vpx_d45_predictor_8x8_c,
vpx_d135_predictor_8x8_c, vpx_d117_predictor_8x8_c,
vpx_d153_predictor_8x8_c, vpx_d207_predictor_8x8_c,
vpx_d63_predictor_8x8_c, vpx_tm_predictor_8x8_c)
#if HAVE_SSE && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSE, TestIntraPred8, vpx_dc_predictor_8x8_sse,
vpx_dc_left_predictor_8x8_sse, vpx_dc_top_predictor_8x8_sse,
vpx_dc_128_predictor_8x8_sse, vpx_v_predictor_8x8_sse, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL)
#endif // HAVE_SSE && CONFIG_USE_X86INC
#if HAVE_SSE2 && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSE2, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_sse2)
#endif // HAVE_SSE2 && CONFIG_USE_X86INC
#if HAVE_SSSE3 && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL,
vpx_h_predictor_8x8_ssse3, vpx_d45_predictor_8x8_ssse3, NULL,
NULL, vpx_d153_predictor_8x8_ssse3,
vpx_d207_predictor_8x8_ssse3, vpx_d63_predictor_8x8_ssse3, NULL)
#endif // HAVE_SSSE3 && CONFIG_USE_X86INC
#if HAVE_DSPR2
INTRA_PRED_TEST(DSPR2, TestIntraPred8, vpx_dc_predictor_8x8_dspr2, NULL, NULL,
NULL, NULL, vpx_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL,
NULL, NULL, vpx_tm_predictor_8x8_c)
#endif // HAVE_DSPR2
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred8, vpx_dc_predictor_8x8_neon,
vpx_dc_left_predictor_8x8_neon, vpx_dc_top_predictor_8x8_neon,
vpx_dc_128_predictor_8x8_neon, vpx_v_predictor_8x8_neon,
vpx_h_predictor_8x8_neon, vpx_d45_predictor_8x8_neon, NULL,
NULL, NULL, NULL, NULL, vpx_tm_predictor_8x8_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred8, vpx_dc_predictor_8x8_msa,
vpx_dc_left_predictor_8x8_msa, vpx_dc_top_predictor_8x8_msa,
vpx_dc_128_predictor_8x8_msa, vpx_v_predictor_8x8_msa,
vpx_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vpx_tm_predictor_8x8_msa)
#endif // HAVE_MSA
// -----------------------------------------------------------------------------
// 16x16
INTRA_PRED_TEST(C, TestIntraPred16, vpx_dc_predictor_16x16_c,
vpx_dc_left_predictor_16x16_c, vpx_dc_top_predictor_16x16_c,
vpx_dc_128_predictor_16x16_c, vpx_v_predictor_16x16_c,
vpx_h_predictor_16x16_c, vpx_d45_predictor_16x16_c,
vpx_d135_predictor_16x16_c, vpx_d117_predictor_16x16_c,
vpx_d153_predictor_16x16_c, vpx_d207_predictor_16x16_c,
vpx_d63_predictor_16x16_c, vpx_tm_predictor_16x16_c)
#if HAVE_SSE2 && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSE2, TestIntraPred16, vpx_dc_predictor_16x16_sse2,
vpx_dc_left_predictor_16x16_sse2,
vpx_dc_top_predictor_16x16_sse2,
vpx_dc_128_predictor_16x16_sse2, vpx_v_predictor_16x16_sse2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
vpx_tm_predictor_16x16_sse2)
#endif // HAVE_SSE2 && CONFIG_USE_X86INC
#if HAVE_SSSE3 && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL,
vpx_h_predictor_16x16_ssse3, vpx_d45_predictor_16x16_ssse3,
NULL, NULL, vpx_d153_predictor_16x16_ssse3,
vpx_d207_predictor_16x16_ssse3, vpx_d63_predictor_16x16_ssse3,
NULL)
#endif // HAVE_SSSE3 && CONFIG_USE_X86INC
#if HAVE_DSPR2
INTRA_PRED_TEST(DSPR2, TestIntraPred16, vpx_dc_predictor_16x16_dspr2, NULL,
NULL, NULL, NULL, vpx_h_predictor_16x16_dspr2, NULL, NULL, NULL,
NULL, NULL, NULL, NULL)
#endif // HAVE_DSPR2
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred16, vpx_dc_predictor_16x16_neon,
vpx_dc_left_predictor_16x16_neon,
vpx_dc_top_predictor_16x16_neon,
vpx_dc_128_predictor_16x16_neon, vpx_v_predictor_16x16_neon,
vpx_h_predictor_16x16_neon, vpx_d45_predictor_16x16_neon, NULL,
NULL, NULL, NULL, NULL, vpx_tm_predictor_16x16_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred16, vpx_dc_predictor_16x16_msa,
vpx_dc_left_predictor_16x16_msa, vpx_dc_top_predictor_16x16_msa,
vpx_dc_128_predictor_16x16_msa, vpx_v_predictor_16x16_msa,
vpx_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vpx_tm_predictor_16x16_msa)
#endif // HAVE_MSA
// -----------------------------------------------------------------------------
// 32x32
INTRA_PRED_TEST(C, TestIntraPred32, vpx_dc_predictor_32x32_c,
vpx_dc_left_predictor_32x32_c, vpx_dc_top_predictor_32x32_c,
vpx_dc_128_predictor_32x32_c, vpx_v_predictor_32x32_c,
vpx_h_predictor_32x32_c, vpx_d45_predictor_32x32_c,
vpx_d135_predictor_32x32_c, vpx_d117_predictor_32x32_c,
vpx_d153_predictor_32x32_c, vpx_d207_predictor_32x32_c,
vpx_d63_predictor_32x32_c, vpx_tm_predictor_32x32_c)
#if HAVE_SSE2 && CONFIG_USE_X86INC
#if ARCH_X86_64
INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
vpx_dc_left_predictor_32x32_sse2,
vpx_dc_top_predictor_32x32_sse2,
vpx_dc_128_predictor_32x32_sse2, vpx_v_predictor_32x32_sse2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
vpx_tm_predictor_32x32_sse2)
#else
INTRA_PRED_TEST(SSE2, TestIntraPred32, vpx_dc_predictor_32x32_sse2,
vpx_dc_left_predictor_32x32_sse2,
vpx_dc_top_predictor_32x32_sse2,
vpx_dc_128_predictor_32x32_sse2, vpx_v_predictor_32x32_sse2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
#endif // ARCH_X86_64
#endif // HAVE_SSE2 && CONFIG_USE_X86INC
#if HAVE_SSSE3 && CONFIG_USE_X86INC
INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL,
vpx_h_predictor_32x32_ssse3, vpx_d45_predictor_32x32_ssse3,
NULL, NULL, vpx_d153_predictor_32x32_ssse3,
vpx_d207_predictor_32x32_ssse3, vpx_d63_predictor_32x32_ssse3,
NULL)
#endif // HAVE_SSSE3 && CONFIG_USE_X86INC
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred32, vpx_dc_predictor_32x32_neon,
vpx_dc_left_predictor_32x32_neon,
vpx_dc_top_predictor_32x32_neon,
vpx_dc_128_predictor_32x32_neon, vpx_v_predictor_32x32_neon,
vpx_h_predictor_32x32_neon, NULL, NULL, NULL, NULL, NULL, NULL,
vpx_tm_predictor_32x32_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred32, vpx_dc_predictor_32x32_msa,
vpx_dc_left_predictor_32x32_msa, vpx_dc_top_predictor_32x32_msa,
vpx_dc_128_predictor_32x32_msa, vpx_v_predictor_32x32_msa,
vpx_h_predictor_32x32_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vpx_tm_predictor_32x32_msa)
#endif // HAVE_MSA
#include "test/test_libvpx.cc"

View File

@@ -8,9 +8,6 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include <string> #include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h" #include "./vpx_config.h"
#if ARCH_X86 || ARCH_X86_64 #if ARCH_X86 || ARCH_X86_64
#include "vpx_ports/x86.h" #include "vpx_ports/x86.h"
@@ -18,15 +15,13 @@
extern "C" { extern "C" {
#if CONFIG_VP8 #if CONFIG_VP8
extern void vp8_rtcd(); extern void vp8_rtcd();
#endif // CONFIG_VP8 #endif
#if CONFIG_VP9 #if CONFIG_VP9
extern void vp9_rtcd(); extern void vp9_rtcd();
#endif // CONFIG_VP9 #endif
extern void vpx_dsp_rtcd();
extern void vpx_scale_rtcd();
} }
#include "third_party/googletest/src/include/gtest/gtest.h"
#if ARCH_X86 || ARCH_X86_64
static void append_negative_gtest_filter(const char *str) { static void append_negative_gtest_filter(const char *str) {
std::string filter = ::testing::FLAGS_gtest_filter; std::string filter = ::testing::FLAGS_gtest_filter;
// Negative patterns begin with one '-' followed by a ':' separated list. // Negative patterns begin with one '-' followed by a ':' separated list.
@@ -34,7 +29,6 @@ static void append_negative_gtest_filter(const char *str) {
filter += str; filter += str;
::testing::FLAGS_gtest_filter = filter; ::testing::FLAGS_gtest_filter = filter;
} }
#endif // ARCH_X86 || ARCH_X86_64
int main(int argc, char **argv) { int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
@@ -42,22 +36,22 @@ int main(int argc, char **argv) {
#if ARCH_X86 || ARCH_X86_64 #if ARCH_X86 || ARCH_X86_64
const int simd_caps = x86_simd_caps(); const int simd_caps = x86_simd_caps();
if (!(simd_caps & HAS_MMX)) if (!(simd_caps & HAS_MMX))
append_negative_gtest_filter(":MMX.*:MMX/*"); append_negative_gtest_filter(":MMX/*");
if (!(simd_caps & HAS_SSE)) if (!(simd_caps & HAS_SSE))
append_negative_gtest_filter(":SSE.*:SSE/*"); append_negative_gtest_filter(":SSE/*");
if (!(simd_caps & HAS_SSE2)) if (!(simd_caps & HAS_SSE2))
append_negative_gtest_filter(":SSE2.*:SSE2/*"); append_negative_gtest_filter(":SSE2/*");
if (!(simd_caps & HAS_SSE3)) if (!(simd_caps & HAS_SSE3))
append_negative_gtest_filter(":SSE3.*:SSE3/*"); append_negative_gtest_filter(":SSE3/*");
if (!(simd_caps & HAS_SSSE3)) if (!(simd_caps & HAS_SSSE3))
append_negative_gtest_filter(":SSSE3.*:SSSE3/*"); append_negative_gtest_filter(":SSSE3/*");
if (!(simd_caps & HAS_SSE4_1)) if (!(simd_caps & HAS_SSE4_1))
append_negative_gtest_filter(":SSE4_1.*:SSE4_1/*"); append_negative_gtest_filter(":SSE4_1/*");
if (!(simd_caps & HAS_AVX)) if (!(simd_caps & HAS_AVX))
append_negative_gtest_filter(":AVX.*:AVX/*"); append_negative_gtest_filter(":AVX/*");
if (!(simd_caps & HAS_AVX2)) if (!(simd_caps & HAS_AVX2))
append_negative_gtest_filter(":AVX2.*:AVX2/*"); append_negative_gtest_filter(":AVX2/*");
#endif // ARCH_X86 || ARCH_X86_64 #endif
#if !CONFIG_SHARED #if !CONFIG_SHARED
// Shared library builds don't support whitebox tests // Shared library builds don't support whitebox tests
@@ -65,13 +59,11 @@ int main(int argc, char **argv) {
#if CONFIG_VP8 #if CONFIG_VP8
vp8_rtcd(); vp8_rtcd();
#endif // CONFIG_VP8 #endif
#if CONFIG_VP9 #if CONFIG_VP9
vp9_rtcd(); vp9_rtcd();
#endif // CONFIG_VP9 #endif
vpx_dsp_rtcd(); #endif
vpx_scale_rtcd();
#endif // !CONFIG_SHARED
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@@ -12,7 +12,6 @@
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include "third_party/googletest/src/include/gtest/gtest.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "../tools_common.h"
#include "./vpx_config.h" #include "./vpx_config.h"
#include "test/codec_factory.h" #include "test/codec_factory.h"
#include "test/decode_test_driver.h" #include "test/decode_test_driver.h"
@@ -27,24 +26,10 @@
namespace { namespace {
enum DecodeMode {
kSerialMode,
kFrameParallelMode
};
const int kDecodeMode = 0;
const int kThreads = 1;
const int kFileName = 2;
typedef std::tr1::tuple<int, int, const char*> DecodeParam;
class TestVectorTest : public ::libvpx_test::DecoderTest, class TestVectorTest : public ::libvpx_test::DecoderTest,
public ::libvpx_test::CodecTestWithParam<DecodeParam> { public ::libvpx_test::CodecTestWithParam<const char*> {
protected: protected:
TestVectorTest() TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(NULL) {}
: DecoderTest(GET_PARAM(0)),
md5_file_(NULL) {
}
virtual ~TestVectorTest() { virtual ~TestVectorTest() {
if (md5_file_) if (md5_file_)
@@ -86,25 +71,8 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
// checksums match the correct md5 data, then the test is passed. Otherwise, // checksums match the correct md5 data, then the test is passed. Otherwise,
// the test failed. // the test failed.
TEST_P(TestVectorTest, MD5Match) { TEST_P(TestVectorTest, MD5Match) {
const DecodeParam input = GET_PARAM(1); const std::string filename = GET_PARAM(1);
const std::string filename = std::tr1::get<kFileName>(input);
const int threads = std::tr1::get<kThreads>(input);
const int mode = std::tr1::get<kDecodeMode>(input);
libvpx_test::CompressedVideoSource *video = NULL; libvpx_test::CompressedVideoSource *video = NULL;
vpx_codec_flags_t flags = 0;
vpx_codec_dec_cfg_t cfg = {0};
char str[256];
if (mode == kFrameParallelMode) {
flags |= VPX_CODEC_USE_FRAME_THREADING;
}
cfg.threads = threads;
snprintf(str, sizeof(str) / sizeof(str[0]) - 1,
"file: %s mode: %s threads: %d",
filename.c_str(), mode == 0 ? "Serial" : "Parallel", threads);
SCOPED_TRACE(str);
// Open compressed video file. // Open compressed video file.
if (filename.substr(filename.length() - 3, 3) == "ivf") { if (filename.substr(filename.length() - 3, 3) == "ivf") {
@@ -124,50 +92,18 @@ TEST_P(TestVectorTest, MD5Match) {
const std::string md5_filename = filename + ".md5"; const std::string md5_filename = filename + ".md5";
OpenMD5File(md5_filename); OpenMD5File(md5_filename);
// Set decode config and flags.
set_cfg(cfg);
set_flags(flags);
// Decode frame, and check the md5 matching. // Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg)); ASSERT_NO_FATAL_FAILURE(RunLoop(video));
delete video; delete video;
} }
// Test VP8 decode in serial mode with single thread. VP8_INSTANTIATE_TEST_CASE(TestVectorTest,
// NOTE: VP8 only support serial mode. ::testing::ValuesIn(libvpx_test::kVP8TestVectors,
#if CONFIG_VP8_DECODER libvpx_test::kVP8TestVectors +
VP8_INSTANTIATE_TEST_CASE( libvpx_test::kNumVP8TestVectors));
TestVectorTest, VP9_INSTANTIATE_TEST_CASE(TestVectorTest,
::testing::Combine( ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
::testing::Values(0), // Serial Mode. libvpx_test::kVP9TestVectors +
::testing::Values(1), // Single thread. libvpx_test::kNumVP9TestVectors));
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
libvpx_test::kVP8TestVectors +
libvpx_test::kNumVP8TestVectors)));
#endif // CONFIG_VP8_DECODER
// Test VP9 decode in serial mode with single thread.
#if CONFIG_VP9_DECODER
VP9_INSTANTIATE_TEST_CASE(
TestVectorTest,
::testing::Combine(
::testing::Values(0), // Serial Mode.
::testing::Values(1), // Single thread.
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
libvpx_test::kVP9TestVectors +
libvpx_test::kNumVP9TestVectors)));
// Test VP9 decode in frame parallel mode with different number of threads.
INSTANTIATE_TEST_CASE_P(
VP9MultiThreadedFrameParallel, TestVectorTest,
::testing::Combine(
::testing::Values(
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
::testing::Combine(
::testing::Values(1), // Frame Parallel mode.
::testing::Range(2, 9), // With 2 ~ 8 threads.
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
libvpx_test::kVP9TestVectors +
libvpx_test::kNumVP9TestVectors))));
#endif
} // namespace } // namespace

View File

@@ -165,10 +165,7 @@ const char *const kVP9TestVectors[] = {
"vp90-2-11-size-351x287.webm", "vp90-2-11-size-351x288.webm", "vp90-2-11-size-351x287.webm", "vp90-2-11-size-351x288.webm",
"vp90-2-11-size-352x287.webm", "vp90-2-12-droppable_1.ivf", "vp90-2-11-size-352x287.webm", "vp90-2-12-droppable_1.ivf",
"vp90-2-12-droppable_2.ivf", "vp90-2-12-droppable_3.ivf", "vp90-2-12-droppable_2.ivf", "vp90-2-12-droppable_3.ivf",
#if !CONFIG_SIZE_LIMIT || \
(DECODE_WIDTH_LIMIT >= 20400 && DECODE_HEIGHT_LIMIT >= 120)
"vp90-2-13-largescaling.webm", "vp90-2-13-largescaling.webm",
#endif
"vp90-2-14-resize-fp-tiles-1-16.webm", "vp90-2-14-resize-fp-tiles-1-16.webm",
"vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm", "vp90-2-14-resize-fp-tiles-1-2-4-8-16.webm",
"vp90-2-14-resize-fp-tiles-1-2.webm", "vp90-2-14-resize-fp-tiles-1-4.webm", "vp90-2-14-resize-fp-tiles-1-2.webm", "vp90-2-14-resize-fp-tiles-1-4.webm",
@@ -187,14 +184,6 @@ const char *const kVP9TestVectors[] = {
"vp90-2-18-resize.ivf", "vp90-2-19-skip.webm", "vp90-2-18-resize.ivf", "vp90-2-19-skip.webm",
"vp90-2-19-skip-01.webm", "vp90-2-19-skip-02.webm", "vp90-2-19-skip-01.webm", "vp90-2-19-skip-02.webm",
"vp91-2-04-yuv444.webm", "vp91-2-04-yuv444.webm",
"vp91-2-04-yuv422.webm", "vp91-2-04-yuv440.webm",
#if CONFIG_VP9_HIGHBITDEPTH
"vp92-2-20-10bit-yuv420.webm", "vp92-2-20-12bit-yuv420.webm",
"vp93-2-20-10bit-yuv422.webm", "vp93-2-20-12bit-yuv422.webm",
"vp93-2-20-10bit-yuv440.webm", "vp93-2-20-12bit-yuv440.webm",
"vp93-2-20-10bit-yuv444.webm", "vp93-2-20-12bit-yuv444.webm",
#endif // CONFIG_VP9_HIGHBITDEPTH`
"vp90-2-20-big_superframe-01.webm", "vp90-2-20-big_superframe-02.webm",
}; };
const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors); const int kNumVP9TestVectors = NELEMENTS(kVP9TestVectors);
#endif // CONFIG_VP9_DECODER #endif // CONFIG_VP9_DECODER

View File

@@ -104,5 +104,4 @@ TEST_P(TileIndependenceTest, MD5Match) {
VP9_INSTANTIATE_TEST_CASE(TileIndependenceTest, ::testing::Range(0, 2, 1)); VP9_INSTANTIATE_TEST_CASE(TileIndependenceTest, ::testing::Range(0, 2, 1));
VP10_INSTANTIATE_TEST_CASE(TileIndependenceTest, ::testing::Range(0, 2, 1));
} // namespace } // namespace

View File

@@ -106,24 +106,22 @@ check_git_hashes() {
fi fi
} }
# $1 is the name of an environment variable containing a directory name to
# test.
test_env_var_dir() {
local dir=$(eval echo "\${$1}")
if [ ! -d "${dir}" ]; then
elog "'${dir}': No such directory"
elog "The $1 environment variable must be set to a valid directory."
return 1
fi
}
# This script requires that the LIBVPX_BIN_PATH, LIBVPX_CONFIG_PATH, and # This script requires that the LIBVPX_BIN_PATH, LIBVPX_CONFIG_PATH, and
# LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that # LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that
# the variables are set and that they all evaluate to directory paths. # the variables are set and that they all evaluate to directory paths.
verify_vpx_test_environment() { verify_vpx_test_environment() {
test_env_var_dir "LIBVPX_BIN_PATH" \ if [ ! -d "${LIBVPX_BIN_PATH}" ]; then
&& test_env_var_dir "LIBVPX_CONFIG_PATH" \ echo "The LIBVPX_BIN_PATH environment variable must be set."
&& test_env_var_dir "LIBVPX_TEST_DATA_PATH" return 1
fi
if [ ! -d "${LIBVPX_CONFIG_PATH}" ]; then
echo "The LIBVPX_CONFIG_PATH environment variable must be set."
return 1
fi
if [ ! -d "${LIBVPX_TEST_DATA_PATH}" ]; then
echo "The LIBVPX_TEST_DATA_PATH environment variable must be set."
return 1
fi
} }
# Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which # Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which
@@ -263,9 +261,6 @@ run_tests() {
return return
fi fi
# Don't bother with the environment tests if everything else was disabled.
[ -z "${tests_to_filter}" ] && return
# Combine environment and actual tests. # Combine environment and actual tests.
local tests_to_run="${env_tests} ${tests_to_filter}" local tests_to_run="${env_tests} ${tests_to_filter}"
@@ -383,7 +378,8 @@ else
VPX_TEST_TEMP_ROOT=/tmp VPX_TEST_TEMP_ROOT=/tmp
fi fi
VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_$$" VPX_TEST_RAND=$(awk 'BEGIN { srand(); printf "%d\n",(rand() * 32768)}')
VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_${VPX_TEST_RAND}"
if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \ if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \
[ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then [ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then
@@ -401,16 +397,11 @@ VP8_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp80-00-comprehensive-001.ivf"
VP9_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-09-subpixel-00.ivf" VP9_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-09-subpixel-00.ivf"
VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm" VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm"
VP9_FPM_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-07-frame_parallel-1.webm"
VP9_LT_50_FRAMES_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-02-size-32x08.webm"
YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv" YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv"
YUV_RAW_INPUT_WIDTH=352 YUV_RAW_INPUT_WIDTH=352
YUV_RAW_INPUT_HEIGHT=288 YUV_RAW_INPUT_HEIGHT=288
Y4M_NOSQ_PAR_INPUT="${LIBVPX_TEST_DATA_PATH}/park_joy_90p_8_420_a10-1.y4m"
Y4M_720P_INPUT="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.y4m"
# Setup a trap function to clean up after tests complete. # Setup a trap function to clean up after tests complete.
trap cleanup EXIT trap cleanup EXIT
@@ -426,13 +417,13 @@ vlog "$(basename "${0%.*}") test configuration:
VPX_TEST_LIST_TESTS=${VPX_TEST_LIST_TESTS} VPX_TEST_LIST_TESTS=${VPX_TEST_LIST_TESTS}
VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR} VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}
VPX_TEST_PREFIX=${VPX_TEST_PREFIX} VPX_TEST_PREFIX=${VPX_TEST_PREFIX}
VPX_TEST_RAND=${VPX_TEST_RAND}
VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS} VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS}
VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT} VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT}
VPX_TEST_TEMP_ROOT=${VPX_TEST_TEMP_ROOT} VPX_TEST_TEMP_ROOT=${VPX_TEST_TEMP_ROOT}
VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT} VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT}
YUV_RAW_INPUT=${YUV_RAW_INPUT} YUV_RAW_INPUT=${YUV_RAW_INPUT}
YUV_RAW_INPUT_WIDTH=${YUV_RAW_INPUT_WIDTH} YUV_RAW_INPUT_WIDTH=${YUV_RAW_INPUT_WIDTH}
YUV_RAW_INPUT_HEIGHT=${YUV_RAW_INPUT_HEIGHT} YUV_RAW_INPUT_HEIGHT=${YUV_RAW_INPUT_HEIGHT}"
Y4M_NOSQ_PAR_INPUT=${Y4M_NOSQ_PAR_INPUT}"
fi # End $VPX_TEST_TOOLS_COMMON_SH pseudo include guard. fi # End $VPX_TEST_TOOLS_COMMON_SH pseudo include guard.

View File

@@ -19,7 +19,8 @@
// Macros // Macros
#define GET_PARAM(k) std::tr1::get< k >(GetParam()) #define GET_PARAM(k) std::tr1::get< k >(GetParam())
inline double compute_psnr(const vpx_image_t *img1, const vpx_image_t *img2) { static double compute_psnr(const vpx_image_t *img1,
const vpx_image_t *img2) {
assert((img1->fmt == img2->fmt) && assert((img1->fmt == img2->fmt) &&
(img1->d_w == img2->d_w) && (img1->d_w == img2->d_w) &&
(img1->d_h == img2->d_h)); (img1->d_h == img2->d_h));

File diff suppressed because it is too large Load Diff

View File

@@ -11,9 +11,6 @@
#define TEST_VIDEO_SOURCE_H_ #define TEST_VIDEO_SOURCE_H_
#if defined(_WIN32) #if defined(_WIN32)
#undef NOMINMAX
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#endif #endif
#include <cstdio> #include <cstdio>
@@ -51,7 +48,7 @@ static std::string GetDataPath() {
#undef TO_STRING #undef TO_STRING
#undef STRINGIFY #undef STRINGIFY
inline FILE *OpenTestDataFile(const std::string& file_name) { static FILE *OpenTestDataFile(const std::string& file_name) {
const std::string path_to_source = GetDataPath() + "/" + file_name; const std::string path_to_source = GetDataPath() + "/" + file_name;
return fopen(path_to_source.c_str(), "rb"); return fopen(path_to_source.c_str(), "rb");
} }
@@ -137,13 +134,8 @@ class VideoSource {
class DummyVideoSource : public VideoSource { class DummyVideoSource : public VideoSource {
public: public:
DummyVideoSource() DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
: img_(NULL), SetSize(80, 64);
limit_(100),
width_(80),
height_(64),
format_(VPX_IMG_FMT_I420) {
ReallocImage();
} }
virtual ~DummyVideoSource() { vpx_img_free(img_); } virtual ~DummyVideoSource() { vpx_img_free(img_); }
@@ -182,35 +174,23 @@ class DummyVideoSource : public VideoSource {
void SetSize(unsigned int width, unsigned int height) { void SetSize(unsigned int width, unsigned int height) {
if (width != width_ || height != height_) { if (width != width_ || height != height_) {
vpx_img_free(img_);
raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, width, height, 32);
width_ = width; width_ = width;
height_ = height; height_ = height;
ReallocImage();
}
}
void SetImageFormat(vpx_img_fmt_t format) {
if (format_ != format) {
format_ = format;
ReallocImage();
} }
} }
protected: protected:
virtual void FillFrame() { if (img_) memset(img_->img_data, 0, raw_sz_); } virtual void FillFrame() { if (img_) memset(img_->img_data, 0, raw_sz_); }
void ReallocImage() {
vpx_img_free(img_);
img_ = vpx_img_alloc(NULL, format_, width_, height_, 32);
raw_sz_ = ((img_->w + 31) & ~31) * img_->h * img_->bps / 8;
}
vpx_image_t *img_; vpx_image_t *img_;
size_t raw_sz_; size_t raw_sz_;
unsigned int limit_; unsigned int limit_;
unsigned int frame_; unsigned int frame_;
unsigned int width_; unsigned int width_;
unsigned int height_; unsigned int height_;
vpx_img_fmt_t format_;
}; };

View File

@@ -1,111 +0,0 @@
/*
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <stdlib.h>
#include <new>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/util.h"
#include "./vpx_config.h"
#include "vpx_ports/msvc.h"
#undef CONFIG_COEFFICIENT_RANGE_CHECKING
#define CONFIG_COEFFICIENT_RANGE_CHECKING 1
#include "vp10/encoder/dct.c"
using libvpx_test::ACMRandom;
namespace {
void reference_dct_1d(const double *in, double *out, int size) {
const double PI = 3.141592653589793238462643383279502884;
const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < size; ++k) {
out[k] = 0;
for (int n = 0; n < size; ++n) {
out[k] += in[n] * cos(PI * (2 * n + 1) * k / (2 * size));
}
if (k == 0)
out[k] = out[k] * kInvSqrt2;
}
}
typedef void (*FdctFuncRef)(const double *in, double *out, int size);
typedef void (*IdctFuncRef)(const double *in, double *out, int size);
typedef void (*FdctFunc)(const tran_low_t *in, tran_low_t *out);
typedef void (*IdctFunc)(const tran_low_t *in, tran_low_t *out);
class TransTestBase {
public:
virtual ~TransTestBase() {}
protected:
void RunFwdAccuracyCheck() {
tran_low_t *input = new tran_low_t[txfm_size_];
tran_low_t *output = new tran_low_t[txfm_size_];
double *ref_input = new double[txfm_size_];
double *ref_output = new double[txfm_size_];
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 5000;
for (int ti = 0; ti < count_test_block; ++ti) {
for (int ni = 0; ni < txfm_size_; ++ni) {
input[ni] = rnd.Rand8() - rnd.Rand8();
ref_input[ni] = static_cast<double>(input[ni]);
}
fwd_txfm_(input, output);
fwd_txfm_ref_(ref_input, ref_output, txfm_size_);
for (int ni = 0; ni < txfm_size_; ++ni) {
EXPECT_LE(
abs(output[ni] - static_cast<tran_low_t>(round(ref_output[ni]))),
max_error_);
}
}
delete[] input;
delete[] output;
delete[] ref_input;
delete[] ref_output;
}
double max_error_;
int txfm_size_;
FdctFunc fwd_txfm_;
FdctFuncRef fwd_txfm_ref_;
};
typedef std::tr1::tuple<FdctFunc, FdctFuncRef, int, int> FdctParam;
class Vp10FwdTxfm
: public TransTestBase,
public ::testing::TestWithParam<FdctParam> {
public:
virtual void SetUp() {
fwd_txfm_ = GET_PARAM(0);
fwd_txfm_ref_ = GET_PARAM(1);
txfm_size_ = GET_PARAM(2);
max_error_ = GET_PARAM(3);
}
virtual void TearDown() {}
};
TEST_P(Vp10FwdTxfm, RunFwdAccuracyCheck) {
RunFwdAccuracyCheck();
}
INSTANTIATE_TEST_CASE_P(
C, Vp10FwdTxfm,
::testing::Values(
FdctParam(&fdct4, &reference_dct_1d, 4, 1),
FdctParam(&fdct8, &reference_dct_1d, 8, 1),
FdctParam(&fdct16, &reference_dct_1d, 16, 2)));
} // namespace

View File

@@ -1,321 +0,0 @@
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp10_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "vp10/common/blockd.h"
#include "vp10/common/scan.h"
#include "vpx/vpx_integer.h"
#include "vp10/common/vp10_inv_txfm.h"
using libvpx_test::ACMRandom;
namespace {
const double PI = 3.141592653589793238462643383279502884;
const double kInvSqrt2 = 0.707106781186547524400844362104;
void reference_idct_1d(const double *in, double *out, int size) {
for (int n = 0; n < size; ++n) {
out[n] = 0;
for (int k = 0; k < size; ++k) {
if (k == 0)
out[n] += kInvSqrt2 * in[k] * cos(PI * (2 * n + 1) * k / (2 * size));
else
out[n] += in[k] * cos(PI * (2 * n + 1) * k / (2 * size));
}
}
}
typedef void (*IdctFuncRef)(const double *in, double *out, int size);
typedef void (*IdctFunc)(const tran_low_t *in, tran_low_t *out);
class TransTestBase {
public:
virtual ~TransTestBase() {}
protected:
void RunInvAccuracyCheck() {
tran_low_t *input = new tran_low_t[txfm_size_];
tran_low_t *output = new tran_low_t[txfm_size_];
double *ref_input = new double[txfm_size_];
double *ref_output = new double[txfm_size_];
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 5000;
for (int ti = 0; ti < count_test_block; ++ti) {
for (int ni = 0; ni < txfm_size_; ++ni) {
input[ni] = rnd.Rand8() - rnd.Rand8();
ref_input[ni] = static_cast<double>(input[ni]);
}
fwd_txfm_(input, output);
fwd_txfm_ref_(ref_input, ref_output, txfm_size_);
for (int ni = 0; ni < txfm_size_; ++ni) {
EXPECT_LE(
abs(output[ni] - static_cast<tran_low_t>(round(ref_output[ni]))),
max_error_);
}
}
delete[] input;
delete[] output;
delete[] ref_input;
delete[] ref_output;
}
double max_error_;
int txfm_size_;
IdctFunc fwd_txfm_;
IdctFuncRef fwd_txfm_ref_;
};
typedef std::tr1::tuple<IdctFunc, IdctFuncRef, int, int> IdctParam;
class Vp10InvTxfm
: public TransTestBase,
public ::testing::TestWithParam<IdctParam> {
public:
virtual void SetUp() {
fwd_txfm_ = GET_PARAM(0);
fwd_txfm_ref_ = GET_PARAM(1);
txfm_size_ = GET_PARAM(2);
max_error_ = GET_PARAM(3);
}
virtual void TearDown() {}
};
TEST_P(Vp10InvTxfm, RunInvAccuracyCheck) {
RunInvAccuracyCheck();
}
INSTANTIATE_TEST_CASE_P(
C, Vp10InvTxfm,
::testing::Values(
IdctParam(&vp10_idct4_c, &reference_idct_1d, 4, 1),
IdctParam(&vp10_idct8_c, &reference_idct_1d, 8, 2),
IdctParam(&vp10_idct16_c, &reference_idct_1d, 16, 4),
IdctParam(&vp10_idct32_c, &reference_idct_1d, 32, 6))
);
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<FwdTxfmFunc,
InvTxfmFunc,
InvTxfmFunc,
TX_SIZE, int> PartialInvTxfmParam;
const int kMaxNumCoeffs = 1024;
class Vp10PartialIDctTest
: public ::testing::TestWithParam<PartialInvTxfmParam> {
public:
virtual ~Vp10PartialIDctTest() {}
virtual void SetUp() {
ftxfm_ = GET_PARAM(0);
full_itxfm_ = GET_PARAM(1);
partial_itxfm_ = GET_PARAM(2);
tx_size_ = GET_PARAM(3);
last_nonzero_ = GET_PARAM(4);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
int last_nonzero_;
TX_SIZE tx_size_;
FwdTxfmFunc ftxfm_;
InvTxfmFunc full_itxfm_;
InvTxfmFunc partial_itxfm_;
};
TEST_P(Vp10PartialIDctTest, RunQuantCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int size;
switch (tx_size_) {
case TX_4X4:
size = 4;
break;
case TX_8X8:
size = 8;
break;
case TX_16X16:
size = 16;
break;
case TX_32X32:
size = 32;
break;
default:
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
const int count_test_block = 1000;
const int block_size = size * size;
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
int max_error = 0;
for (int i = 0; i < count_test_block; ++i) {
// clear out destination buffer
memset(dst1, 0, sizeof(*dst1) * block_size);
memset(dst2, 0, sizeof(*dst2) * block_size);
memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
ACMRandom rnd(ACMRandom::DeterministicSeed());
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-255, 255].
if (i == 0) {
for (int j = 0; j < block_size; ++j)
input_extreme_block[j] = 255;
} else if (i == 1) {
for (int j = 0; j < block_size; ++j)
input_extreme_block[j] = -255;
} else {
for (int j = 0; j < block_size; ++j) {
input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
}
}
ftxfm_(input_extreme_block, output_ref_block, size);
// quantization with maximum allowed step sizes
test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
for (int j = 1; j < last_nonzero_; ++j)
test_coef_block1[vp10_default_scan_orders[tx_size_].scan[j]]
= (output_ref_block[j] / 1828) * 1828;
}
ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));
for (int j = 0; j < block_size; ++j) {
const int diff = dst1[j] - dst2[j];
const int error = diff * diff;
if (max_error < error)
max_error = error;
}
}
EXPECT_EQ(0, max_error)
<< "Error: partial inverse transform produces different results";
}
TEST_P(Vp10PartialIDctTest, ResultsMatch) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int size;
switch (tx_size_) {
case TX_4X4:
size = 4;
break;
case TX_8X8:
size = 8;
break;
case TX_16X16:
size = 16;
break;
case TX_32X32:
size = 32;
break;
default:
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
const int count_test_block = 1000;
const int max_coeff = 32766 / 4;
const int block_size = size * size;
int max_error = 0;
for (int i = 0; i < count_test_block; ++i) {
// clear out destination buffer
memset(dst1, 0, sizeof(*dst1) * block_size);
memset(dst2, 0, sizeof(*dst2) * block_size);
memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
int max_energy_leftover = max_coeff * max_coeff;
for (int j = 0; j < last_nonzero_; ++j) {
int16_t coef = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
(rnd.Rand16() - 32768) / 65536);
max_energy_leftover -= coef * coef;
if (max_energy_leftover < 0) {
max_energy_leftover = 0;
coef = 0;
}
test_coef_block1[vp10_default_scan_orders[tx_size_].scan[j]] = coef;
}
memcpy(test_coef_block2, test_coef_block1,
sizeof(*test_coef_block2) * block_size);
ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));
for (int j = 0; j < block_size; ++j) {
const int diff = dst1[j] - dst2[j];
const int error = diff * diff;
if (max_error < error)
max_error = error;
}
}
EXPECT_EQ(0, max_error)
<< "Error: partial inverse transform produces different results";
}
using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, Vp10PartialIDctTest,
::testing::Values(
make_tuple(&vpx_fdct32x32_c,
&vp10_idct32x32_1024_add_c,
&vp10_idct32x32_34_add_c,
TX_32X32, 34),
make_tuple(&vpx_fdct32x32_c,
&vp10_idct32x32_1024_add_c,
&vp10_idct32x32_1_add_c,
TX_32X32, 1),
make_tuple(&vpx_fdct16x16_c,
&vp10_idct16x16_256_add_c,
&vp10_idct16x16_10_add_c,
TX_16X16, 10),
make_tuple(&vpx_fdct16x16_c,
&vp10_idct16x16_256_add_c,
&vp10_idct16x16_1_add_c,
TX_16X16, 1),
make_tuple(&vpx_fdct8x8_c,
&vp10_idct8x8_64_add_c,
&vp10_idct8x8_12_add_c,
TX_8X8, 12),
make_tuple(&vpx_fdct8x8_c,
&vp10_idct8x8_64_add_c,
&vp10_idct8x8_1_add_c,
TX_8X8, 1),
make_tuple(&vpx_fdct4x4_c,
&vp10_idct4x4_16_add_c,
&vp10_idct4x4_1_add_c,
TX_4X4, 1)));
} // namespace

View File

@@ -16,13 +16,13 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h" #include "test/acm_random.h"
#include "vp8/decoder/dboolhuff.h" #include "third_party/googletest/src/include/gtest/gtest.h"
#include "vp8/encoder/boolhuff.h"
#include "vpx/vpx_integer.h" #include "vpx/vpx_integer.h"
#include "vp8/encoder/boolhuff.h"
#include "vp8/decoder/dboolhuff.h"
namespace { namespace {
const int num_tests = 10; const int num_tests = 10;

View File

@@ -28,18 +28,19 @@ using libvpx_test::ACMRandom;
namespace { namespace {
const int kNumPixels = 16 * 16; const int kNumPixels = 16 * 16;
class VP8DenoiserTest : public ::testing::TestWithParam<int> { class VP8DenoiserTest
: public ::testing::TestWithParam<int> {
public: public:
virtual ~VP8DenoiserTest() {} virtual ~VP8DenoiserTest() {}
virtual void SetUp() { virtual void SetUp() {
increase_denoising_ = GetParam(); increase_denoising = GetParam();
} }
virtual void TearDown() { libvpx_test::ClearSystemState(); } virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected: protected:
int increase_denoising_; int increase_denoising;
}; };
TEST_P(VP8DenoiserTest, BitexactCheck) { TEST_P(VP8DenoiserTest, BitexactCheck) {
@@ -52,18 +53,18 @@ TEST_P(VP8DenoiserTest, BitexactCheck) {
// mc_avg_block is the denoised reference block, // mc_avg_block is the denoised reference block,
// avg_block_c is the denoised result from C code, // avg_block_c is the denoised result from C code,
// avg_block_sse2 is the denoised result from SSE2 code. // avg_block_sse2 is the denoised result from SSE2 code.
DECLARE_ALIGNED(16, uint8_t, sig_block_c[kNumPixels]); DECLARE_ALIGNED_ARRAY(16, uint8_t, sig_block_c, kNumPixels);
// Since in VP8 denoiser, the source signal will be changed, // Since in VP8 denoiser, the source signal will be changed,
// we need another copy of the source signal as the input of sse2 code. // we need another copy of the source signal as the input of sse2 code.
DECLARE_ALIGNED(16, uint8_t, sig_block_sse2[kNumPixels]); DECLARE_ALIGNED_ARRAY(16, uint8_t, sig_block_sse2, kNumPixels);
DECLARE_ALIGNED(16, uint8_t, mc_avg_block[kNumPixels]); DECLARE_ALIGNED_ARRAY(16, uint8_t, mc_avg_block, kNumPixels);
DECLARE_ALIGNED(16, uint8_t, avg_block_c[kNumPixels]); DECLARE_ALIGNED_ARRAY(16, uint8_t, avg_block_c, kNumPixels);
DECLARE_ALIGNED(16, uint8_t, avg_block_sse2[kNumPixels]); DECLARE_ALIGNED_ARRAY(16, uint8_t, avg_block_sse2, kNumPixels);
for (int i = 0; i < count_test_block; ++i) { for (int i = 0; i < count_test_block; ++i) {
// Generate random motion magnitude, 20% of which exceed the threshold. // Generate random motion magnitude, 20% of which exceed the threshold.
const int motion_magnitude_ran = uint8_t motion_magnitude_random
rnd.Rand8() % static_cast<int>(MOTION_MAGNITUDE_THRESHOLD * 1.2); = rnd.Rand8() % (uint8_t)(MOTION_MAGNITUDE_THRESHOLD * 1.2);
// Initialize a test block with random number in range [0, 255]. // Initialize a test block with random number in range [0, 255].
for (int j = 0; j < kNumPixels; ++j) { for (int j = 0; j < kNumPixels; ++j) {
@@ -71,20 +72,20 @@ TEST_P(VP8DenoiserTest, BitexactCheck) {
sig_block_sse2[j] = sig_block_c[j] = rnd.Rand8(); sig_block_sse2[j] = sig_block_c[j] = rnd.Rand8();
// The pixels in mc_avg_block are generated by adding a random // The pixels in mc_avg_block are generated by adding a random
// number in range [-19, 19] to corresponding pixels in sig_block. // number in range [-19, 19] to corresponding pixels in sig_block.
temp = sig_block_c[j] + (rnd.Rand8() % 2 == 0 ? -1 : 1) * temp = sig_block_c[j] + (rnd.Rand8() % 2 == 0? -1 : 1) *
(rnd.Rand8() % 20); (rnd.Rand8()%20);
// Clip. // Clip.
mc_avg_block[j] = (temp < 0) ? 0 : ((temp > 255) ? 255 : temp); mc_avg_block[j] = (temp < 0? 0 : (temp > 255? 255 : temp));
} }
// Test denosiser on Y component. // Test denosiser on Y component.
ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_c( ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_c(mc_avg_block, stride,
mc_avg_block, stride, avg_block_c, stride, sig_block_c, stride, avg_block_c, stride, sig_block_c, stride,
motion_magnitude_ran, increase_denoising_)); motion_magnitude_random, increase_denoising));
ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_sse2( ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_sse2(mc_avg_block, stride,
mc_avg_block, stride, avg_block_sse2, stride, sig_block_sse2, stride, avg_block_sse2, stride, sig_block_sse2, stride,
motion_magnitude_ran, increase_denoising_)); motion_magnitude_random, increase_denoising));
// Check bitexactness. // Check bitexactness.
for (int h = 0; h < 16; ++h) { for (int h = 0; h < 16; ++h) {
@@ -93,14 +94,14 @@ TEST_P(VP8DenoiserTest, BitexactCheck) {
} }
} }
// Test denoiser on UV component. // Test denosiser on UV component.
ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_uv_c( ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_uv_c(mc_avg_block, stride,
mc_avg_block, stride, avg_block_c, stride, sig_block_c, stride, avg_block_c, stride, sig_block_c, stride,
motion_magnitude_ran, increase_denoising_)); motion_magnitude_random, increase_denoising));
ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_uv_sse2( ASM_REGISTER_STATE_CHECK(vp8_denoiser_filter_uv_sse2(mc_avg_block, stride,
mc_avg_block, stride, avg_block_sse2, stride, sig_block_sse2, stride, avg_block_sse2, stride, sig_block_sse2, stride,
motion_magnitude_ran, increase_denoising_)); motion_magnitude_random, increase_denoising));
// Check bitexactness. // Check bitexactness.
for (int h = 0; h < 16; ++h) { for (int h = 0; h < 16; ++h) {
@@ -112,5 +113,7 @@ TEST_P(VP8DenoiserTest, BitexactCheck) {
} }
// Test for all block size. // Test for all block size.
INSTANTIATE_TEST_CASE_P(SSE2, VP8DenoiserTest, ::testing::Values(0, 1)); INSTANTIATE_TEST_CASE_P(
SSE2, VP8DenoiserTest,
::testing::Values(0, 1));
} // namespace } // namespace

Some files were not shown because too many files have changed in this diff Show More