Compare commits

..

1732 Commits

Author SHA1 Message Date
Jingning Han
0fe7ee6df5 Merge "Fix sub8x8 motion search on scaled reference frame" into sandbox/jingning@google.com/decoder_test_suite 2015-12-11 20:28:21 +00:00
Jingning Han
35b121b0d8 Merge "Fix high bit depth with scaled reference frame" into sandbox/jingning@google.com/decoder_test_suite 2015-12-11 20:27:56 +00:00
Jingning Han
e50c37ba82 Fix sub8x8 motion search on scaled reference frame
This commit fixes a buffer overflow issue related to sub8x8 motion
search on scaled reference frame.

Change-Id: Iffeebc8787c1ed2b0cb3a7821349e028639d9eb5
2015-12-10 22:26:41 -08:00
Jingning Han
db7312483f Fix high bit depth with scaled reference frame
This commit fixes an encoder issue in high bit depth implementation
that causes enc/dec mismatch in scaled reference frame.

Change-Id: I97655aa213f830d8e2dcd98253c3008abda30eea
2015-12-10 15:47:33 -08:00
hui su
e38e2b8343 Add moving-average bit rate stats
Change-Id: Id764e573776d4d0ee2c400a4eca0832268e1e2b1
2015-11-17 17:58:42 -08:00
Jingning Han
fb27ffbb06 Exercise internal frame resizing
This commit enables the encoder to exercise internal frame resizing
and to use scaled reference frame for sub8x8 block motion compensated
prediction.

Change-Id: I42703da4a4b075c6aefe9a9f687374af65c3c73f
2015-09-08 11:20:39 -07:00
Debargha Mukherjee
29a325f78e Expose params min-gf-interval/max-gf-interval
Adds two new vp9 parameters --min-gf-interval and --max-gf-interval
to enable testing based on frequency of alt-ref frames.

Also adds a unit-test to test enforcement of min-gf-interval.

For both these parameters the default value is 0, which indicates
they are picked by the encoder, based on resolution and framerate
considerations. If they are greater than zero, the specified
parameter is honored.

(Additional note by paulwilkins)
Note that there is a slight oddity in that key frames are also GFs and
considered part of  GF only group. However they are treated as not
being part of an arf group because for arf groups the previous GF is
assumed to be the terminal or overlay frame for the previous group.

(end note)

Change-Id: Ibf0c30b72074b3f71918ab278ccccc02a95a70a0
(cherry picked from commit 9852643373)
2015-09-01 17:50:59 +00:00
Jingning Han
f4e1933c57 Merge "VP9 decoder performance test suite - buffer process" into sandbox/jingning@google.com/decoder_test_suite 2015-08-27 18:31:49 +00:00
Jingning Han
cb8b7d0dc2 VP9 decoder performance test suite - buffer process
This commit hacks the vp9 encoder to produce bit-streams that
exercise maximum reference frame buffers at decoder, as part of
the VP9 decoder performance test suite. It fullfills all the 8
reference frame buffers first and then temporarily suspends the
buffer update. It selects the frames from this static buffer pool
as reference frames for the next a few coding frames. When all
the frames in the reference frame buffer are covered, the codec
resumes the buffer update process. Such pattern repeats every
64 frames.

It verifies the decoder capability to handle up to 8 reference
frames in buffer.

Change-Id: I796701eba53ed19ae73351d23d676311f12c43a1
2015-08-26 15:33:20 -07:00
Jingning Han
1d8526d0cc Merge "Add more coding staticstics tracker" into sandbox/jingning@google.com/decoder_test_suite 2015-07-31 01:35:19 +00:00
Jingning Han
9cec9cb26f Add more coding staticstics tracker
Count the average sub-pixel motion vector, sub8x8 block, intra
prediction mode use case.

Change-Id: Idbccc67a7eb4d2447b02b1fc158fdc8a344c2f21
2015-07-29 10:31:47 -07:00
Jingning Han
006085d4a7 Merge "Set up decoder end coding statistics tracker" into sandbox/jingning@google.com/decoder_test_suite 2015-07-28 00:36:36 +00:00
Jingning Han
b75e4d0f13 Set up decoder end coding statistics tracker
This commit allows the decoder to track the percentage of intra
coding mode and sub pixel filter usage, when it is configured. This
provides a measurable approach to generate the VP9 decoder
performance test suite.

Change-Id: I26d40b991f41b1408de2b206ecb0a322cdb561b8
2015-06-29 12:26:54 -07:00
Jingning Han
c39736a550 Set up decoder end coding statistics tracker
This commit allows the decoder to track the percentage of intra
coding mode and sub pixel filter usage, when it is configured. This
provides a measurable approach to generate the VP9 decoder
performance test suite.

Change-Id: I26d40b991f41b1408de2b206ecb0a322cdb561b8
2015-06-29 10:57:27 -07:00
Parag Salasakar
f3a1295cff Merge "mips msa vp9 temporal filter optimization" 2015-06-27 01:29:04 +00:00
Tom Finegan
8fdfeb3f40 Merge "vpxenc.sh: Add basic multithreaded frame parallel encode test." 2015-06-26 16:12:34 +00:00
Parag Salasakar
b92cc27b76 mips msa vp9 temporal filter optimization
average improvement ~4x-5x

Change-Id: Iad9c0a296dbc2ea96d000bd009077999ed58a3c5
2015-06-26 12:00:24 +05:30
Parag Salasakar
c040f96e4b mips msa vp9 subtract block optimization
average improvement ~3x-4x

Change-Id: Idbe4d13a00d05ff8be6559b116f416e42c3b4097
2015-06-26 09:23:56 +05:30
Parag Salasakar
d017f5ba38 Merge "mips msa vp9 block error optimization" 2015-06-26 03:42:31 +00:00
Parag Salasakar
1543f2b60e mips msa vp9 block error optimization
average improvement ~3x-4x

Change-Id: If0fdcc34b17437a7e3e7fb4caaf1067bc175f291
2015-06-26 09:04:00 +05:30
Tom Finegan
92f7d79030 vpxenc.sh: Add basic multithreaded frame parallel encode test.
Change-Id: Id526783fa2e3e9bb31229931b6548ac7a9b2b7e6
2015-06-25 13:52:04 -07:00
Marco
1c7b1f9aec Update to dynamic resize logic for 1pass CBR.
Only do the check for resizing if the feature is selected
(i.e., resize_mode = RESIZE_DYNAMIC).

And modify condition for checking to be resize_count >= window,
(since framerate can change).

Change-Id: Idceb4e50956bb965a1492b4993b0dcb393c9be4d
2015-06-25 12:28:43 -07:00
James Zern
3393243d5e Merge "vp8_subpixelvariance_neon: right size coeff table" 2015-06-25 02:14:18 +00:00
Marco
3dd9cde2a5 Fix to unstable build from commit 517a66.
Change-Id: I123db2d20ae65a10e2dec95eec61150e2f69546d
2015-06-24 17:28:57 -07:00
James Zern
d219f2b9d2 Merge "vp9_reconintra_neon: add d45 16x16" 2015-06-24 21:23:15 +00:00
Tom Finegan
0bd61519c0 Merge "vpxenc.sh: Add basic vp9 multithread encode test." 2015-06-24 16:36:09 +00:00
James Zern
4bd87a9b9e vp8_subpixelvariance_neon: right size coeff table
only uint8 is required; each use only loads one value as a uint8
quiets a few type conversion warnings

Change-Id: I03dc0dc0eb01ac23a6e8673daa2b77c6c57bf1b0
2015-06-23 23:48:12 -07:00
James Zern
9f0383c66f Merge "build: add *test-no-data-check targets" 2015-06-24 06:20:38 +00:00
Tom Finegan
8281a19465 vpxenc.sh: Add basic vp9 multithread encode test.
- Change default real time speed to -6.
- Add vpxenc_vp9_webm_rt_multithread, which encodes
  niklas_1280_720_30.y4m with 2 to 4 threads using 2 to 4
  tile columns.

Change-Id: I4d86c3360aec67ae5d1ba82eb6e0f0be8068b5af
2015-06-23 18:30:52 -07:00
Marco
4774d38970 Merge "aq-mode=3: Reduce boost for segment#2 at low bitrates/low res." 2015-06-23 23:55:16 +00:00
Marco
517a662005 aq-mode=3: Reduce boost for segment#2 at low bitrates/low res.
Reduce boost for segment#2 for low bitrates and low-res.

This change is to reduce the rate overshoot at low bitrates.
No change in behavior, except at the very low bitrates.

Change-Id: I0dbd9d3b6356da5804de94adf10fca6a7a8f8948
2015-06-23 16:50:43 -07:00
Tom Finegan
46df71396d Merge "Fix building with iOS 9 beta SDK" 2015-06-23 22:57:05 +00:00
James Zern
9db1f24c47 vp9_reconintra_neon: add d45 16x16
~90% faster over 20M pixels

Change-Id: I92d80f66e91e0a870a672cfb5dd29bf1a17cb11a
2015-06-22 21:00:07 -07:00
Parag Salasakar
7555e2b822 mips msa vp9 avg optimization
average improvement ~2x-3x

Change-Id: I76f7fc00c0ffdf2b4ba41bf3819f3b6044bcdeff
2015-06-23 07:32:25 +05:30
Parag Salasakar
7b71cdb0b4 Merge "mips msa vp9 fdct 4x4 optimization" 2015-06-23 01:46:54 +00:00
Marco
fb2a89b1fb Fixes for key frame coding at speed 5.
Keep the same transform cutoff and partition selection
for speed 5 as in speeds >=6 (non-rd speed settings).

Existing setting for key frame at speed 5 allowed transform size
up to 32x32 on key frames, and did not allow for 4x4 block partition size.
This created more visual artifacts on first few frames.

avgPSNR/overallPSNR/SSIM gains of 0.2/0.7/0.8 for rtc_derf(low-res) set,
and 0/0.7/1.1 gains for rtc set.

Change-Id: I8c139ec6c9bb74e14b4ffbad5f12e94f18a59c0b
2015-06-22 16:57:35 -07:00
James Zern
c8b9658ecc Merge "vp9_reconintra_neon: add d45 8x8" 2015-06-22 22:27:57 +00:00
Brion Vibber
78637b6136 Fix building with iOS 9 beta SDK
configure.sh was setting some Mac OS X options for iOS targets, which
confuses the iOS 9 beta SDK in Xcode 7 when linking libraries.

Additionally, old armv6 media extensions were being enabled on iOS
when they're not needed (we always have Neon since iOS 6). These
broke on iOS 9 SDK which no longer assembles those instructions.

Change-Id: I4e4d2722392ead3382ce96289c03ef1e489799d6
2015-06-22 12:09:09 -07:00
Marco
8e029fcfa9 Merge "Reduce max_partition_size for low resolutions at speed 5." 2015-06-22 16:59:48 +00:00
Parag Salasakar
bc94999148 mips msa vp9 fdct 4x4 optimization
average improvement ~2x-3x

Change-Id: Idf8be780b8b4228fc91f110a94e4ee1fd9af0163
2015-06-22 14:30:24 +05:30
Frank Galligan
1395b56a1d Add assembly tests for int projections.
BUG=https://code.google.com/p/webm/issues/detail?id=1022

Change-Id: I5ae4acac39fd75c56d3feff0716cb52133de3b22
2015-06-20 12:05:59 -07:00
Parag Salasakar
b6131a733d Merge "mips msa vp9 fdct 8x8 optimization" 2015-06-20 02:58:10 +00:00
James Zern
12c6688e31 vp9_reconintra_neon: add d45 8x8
based on ssse3 implementation

~91% faster over 20M pixels

Change-Id: I6d743a53352c2d6de0efe7899d7996e8b0f7fa29
2015-06-19 19:19:22 -07:00
Parag Salasakar
7ca84888c2 mips msa vp9 fdct 8x8 optimization
average improvement ~4x-5x

Change-Id: I37582efc2622bc20b2bf99617a76110ab24e9f6a
2015-06-20 07:48:35 +05:30
James Zern
7b480ee90c Merge "Add dynamic range comment to vp9_int_pro_row" 2015-06-20 01:43:54 +00:00
Jingning Han
922af194bc Add dynamic range comment to vp9_int_pro_row
Change-Id: Icaa643568159c4e2db24eef42090b002ae02a45e
2015-06-19 17:39:33 -07:00
Jingning Han
c539ec022f Merge "Add dynamic range comment to vp9_int_pro_col" 2015-06-20 00:35:07 +00:00
James Zern
557ae511cb build: add *test-no-data-check targets
skips testdata verification; useful with slow media or if the data was
retrieved via a separate call to testdata

Change-Id: Ifd97892cee6c04b0111874cc8071675e90ec852b
2015-06-19 16:50:26 -07:00
Marco
debe4e920f Reduce max_partition_size for low resolutions at speed 5.
For speed 5 real-time mode, the selection of the partition size for
superblocks on the segment (aq-mode=3) uses the non-rd recursive
pick partition search, and can sometimes select 64x64.

For low resolutions, visually better to limit this to 32x32.

Change-Id: I69657a7ed8899f8b3cf8c9c318a2509c5c72c565
2015-06-19 16:48:16 -07:00
Alex Converse
90c9ede8e6 Limit cyclic refresh revisitng blocks at the same quantizer.
For screen content don't refresh a block at a quantizer higher than
it was last coded at. PReviosuly at realtime speeds the encoder had a
tendency to recode a block from GOLDEN with a higher Q than it was last
coded at.

Change-Id: Iacd561806c769dcce1a81b9827ffc70090f5ba18
2015-06-19 15:23:02 -07:00
Yaowu Xu
e5d4062962 Merge "Fix a msvc compiler warning" 2015-06-19 19:02:15 +00:00
Jingning Han
8e8bc5f28b Add dynamic range comment to vp9_int_pro_col
Change-Id: If14d9f874bd0bf2c5a455982088fd70591f5ea5a
2015-06-19 09:43:57 -07:00
Johann Koenig
001baa5dd8 Merge "Move vp8 variance files" 2015-06-19 16:27:25 +00:00
Yaowu Xu
d8428ae35d Fix a msvc compiler warning
Change-Id: Ida8a04370895ed14bd118324ec2577da926e4648
2015-06-19 09:04:29 -07:00
James Zern
714a46a63c Merge "vp9_filter: make all filter tables static" 2015-06-19 03:32:24 +00:00
James Zern
c5d779d266 Merge changes I2552d810,I51952c0a,Ib82e4247,I9c8d16cb
* changes:
  vp9_mcomp: make search_step_table static
  vp9_encodeframe: delete auto_partition_range()
  vp9_mcomp: don't mark setup_center_error() inline
  vp9_encoder: hide adjust_image_stat()
2015-06-19 03:31:38 +00:00
James Zern
a2c69af50e Merge "vp9_reconintra_neon: add d45 4x4" 2015-06-19 03:27:23 +00:00
James Zern
5d1d72df16 Merge changes from topic 'vp9-intra-pred'
* changes:
  vp9_reconintra_neon: add d135 4x4
  vp9_reconintra: correct d135 4x4 signature
2015-06-19 03:24:58 +00:00
Marco
4b45088fc9 Merge "Add dynamic resize logic for 1 pass CBR." 2015-06-19 00:56:06 +00:00
Marco
d77f51ba9e Add dynamic resize logic for 1 pass CBR.
Decision to scale down/up is based on buffer state and average QP
over previous time window. Limit the total amount of down-scaling
to be at most one scale down for now.

Reset certain quantities after resize (buffer level, cyclic refresh,
rate correction factor).

Feature is enable via the setting rc_resize_allowed = 1.

Change-Id: I9b1a53024e1e1e953fb8a1e1f75d21d160280dc7
2015-06-18 17:13:37 -07:00
Johann
907b33cdc4 Move vp8 variance files
There is a naming conflict in the chromium build system.

The rest of the variance functions will move to vpx_dsp soon.

Change-Id: Iff78da2aafb0d7380eda73e38d7dac72110a1e47
2015-06-18 16:42:28 -07:00
James Zern
ce88d74d34 vp9_reconintra_neon: add d45 4x4
based on webp's LD4()

~59% faster over 20M pixels

Change-Id: I371eaed9ce8f470451046997e130b0ba1a2f7a9c
2015-06-18 15:25:07 -07:00
James Zern
337b221e00 vp9_reconintra_neon: add d135 4x4
based on webp's RD4()

~50% faster over 20M pixels

Change-Id: Ifcb7bf7f7fc8eabf79d9e3b219ce1be67abc524a
2015-06-18 15:25:06 -07:00
James Zern
e8e3583fc7 vp9_reconintra: correct d135 4x4 signature
add missing '_c' suffix

Change-Id: I928d6cf8f90db0b8ca0b1f3bbf10b3d792062cec
2015-06-18 15:25:06 -07:00
James Zern
41d8545ab6 Merge "vp9_reconintra_neon: add DC 4x4 predictors" 2015-06-18 22:24:55 +00:00
James Zern
6e44bf20f7 vp9_reconintra_neon: add DC 4x4 predictors
~85-89% faster over 20M pixels

Change-Id: I3812e8adfffe5255034da88dfe6546e12f4d10ee
2015-06-18 15:22:43 -07:00
James Zern
e77f859d72 Merge "vp9_reconintra_neon: add DC 32x32 predictors" 2015-06-18 22:17:51 +00:00
Jingning Han
d1398e9f13 Merge "Add dynamic range comment to vp9_satd" 2015-06-18 19:36:53 +00:00
Jingning Han
4f1f510f16 Add dynamic range comment to vp9_satd
Change-Id: I75873846e6fdafbe7597a1bd0192115d2d1e9987
2015-06-18 09:18:22 -07:00
Parag Salasakar
b6ea0c4c57 Merge "mips msa vp9 fdct 32x32 optimization" 2015-06-18 04:30:53 +00:00
Jingning Han
7f6cddb58f Take out assertion for block_yrd in rtc coding flow
The internal behavior of block_yrd differs in high bit depth
settings from 8-bit one. This causes the assertion condition not
true for high bit depth.

Change-Id: I15dc02e7162d27cabe78c451941d769d488b1174
2015-06-17 08:51:16 -07:00
James Zern
0d51a97ae9 Merge "Fix integer overflow issue in rtc coding flow intra mode search" 2015-06-17 05:29:32 +00:00
Jingning Han
bc7074508a Fix integer overflow issue in rtc coding flow intra mode search
The overflow issue affects a variable that is only used in inter
mode. This commit fixes the ioc warning triggered in the intra
mode. It does not affect the compression performance.

Change-Id: I593d1b5650599de07f3e68176dd1442c6cb7bdbc
2015-06-16 19:31:24 -07:00
Parag Salasakar
d9fedf7832 mips msa vp9 fdct 32x32 optimization
average improvement ~4x-6x

Change-Id: Ibcac3ef8ed5e207cf8c121e696570e6b63d3c0f4
2015-06-17 07:58:34 +05:30
Parag Salasakar
fa53008fb7 Merge "mips msa vp9 fdct 16x16 optimization" 2015-06-17 01:21:59 +00:00
Scott LaVarnway
97b3913dcc Merge "Moved has_rows, has_cols in vp9_decodeframe.c" 2015-06-16 22:01:06 +00:00
Scott LaVarnway
ce6a6c5411 Moved has_rows, has_cols in vp9_decodeframe.c
from read_partition() to decode_partition().

Change-Id: I6bee2a0e9ff315290a690c9d773c9648dd2a200d
2015-06-16 11:50:54 -07:00
Marco
8914ab696d Remove duplicate calls for set_frame_size in 1 pass mode.
set_frame_size() is being called twice, once before entering
encode_encode_frame_to_data_rate(), and once again in that function.
No need to call it twice for one-pass mode.

Change-Id: I5fabaf0a90482d4f42cd89ef7ae1402c31aec600
2015-06-16 09:57:13 -07:00
Scott LaVarnway
5fe0e55ca4 Merge "Eliminated frame_type check in get_partition_probs()" 2015-06-16 13:40:23 +00:00
Scott LaVarnway
b2658ec321 Eliminated frame_type check in get_partition_probs()
Moved the frame_type check to the tile level and stored
the prob ptr in MACROBLOCKD.

Change-Id: I10b5a4abd58213dc7610e3ade1a1583c01526842
2015-06-16 05:37:54 -07:00
Scott LaVarnway
a41fe749a8 Merge "Update use_prev_frame_mvs flag in decoder." 2015-06-16 12:28:46 +00:00
Parag Salasakar
89b4b315aa mips msa vp9 fdct 16x16 optimization
average improvement ~4x-6x

Change-Id: Id3b2243e5b3c7844c90c4231a5e75fa69911362c
2015-06-16 12:49:34 +05:30
James Zern
79fb3a013e vp9_reconintra_neon: add DC 32x32 predictors
~84-85% faster over 20M pixels

Change-Id: Ia67a7f4a342bf7b0a9280e05c25d81a774d90469
2015-06-15 20:57:28 -07:00
Yunqing Wang
e820ca6973 Merge "vp9_ethread: create enough threads while using SVC" 2015-06-15 23:03:32 +00:00
James Zern
a6d126709a Merge changes I19588f9e,I6dc338a6
* changes:
  vp9_encodeframe: make coord_lookup[] static
  vp9_resize: make vp9_filteredinterp_*[] static
2015-06-15 23:03:28 +00:00
James Zern
17c9678a3c Merge "vp9_entropy: delete vp9_coefmodel_tree[]" 2015-06-15 23:02:42 +00:00
James Zern
e8d3491ec2 Merge "vp9_entropymode: make vp9_init_mode_probs private" 2015-06-15 23:02:36 +00:00
James Zern
43d49e4710 Merge "enable vp9_d153_predictor_32x32_ssse3" 2015-06-15 23:01:29 +00:00
Yunqing Wang
c98273c9e7 vp9_ethread: create enough threads while using SVC
This patch modified the thread creating code. When use_svc is true,
the number of threads created is decided by the highest resolution.
This resolved WebM issue 1018.

Change-Id: I367227b14d1f8b08bbdad3635b232a3a37bbba26
2015-06-15 14:30:54 -07:00
Marco
24b3ede251 Remove redundant second declaration in svc_layercontext.c
Change-Id: Ia3b1c1db54204fd92a56b7f698a9f26d27ee572a
2015-06-15 14:06:43 -07:00
James Zern
98f0178611 enable vp9_d153_predictor_32x32_ssse3
unused since its initial commit
~91% faster over 20M pixels

Change-Id: Ic8b5b3246bc97c8406be8bc4496601370403b70a
2015-06-12 19:48:22 -07:00
James Zern
5214bd52c8 vp9_encodeframe: make coord_lookup[] static
Change-Id: I19588f9e674c8635b6e58e4633120be736d256a6
2015-06-12 19:47:46 -07:00
James Zern
5168baea10 vp9_resize: make vp9_filteredinterp_*[] static
+ drop the vp9_ prefix

Change-Id: I6dc338a69265dcaa8c6fe071e5757312bf92efca
2015-06-12 19:47:45 -07:00
James Zern
ef75416ab7 vp9_entropy: delete vp9_coefmodel_tree[]
it's been unused since:
4ac6a25 Moving vp9_tree_probs_from_distribution() to encoder.

Change-Id: Ieae65864277fc3dbe993c5c08d75c6c5fcaa3a2d
2015-06-12 18:43:37 -07:00
James Zern
53b7f33f2d vp9_entropymode: make vp9_init_mode_probs private
rename to init_mode_probs

Change-Id: Id451d7763b784ed37e43f2c35073a778078d3d0f
2015-06-12 18:25:23 -07:00
James Zern
aaa49f0485 vp9_mcomp: make search_step_table static
Change-Id: I2552d8101cf49ed951782ab69adce407579700fc
2015-06-12 18:11:54 -07:00
James Zern
31509af247 vp9_encodeframe: delete auto_partition_range()
unused since:
1f00a9b Fix choose_partitioning threshold setup for speed -5

Change-Id: I51952c0a1be3e6e0aa36ff2ffcfbbea60a505960
2015-06-12 17:57:37 -07:00
James Zern
7ea431df98 vp9_mcomp: don't mark setup_center_error() inline
this function is a bit too involved for the hint; avoids a -Winline
warning

Change-Id: Ib82e424764aa78b37ddb94116e2b009a6de31d35
2015-06-12 17:56:33 -07:00
James Zern
471302a07b vp9_encoder: hide adjust_image_stat()
this function is only needed with CONFIG_INTERNAL_STATS

Change-Id: I9c8d16cb9069dd8370f8b30329933c0d97f6d0aa
2015-06-12 17:55:08 -07:00
James Zern
a4bb5f2a29 Merge "decode_tiles_mt: remove incorrect TODO" 2015-06-12 22:13:38 +00:00
James Zern
dc0f0f1cf2 Merge changes I342075eb,I222eaa4e
* changes:
  vp9_decodeframe: simplify init_read_bit_buffer signature
  vp9_decode_frame: remove explicit read_bit_buffer init
2015-06-12 22:13:28 +00:00
James Zern
e21c1eab9d Merge changes Iedb5b6a3,Iaea98508,I36580cea,Ia0574320
* changes:
  vp9_decodeframe.h: remove unused prototype
  vp9_decodeframe: move public funcs to end of file
  vp9_decodeframe: reorder some functions
  vp9_decodeframe: hide vp9_dec_build_inter_predictors_sb
2015-06-12 22:12:30 +00:00
James Zern
44317a511b Merge "variance_test: fix build w/--disable-vp8-encoder" 2015-06-12 22:08:33 +00:00
Jingning Han
d8985f5360 Merge "Fix potential overflow issue in hadamard_16x16()" 2015-06-12 19:03:21 +00:00
Jingning Han
bea691b5c9 Merge "Add dynamic range comment to hadamard_8x8()" 2015-06-12 18:43:41 +00:00
Parag Salasakar
ecbbef6b67 Merge "mips msa vp9 filter by weight optimization" 2015-06-12 18:30:11 +00:00
Jingning Han
176c291d9c Fix potential overflow issue in hadamard_16x16()
This commit fixes a potential integer overflow issue in function
hadamard_16x16. It adds corresponding dynamic range comment.

Change-Id: Iec22f3be345fb920ec79178e016378e2f65b20be
2015-06-12 10:56:18 -07:00
Jingning Han
4f52d49f1e Add dynamic range comment to hadamard_8x8()
Add comment to assist SIMD optimization.

Change-Id: I300d5a848e6e9947e451de2a871a88940703fc9f
2015-06-12 10:39:49 -07:00
Yunqing Wang
254a4c033c Merge "Allocate tile data adaptively to accommodate the frame size increase" 2015-06-12 15:49:40 +00:00
Parag Salasakar
fbac961b47 mips msa vp9 filter by weight optimization
filter by weight - average improvement ~2x-3x

Change-Id: I4832033335d339cdafdce697f07ce3e643920057
2015-06-12 12:06:42 +05:30
James Zern
07799ef28a Merge "test_intra_pred_speed: add ClearSystemState() call" 2015-06-12 06:27:45 +00:00
James Zern
e0e4045db8 variance_test: fix build w/--disable-vp8-encoder
s/CONFIG_VP8\b/CONFIG_VP8_ENCODER/

Change-Id: I616aace9cf8f18d7e83f00f7aef3b8a26fc4c17b
2015-06-11 23:15:30 -07:00
James Zern
e2b52f6f01 vp9_filter: make all filter tables static
these are returned via vp9_get_interp_kernel()

Change-Id: I45ed75e5b1515c4f5be9212759dcb50a456b5548
2015-06-11 15:15:52 -07:00
James Zern
33b3953c54 vp9_filter: restore vp9_bilinear_filters alignment
the declaration containing the alignment in vp9_filter.h was removed in:
eb88b17 Make vp9 subpixel match vp8

fixes a crash in 32-bit builds

Change-Id: I9a97e6b4e8e94698e43ff79d0d8bb85043b73c61
2015-06-11 15:15:25 -07:00
Scott LaVarnway
0fbc277746 Merge "inline vp9_get_segdata()" 2015-06-11 19:48:19 +00:00
Yunqing Wang
2c838ede68 Allocate tile data adaptively to accommodate the frame size increase
If the frame size increases, the tile data buffer needs to be
re-allocated according to the number of tiles existing in current
frame. This patch makes the multi-tile encoding work in spatial
SVC usage case, and partially solved WebM issue 1018.

Change-Id: I1ad6f33058cf5ce6f60ed5024455a709ca80c5ad
2015-06-11 11:30:18 -07:00
Scott LaVarnway
cca866f578 inline vp9_get_segdata()
and change name.

Change-Id: I706645cf9d9dc04f1b3b6ac80df80edb7f101854
2015-06-11 09:52:00 -07:00
Marco
2aa67ce20f Move adjustment of some CR parameters to existing function.
Refactor/no change in behavior.

Change-Id: Idb3c55b1304feaf689b90403f79bc96dba26f060
2015-06-11 08:31:03 -07:00
Scott LaVarnway
a49c701529 Merge "inline vp9_segfeature_active()" 2015-06-11 12:29:45 +00:00
Scott LaVarnway
42c0b1b1f1 inline vp9_segfeature_active()
and changed name.

Change-Id: Ie023ca66cc2c823032f58d4faeb53fd1863c94f3
2015-06-11 04:20:55 -07:00
Parag Salasakar
c7489f4815 Merge "mips msa vp9 intra-pred optimization" 2015-06-11 03:31:49 +00:00
James Zern
15c839f563 decode_tiles_mt: remove incorrect TODO
all allocated workers are used, the final one in the main thread.

Change-Id: I04647d4fb2e01d6d404790e7899515289047f553
2015-06-10 15:56:51 -07:00
James Zern
b105414118 vp9_decodeframe: simplify init_read_bit_buffer signature
Change-Id: I342075eb5a4ba2a85d36d47ae52d1f3476039e31
2015-06-10 15:53:30 -07:00
James Zern
92146eb8ac vp9_decode_frame: remove explicit read_bit_buffer init
this is done by init_read_bit_buffer()

Change-Id: I222eaa4e9758ff9f7e1e4122106c5c4652ffa99c
2015-06-10 15:50:54 -07:00
James Zern
dca319040c vp9_decodeframe.h: remove unused prototype
vp9_init_dequantizer() was deleted in:
bdd249b Optimize the dequantization process on decoder side.

Change-Id: Iedb5b6a3a03964dd6901c1e3b2325194d94bc708
2015-06-10 15:48:59 -07:00
James Zern
b0bafd0439 vp9_decodeframe: move public funcs to end of file
Change-Id: Iaea9850890b726c7b5552c5f02b3a309086edc85
2015-06-10 15:47:57 -07:00
James Zern
38dd0448cd vp9_decodeframe: reorder some functions
removes the need for a prototype for the static function
dec_build_inter_predictors_sb

Change-Id: I36580ceae061d27f341ab0a16ece479f92e98004
2015-06-10 15:44:21 -07:00
James Zern
587bd3669e vp9_decodeframe: hide vp9_dec_build_inter_predictors_sb
+ strip 'vp9_' prefix

Change-Id: Ia057432095e5741473275d4da03ab665c37e924e
2015-06-10 15:31:55 -07:00
James Zern
1898d1336d test_intra_pred_speed: add ClearSystemState() call
fixes instability; noticed on mingw

Change-Id: Idef4349339444ec84916e5fcd908ee9633d28aaa
2015-06-10 12:44:07 -07:00
James Zern
44afbbb72d Merge "vp9_reconintra/d45_predictor: remove temp storage" 2015-06-10 19:23:57 +00:00
James Zern
c620c632c1 Merge "test/android/Android.mk: fix build w/ENABLE_SHARED=0" 2015-06-10 19:22:42 +00:00
James Zern
4ded624ff3 Merge changes I89a8440f,Ifa3926e1
* changes:
  libs.mk: relocate TEST_INTRA_PRED_SPEED_OBJS init
  test_intra_pred_speed: remove #if w/in another macro
2015-06-10 19:18:04 +00:00
Paul Wilkins
59114915bc Merge "Changes to active maxq calculation in two pass." 2015-06-10 13:33:53 +00:00
Scott LaVarnway
97880c3324 Merge "Reducing size of MODE_INFO struct" 2015-06-10 13:15:19 +00:00
James Zern
39d93f3891 libs.mk: relocate TEST_INTRA_PRED_SPEED_OBJS init
allows the visual studio project to be generated

Change-Id: I89a8440fb0bcaef11ff89dd967aa37bfe200758d
2015-06-09 19:30:46 -07:00
James Zern
6a422e4452 test_intra_pred_speed: remove #if w/in another macro
fixes the compile under visual studio

Change-Id: Ifa3926e198af97d73250540c6d0ef692f5e354ff
2015-06-09 19:30:04 -07:00
James Zern
0f8ee6eb4b test/android/Android.mk: fix build w/ENABLE_SHARED=0
add a dependency on *_rtcd.h to ensure they're generated before
attempting to build the test files

Change-Id: Ibbbd1f6ea77912bfd297129e7c83b9a80923ea12
2015-06-09 19:27:20 -07:00
Marco
61c5c96ae1 Merge "Adjust some parameters for cyclic refresh for low bitrates." 2015-06-09 23:22:29 +00:00
Marco
997ac14c6a Adjust some parameters for cyclic refresh for low bitrates.
Reduce motion threshold and boost factor for second segment,
for low bitrates, at low resolutions for now.
This is to reduce the rate fluctuation/frame dropping that occurs
at these low bitrates.

Change-Id: Ia66c3be41831882fca8c1e4fe104f5ea8fbe7142
2015-06-09 15:10:03 -07:00
Debargha Mukherjee
2fd31bbba7 Merge "Prevent dividing by 0 when target-bitrate is 0." 2015-06-09 17:03:22 +00:00
Paul Wilkins
faf8c63b0f Changes to active maxq calculation in two pass.
Some initial experiments into discounting dead zone
formating bars and intra skip blocks (common in some
types of animation and graphics) in the calculation of
the active max Q for each ARF/GF group.

TODO: check for vertical formating bars and validate the
horizontal bar at the bottom edge of the image.

As expected, this change as it stands, does not make much
difference for the natural videos in the std-hd and derf sets.
However, for the yt and yt hd set there is a significant rise
in the average PSNR with overall PSNR and SSIM remaining
neutral.

The mean rise for the YT-HD test set was > 6%. This is mainly
because the change allows Q to drop further on titles and
other graphics sections where spending a small number of
extra bits gives a sharp rise in PSNR.

Change-Id: I3f878ae91fc1854312d7ecf9fa792c17bc1aa6b7
2015-06-09 15:31:24 +01:00
Paul Wilkins
4a28da5843 Enable more split modes for animated content.
For content that is identified as likely to contain some
animation or graphics content, increase the availability
of split modes for good quality speeds 1-3.

On a problem test animation clip this improves metrics
results by about 0.25 db and makes a noticeable difference
visually. It also causes a small drop in file size (~0.5%) but
a rise in encode time of about 5-6% at speed  2.

For more normal content it should have no effect.

Change-Id: Ic4cd9a8de065af9f9402f4477a17442aebf0e439
2015-06-09 14:50:44 +01:00
Debargha Mukherjee
c23a9e218c Prevent dividing by 0 when target-bitrate is 0.
Change-Id: I05b7fb378b6b0c5f263e7839f96ba6830ee34fd2
2015-06-08 16:19:13 -07:00
Paul Wilkins
b19b16cfa1 Merge "Animation and dead zone detection." 2015-06-08 14:26:07 +00:00
Scott LaVarnway
c9976b32b4 Update use_prev_frame_mvs flag in decoder.
Added check to see if last frame was all intra.  This will
eliminate two checks in find_mv_refs_idx().  Also, do not
update the frame mvs if the current frame is all intra.

This improved performance on material with frequent
intra-only frames.

Change-Id: I44a4042c3670ab0d38439d565062a0e2a1ba9d1e
2015-06-08 03:38:13 -07:00
Parag Salasakar
a2288d274c mips msa vp9 intra-pred optimization
intra pred - average improvement ~2x-3x

Change-Id: Ie3f7d6eded5ecb7ed7ee506ba8e4d98f93803b09
2015-06-06 22:29:32 +05:30
James Zern
e67d45d4ce Merge "vpxdec: cosmetics: break some long lines" 2015-06-06 16:11:00 +00:00
James Zern
913ddbf747 Merge "vpxenc: relocate vp8/vp9 only options" 2015-06-06 16:10:18 +00:00
James Zern
ad8e6f2ed6 Merge "disable vp8_sub_pixel_variance8x8_neon" 2015-06-06 16:07:58 +00:00
James Zern
a3938266f5 Merge "vs/armv7: use -oldit armasm flag" 2015-06-06 03:24:35 +00:00
James Zern
47fe535422 disable vp8_sub_pixel_variance8x8_neon
fails unit tests:
[  FAILED  ] NEON/VP8SubpelVarianceTest.ExtremeRef/0, where GetParam() = (3, 3, 0x14e36d, 0)
[  FAILED  ] NEON/VP8SubpelVarianceTest.Ref/0, where GetParam() = (3, 3, 0x14e36d, 0)

the tests were recently enabled in:
eb88b17 Make vp9 subpixel match vp8

the functions likely haven't changed since being converted from assembly

Change-Id: I6141717b111b8f735f436c160d74270af53ef722
2015-06-05 20:18:51 -07:00
James Zern
3a070ba502 vpxdec: cosmetics: break some long lines
Change-Id: I95827a6f5e585d2accbb8fc09501f2d38db585e4
2015-06-05 16:18:49 -07:00
James Zern
f82cfc2ee8 vpxenc: relocate vp8/vp9 only options
move them under their respective config check to avoid some unused
variable warnings when disabled

Change-Id: Ic5e5280cf1bc1f56e8349676f0bedae4acef34ea
2015-06-05 16:14:14 -07:00
hkuang
87c21a95ae Optimize the decode_partition. About 0.7% gain on N10.
Change-Id: Ia689c254bd2d4f274abcc451a9b758f62e3a2b1f
2015-06-05 15:47:09 -07:00
James Zern
5908e0b664 vs/armv7: use -oldit armasm flag
this quiets warnings from armv6 code [1].
from msdn [2]:
-oldit
Generate ARMv7-style IT blocks. By default, ARMv8-compatible IT blocks
are generated.

a new configuration would be needed for armv8 in any case as the neon
assembly is being built, so removing this should be harmless

[1] A4509: This form of conditional instruction is deprecated
[2] https://msdn.microsoft.com/en-us/library/hh873189.aspx

Change-Id: I4c3b838b52a87401c6daecd83d22ab148ed7c5d9
2015-06-05 15:21:10 -07:00
James Zern
9c6eea35b6 Merge "vp9_reconintra: simplify d63_predictor" 2015-06-05 21:49:13 +00:00
Scott LaVarnway
5831a7127e Merge "BUG FIX: Remove counts param" 2015-06-05 20:04:26 +00:00
Scott LaVarnway
63819c033c BUG FIX: Remove counts param
member access within null pointer of type 'FRAME_COUNTS'

Change-Id: Id3bf75e0a6f2a1abf8522cf9fbb98b3a4443de38
2015-06-05 11:54:04 -07:00
Frank Galligan
8c854769fc Merge "Add control to skip loop filter in VP9 decoder." 2015-06-05 18:03:51 +00:00
Frank Galligan
44138d7d9e Merge "vpxenc: Add support for pixel aspect ratio." 2015-06-05 18:01:52 +00:00
Frank Galligan
bfb6d48812 Add control to skip loop filter in VP9 decoder.
This control allows the application to skip the loop filter in the
decoder. This is an advanced control that should only be used in
extreme circumstances as it may introduce and accumulate decode
artifacts.

Change-Id: I278c65c60826f84c9141ebe06c6eeed3c2335fa8
2015-06-05 10:07:09 -07:00
Frank Galligan
09acd267bc vpxenc: Add support for pixel aspect ratio.
WebM files will adjust the display width and height according to the
input pixel aspect ratio. The default pixel aspect ratio is 1:1.

BUG=https://code.google.com/p/webm/issues/detail?id=1005

Change-Id: I23e0a601b7259fa9513cb86110c41b8437769808
2015-06-05 09:56:50 -07:00
Johann
a4dad3e961 Merge "Duplicate reference variance code" 2015-06-05 16:54:33 +00:00
Marco
8710cceb45 Fix to spatial svc: set reference_frame masking.
For real-time mode: keep reference_frame masking off
for spatial svc.

Change-Id: I15e123c06f67ea040172b8d4042a672f3525b9d8
2015-06-05 08:25:33 -07:00
Parag Salasakar
78b434e8b1 Merge "mips msa vp9 loopfilter 4, 8 optimization" 2015-06-05 05:32:18 +00:00
Parag Salasakar
d43fd99822 mips msa vp9 loopfilter 4, 8 optimization
average improvement ~3x-4x

Change-Id: I59279293ce4b2a1e99bd10579ac97740e943643f
2015-06-05 09:56:08 +05:30
Marco
0d0db3e8c3 Merge "Bugfx in setting layer framerate." 2015-06-05 04:26:06 +00:00
James Zern
60d0b3364c vp9_reconintra/d45_predictor: remove temp storage
dst row 0 can be reused in the same way

Change-Id: Id977da62545dcc4a89cebbcbad90ba84f8ff5d6b
2015-06-04 20:11:53 -07:00
James Zern
7012ba6395 vp9_reconintra: simplify d63_predictor
calculate the averages needed for even and odd rows once; this removes a
conditional from the inner loop
the final average calculated currently relies on above[] being extended,
it could be reduced to use
above[block_size - 2] + 3 * above[block_size - 1]

Change-Id: I70f5eac8d8a2a959c7114844a95826f445c3dd4d
2015-06-04 19:21:05 -07:00
Parag Salasakar
dc07cc6fed Merge "mips msa vp9 loopfilter 16 optimization" 2015-06-05 02:15:26 +00:00
James Zern
c2cf347fe2 Merge "vp9_reconintra: use AVG[23] consistently" 2015-06-05 02:15:22 +00:00
James Zern
2b6d62140e Merge "vp9_reconintra_neon_asm/tm4x4: simplify left load" 2015-06-05 01:46:39 +00:00
James Zern
6c3b691c49 Merge "vp9_reconintra: fix d45/d63 discrepancies" 2015-06-04 22:56:43 +00:00
Scott LaVarnway
7ccd7fc325 Merge "Remove cm parameter from vp9_decode_block_tokens() part 2" 2015-06-04 22:20:55 +00:00
James Zern
faea038f4f vp9_reconintra: fix d45/d63 discrepancies
the final index in rows 2, 3 differ from vp8

Change-Id: I0fcea907b4ab44e266c0f1fd77b290d2236b280a
2015-06-04 14:49:56 -07:00
Marco
8f7e7663ad Bugfx in setting layer framerate.
Index for ts_rate_decimator should be temporal layer (tl) index.

Change-Id: I0320b7f7ae987ef64fdfe7c45099e7978a8fef17
2015-06-04 13:12:09 -07:00
Yaowu Xu
f990b35fa4 Make vp9 the default codec for vpxenc
Change-Id: Ic3b4f3c9a6d8f9b04efb8b5ee080880895063564
2015-06-04 08:28:12 -07:00
Scott LaVarnway
baaaa57533 Reducing size of MODE_INFO struct
Reduced size from 124 bytes to 104 bytes.  For decode only builds,
it is reduced to 68 bytes.

Change-Id: If9e6b92285459425fa086ab5a743d0a598a69de3
2015-06-04 07:32:16 -07:00
Scott LaVarnway
8bb37dd069 Remove cm parameter from vp9_decode_block_tokens() part 2
Change-Id: Iee24b6bb095f748333223e6036fc5c9d9e7e5f1c
2015-06-04 07:13:19 -07:00
Scott LaVarnway
877fac122b Merge "Remove counts param" 2015-06-04 13:46:42 +00:00
Parag Salasakar
914f8f9ee0 mips msa vp9 loopfilter 16 optimization
average improvement ~3x-4x

Change-Id: I8ef263da6ebcf8f20aabaefeccf25a84640ba048
2015-06-04 11:50:41 +05:30
Johann Koenig
c005792951 Merge "Make vp9 subpixel match vp8" 2015-06-04 06:16:13 +00:00
Parag Salasakar
fd891a9655 Merge "mips msa vp9 convolve8 avg hv optimization" 2015-06-04 05:44:24 +00:00
Johann
eb88b172fe Make vp9 subpixel match vp8
The only difference between the two was that the vp9 function allowed
for every step in the bilinear filter (16 steps) while vp8 only allowed
for half of those. Since all the call sites in vp9 (<< 1) the input, it
only ever used the same steps as vp8.

This will allow moving the subpel variance to vpx_dsp with the rest of
the variance functions.

Change-Id: I6fa2509350a2dc610c46b3e15bde98a15a084b75
2015-06-03 22:10:51 -07:00
hkuang
ce5e17072d Merge "Optimize the idct assembly code." 2015-06-04 04:32:11 +00:00
James Zern
4fcabf5169 vp9_reconintra: use AVG[23] consistently
Change-Id: Iab7215f82be0c0c831cd81b6f8091afc3710dd54
2015-06-03 19:52:46 -07:00
Parag Salasakar
bdfbc3e876 mips msa vp9 convolve8 avg hv optimization
average improvement ~4x-6x

Change-Id: I7c8b4f2334491be8a859592606e568bc95d019aa
2015-06-04 08:11:01 +05:30
James Zern
2da8d24e8f Merge "vp9_reconintra: simplify d45_predictor" 2015-06-04 01:59:10 +00:00
James Zern
a9f55e8324 Merge changes from topic 'vp9-intra-pred'
* changes:
  vp9_reconintra: specialize d135 4x4
  vp9_reconintra: specialize d117 4x4
  vp9_reconintra: specialize d207 4x4
  vp9_reconintra: specialize d153 4x4
  vp9_reconintra: specialize d63 4x4
  vp9_reconintra: specialize d45 4x4
2015-06-04 01:58:28 +00:00
Marco
2561b4dd4c Merge "Remove ABI check for 1 pass CBR SVC." 2015-06-04 01:54:19 +00:00
James Zern
65d9599807 vp9_reconintra_neon_asm/tm4x4: simplify left load
use vld1.8 {d0[]}, [r0] rather than ldrb+vdup; mildly faster

Change-Id: Ia5ffc736bcb0f5497b7d9e55a93bf5a5f5f6928c
2015-06-03 18:51:13 -07:00
Parag Salasakar
f1b09c0433 Merge "mips msa vp9 convolve8 avg horiz optimization" 2015-06-04 01:16:21 +00:00
Marco
a8c5ab2ca6 Remove ABI check for 1 pass CBR SVC.
Remove the ABI check for the controls needed for SVC 1 pass CBR mode.
Bump up the ABI version.

Change-Id: I35b79ee010e14af83c6d1e801d574deaaa2fc7eb
2015-06-03 17:43:22 -07:00
hkuang
98e88e6ad8 Optimize the idct assembly code.
Change-Id: Ia0ff859ff1c813dbe100e2f27b1ef78167483f4e
2015-06-03 17:20:35 -07:00
Paul Wilkins
668e804504 Animation and dead zone detection.
Adds code to detect dead zone bars at the top and bottom
of reformatted letterbox video (note that the code only
looks at the top of the image and assumes any dead zone
is symmetrical).  Use of this to adapt rate control etc.
will follow in a subsequent patch.

Also counts other blocks (excluding the dead zone) that
have no intra signal. The presence of a significant
number of such blocks can be used as a identify that the frame
may be artificial (e.g.  animation, screen capture, graphics).
This patch contains plumbing only and does not use
the signal.

Change-Id: I59bc93529cd4065416cef773e405fda3ae006a20
2015-06-04 01:01:20 +01:00
Marco
5df6c04585 Fix to sample encoder: vpx_temporal_svc_encoder.c
vp8 uses ts_target_bitrate for layer settings.

Change-Id: Ie72477b549051396feebff87a3744fed04366bf4
2015-06-03 14:50:27 -07:00
Johann
ce2ca9f777 Duplicate reference variance code
Some places are using the unoptimized variance function. This was never
intended and does not fit into the optimization framework.

Change-Id: Id96238407aad03b0ffd4a46cd183555a026daedc
2015-06-03 13:28:59 -07:00
Johann
516c087c51 Remove unused sub pixel mse
Change-Id: I7a5e4e2632c3fa69d2a85a68fa9b418631caf09c
2015-06-03 08:00:51 -07:00
Parag Salasakar
b8c1cdcd12 mips msa vp9 convolve8 avg horiz optimization
average improvement ~5x-8x

Change-Id: I179a69ec620fbd69979bd128f05d18113618aab4
2015-06-03 11:33:42 +05:30
Parag Salasakar
179bceffdb Merge "mips msa vp9 convolve8 avg vert optimization" 2015-06-03 05:58:43 +00:00
James Zern
0601f92a88 Merge "test-data.sha1: mark test data files as binary" 2015-06-03 05:49:43 +00:00
James Zern
88fadafa9e Merge "Support building shared libraries on OS/2" 2015-06-03 05:47:43 +00:00
KO Myung-Hun
19dbc0f066 test-data.sha1: mark test data files as binary
Change-Id: Ie3605bf4c4fb16eb21186adbb4577c20a8027344
2015-06-03 13:48:35 +09:00
KO Myung-Hun
6d52fe2e71 Support building shared libraries on OS/2
Change-Id: I5750db0504cb69ead52f9f44bf583e693bffbb7e
2015-06-03 13:48:34 +09:00
Parag Salasakar
c543d38ac7 mips msa vp9 convolve8 avg vert optimization
average improvement ~4x-6x

Change-Id: Ia2e6f770da46416ebec31fdcea5cc7878879a9d9
2015-06-03 09:55:25 +05:30
Parag Salasakar
622beaba67 Merge "mips msa vp9 idct4x4 and iwht4x4 optimization" 2015-06-03 04:10:14 +00:00
Johann
01853d7ce9 Merge "Unify reference variance functions" 2015-06-03 02:03:45 +00:00
Johann
d90536c1a2 Unify reference variance functions
Use uint32_t for all output and make all functions static

Change-Id: I2c9c6f6310732dc53444607d1c1a268ac1ab83ba
2015-06-02 15:14:55 -07:00
Johann
e2a5fd2cf4 Merge "Disable neon bilinear 4x4" 2015-06-02 21:44:14 +00:00
Scott LaVarnway
f779dba405 Remove counts param
Moved to MACROBLOCKD.

Change-Id: Icce765b334f2755f4fe2a4c39fb2ae2d7660d004
2015-06-02 09:06:00 -07:00
Marco
c139b81a13 Vidyo patch: Rate control for SVC, 1 pass CBR mode.
-Make Rate control work for SVC 1 pass CBR mode.
-Added temporal layering mode.
-Fixed bug in non-rd variance partition.
-Modified/updated the sample encoders (vp9_spatial_svc_encoder, vpx_temporal_svc_encoder).
-Added datarate unittest(s) for 1 pass CBR SVC.

Change-Id: Ie94b1b68a56ea1267b5087c625e5df04def2ee48
2015-06-02 07:54:13 -07:00
Parag Salasakar
54a6f73958 mips msa vp9 idct4x4 and iwht4x4 optimization
average improvement ~3x-4x
moved assert to respective files

Change-Id: I6c915059d456a00bdd76fab0dd2eede8b6c6ea58
2015-06-02 12:16:28 +05:30
Parag Salasakar
ebf7466cd8 mips msa vp9 updated convolve horiz, vert, hv, copy, avg module
Updated sources according to improved version of common MSA macros.
Enabled respective convolve MSA hooks and tests.
Overall, this is just upgrading the code with styling changes.

Change-Id: If5ad6ef8ea7ca47feed6d2fc9f34f0f0e8b6694d
2015-06-02 12:03:51 +05:30
Parag Salasakar
cf1c0ebc3a Merge "mips msa vp9 updated idct 8x8, 16x16 and 32x32 module" 2015-06-02 04:48:02 +00:00
Johann
86d0cb8325 Disable neon bilinear 4x4
Clang adds alignment hints when casting up the loads/stores. Although
this should be safe for most paths, it's causing some crashes. Either
the source of the misalignment needs to be determined and adjusted or
the intrinsics need to be rewritten to avoid using the cast to load the
data.

BUG=817,892

Change-Id: Ia3aa824d6a4cd97e14325ff49dc730b6f85ec7e8
2015-06-02 00:02:55 +00:00
Johann Koenig
cbebbff025 Merge "Adds subsecond frame rates to webm" 2015-06-01 22:36:09 +00:00
James Zern
71d923232c Merge changes from topic 'vp9-intra-pred'
* changes:
  vp9_reconintra_neon/tm: improve above_left load
  vp9_reconintra_neon: cosmetics: normalize fn params
2015-06-01 20:03:47 +00:00
James Zern
b601202905 Merge "vp9_reconintra_neon_asm/tm: simplify above_left load" 2015-06-01 20:01:38 +00:00
Johann
275c102787 Merge "Cast variance reference output" 2015-06-01 18:56:50 +00:00
paulwilkins
dbd3760712 Merge "Fast feedback of bits on undershoot." 2015-06-01 18:15:10 +00:00
Johann
fdc549994a Cast variance reference output
The larger internal variables are required for the intermediates
but RoundHighBitDepth brings them down to uint32_t/unsigned int.

Fixes type warnings in visual studio.

Change-Id: I48d35284d6cbde330ccdc1f46b6215a645d5eb00
2015-06-01 10:56:52 -07:00
Johnny Klonaris
d02aa04422 Adds subsecond frame rates to webm
Numerator was being range checked against the
denominator - preventing any frame rate slower
than 1 fps.

I've tested this on a Mac using using ffmpeg and
results are comparable to mp4 and ogg files generated
at the same time.

Not yet tested on Windows.

Johnny Klonaris
google@jawknee.com

Change-Id: Idb358dbc2e7dc000037880ede4a1b0df248a42c8
2015-06-01 10:13:58 -07:00
Parag Salasakar
6af9d7f2e2 mips msa vp9 updated idct 8x8, 16x16 and 32x32 module
Updated sources according to improved version of common MSA macros.
Enabled idct MSA hooks and tests.
Overall, this is just upgrading the code with styling changes.

Change-Id: I1f488ab2c741f6c622b7a855388a202168082209
2015-06-01 09:24:23 +05:30
James Zern
acc481eaae vp9_reconintra: simplify d45_predictor
only the immediate above right pixel is needed; this removes a
conditional from the inner loop
the final average calculated currently relies on above[] being extended,
it could be reduced to use above[block_size - 2] + 3 * above_right

Change-Id: Ica4f2b8d25eec3ca1d6fa52ef0d4adc228eeea3f
2015-05-30 13:30:59 -07:00
James Zern
6e068e51b5 vp9_reconintra: specialize d135 4x4
based on webp's RD4()

Change-Id: I64c8f0a1325a8f201eaad39b396fae7a2d06efff
2015-05-30 13:29:40 -07:00
James Zern
b6782686f4 vp9_reconintra: specialize d117 4x4
based on webp's VR4()

Change-Id: Ic8c0b8ed65a63772ca0a4321592880a5e8947db5
2015-05-30 13:29:02 -07:00
James Zern
c022dbc4d3 vp9_reconintra: specialize d207 4x4
based on webp's HU4()

Change-Id: I2401ef307cd94e70cc7904f55954af04290c8af9
2015-05-30 13:28:22 -07:00
James Zern
2276eb16f3 vp9_reconintra: specialize d153 4x4
based on webp's HD4()

Change-Id: Icba1e21ec4b8f5026dc92e49741a68b059c8b9b1
2015-05-30 13:27:50 -07:00
James Zern
102123821d vp9_reconintra: specialize d63 4x4
based on webp's VL4()

Change-Id: Ibab962053843eae8752b4e74b6481a53bb034ae9
2015-05-30 13:27:03 -07:00
James Zern
6051bcc3dc vp9_reconintra: specialize d45 4x4
based on webp's LD4()

Change-Id: I74855d23ce73e1c6988fe08bf7c959b7a69b4abf
2015-05-30 13:26:21 -07:00
Parag Salasakar
71e88f903d Merge "mips msa vp9 updated macros and disable all MSA functions" 2015-05-30 02:52:27 +00:00
James Zern
7621b48a1c vp9_reconintra_neon/tm: improve above_left load
use vld1?_dup_u8 over vdup?_n_u8, reduces general register use; mildly
faster

Change-Id: Ie0e4e550849a207b34b378541196b553c9f12011
2015-05-29 19:18:43 -07:00
James Zern
f2d621e383 vp9_reconintra_neon: cosmetics: normalize fn params
s/y_stride/stride/

Change-Id: Ie98c3fe241dc240b653849eda356a8862bdd52f4
2015-05-29 19:01:39 -07:00
James Zern
b337c54cc4 vp9_reconintra_neon_asm/tm: simplify above_left load
use vld1.8 {d0[]}, [r0] rather than ldrb+vdup; mildly faster

Change-Id: I5c24d49a90c2855c94395184774b289da8e9d5a7
2015-05-29 18:56:16 -07:00
James Zern
7544e766e4 Merge changes from topic 'vp9-intra-pred'
* changes:
  vp9_reconintra_neon: add DC 16x16 predictors
  vp9_reconintra_neon: add DC 8x8 predictors
2015-05-30 01:51:35 +00:00
James Zern
a2a13cbe5f vp9_reconintra_neon: add DC 16x16 predictors
85-89% faster over 20M pixels

Change-Id: I9b320ed6b9e67f27df738b84c8b43b65a93c50c2
2015-05-29 15:41:44 -07:00
James Zern
e97b849219 vp9_reconintra_neon: add DC 8x8 predictors
~90% faster over 20M pixels

Change-Id: Iab791510cc57c8332c2f9a5da0ed50702e5f5763
2015-05-29 15:39:08 -07:00
Parag Salasakar
f9f078ebb6 mips msa vp9 updated macros and disable all MSA functions
Done little restructuring/styling changes to the sources like generic macro definitions, their use to reduce code lines, better code alignments etc.
Disabled all MSA hooks and tests

Change-Id: Ic6f2dce0b501f46b80c06c46c0fe2043d557b190
2015-05-29 13:34:33 +05:30
James Zern
be380f2005 variance_neon: add missing include
vpx_ports/mem.h is necessary for MSVC __builtin_prefetch compatibility
macro

Change-Id: I210fad6c6b4545df1874d028b31f42018490b029
2015-05-28 23:38:53 -07:00
Marco
26ab314176 For non-rd pickmode: remove VAR_PARTITION condition.
Keep the logic, transform size based on cyclic refresh and bsize,
(that was conditioned on VAR_PARTITION conditions) the same
for all speeds in non-rd mode (speeds >= 5).

No change to speeds >=6.
Small improvement for speed 5, ~0.5/1.5% gain for avg psnr/ssim.

Change-Id: If9c5657f3d30efd3c7f147166bba7cb69ea55114
2015-05-28 17:29:47 -07:00
Minghai Shang
45db29784d Merge "[svc] Disable tiles for spatial svc case" 2015-05-28 22:13:54 +00:00
Johann
7c16dcc79b Merge "Check size restrictions before running test vector" 2015-05-28 22:01:53 +00:00
Scott LaVarnway
bbea7c95d8 Merge "Re-worked header files" 2015-05-28 19:56:39 +00:00
Johann
a927aec5f8 Merge "Use correct parameters for NEON variance tests" 2015-05-28 19:53:50 +00:00
Johann
89ab1dca50 Merge "Remove conversion warnings from hbd shifts" 2015-05-28 19:39:32 +00:00
Johann
3f2a06674a Merge "Don't #define snprintf in VS 2015 or higher." 2015-05-28 19:38:57 +00:00
Johann
efc2e9844e Use correct parameters for NEON variance tests
Change-Id: Ib2949d0a3e9273e7952bbf91956357c1138093f1
2015-05-28 11:28:06 -07:00
hkuang
5317185eb0 Merge "Add error handling when running out of free frame buffers." 2015-05-28 17:41:01 +00:00
Johann
cad0eca25c Don't #define snprintf in VS 2015 or higher.
In VS 2015 and higher snprintf is supplied and therefore vsnprintf
doesn't need to be defined. This also avoids problems caused by
_snprintf being different from snprintf.

This fixes a build break with VS 2015 and improves security.

Originally submitted via chromium by brucedawson@chromium.org
https://codereview.chromium.org/1055603003

Additionally break this MSVC-specific tweak to a new file, which will
become the home of all such MSVC-specific things.

This requires adding a dependency on msvc.h to every example which uses
args.c and tools_common.h

Change-Id: I35b5f8e7ea00f6627403aabc9ea79b0412557a99
2015-05-27 18:28:25 -07:00
Johann
c855ed72a6 Remove conversion warnings from hbd shifts
ROUND_POWER_OF_TWO has some poor side effects when used
with [u]int64_t such as doing the shifting in 32bits.

Change-Id: Ic85a19765cd316fb43657cb21c86f35ceb772773
2015-05-27 17:54:22 -07:00
Johann
1e4473b216 Check size restrictions before running test vector
Change-Id: I60ea7724e6ab06fc658f678c1b76d984a43f5a5e
2015-05-27 15:55:17 -07:00
hkuang
131cab7c27 Add error handling when running out of free frame buffers.
Change-Id: If28b59b9521204a6e3aecedcf75932d76a752567
2015-05-27 14:20:58 -07:00
Johann
ed93470a69 Merge "Only use one 'END' per file" 2015-05-27 20:36:31 +00:00
Minghai Shang
cbdfdb947c Merge "[decoder] Optimize context buffer re-allocation" 2015-05-27 20:24:30 +00:00
Marco
a49fff632c Non-rd variance partition: Adjust thresholds for 1080p.
Increase the 32x32 split threshold, to allow for more 32x32
at expense of 16x16. Visually looks somewhat better.

Change-Id: Ia1439c3a0dc2d7933468b88bd59266fcd9f03505
2015-05-27 12:30:35 -07:00
Johann
7e272e8c43 Merge "Correct case in Get4x4SSEFunc" 2015-05-27 19:26:47 +00:00
Marco
109a2edf90 Merge "Refactor set_vbp_thresholds." 2015-05-27 19:10:28 +00:00
Johann
bbefdce7eb Only use one 'END' per file
On visual studio builds the 'END' directive aggressively signals the end
of file.

Change-Id: I28714da32762ef5abcbaeb5a109fb02b80dd13ec
2015-05-27 12:01:32 -07:00
Johann
c5a7c89e89 Correct case in Get4x4SSEFunc
Change-Id: Ie8a7508798fa8e65c579a77cedb8305cee4ddc81
2015-05-27 11:38:43 -07:00
Minghai Shang
30181c46d8 Merge "[svc] Make size of empty frame to be 16x16 all the time" 2015-05-27 17:49:00 +00:00
Marco
f76d42a98a Refactor set_vbp_thresholds.
Break out the setting of the block variance split thresholds,
since they are locally modified, e.g., based on local/segment qp.

No change in performance.

Change-Id: I0a3238e6dab05140657539fc4bd27ac5ff7a554e
2015-05-27 09:25:18 -07:00
Minghai Shang
15353216c5 [svc] Make size of empty frame to be 16x16 all the time
Change-Id: Ibab09aa0e8c69cf5efea2f0ec035e5da9cc894b0
2015-05-26 16:04:36 -07:00
Johann
dee70d355f Merge "Move variance functions to vpx_dsp" 2015-05-26 23:02:11 +00:00
Johann
c3bdffb0a5 Move variance functions to vpx_dsp
subpel functions will be moved in another patch.

Change-Id: Idb2e049bad0b9b32ac42cc7731cd6903de2826ce
2015-05-26 12:01:52 -07:00
Minghai Shang
9ae5fb706e Merge "[svc] Turn on frame_parallel_decoding_mode" 2015-05-26 17:50:45 +00:00
Jingning Han
55ef1ae9e7 Merge "Fix integral projection motion search for frame resize" 2015-05-26 16:08:31 +00:00
James Zern
02fda6582c Merge changes Ie15e301e,Ib070c79b
* changes:
  vp9_reconintra_neon: cosmetics: reindent
  vp9_reconintra_neon: cosmetics: drop unneeded returns
2015-05-23 17:47:52 +00:00
James Zern
4e11f3ca6e vp9_reconintra_neon: cosmetics: reindent
Change-Id: Ie15e301e8f55cf928f42a03e53a8bb8b66d0e5d5
2015-05-22 21:04:30 -07:00
James Zern
ff683ab1da vp9_reconintra_neon: cosmetics: drop unneeded returns
Change-Id: Ib070c79bdbb9c1f4e25af693d7056ec9f964c789
2015-05-22 20:59:36 -07:00
James Zern
8c15ced172 vp9: move ssse3 convolve fns to intrinsics file
+ synchronize filter function signatures

this makes any intrinsics filters available for inlining and has the
side-effect of making those filters static, quieting missing-prototype
warnings.

Change-Id: I1908875caffa585bd4fc65aaf10d17a5e20cfb46
2015-05-22 20:14:16 -07:00
James Zern
2161e44025 vp9: move avx2 convolve fns to intrinsics file
+ synchronize filter function signatures

this makes any intrinsics filters available for inlining and has the
side-effect of making those filters static, quieting missing-prototype
warnings.

Change-Id: I1cd55c9d52547793ad65aa90c7620f0e426edaa2
2015-05-22 20:13:06 -07:00
James Zern
ef2b3cce50 add vp9/common/x86/convolve.h
collect the vp9_convolve function definition macros there; this will
allow some relocation of functions from vp9_asm_stubs.c

Change-Id: Idadd117fa256dd48748379856973fd985b8204e8
2015-05-22 20:12:16 -07:00
Johann
9e420c01da Merge "Remove unused "alt-tree-layout"" 2015-05-22 23:52:48 +00:00
Jingning Han
96dba4902c Fix integral projection motion search for frame resize
This commit fixes the integral projection motion search crash when
frame resize is used. It fixes issue 994.

Change-Id: Ieeb52619121d7444f7d6b3d0cf09415f990d1506
2015-05-22 15:40:45 -07:00
James Zern
48d8291df4 vp9_subpixel_8t_intrin_ssse3: quiet vs9 warning
reorder includes to avoid:
warning C4985: 'ceil': attributes not present on previous declaration.

this is the same workaround used in vp9/common/vp9_systemdependent.h

Change-Id: Ia10dd63de24f96fa1507a6179220e9d6ec774db6
2015-05-22 12:05:02 -07:00
Johann
7875e1d8ad Remove unused "alt-tree-layout"
Change-Id: Idddefb2fd3e4441421f61bd246479c627020a652
2015-05-22 11:35:37 -07:00
Scott LaVarnway
b962646fc5 Re-worked header files
Various header/test files had to be re-worked in order to
build "Remove cm parameter from vp9_decode_block_tokens()".

This patch reverts the "Remove cm" part and only contains
the re-worked header files.

Change-Id: I520958a88d1991fee988a3c784d0eac40e117a32
2015-05-22 11:19:51 -07:00
Marco
7ca17435d5 Fix to visual studio build error.
Change-Id: Ide080141ebc064584574c861fb324fe64cc572cc
2015-05-21 14:08:32 -07:00
paulwilkins
da8c3bf218 Merge "Fix issues with mixed ARF and GF groups." 2015-05-21 12:08:15 +00:00
James Zern
a492bcef87 vp9_mvref_common.c: fix compile warning
string literal to int within an assert

Change-Id: Ifd7acc717e01ee1bb3955ef830ec0d1645942459
2015-05-20 16:45:16 -07:00
Minghai Shang
9843e7c635 [svc] Disable tiles for spatial svc case
Change-Id: I8655a6760ab61947c09f337ddd9f4c1baf803a56
2015-05-20 14:31:49 -07:00
Marco
6f41e29064 vp8_drop_encodedframe_overshoot: fix to return setting.
Make sure force_maxqp is set to 0 for return 0.

Change-Id: Ie7c57842637226e932a390e7080e5ebb99996da3
2015-05-20 12:26:08 -07:00
Minghai Shang
48bfee8797 [decoder] Optimize context buffer re-allocation
1. Check existing buffer sizes when re-allocate context buffers.
2. Don't need to set mi buffers to 0 during setup_mi.

Change-Id: I6b48b0e077a4d804312b605ad0dc34aec5795a6d
2015-05-20 11:05:22 -07:00
Minghai Shang
e2c6a633fb [svc] Turn on frame_parallel_decoding_mode
Change-Id: I33b0384ee87f83950e03be6c999bc5f193055fd3
2015-05-20 10:56:48 -07:00
paulwilkins
883fdd45cf Fast feedback of bits on undershoot.
This patch provides a partial rapid feedback of bits
resulting from extreme undershoot.

Some  improvement on some problem animated material
but in its current form only a small impact on the metrics results
of our standard test sets.

Change-Id: Ie03036ea8123bc2553437cb8c8c9e7a9fc5dac5d
2015-05-20 16:47:34 +01:00
paulwilkins
ade9693a30 Fix issues with mixed ARF and GF groups.
This patch addresses two issues that can occur when the
encoder chooses to use a mixture of ARF and GF groups.

The first issue relates to a failure to reset the "ARF active" flag
correctly when transitioning from coding ARF groups to coding
GF groups. This caused some golden frames to be  encoded
with an incorrect bit rate target as if they were ARF overlay frames.

The second issue relates to the encoding of a single short GF group
just before a key frame.  Where the last group before a key frame
is an ARF group we expect the final frame before the key frame  to
be an low data rate overlay frame. However, when the last  group
is a GF group, the final frame before the key frame should be a normal
frame with a normal bit allocation. This issue had the potential to cause
a single poorly coded frame just before a key frame. If that key frame
were a forced key frame rather than a real scene cut, this might cause
pulsing.

Change-Id: Idf1eb5eaf63a231495a74de7899236e1ead9fb00
2015-05-20 16:46:44 +01:00
Marco
976f7f42c1 VP8: For high overshoot, force drop frame and max-out QP.
This allows rate control to react to content of current frame being encoded.
Enabling this feature via the setting: screen_content_mode = 2.

Change-Id: Ib2c6670551d96f4907495d5b7b76bb8c49e673db
2015-05-19 08:19:21 -07:00
James Zern
37d03809bf Merge "rename vp9_dct_impl_sse2.c to vp9_dct_sse2_impl.h" 2015-05-19 00:01:57 +00:00
James Zern
1bcf7a35e9 Merge "rename vp9_dct32x32_sse2.c to vp9_dct32x32_sse2_impl.h" 2015-05-19 00:01:22 +00:00
James Zern
0f854e9ab5 Merge "rename vp9_dct32x32_avx2.c to vp9_dct32x32_avx2_impl.h" 2015-05-19 00:01:07 +00:00
James Zern
3373f0e93b md5_helper.h: fix type conversion warning
add a cast in Add() from size_t -> uint32; quiets a visual studio build
warning

Change-Id: I0d87a3e460faf1fe2d4fb44df5f4042ef7500190
2015-05-17 11:21:22 -07:00
James Zern
8089f1cf13 test_intra_pred_speed: reuse test_libvpx's main()
this allows test_libvpx's simd caps check to be used; it also fixes a
link error on OS X with -fcommon.

Change-Id: I1a62a3e74ba06b8f3b37a22fcfdebf90c04ab289
2015-05-16 17:16:27 -07:00
James Zern
129a25c76d test_libvpx: add <arch>.* to negative filter
in addition to <arch>/*. this will pick up tests defined with TEST()
instead of INSTANTIATE_TEST_CASE_P()

Change-Id: I0917741baac89d9ce857f4d4aa53790e8a0c6c12
2015-05-16 11:52:59 -07:00
James Zern
85076fc5ab dec_build_inter_predictors: don't return a void fn
split call of extend_and_predict() and return, fixes visual studio build
warning since:
0a80164 Move mc_buf to cut down size of MACROBLOCKD.

Change-Id: I7cdf712941ef773a07f038539cb8080dc27861cd
2015-05-16 10:33:57 -07:00
James Zern
a989c66b84 rename vp9_dct_impl_sse2.c to vp9_dct_sse2_impl.h
this file shouldn't be built directly, it is included in vp9_dct_sse2.c
to create a non-high-bitdepth and a high-bitdepth version

silences missing prototype warnings for the unused FDCT* functions

Change-Id: Ide6ff8c24ab31bdb0f833260505ae33660a1ad5b
2015-05-15 17:01:19 -07:00
James Zern
587a71f1d6 rename vp9_dct32x32_sse2.c to vp9_dct32x32_sse2_impl.h
this file shouldn't be built directly, it is included in vp9_dct_sse2.c
to create a non-high-bitdepth and a high-bitdepth version

silences missing prototype warnings for the unused FDCT32x32* functions

Change-Id: I0e38f16dae5ea1728de184ee2c89287d48675c51
2015-05-15 16:59:52 -07:00
James Zern
4ec47249bc rename vp9_dct32x32_avx2.c to vp9_dct32x32_avx2_impl.h
this file shouldn't be built directly, it is included in vp9_dct_avx2.c
to create a non-high-bitdepth and a high-bitdepth version

silences missing prototype warnings for the unused FDCT32x32* functions

Change-Id: I4c19935c0e035b393be513bde735e9a78064a494
2015-05-15 16:47:51 -07:00
James Zern
cdf16c22ba Merge "tests: add test_intra_pred_speed" 2015-05-15 23:34:06 +00:00
James Zern
985f19bc6b Merge changes from topic 'missing-proto'
* changes:
  vp9_subexp.h: add a missing prototype
  vp9: add some missing includes
  vp9 intrinsics: add vp9_rtcd include
  vp9: correct some function signatures
  vp9_variance_sse2: sync function signatures
  vp9/encoder: make some functions static
  vp9_dct_sse2: make some functions static
  vp9_decodeframe.c: make a function static
2015-05-15 23:08:15 +00:00
Marco
beec69cfe2 Merge "Change tx_size_search_method setting for non-rd speed 5." 2015-05-15 21:29:01 +00:00
Marco
e88de49faa Change tx_size_search_method setting for non-rd speed 5.
Use the same settting as in speed >=6.
This will use same logic for tx_size selecton as in speed >=6,
which limits the transform size and reduces ringing artifact.
Also metrics go up on average with this change: ~2% for PSNR, ~10% for SSIM.

Change-Id: Ia2d50db236ae1cc72f742bfa6c9ec5ea50ff0e0a
2015-05-15 11:12:47 -07:00
James Zern
ca5a54113f vp9_subexp.h: add a missing prototype
+ include the .h in the .c
silences missing prototype warnings

Change-Id: Ia87366dccb4bf4e9f2ffa5d3ab51ac6ca5488c91
2015-05-15 10:43:48 -07:00
James Zern
97db651ce0 vp9: add some missing includes
mostly: <file>.c should include <file>.h
silences missing prototype warnings

Change-Id: Ic05ec32c6f7b2224b78825904d96d73aacad6000
2015-05-15 10:43:47 -07:00
James Zern
330fba41e2 vp9 intrinsics: add vp9_rtcd include
silences a missing declaration warning

Change-Id: I59a34e1a1377cf3529b678d7ec0122bd43ab1bf1
2015-05-15 10:43:47 -07:00
James Zern
18b60af27c vp9: correct some function signatures
silences missing prototype warnings

Change-Id: Idaf68d83d2cb03847f3ee002c4d00c2ac79da604
2015-05-15 10:43:47 -07:00
James Zern
43d5cc7fe1 vp9_variance_sse2: sync function signatures
+ include vp9_rtcd.h
silences missing prototype warnings

Change-Id: I77902f07a454029baad4fe5fe6fc37c65644e6f7
2015-05-15 10:43:47 -07:00
James Zern
700b7fd0a9 vp9/encoder: make some functions static
silences missing prototype warnings

Change-Id: I3338fcaa67b5dcdf6bf237e8b374db3befd18753
2015-05-15 10:43:47 -07:00
James Zern
8515e62e6b vp9_dct_sse2: make some functions static
silences missing prototype warnings

Change-Id: I773b6a6b5bd7c57db18c3b17c519534f80e131de
2015-05-15 10:43:47 -07:00
James Zern
f3bf5f2029 vp9_decodeframe.c: make a function static
silences a missing declaration warning

Change-Id: I2f49ebca9ba7a47f3c48f5fe919b90cd4114a9bc
2015-05-15 10:43:47 -07:00
Adrian Grange
8371c897dc Merge "Fix illegal memory access when stream starts w/ invisible frame." 2015-05-15 17:36:41 +00:00
James Zern
8dfeece878 Merge changes from topic 'missing-proto'
* changes:
  vp8/rdopt.h+onyx_int.h: add some missing prototypes
  vp8: add some missing includes
  vp8: make some functions static
  vp8/common/variance*: add vp8_rtcd include
  vp8_copy32xn: sync function signature
2015-05-15 17:19:50 +00:00
James Zern
0e5d0f7485 Merge changes from topic 'missing-proto'
* changes:
  sad*_avx2.c: sync function signatures
  vpx_scale: add missing rtcd + vpx_scale includes
2015-05-15 17:17:13 +00:00
James Zern
1fb9a8eed2 Merge changes from topic 'missing-proto'
* changes:
  fdct8x8_test: move functions to an anonymous namespace
  md5_utils.c: make a function static
  vpx_config.c: add vpx_codec include
2015-05-15 17:16:52 +00:00
Frank Galligan
d610ead258 Merge "Move mc_buf to cut down size of MACROBLOCKD." 2015-05-15 15:20:39 +00:00
paulwilkins
4f569e8485 Merge "Revert "Skip the last frame update for some frame repeats."" 2015-05-15 09:17:19 +00:00
James Zern
60b9f685cb vp8/rdopt.h+onyx_int.h: add some missing prototypes
silences missing prototype warnings

Change-Id: Icd477e37b502205d0a60e7389e51b1ba17d8888e
2015-05-14 22:41:26 -07:00
James Zern
62ad8baa40 vp8: add some missing includes
silences missing prototype warnings

Change-Id: Ib62e4743532b871e63bc99732875fff20501b8ac
2015-05-14 22:41:25 -07:00
James Zern
632177fa7f vp8: make some functions static
silences missing prototype warnings

Change-Id: I9f24a3214c832c982ca0dc5a032316eba48472ff
2015-05-14 22:41:25 -07:00
James Zern
f80bbc0efb vp8/common/variance*: add vp8_rtcd include
silences missing prototype warnings

Change-Id: I5ca198b56a5ff0cf5b93c89957526f243c04e9c8
2015-05-14 22:41:25 -07:00
James Zern
6eb1016301 vp8_copy32xn: sync function signature
+ include vp8_rtcd.h in copy_c.c
silences missing prototype warnings

Change-Id: Iecc279c695b08a26b231dedb41e3b84c551703f3
2015-05-14 22:41:13 -07:00
James Zern
4be50c5289 sad*_avx2.c: sync function signatures
+ include vpx_dsp_rtcd.h
silences missing prototype warnings

Change-Id: Ifa1780bcf72b1fa2b153025d0d78d91ad38774c3
2015-05-14 20:58:56 -07:00
James Zern
ad8bae3c2d vpx_scale: add missing rtcd + vpx_scale includes
silences missing prototype warnings

Change-Id: I33320f66c789b8c5c51d69f9dc0e017f9e06b0d0
2015-05-14 20:58:44 -07:00
James Zern
c47d868d99 fdct8x8_test: move functions to an anonymous namespace
silences missing declaration warnings

Change-Id: I9486c13c973df3d25fcdc2c3de9a0da783ce8fd6
2015-05-14 20:51:17 -07:00
James Zern
26453e7b67 md5_utils.c: make a function static
silences a missing prototype warning

Change-Id: I982c9c70e0e9f94a5201559300cadb8bd22441f9
2015-05-14 20:51:14 -07:00
James Zern
db4afa6bd2 vpx_config.c: add vpx_codec include
silences a missing prototype warning

Change-Id: I31a11c8390ae58e9a99ecc7cdf2a36334fac3f65
2015-05-14 20:51:08 -07:00
Frank Galligan
0a80164c94 Move mc_buf to cut down size of MACROBLOCKD.
Change-Id: Icea64b9e5632b41aaa7cd7018c501d6add9b7a7f
2015-05-14 19:10:02 -07:00
James Zern
0d2f348392 tests: add test_intra_pred_speed
useful for speed testing / verifying individual function optimizations;
currently tests non-high-bitdepth VP9 intra predictors

Change-Id: Ibd247765e43a31894697d43f1d39d312e0ba2090
2015-05-14 16:20:21 -07:00
Adrian Grange
f480c1256d Fix illegal memory access when stream starts w/ invisible frame.
Add a check to make sure we have a decoded frame available
before copying its 'corrupt' flag.

(Originally submitted to the old repository by Alexander Voronov
as: https://gerrit.chromium.org/gerrit/#/c/74305/).

Change-Id: Iceb4686c785afb437b668015bf8818b18d60e0ce
2015-05-14 15:49:10 -07:00
Tom Finegan
0de534b725 Merge "Remove BUILD_LIBVPX_SO variable from the build system." 2015-05-14 20:47:43 +00:00
Tom Finegan
f9a5b96fd2 Merge "Remove the BUILD_LIBVPX variable from the build system." 2015-05-14 19:08:06 +00:00
Tom Finegan
556ff27e2e Remove BUILD_LIBVPX_SO variable from the build system.
Was just an additional layer of indirection for CONFIG_SHARED, so
use CONFIG_SHARED directly.

Change-Id: I7c022b9f926a63c2c5884def5f03dfd648329afc
2015-05-14 11:20:34 -07:00
Tom Finegan
d104b16b56 Remove the BUILD_LIBVPX variable from the build system.
Replace it with it's value (yes), which is constant.

Change-Id: Ifb0c0408a53ecadf81156da6a64fa583b2ada746
2015-05-14 10:46:44 -07:00
paulwilkins
eb8faf1c89 Revert "Skip the last frame update for some frame repeats."
Testing on another rate control patch reveals that in some
situations, where the encoder is flipping in and out of arf
mode, we get an encoder decoder mismatch.

Whilst it is still not clear why, skipping  the last buffer
update seems to trigger the problem. Until I can establish
why, or if there is another underlying cause, I am reverting
this change.

This reverts commit e5112b3ae3.

Change-Id: I315c5200414de89458015823344b7367e9dd75ba
2015-05-14 17:21:44 +01:00
Johann
cafae5b544 Merge "Relocate memory operations for common code" 2015-05-13 19:47:24 +00:00
Johann
1d7ccd5325 Relocate memory operations for common code
With the sad functions, and hopefully the variance functions soon,
moving to the vpx_dsp location, place the defines used in the
reference C code in a common location.

Change-Id: I4c8ce7778eb38a0a3ee674d2f1c488eda01cfeca
2015-05-13 11:41:15 -07:00
Tom Finegan
3007db0b45 Avoid failed include when Makefile is processed with no target.
Basically just a warning, but disconcerting nonetheless. Removes this
output from the build:
Makefile:59: -x86_64-darwin13-gcc.mk: No such file or directory

Change-Id: Ibb379506352b2f613ef4a7b1ac47e9c95d0d1580
2015-05-13 11:16:09 -07:00
Tom Finegan
ae14b37431 Merge "Remove claims of universal target support from the build system." 2015-05-13 17:05:46 +00:00
Parag Salasakar
686616a989 Merge "mips msa vp9 idct 8x8 optimization" 2015-05-13 04:36:34 +00:00
Tom Finegan
3d7063d4b0 Remove claims of universal target support from the build system.
These targets no longer build (PPC support was removed from
libvpx). Remove the dead code and misleading help output.

BUG=https://code.google.com/p/webm/issues/detail?id=997

Change-Id: Ib35614806adeae970f3821da0d8dbcc54ab8d868
2015-05-12 19:16:49 -07:00
Yunqing Wang
f72af26305 Merge "Remove unneeded variable declaration" 2015-05-12 23:33:31 +00:00
Yaowu Xu
a8015e217e Merge "Protect new metric computation with use_highbitdepth flag" 2015-05-12 23:20:35 +00:00
Yaowu Xu
3f42d10805 Protect new metric computation with use_highbitdepth flag
The computation of new metrics is not supported yet in highbitdepth
mode. This commit adds protection to make sure the computation is
done only when highbitdepth is not on. This protection shall be
revised when support of highbitdpeth computation is added.

This resolves the encoder crash when configured with both
--enable-internal-stats
--enable-vp9-highbitdepth

Change-Id: Id9f4bcc4fa26d9ca0e9eabade83f3f88a5b212e6
2015-05-12 15:12:05 -07:00
Yunqing Wang
8ba2d2d5a0 Remove unneeded variable declaration
This patch fixed the following warning:
src\third_party\libvpx\source\libvpx\vp9\encoder\vp9_pickmode.c(1607) :
warning C6246: Local declaration of 'this_mode' hides declaration of the
same name in outer scope.

Change-Id: I1d93c4a47a13cb13089fec5bd61e8b58e6cd8d58
2015-05-12 15:01:40 -07:00
James Zern
5c02f88a81 Merge "libs.mk: simplify test_libvpx target" 2015-05-12 21:10:43 +00:00
James Zern
f237849862 Merge changes from topic 'missing-proto'
* changes:
  vpxenc: make some functions static
  vpxdec: make some functions static
  tools_common.h: fix get_vpx_decoder_count() proto
  tools_common.h: fix get_vpx_encoder_count() proto
  tools_common.h: fix usage_exit() prototype
2015-05-12 19:02:05 +00:00
Johann
73de6ad522 Merge "Remove reference to compatibility layer" 2015-05-12 18:44:24 +00:00
Adrian Grange
17fc3e94c9 Merge "Recompute tile params on frame resize" 2015-05-12 17:48:16 +00:00
Johann
4aaf4661c3 Remove reference to compatibility layer
The compatibility layer was removed before the 1.4.0 release.

Change-Id: I268513ee9b3a2640ec33c4a25a5c5614fee7b3b2
2015-05-12 10:40:13 -07:00
James Zern
5c337fd08a vpxenc: make some functions static
silences missing-prototype warnings

Change-Id: I641a61b21f9de135e59e3769a2063d5a94f34746
2015-05-11 20:55:03 -07:00
James Zern
6a2e0f029a vpxdec: make some functions static
silences missing-prototype warnings

Change-Id: I080d2a24eeb6faa8c160683cc1fbf30d3b0b49e5
2015-05-11 20:55:02 -07:00
James Zern
d1999cb234 tools_common.h: fix get_vpx_decoder_count() proto
silences a missing-prototype warning

Change-Id: I99f8b4a9b7df836208e93170159733c5b5c2d881
2015-05-11 20:55:02 -07:00
James Zern
5a73bbdb83 tools_common.h: fix get_vpx_encoder_count() proto
silences a missing-prototype warning

Change-Id: Icf5c7f1f3e8ae9792276068fb3c0fd04b40fc7ad
2015-05-11 20:55:01 -07:00
James Zern
59e7a47c41 tools_common.h: fix usage_exit() prototype
+ the definitions in the examples

silences a missing-prototype warning

Change-Id: I7c064cacd6d2073a6107de6c3e2cc46ef8a68411
2015-05-11 20:54:55 -07:00
James Zern
b0789cd299 libs.mk: simplify test_libvpx target
rename LIBVPX_TEST_BINS to LIBVPX_TEST_BIN and remove foreach usage.
this was a leftover from having multiple targets with their own (single)
object list; the use of LIBVPX_TEST_OBJS so widely makes extending these
loops difficult.

Change-Id: I61bda1b91acb43145609f04b8fe6e45ec4483e22
2015-05-11 19:13:38 -07:00
James Zern
465ce0e420 Merge "build_intra_predictors*: reduce above_data size" 2015-05-11 23:48:58 +00:00
Adrian Grange
5f0dc57653 Merge "Reduce border extension by 1 line" 2015-05-11 22:47:49 +00:00
Adrian Grange
65b768fdf9 Recompute tile params on frame resize
When the frame size changes we must recompute details
of the tile dimensions.

Change-Id: Ie519bd6da47b5cd43933c0bcfc0f2429bcb01986
2015-05-11 15:45:26 -07:00
Jingning Han
2dcfd16fbd Merge "Sort variables dependency in read_uncompressed_header" 2015-05-11 19:11:56 +00:00
Jingning Han
2b2b461d39 Sort variables dependency in read_uncompressed_header
Remove a few repeated data structure reads from
read_uncompressed_header.

Change-Id: I6eb741b39f9415ad0aa4631dfbf4a1ace4eba56a
2015-05-11 10:07:55 -07:00
Marco
913862be8c Fix rate control issue with layers and aq-mode=3.
When aq-mode=3 is enabled, only for base layer frames should the
qp of the frame incorporate the segment delta-qp.

This was causing more rate mismatch for the enhancement layer frames
when running temporal layers with aq-mode=3 on.

Change-Id: I1c5e69d1ef8a51188af8696753c17fd8f67699b3
2015-05-11 10:04:18 -07:00
paulwilkins
aa5c1b4c5d Merge "Skip the last frame update for some frame repeats." 2015-05-11 12:28:45 +00:00
James Zern
a5e4ca8390 build_intra_predictors*: reduce above_data size
currently this needs to be 2x (NEED_ABOVERIGHT) the size of the largest
block (32) + 1 (for above_left). reduce the buffer size from 128 + 16
(alignment) to 64 + 16.

Change-Id: Idaca1806c7e1214e9437de24e15edc2ebf18f95d
2015-05-08 20:17:20 -07:00
James Zern
6d22713722 Merge "build_intra_predictors*: reduce left_col size" 2015-05-09 00:53:55 +00:00
hkuang
d53fb0fda5 Fix clang ioc warning due to NULL mi pointer.
The warning only happens in VP9 encoder's first pass due to src_mi
is not set up yet. But it will not fail the encoder as left_mi and
above_mi are not used in the first_pass and they will be set up again
in the second pass.

Change-Id: I0713b4660d71e229e196654cb0970ba6b1574f28
2015-05-08 15:42:50 -07:00
Johann Koenig
f003f77b8c Merge "Fix ndk build." 2015-05-08 18:56:21 +00:00
hkuang
f5574fb44c Merge "Add more sse2 code for intra prediction." 2015-05-08 17:26:30 +00:00
paulwilkins
e5112b3ae3 Skip the last frame update for some frame repeats.
Where a frame appears to be a repeat of an earlier
frame or frame buffer,  but the first pass code
does not anticipate this (usually because it is matching
the GF or ARF buffer not the last frame buffer), do not
update the last frame buffer.

This helps ensure that the content of the last frame buffer
is kept "different" where possible, and not updated to
match the GF or ARF. This is particularly helpful in some
animated sequences where there are groups of repeating
frames. Here it has quite a big impact. However, in most
of our standard test clips it has little or no impact.

Change-Id: I77332ee1a69f9ffc0c6080bfeb811c43fd8828e6
2015-05-08 17:51:26 +01:00
Parag Salasakar
7c5f00f868 mips msa vp9 idct 8x8 optimization
average improvement ~4x-6x

Change-Id: I5edf713721b9e24c7e0ce2e69d8fc3ecab625d91
2015-05-08 12:23:27 +05:30
Parag Salasakar
a8a9c2bb45 Merge "mips msa vp9 idct 32x32 optimization" 2015-05-08 04:27:44 +00:00
Frank Galligan
a4bcc8c318 Fix ndk build.
Android.mk should depend on vpx_dsp_rtcd.h

Change-Id: Ib614af195a9574fd849c28b695f9f4b3b2bd125c
2015-05-07 18:22:29 -07:00
Johann
11a4a3c065 Merge "Remove only remaining uses of 'fast_unaligned'" 2015-05-07 23:32:18 +00:00
James Zern
7e55ff1593 build_intra_predictors*: reduce left_col size
this should only need to be the size of the largest block, i.e., 32, not
64.

Change-Id: Ib8cb2424771fdd2a64c55379597248b2722a5ceb
2015-05-07 16:16:42 -07:00
Johann
802e1d84cc Remove only remaining uses of 'fast_unaligned'
Use memcpy instead of casting.

Change-Id: Ieca725cc628883985bde23c7d742af8781c5dbb5
2015-05-07 14:39:37 -07:00
James Zern
fd3658b0e4 replace DECLARE_ALIGNED_ARRAY w/DECLARE_ALIGNED
this macro was used inconsistently and only differs in behavior from
DECLARE_ALIGNED when an alignment attribute is unavailable. this macro
is used with calls to assembly, while generic c-code doesn't rely on it,
so in a c-only build without an alignment attribute the code will
function as expected.

Change-Id: Ie9d06d4028c0de17c63b3a27e6c1b0491cc4ea79
2015-05-07 11:55:08 -07:00
Johann
76a08210b6 Merge "Move shared SAD code to vpx_dsp" 2015-05-07 18:33:06 +00:00
hkuang
086934136b Merge "Remove an unnecessary check." 2015-05-07 15:51:11 +00:00
Marco
97307af21a Merge "Remvoe EIGHTTAP_SHARP filter check for non-rd mode." 2015-05-07 15:40:11 +00:00
paulwilkins
aecb1770d5 Merge "Image size restriction to rd auto partition search." 2015-05-07 14:12:14 +00:00
Parag Salasakar
1601c1385a mips msa vp9 idct 32x32 optimization
average improvement ~4x-6x

Change-Id: Idaba7e49fbd7f388caee0d73773ccf6e4807ef17
2015-05-07 12:42:23 +05:30
hkuang
7153b822ed Add more sse2 code for intra prediction.
vp9_dc_left_predictor_16x16
vp9_dc_top_predictor_32x32
vp9_dc_left_predictor_32x32
vp9_dc_128_predictor_32x32

Change-Id: Ib9861deefd01c3527235b92ff6b3d571ef6b4bc6
2015-05-06 17:17:00 -07:00
Marco
76fe5dfc67 Remvoe EIGHTTAP_SHARP filter check for non-rd mode.
Using EIGHTTAP and EIGHTTAP_SMOOTH seem sufficient.
Hard to see any visual gain from allowing EIGHTTAP_SHARP, and it is
rarely selected.

PSNR/SSIM metrics go up by ~0.18/0.14%.

Change-Id: I96fa0d98f9321b913e3ebcd464d4ff3c63018791
2015-05-06 17:08:34 -07:00
Johann
d5d9289800 Move shared SAD code to vpx_dsp
Create a new component, vpx_dsp, for code that can be shared
between codecs. Move the SAD code into the component.

This reduces the size of vpxenc/dec by 36k on x86_64 builds.

Change-Id: I73f837ddaecac6b350bf757af0cfe19c4ab9327a
2015-05-06 16:58:20 -07:00
Adrian Grange
0af5ff49bd Reduce border extension by 1 line
The code was using one row too many.

Change-Id: Ie0c05d02c22ae3d0d13d3b6565c40de3bc4fa17a
2015-05-06 14:44:24 -07:00
hkuang
240767b29d Remove an unnecessary check.
Change-Id: Id0f224ac4667dd173363b0f05711678448291d4e
2015-05-06 14:15:00 -07:00
hkuang
92b199061a Correct the inter prediction coordinate calculation which greatly reduced the
times of border extension.

Change-Id: I8e5bd590cc696ee71cfe1f4cc66c12fb24aaf44e
2015-05-06 10:55:56 -07:00
hkuang
623e6eed5e Merge "Optimize the read_partition." 2015-05-06 17:29:52 +00:00
Yunqing Wang
7dbdada49f Merge "Add intra mode early termination in non-rd mode" 2015-05-06 17:12:11 +00:00
Parag Salasakar
d1cdda88bd Merge "mips msa vp9 idct 16x16 optimization" 2015-05-06 06:40:56 +00:00
Yunqing Wang
36eabb1c3c Add intra mode early termination in non-rd mode
Added the intra mode early termination in order to
speed up the mode search in non-rd case since we
started to include more intra modes in the search
list. Borg tests(rtc set) showed a 0.048% PSNR gain
and 0.061 SSIM gain. No speed change.

Change-Id: I6f255fe534dc50b736e6a66a726ad458eb9b4443
2015-05-05 16:31:36 -07:00
hkuang
4c1a8be29d Optimize the read_partition.
Change-Id: I5a796425ce5706824a2fc17c6f24f983c5b9e43b
2015-05-05 15:51:04 -07:00
James Zern
ccae5d99d2 fix and enable vp9_dc_128_predictor_16x16
widen the loads and stores to 128-bit.

this was added, but not enabled in:
493a857 Add some sse2 code for intra prediction.

Change-Id: I277d7db608a7db7d75cc0bde86f48fa66ad487e4
2015-05-05 11:40:13 -07:00
hkuang
e47811ef8f Merge "Add some sse2 code for intra prediction." 2015-05-05 17:11:07 +00:00
paulwilkins
af76953448 Merge "Remove CONSTRAIN_NEIGHBORING_MIN_MAX." 2015-05-05 09:32:11 +00:00
paulwilkins
4cd65e4f19 Merge "Adjust ARF min and max interval." 2015-05-05 09:31:38 +00:00
Parag Salasakar
60052b618f mips msa vp9 idct 16x16 optimization
average improvement ~4x-6x

Change-Id: I55e95b7f2ba403dff11813958dc7c73a900dd022
2015-05-05 12:37:06 +05:30
Marco
b9a72d3c4d Allow for H and V intra modes for non-rd mode.
For non-rd mode (speed >=5): use mask based on prediction block size, and
(for non-screen content mode) allow for checking horiz and vert intra modes
for blocks sizes < 16x16.

Avg psnr/ssim metrics go up by about ~0.2%.

Only allowing H/V intra on block sizes below 16x16 for now, to keep
encoding time increase very small, and also when allowing H/V on 16x16 blocks,
metrics went down on a few clips which need to be further examined.

Change-Id: I8ae0bc8cb2a964f9709612c76c5661acaab1381e
2015-05-04 09:48:41 -07:00
James Zern
670b2c09ce vp9_idct_intrin_sse2: cosmetics: reindent
+ fix some whitespace

Change-Id: Id61b739282014288a7e5d3c17a9d6448d9d4cda2
2015-05-01 16:07:54 -07:00
Yunqing Wang
d31256cd38 Merge "Reduce intra_cost_penalty for BLOCK_8X8" 2015-05-01 18:29:38 +00:00
Yunqing Wang
57fefd5f9a Merge "Adjust the vbp early termination threshold slightly" 2015-05-01 18:29:25 +00:00
Scott LaVarnway
7b0f24fc21 FIX: Use correct above/left in read_intra_frame_mode_info
Should be using xd->above_mi and xd->left_mi.

Change-Id: Ifab83512db5491a955a3ed44a2d6e3b25b5ae5a5
2015-05-01 08:23:47 -07:00
paulwilkins
4a7dcf8eb2 Image size restriction to rd auto partition search.
Impose a limit on the rd auto partition search based on
the image format. Smaller formats require that the search
includes includes a smaller minimum block size.

This change is intended to mitigate the visual impact of
ringing in some problem clips, for smaller image formats.

Change-Id: Ie039e5f599ee079bbef5d272f3e40e2e27d8f97b
2015-05-01 16:16:02 +01:00
paulwilkins
287b0c6da9 Remove CONSTRAIN_NEIGHBORING_MIN_MAX.
Remove one of the auto partition size cases.
This case can behaves badly in some types of animated content
and was only used for the rd encode path. A subsequent patch
will add additional checks to help further improve visual quality.

Change-Id: I0ebd8da3d45ab8501afa45d7959ced8c2d60ee4e
2015-05-01 15:15:16 +01:00
paulwilkins
e0786c280e Adjust ARF min and max interval.
Previously limit on max interval  set to 0.5 seconds.
Though this helped some low frame rate material it
appears to be a bit too aggressive for some 24 and 25 fps
content. This patch relaxes the limit to 0.75 seconds.

The patch also adds a new minimum interval variable
to replace the current hard wired value. This allows us
to impose a limit on the maximum number of primary
arfs per second for high frame rate (e.g. 50 & 60fps)
content. This is to address concerns regarding playback
performance on some platforms if there is a high base
frame rate and very frequent arfs.

Change-Id: I373e8b6b2a8ef522eced6c6d2cceb234ff763fcf
2015-05-01 15:11:49 +01:00
James Zern
c77b1f5acd vp9: RECON_AND_STORE4X4: remove dest offset
offsetting by a variable stride prevents instruction reordering,
resulting in poor assembly

Change-Id: Id62d6b3299cdd23f8c44f97b630abf4fea241446
2015-04-30 19:14:17 -07:00
James Zern
778845da05 vp9_idct_intrin_*: RECON_AND_STORE: remove dest offset
offsetting by a variable stride prevents instruction reordering,
resulting in poor assembly.
additionally reroll 16x16/32x32 loops to reduce register spill with this
new format

Change-Id: I0635b8ba21ecdb88116e927dbdab53acdf256e11
2015-04-30 19:14:17 -07:00
Yaowu Xu
2061359fcf Merge "Remove vp9_idct16x16_10_add_ssse3()" 2015-04-30 23:13:33 +00:00
James Zern
0ae1e4a95a Merge "vp9_decodeframe: simplify compare_tile_buffers" 2015-04-30 23:05:42 +00:00
hkuang
493a8579f1 Add some sse2 code for intra prediction.
Change-Id: I16c0a62e52dab62837c547345df31e7518620ed4
2015-04-30 15:42:57 -07:00
Yunqing Wang
4907c29904 Reduce intra_cost_penalty for BLOCK_8X8
This patch reduced the BLOCK_8X8's intra_cost_penalty, which
allows 8x8 blocks to conduct intra mode search. Borg test
result(rtc set): 0.077% PSNR gain, 0.228% SSIM gain. No speed
changes.

Change-Id: Icfe90c4f6969de24bda8ecacbd3da50330bf22b2
2015-04-30 11:03:06 -07:00
Yaowu Xu
47767609fe Remove vp9_idct16x16_10_add_ssse3()
The rotation computation using 2X of cos(pi/16) has a potential to
overflow 32 bit, this commit disable the function to allow further
investigation and optimization.

Change-Id: I4a9803bc71303d459cb1ec5bbd7c4aaf8968e5cf
2015-04-30 09:07:30 -07:00
Yunqing Wang
fd90ce2711 Merge "Improve golden frame refreshing in non-rd mode" 2015-04-30 15:57:55 +00:00
Yunqing Wang
a257e469e1 Adjust the vbp early termination threshold slightly
Calculated cpi->vbp_threshold_sad from this frame's dequant value.
The encoding quality and speed didn't change much. Borg test
result: PSNR: -0.002%, SSIM: -0.003%.

Change-Id: I97c9826986f39582f29910d637d08a69c90afdee
2015-04-30 08:51:02 -07:00
Parag Salasakar
95cb130f32 Merge "mips msa vp9 copy and avg convolve optimization" 2015-04-30 04:39:13 +00:00
Yaowu Xu
d45870be8d Merge "Disable ssse3 version idct16x16_256_add()" 2015-04-30 03:09:23 +00:00
James Zern
9e81112df2 vp9_decodeframe: simplify compare_tile_buffers
return the difference between the 2 buffer sizes rather than exactly
-1/0/1.

Change-Id: Idf1ccff7088b31845470bcc71bea5927b0598cc7
2015-04-29 17:42:30 -07:00
Yaowu Xu
486a73a9ce Disable ssse3 version idct16x16_256_add()
The version is currently producing different result from c version
for some input. Disable the use of it for now to allow time for
investigation the source of mismatch.

Change-Id: Id039455494ee531db4886a9f1fa4761174ef6df3
2015-04-29 16:58:59 -07:00
Yunqing Wang
d31698b0e0 Improve golden frame refreshing in non-rd mode
The default golden frame interval was doubled. After encoding a
frame, the background motion was measured. If the motion was high,
the current frame was set as the golden frame. Currently, the
changes were applied only while aq-mode 3 was on.

Borg tests(rtc set) showed a 0.226% PSNR gain and 0.312% SSIM gain.
No speed changes.

Change-Id: Id1e2793cc5be37e8a9bacec1380af6f36182f9b1
2015-04-29 16:43:43 -07:00
Marco
3a7bc16156 Merge "vpx_temporal_svc_encoder: Keep static_threshold off as default." 2015-04-29 21:42:57 +00:00
Marco
ee3d42bf3f vpx_temporal_svc_encoder: Keep static_threshold off as default.
Change-Id: Iadb42041f08ac969cc0b6af6f15e30c8498db680
2015-04-29 14:41:36 -07:00
James Zern
4aec440682 Merge changes from topic 'vpx_mem-cruft'
* changes:
  vpx_mem: remove vpx_memset
  vpx_mem: remove vpx_memcpy
  vpx_mem: remove vpx_memmove
2015-04-29 19:01:48 +00:00
Marco
0810a2d8bc vpx_temporal_svc_encoder: Update some settings.
Set denoiser off by default: should add this option to command line.

Change-Id: Iaecc94f5b5099feaacd7a5c415fc86eb68a2eea5
2015-04-29 09:26:24 -07:00
Marco
03f12e142b vpx_temporal_svc_encoder: Set static threshold to off by default.
Change-Id: I029484a5ffddcc3e518eeee609a6709b01cba146
2015-04-29 08:38:14 -07:00
Parag Salasakar
2301d10f73 mips msa vp9 copy and avg convolve optimization
average improvement ~3x-5x

Change-Id: I422e4c33ea7e6d6783ba40029438ccf21b0e76bb
2015-04-29 12:28:17 +05:30
James Zern
f58011ada5 vpx_mem: remove vpx_memset
vestigial. replace instances with memset() which they already were being
defined to.

Change-Id: Ie030cfaaa3e890dd92cf1a995fcb1927ba175201
2015-04-28 20:00:59 -07:00
James Zern
f274c2199b vpx_mem: remove vpx_memcpy
vestigial. replace instances with memcpy() which they already were being
defined to.

Change-Id: Icfd1b0bc5d95b70efab91b9ae777ace1e81d2d7c
2015-04-28 19:59:41 -07:00
James Zern
fbd3b89488 vpx_mem: remove vpx_memmove
vestigial. replace instances with memmove() which they already were
being defined to.

Change-Id: If396d3f9e3cf79c0ee5d7429615ef3d6b2a34afa
2015-04-28 19:59:40 -07:00
James Zern
ccc9e1da8d Merge "vpx_mem: remove REPLACE_BUILTIN_FUNCTIONS" 2015-04-29 02:58:39 +00:00
James Zern
4902606bb6 Merge "x86_simd_caps: check max cpuid before testing AVX2" 2015-04-28 21:31:03 +00:00
Frank Galligan
2be50a1c9c Merge "WIP: Use LUT for y_dequant/uv_dequant" 2015-04-28 16:12:10 +00:00
Yunqing Wang
bfce02971e Merge "Fix debugmodes file to print modes and MVs correctly" 2015-04-28 15:47:46 +00:00
Scott LaVarnway
afcb62b414 WIP: Use LUT for y_dequant/uv_dequant
instead of calculating every block.

Change-Id: Ib19ff2546be8441f8755ae971ba2910f29412029
2015-04-28 07:52:06 -07:00
Yunqing Wang
297b2b99de Fix debugmodes file to print modes and MVs correctly
This patch fixed the issues in debugmodes file because of the recent
changes in MODE_INFO struct.

Change-Id: I4df83379ecc887c1f009d4a8329c9809c5b299d6
2015-04-27 17:09:38 -07:00
James Zern
6686e4411d Merge "PATENTS: fix a typo: constitutes -> constitute" 2015-04-25 06:06:08 +00:00
James Zern
8d98aef055 PATENTS: fix a typo: constitutes -> constitute
Change-Id: Ie54413818b7f731b8a48b719038e66c9744de81e
2015-04-24 20:24:02 -07:00
James Zern
abff8b24b9 x86_simd_caps: check max cpuid before testing AVX2
structured extended feature flags require eax = 7; avoids incorrectly
detecting avx2 on some older processors that support avx.

from [1]:
INPUT EAX = 0: Returns CPUID’s Highest Value for Basic Processor
Information and the Vendor Identification String

[1] http://www.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html

Change-Id: I6b4735b5f7b7729a815e428fca767d1e5a10bcab
2015-04-24 19:24:14 -07:00
Yaowu Xu
b3e411e481 Add validation of UV partition size
For color sampling format other than 420, valid partion size in Y may
not work for UV plane. This commit adds validation of UV partition
size before select the partition choice.

This fixes a crash for real time encoding of 422 input.

Change-Id: I1fe3282accfd58625e8b5e6a4c8d2c84199751b6
2015-04-24 12:34:18 -07:00
James Zern
3e9263e1ca vpx_mem: remove REPLACE_BUILTIN_FUNCTIONS
vestigial. there are other ways to achieve this.

Change-Id: Ie977ce952527e596479df3084f331b694a682e39
2015-04-23 20:31:59 -07:00
James Zern
4feae6791c vpx_mem: remove global function pointer
vestigial.

Change-Id: I11389f660d0c5db8fa48bd355cbc3223fc3bcabb
2015-04-22 13:11:07 -07:00
James Zern
4659e3644f vpx_mem: remove mem tracker
vestigial. there are tools better suited for this

Change-Id: I7a72a2cfe32377f07c8cd0973ddb18842720a225
2015-04-22 13:10:12 -07:00
Johann
4a29474c83 Merge "vpx_mem: remove 'mem checks'" 2015-04-22 13:09:47 -07:00
Johann
9ed0e071fe Merge "vpx_mem: remove memory manager code" 2015-04-22 13:09:39 -07:00
Jim Bankoski
a6e9ae9066 Adds worst frame metrics for a bunch of metrics.
Change-Id: Ieaccc36ed1bee024bb644a9cfaafdaaa65d31772
2015-04-22 06:45:56 -07:00
paulwilkins
e07b141da0 Merge "Modified test for auto key frame detection." 2015-04-22 02:29:17 -07:00
paulwilkins
5d8877a944 Merge "Limit arf interval for low fpf clips." 2015-04-22 02:25:38 -07:00
Parag Salasakar
1c9af9833d Merge "mips msa vp9 convolve8 horiz optimization" 2015-04-21 22:08:25 -07:00
Jim Bankoski
3b35e962e2 Merge "Adds a new temporal consistency metric to libvpx." 2015-04-21 16:11:11 -07:00
Johann
931c0a954f Merge "Rename neon convolve avg file" 2015-04-21 15:45:29 -07:00
Johann
66b9933b8d Rename neon convolve avg file
Some build systems use just the basename for object files.

Change-Id: I333e1107ee866f3906cc46476ef8d04c6200a8a0
2015-04-21 14:18:17 -07:00
Scott LaVarnway
8b17f7f4eb Revert "Remove mi_grid_* structures."
(see I3a05cf1610679fed26e0b2eadd315a9ae91afdd6)

For the test clip used, the decoder performance improved by ~2%.
This is also an intermediate step towards adding back the
mode_info streams.

Change-Id: Idddc4a3f46e4180fbebddc156c4bbf177d5c2e0d
2015-04-21 11:16:45 -07:00
Jim Bankoski
ee87e20d53 Adds a new temporal consistency metric to libvpx.
Change-Id: Id61699ebf57ae4f8af96a468740c852b2f45f8e1
2015-04-21 10:05:37 -07:00
Yaowu Xu
924d06a075 Merge "Resolve configuration conflict" 2015-04-21 08:00:49 -07:00
paulwilkins
3606b78108 Modified test for auto key frame detection.
The existing test was triggering a lot of false positives on some types
of animated material with very plain backgrounds. These were triggering
code designed to catch key frames in letter box format clips.

This patch tightens up the criteria and imposes a minimum requirement
on the % blocks coded intra in the first pass and the ratio between the
% coded intra and the modified inter % after discounting neutral (flat)
blocks that are coded equally well either way.

On a particular problem animation clip this change eliminated a large
number of false positives including some cases where the old code
selected kf several times in a row. Marginal false negatives are less
damaging typically to compression and in the problem clip there are now
a couple of cases where "visual" scene cuts are ignored because of well
correlated content across the scene cut.

Replaced some magic numbers related to this with #defines and added
explanatory comments.

Change-Id: Ia3d304ac60eb7e4323e3817eaf83b4752cd63ecf
2015-04-21 12:50:11 +01:00
Parag Salasakar
ca90d4fd96 mips msa vp9 convolve8 horiz optimization
average improvement ~6x-8x

Change-Id: I7c91eec41aada3b0a5231dda7869b3b968f3ad18
2015-04-21 12:31:26 +05:30
Parag Salasakar
391ecffed9 Merge "mips msa vp9 convolve8 hv optimization" 2015-04-20 23:39:24 -07:00
James Zern
02804821cc vpx_mem: remove 'mem checks'
vestigial. there are tools better suited for this

Change-Id: I1d6f604452fbc62cb7523eec8d1f8a72a276d6b5
2015-04-20 20:52:32 -07:00
James Zern
e5eda53e3d vpx_mem: remove memory manager code
vestigial. the code is stale and couldn't be configured directly; there
are better ways to achieve this now

Change-Id: I5a9c62e099215588cd0d7e5ae002dfc77c21a895
2015-04-20 20:52:32 -07:00
Parag Salasakar
ef51c1ab5b mips msa vp9 convolve8 hv optimization
average improvement ~5x-8x

Change-Id: I3214734cb3716e742907ce0d2d7a042d953df82b
2015-04-21 09:17:49 +05:30
Yaowu Xu
b423a6b212 Resolve configuration conflict
Between --enable-internal-stats and --enable-vp9-highbitdepth

Change-Id: I36b741554e835033e69883270b6b0e5374a1aafa
2015-04-20 16:44:12 -07:00
Yaowu Xu
305492c375 Move declaration before statement
Change-Id: Ib64786fcc0d6dc11c4e66f5b7f3e93b2a4fcb664
2015-04-20 09:50:59 -07:00
Parag Salasakar
2e36149ccd Merge "mips msa vp9 convolve8 vert optimization" 2015-04-18 23:39:25 -07:00
Parag Salasakar
27d083c1b9 mips msa vp9 convolve8 vert optimization
average improvement ~6x-10x

Change-Id: Ie3f3ab3a9005be84935919701e56b404e420affa
2015-04-18 08:13:04 +05:30
Jim Bankoski
03829f2fea Merge "Adds a blockiness metric to internal stats." 2015-04-17 16:06:26 -07:00
Jim Bankoski
3d2f037a44 Merge "adds psnrhvs to internal stats." 2015-04-17 16:06:10 -07:00
Jim Bankoski
f2cbee9a04 Merge "Adds a fastssim metric to VPX internal stats." 2015-04-17 16:05:53 -07:00
Jim Bankoski
1777413a2a Adds a blockiness metric to internal stats.
Change-Id: Iedceeb020492050063acf3fd2326f96c29db9ae5
2015-04-17 11:13:18 -07:00
Frank Galligan
3a7ebf9c36 Fix dependency of android vpx test application.
Change-Id: I32b7c92c89c9a2be0cf38e67a17266b9d3866154
2015-04-17 10:59:11 -07:00
Jim Bankoski
9757c1aded adds psnrhvs to internal stats.
PSNR HVS is a human visual system weighted version of SNR that's
gained some popularity from academia and apparently better matches
MOS testing.

This code is borrowed from the Daala Project but uses our FDCT code.

Change-Id: Idd10fbc93129f7f4734946f6009f87d0f44cd2d7
2015-04-17 10:29:27 -07:00
Jim Bankoski
3f7f194304 Adds a fastssim metric to VPX internal stats.
This code appeared in the Daala project first and was originally
committed by Nathan Egge.

Change-Id: Iadce416a091929c51b46637ebdec984cddcaf18c
2015-04-17 10:23:24 -07:00
Jingning Han
73bce9ec7e Merge "Remove unnecessary backup token stream pointer" 2015-04-17 09:13:53 -07:00
Marco Paniconi
f76ccce5bc Revert "Revert "Force_split on 16x16 blocks in variance partition.""
This reverts commit 004b9d83e3

Change-Id: I2f2d0bdb9368c2c07f1d29a69cd461267a3a8743
2015-04-16 17:52:13 -07:00
Jingning Han
645c70f852 Remove unnecessary backup token stream pointer
When the tokenization is not taking effect, the tokenization
pointer remains unchanged. No need to re-assign the backup pointer
value.

Change-Id: I58fe1f6285aa3b4a88ceb864c11d5de8ac6235dd
2015-04-16 16:44:44 -07:00
Frank Galligan
c0b23ac20d Merge "Fix multithread encode test" 2015-04-16 16:00:54 -07:00
Frank Galligan
45f9ee263f Fix multithread encode test
The multithread encode test was never actually setting more than
one thread.

Change-Id: Ie7a3b7b138e88344c943bffd544cf2b4aab866a9
2015-04-16 14:20:18 -07:00
Minghai Shang
29b5cf6a9d Merge "[svc] Fix syntax error when encoding multiple tiles." 2015-04-16 13:43:44 -07:00
Johann
a53c495b3e Merge "Use extern for *_rtcd() in test/test_libvpx.cc" 2015-04-16 13:42:34 -07:00
Minghai Shang
4aa9255efa [svc] Fix syntax error when encoding multiple tiles.
Change-Id: Ia77b551415f3b3386e22a6c805f244f2d13fe3e3
2015-04-16 12:56:30 -07:00
Johann
e8645ce9f9 Use extern for *_rtcd() in test/test_libvpx.cc
This partially reverts commit 14ef4aeafb

Including the rtcd headers to get the function definitions causes
problems on VS9.

Change-Id: I780874d9e03af2d3124192ab0e3907301f22674c
2015-04-16 15:04:59 -04:00
James Zern
278593c9a9 Merge "Android.mk: remove unnecessary -llog reference" 2015-04-16 12:00:11 -07:00
paulwilkins
effd974b16 Limit arf interval for low fpf clips.
This patch limits  the maximum arf interval length to
approximately half a second. In some low fps animations in
particular the existing code was selecting an overly long interval
which was hurting visual quality. For a sample problem test clip
(360P animation , 15fps, ~200Kbit/s) this change also improved
metrics by >0.5 db.

There may be some clips where this hurts metrics a little, but the
worst case impact visually is likely to be less than having an
interval that is much too long. On more normal material at 24
fps or higher, the impact is likely to be nil/minimal.

Change-Id: Id8b57413931a670c861213ea91d7cc596375a297
2015-04-16 11:50:37 +01:00
Parag Salasakar
3701dcc5c1 Merge "mips msa configuration fix" 2015-04-15 21:17:13 -07:00
James Zern
e3bf76f9ec Android.mk: remove unnecessary -llog reference
nothing is using android/log.h currently; also quiets a warning when
building a static lib:
Android NDK: WARNING:libvpx/build/make/Android.mk:vpx: LOCAL_LDLIBS is
always ignored for static libraries

Change-Id: I1469a5d6fca4f7338a4a82e26a03e60fc91d92ca
2015-04-15 20:54:04 -07:00
James Zern
1551d7c00b Merge "Android.mk: add a flag to control shared/static lib" 2015-04-15 20:33:03 -07:00
Yunqing Wang
14e7203e7b Merge "Fix Tsan errors" 2015-04-15 15:34:03 -07:00
Yunqing Wang
63c5bf2b9c Fix Tsan errors
This patch fixed 2 reported Tsan errors while running VP9 real-time
encoder.

Change-Id: Ib0278fe802852862c3ce87c4a500e544d7089f67
2015-04-15 12:33:39 -07:00
Johann
3cba8dc304 Merge "Reorganize *_rtcd() calling conventions" 2015-04-15 12:27:59 -07:00
Johann
d61c1ea69b Merge "Allow specifying a different prefix in x86inc.asm" 2015-04-15 12:12:58 -07:00
Johann
14ef4aeafb Reorganize *_rtcd() calling conventions
Change-Id: Ib1e17d8aae9b713b87f560ab5e49952ee2bfdcc2
2015-04-15 11:12:05 -04:00
Johann
b09ac154af Allow specifying a different prefix in x86inc.asm
Currently the prefix is forced to vp9 for any function using
x86inc.asm.

Change-Id: Icbca57ce68a52e743bdd7e9be86cfe8353f274c1
2015-04-15 09:42:48 -04:00
Johann
d011a8a45c Merge "Remove unused scaleopt.cpp" 2015-04-15 06:36:45 -07:00
Parag Salasakar
4009b63c42 mips msa configuration fix
for big endian disable msa
removed -flax-vector-conversion flag
disable runtime_cpu_detect feature if enabled

Change-Id: Icd5130b733f2ddcdb94ffb6e4d170e6ca0f9832b
2015-04-15 11:56:42 +05:30
Yunqing Wang
004b9d83e3 Revert "Force_split on 16x16 blocks in variance partition."
This reverts commit eb8c667570.
The patch caused mismatch while using multi-threads.

Change-Id: Icd646340af25b5d91e32f03ed3ea212e00e3e0be
2015-04-14 15:19:31 -07:00
Johann
af7484a332 Remove unused scaleopt.cpp
Change-Id: Ibaeede61c128c73809332b9a853cd62b8d6d5325
2015-04-14 16:59:30 -04:00
Marco
2baa3debd5 Merge "Force_split on 16x16 blocks in variance partition." 2015-04-14 09:44:58 -07:00
hkuang
3b2510374a Merge "Remove unnecessary set postproc flags." 2015-04-13 14:33:43 -07:00
Marco
eb8c667570 Force_split on 16x16 blocks in variance partition.
Force split on 16x16 block (to 8x8) based on the minmax over the 8x8 sub-blocks.

Also increase variance threshold for 32x32, and add exit condiiton in choose_partition
(with very safe threshold) based on sad used to select reference frame.

Some visual improvement near moving boundaries.
Average gain in psnr/ssim: ~0.6%, some clips go up ~1 or 2%.
Encoding time increase (due to more 8x8 blocks) from ~1-4%, depending on clip.

Change-Id: I4759bb181251ac41517cd45e326ce2997dadb577
2015-04-13 12:05:07 -07:00
Parag Salasakar
2f693be8f8 Merge "mips msa vp9 common headers added" 2015-04-09 21:50:15 -07:00
Jingning Han
2404332c1b Merge "Remove get_nonrd_var_based_fixed_partition function" 2015-04-09 14:45:19 -07:00
Jingning Han
4565812032 Merge "Compute prediction filter type cost only when needed" 2015-04-09 14:45:11 -07:00
Jingning Han
93d9c50419 Merge "SSSE3 assembly implementation of 8x8 Hadamard transform" 2015-04-09 11:16:11 -07:00
hkuang
9244ac8592 Merge "Remove unnecessary mv clamp with on demand border extension." 2015-04-09 10:08:06 -07:00
Jingning Han
208aa6158b Remove get_nonrd_var_based_fixed_partition function
This function has been replaced by other approaches and is not
in use now.

Change-Id: I387f45b5607d202539e482468ccc70e6c0f9341f
2015-04-09 09:49:55 -07:00
Parag Salasakar
481fb7640c mips msa vp9 common headers added
Change-Id: Ia31ada59172eb1818e1eb91009f83cbb1f581223
2015-04-09 15:35:12 +05:30
James Zern
b815f3a977 Android.mk: add a flag to control shared/static lib
ndk-build ENABLE_SHARED=1 ...

Change-Id: Idd64804b165d0d4bbfb0b242d6c4eee5e828dab4
2015-04-08 21:03:36 -07:00
James Zern
8a75847497 Merge "vpxdec.sh: fix vp9_webm_less_than_50_frames w/valgrind" 2015-04-08 21:01:34 -07:00
hkuang
7e8e507bfb Remove unnecessary mv clamp with on demand border extension.
Change-Id: Ia2956f06f409b9b0ca8320ca4c1ea5680e938402
2015-04-08 17:16:52 -07:00
Frank Galligan
5668dcc7b9 Refactor dec_build_inter_predictors
Refactor the loops in dec_build_inter_predictors to try and decrease
the number of instructions. Limited testing saw about 1% perf
increase on x86 and about 0.67 % perf increase on Arm.

Change-Id: I69cfe6335bb562fbaaebf43fb3f5c5a2a28882a2
2015-04-08 15:00:29 -07:00
James Zern
aac3adb3c5 vpxdec.sh: fix vp9_webm_less_than_50_frames w/valgrind
add a check for the status line to awk and better report failure given
the program output will be lost in this case

Change-Id: I1348a80108c81099d609f2e2227dd2c31bd8cd54
2015-04-08 11:45:04 -07:00
Debargha Mukherjee
59681be0a0 Merge "Improve accuracy of rate control in CQ mode" 2015-04-08 10:48:17 -07:00
James Zern
2ed0cf06f9 Merge "vp9_full_search_sadx[38]: align sad arrays" 2015-04-07 20:57:21 -07:00
Yaowu Xu
c88ce84bb5 Merge "Optimize the checking for transform skipping" 2015-04-07 16:29:51 -07:00
Yaowu Xu
90517b5e85 Merge "move ref_frame_cost computations into a function" 2015-04-07 16:29:45 -07:00
Debargha Mukherjee
60bd744c88 Improve accuracy of rate control in CQ mode
Modifies a special handling that improves rate control accuracy in
the constrained quality mode, when the undershoot and overshoot
limits are set tighter.

Change-Id: If62103f0ef3ed1cac92807400678c93da50cf046
2015-04-07 16:29:21 -07:00
Yaowu Xu
5eee2a88f8 Merge "Test loopfilters with count=2" 2015-04-07 16:08:25 -07:00
James Zern
e1ff83f4b0 vp9_full_search_sadx[38]: align sad arrays
the sse4 code expects 16-byte aligned arrays; vp8 already had a similar
change applied:
b2aa401 Align SAD output array to be 16-byte aligned

Change-Id: I5e902035e5a87e23309e151113f3c0d4a8372226
2015-04-07 14:34:06 -07:00
Jingning Han
927693a991 Merge "Enable Hadamard transform based cost estimate for all block sizes" 2015-04-07 12:51:27 -07:00
Jingning Han
6de407b638 Merge "Account for eob cost in the RTC mode decision process" 2015-04-07 12:50:30 -07:00
Jingning Han
25206e7b7f Compute prediction filter type cost only when needed
Skip redundant prediction filter type cost in filter search loop,
if the rate value will be reset in Hadamard transform based rate
distortion estimate.

Change-Id: Ie5221f4bc8da9461c449df367251aeeac52c6e5d
2015-04-07 12:41:46 -07:00
Vignesh Venkatasubramanian
8de26efa66 Merge "webmdec: Fix for reaching eof in webm_guess_framerate" 2015-04-07 11:53:43 -07:00
Vignesh Venkatasubramanian
866447a008 webmdec: Fix for reaching eof in webm_guess_framerate
Reset the reached_eos flag in webm_guess_framerate in case it ends
up consuming the entire file. Also adding a vpxdec shell test to
verify this behavior.

Change-Id: I371eebd2105231dc0f60e65da1f71b233ad14be5
2015-04-07 11:04:51 -07:00
Yaowu Xu
0bb897211d Optimize the checking for transform skipping
If U is not skippable, then do not perform the check on V.

Change-Id: Iba5e8362bd42390197f373c44388a426a4404549
2015-04-06 17:54:05 -07:00
Jim Bankoski
5e300cac2c Merge changes Ide5eefad,I28026b86,Ie9a6fac0,Ia8a20c67,I8c7f5b97,I33ca9cdd,I438cbf49
* changes:
  vp8_regular_quantize_b_sse2: remove dead init
  vp8cx_pick_filter_level*: remove dead inits
  vp8_decode_frame: remove dead increment
  rdopt: remove dead stores
  find_next_key_frame: remove dead init & store
  multiframe_quality_enhance_block: remove dead stores
  vp8_print_modes_and_motion_vectors: remove dead stores
2015-04-06 17:05:35 -07:00
Jingning Han
7f629dfca4 SSSE3 assembly implementation of 8x8 Hadamard transform
It uses about 10% less CPU cycles than the SSE2 intrinsic
implementation.

Change-Id: I91017c0c068679a214b98cdd4cff3a6facfb7499
2015-04-04 09:59:37 -07:00
Jingning Han
9922e4344a Enable Hadamard transform based cost estimate for all block sizes
This commit turns on the Hadamard transform based rate distortion
estimate for all block sizes in RTC coding mode. It conditionally
skips the rate distortion estimation if all zero block flag is set
on. No significant encoding speed change is observed. The
compression performance of speed -6 is improved by 1.7% over using
it only for block sizes of 32x32 and below.

Change-Id: I768145e6f05c737b05b5b5f1ee674e929532cafb
2015-04-04 09:58:45 -07:00
Yunqing Wang
b2baaa215b Merge "Fix the scaling factor in UV skipping test" 2015-04-03 17:09:59 -07:00
James Zern
5afa7d1f87 vp8_regular_quantize_b_sse2: remove dead init
Change-Id: Ide5eefadbb3cab38743a69f744a003abb37a6506
2015-04-03 16:44:16 -07:00
James Zern
30205e14b7 vp8cx_pick_filter_level*: remove dead inits
Change-Id: I28026b86d03264b9f4e2fc8ac1d3c74aa3954208
2015-04-03 16:44:15 -07:00
James Zern
acb219be25 vp8_decode_frame: remove dead increment
Change-Id: Ie9a6fac02796d24e6f4a15416d0b4c19010547df
2015-04-03 16:44:15 -07:00
James Zern
0c5a140a02 rdopt: remove dead stores
Change-Id: Ia8a20c6751cc6d63c60bb00b99c78faca1e61051
2015-04-03 16:44:14 -07:00
James Zern
04c53d2393 find_next_key_frame: remove dead init & store
Change-Id: I8c7f5b9718ef14e4397a263aa9f52a9edcf7d1cd
2015-04-03 16:43:48 -07:00
James Zern
970acffa8f multiframe_quality_enhance_block: remove dead stores
Change-Id: I33ca9cddfdd54c3d8a23c1cb978986a537a20bf2
2015-04-03 16:15:51 -07:00
James Zern
7b4f727959 vp8_print_modes_and_motion_vectors: remove dead stores
Change-Id: I438cbf4970fa2220fb73b0b41a29e654836d4e3b
2015-04-03 16:08:37 -07:00
Yunqing Wang
1a1114d21c Fix the scaling factor in UV skipping test
The threshold scaling factor was calculated wrong using partition
size "bsize". Thank Yaowu for pointing it out. It was fixed and no
speed change was seen.

Change-Id: If7a5564456f0f68d6957df3bd2d1876bbb8dfd27
2015-04-03 16:07:43 -07:00
Ed Baker
4e73e4bf93 Test loopfilters with count=2
The following functions use the count parameter to either loop or select
dedicated paths:
vp9_lpf_horizontal_16_c
vp9_lpf_horizontal_16_sse2
vp9_lpf_horizontal_16_avx2
vp9_lpf_horizontal_16_neon
vp9_highbd_lpf_horizontal_16_c
vp9_highbd_lpf_horizontal_16_sse2

Change-Id: I7abfd2cb30baa292b4ebe11c847968481103c037
2015-04-03 15:36:52 -07:00
James Zern
44e3640923 Merge "vp9: enable sse4 sad functions" 2015-04-03 14:57:52 -07:00
Johann
0080aca235 Merge "Merge branch 'indianrunnerduck'" 2015-04-03 13:43:20 -07:00
Johann
c5f7842234 Merge "Remove AltiVec flag" 2015-04-03 13:42:49 -07:00
Johann
79bd071373 Merge branch 'indianrunnerduck'
* indianrunnerduck:
  Update CHANGELOG for v1.4.0 (Indian Runner Duck) release
  vp9: fix high-bitdepth NEON build
  Fix use of scaling in joint motion search
  Prepare Release Candidate for libvpx v1.4.0
  vp8cx.h: vpx/vpx_encoder.h -> ./vpx_encoder.h

Change-Id: Ib2eee50f02e12623aae478871cb9150604bb2ac2
2015-04-03 12:53:45 -07:00
Johann
c74bf6d889 Update CHANGELOG for v1.4.0 (Indian Runner Duck) release
Change-Id: Id31b4da40c484aefc1236f5cc568171a9fd12af2
2015-04-03 11:49:19 -07:00
Jingning Han
30e9c091c0 Merge "Tune SSSE3 assembly implementation to improve quantization speed" 2015-04-03 11:24:28 -07:00
Johann
73fe337647 Remove AltiVec flag
Change-Id: I560b1a954a5089a8af69952b8084408c6a420b96
2015-04-03 10:33:20 -07:00
Jingning Han
60e01c6530 Account for eob cost in the RTC mode decision process
This commit accounts for the transform block end of coefficient flag
cost in the RTC mode decision process. This allows a more precise
rate estimate. It also turns on the model to block sizes up to 32x32.
The test sequences shows about 3% - 5% speed penalty for speed -6.
The average compression performance improvement for speed -6 is
1.58% in PSNR. The compression gains for hard clips like jimredvga,
mmmoving, and tacomascmv at low bit-rate range are 1.8%, 2.1%, and
3.2%, respectively.

Change-Id: Ic2ae211888e25a93979eac56b274c6e5ebcc21fb
2015-04-03 10:31:51 -07:00
hkuang
d72ed35374 Merge "Fix error of "Left shift of negative value -1"." 2015-04-02 21:35:12 -07:00
Yunqing Wang
12cb30d4bd Merge "Set vbp thresholds for aq3 boosted blocks" 2015-04-02 18:22:08 -07:00
Yaowu Xu
718feb0f69 move ref_frame_cost computations into a function
Change-Id: Iebf2ad2b1db7e2874788fda8d55e67f4cb1149f1
2015-04-02 18:10:55 -07:00
hkuang
73c8fe5deb Fix error of "Left shift of negative value -1".
Change-Id: Ia4f3feb20df0e89cc51b02def858e12e927312cc
2015-04-02 17:35:33 -07:00
Marco
f85f79f630 Merge "Code cleanup: put (8x8/4x4)fill_variance into separate function." 2015-04-02 17:33:01 -07:00
Johann
327b138b2c Merge "Remove PPC build support" 2015-04-02 16:26:48 -07:00
Yunqing Wang
cae03a7ef5 Set vbp thresholds for aq3 boosted blocks
The vbp thresholds are set seperately for boosted/non-boosted
superblocks according to their segment_id. This way we don't
have to force the boosted blocks to split to 32x32.

Speed 6 RTC set borg test result showed some quality gains.
Overall PSNR: +0.199%; Avg PSNR: +0.245%; SSIM: +0.802%.
No speed change was observed.

Change-Id: I37c6643a3e2da59c4b7dc10ebe05abc8abf4026a
2015-04-02 15:48:32 -07:00
James Zern
d181a627f0 vp9: fix high-bitdepth NEON build
remove incorrect specializations in rtcd and update a configuration
check in partial_idct_test.cc

(cherry picked from commit 8845334097)

Change-Id: I20f551f38ce502092b476fb16d3ca0969dba56f0
2015-04-02 15:19:46 -07:00
Adrian Grange
5ef2d1ddae Fix use of scaling in joint motion search
To enable us to the scale-invariant motion estimation
code during mode selection, each of the reference
buffers is scaled to match the size of the frame
being encoded.

This fix ensures that a unit scaling factor is used in
this case rather than the one calculated assuming that
the reference frame is not scaled.

(cherry picked from commit 8d8d7bfde5)

Change-Id: Id9a5c85dad402f3a7cc7ea9f30f204edad080ebf
2015-04-02 15:19:23 -07:00
Marco
77ea408983 Code cleanup: put (8x8/4x4)fill_variance into separate function.
Code cleanup, no change in behavior.

Change-Id: I043b889f8f0b3afb49de0da00873bc3499ebda24
2015-04-02 13:37:35 -07:00
Marco
6eb05c9ed0 Small fix to segment check in pickmode.
Change-Id: Id5fd82a504def2523292466fbaad5dade9424c72
2015-04-02 09:55:13 -07:00
Johann
bc98e93b53 Remove PPC build support
There are no functional optimizations for AltiVec/PPC

Change-Id: I6877a7a9739017fe36fc769be22679c65ea99976
2015-04-02 09:13:59 -07:00
James Zern
b8a1de86fd Merge "vp9/neon: skip some files in high-bitdepth build" 2015-04-01 23:36:56 -07:00
James Zern
b644384bb5 Merge "vp9: fix high-bitdepth NEON build" 2015-04-01 23:36:17 -07:00
Yaowu Xu
54210f706c Merge "use MAX_MB_PLANE consistently" 2015-04-01 18:24:39 -07:00
hkuang
f3bea3de5b Remove unnecessary set postproc flags.
Change-Id: Iaf136969bc368a890f9671647576ee9d54eef03b
2015-04-01 17:11:35 -07:00
hkuang
4cf68be17a Merge "Fix 10-bit video decode failure with --frame-parallel mode." 2015-04-01 17:07:58 -07:00
Jingning Han
2149f214d5 Merge "Reduce required xmm number by one in block_error_fp" 2015-04-01 15:46:22 -07:00
Jingning Han
657cabe0f7 Tune SSSE3 assembly implementation to improve quantization speed
Change-Id: If0ca8b25b4800d4336e6cbc97194cd9b01c5b5a3
2015-04-01 15:28:01 -07:00
Yaowu Xu
f26b8c84f8 use MAX_MB_PLANE consistently
Change-Id: Ic416a7f145001a88f5a7f70dde9b1edbc1b69381
2015-04-01 15:21:20 -07:00
Yaowu Xu
fff4654d36 Merge "Simplify bsize calculation" 2015-04-01 15:06:55 -07:00
Jingning Han
cf4447339e Merge "Optimize quantization simd implementation" 2015-04-01 14:55:18 -07:00
Jingning Han
a4364e5146 Merge "Simplify effective src_diff address computation" 2015-04-01 14:55:03 -07:00
Jingning Han
7acb2a8795 Merge "Refactor block_yrd function for RTC coding mode" 2015-04-01 14:54:24 -07:00
Yaowu Xu
ba91b54d7c Simplify bsize calculation
Change-Id: Ibc514684def9914c66f04cb7931f773e2b79c168
2015-04-01 12:15:06 -07:00
Jingning Han
19da916716 Simplify effective src_diff address computation
Remove redundant offset calculation for effective src_diff address.

Change-Id: I4aab241a36abcef7fd8adf74aed5e12b8b88e0ef
2015-04-01 12:07:47 -07:00
Jingning Han
f2cf3c06a0 Reduce required xmm number by one in block_error_fp
Use 6 xmms instead of 8.

Change-Id: If976ad85d09191d2fb0565399d690f2869dbbcc7
2015-04-01 12:07:35 -07:00
Jingning Han
1470529f62 Refactor block_yrd function for RTC coding mode
This commit separates Hadamard transform/quantization operations
from rate and distortion computation in block_yrd. This allows one
to skip SATD computation when all transform blocks are quantized
to zero. It also uses a new block error function that skips
repeated computation of sum of squared residuals. It reduces the
CPU cycles spent on block error calculation in block_yrd by 40%.

Change-Id: I726acb2454b44af1c3bd95385abecac209959b10
2015-04-01 12:00:43 -07:00
Jingning Han
eed1badedd Optimize quantization simd implementation
This commit allows the quantizer to compare the AC coefficients to
the quantization step size to determine if further multiplication
operations are needed. It makes the quantization process 20% faster
without coding statistics change.

Change-Id: I735aaf6a9c0874c82175bb565b20e131464db64a
2015-04-01 11:47:09 -07:00
Yunqing Wang
a0043c6d30 Enhance the transform skipping decision-making in non-rd mode
For large partition blocks(block_size > 32x32), the variance
calculation is modified so that every 8x8 block's variance
is stored during the calculation, which is used in the
following transform skipping test. Also, the variance for
every tx block is calculated. The skipping test checks all tx
blocks in the partition, and sets the skip flag only if all tx
blocks are skippable. If the skip flag of Y plane is 1, a
quick evaluation is done on UV planes. If the current partition
block is skippable in YUV planes, the mode search checks fewer
inter modes and doesn't check intra modes.

The rtc set borg test(at speed 6) showed that:
Overall psnr: -0.527%; Avg psnr: -0.510%; ssim: -0.573%.
Average single-thread speedup on rtc set was 3.5%.
For 720p clips, more speedups were seen.
gipsrecmotion: 13%
gipsrestat: 12%
vidyo: 5 - 9%
dark: 15%
niklas: 6%

Change-Id: I8d8ebec0cb305f1de016516400bf007c3042666e
2015-04-01 09:43:40 -07:00
hkuang
1582ac851f Fix 10-bit video decode failure with --frame-parallel mode.
Also add unit test to avoid same error in the future.

Issue:981

Change-Id: Iaf9889d8d5514cfdff1ea098e6ae133be56d501f
2015-04-01 09:19:35 -07:00
James Zern
14e24a1297 vp9: enable sse4 sad functions
sse4 isn't set by configure or used in rtcd, correct the sad entries to
use sse4_1 without changing the signatures for now.
this was done in vp8 post-vp9 branch.

Change-Id: Ia9f1fff9f2476fdfa53ed022778dd2f708caa271
2015-03-31 21:00:55 -07:00
James Zern
a98f6c0254 vp9/neon: skip some files in high-bitdepth build
exclude files that only contain functions for non-high-bitdepth builds.
this removes some warnings related to missing prototypes

Change-Id: Ic6642998c46a7b808c6c53b2f9c34bcd4d037abe
2015-03-31 18:06:21 -07:00
James Zern
8845334097 vp9: fix high-bitdepth NEON build
remove incorrect specializations in rtcd and update a configuration
check in partial_idct_test.cc

Change-Id: I20f551f38ce502092b476fb16d3ca0969dba56f0
2015-03-31 17:45:25 -07:00
Yunqing Wang
fc98114761 Merge "Rename vbp thresholds" 2015-03-31 16:33:30 -07:00
Vignesh Venkatasubramanian
639955f66e Merge "webmdec: Fix read_frame return value for calls after EOS" 2015-03-31 16:11:56 -07:00
Marco
c2b8218eba Merge "Set postproc flags in decoder_get_frame." 2015-03-31 15:22:14 -07:00
Yunqing Wang
c28ff1a9de Rename vbp thresholds
Code refactoring

Change-Id: I410fcce1bc6d95c62c474445f4c97ea8469f1e79
2015-03-31 15:14:44 -07:00
Jingning Han
502ac72233 Merge "Tuning SATD rate calculation for speed" 2015-03-31 14:24:26 -07:00
Jingning Han
1c39c5b96f Merge "Use aligned copy in 8x8 Hadamard transform SSE2" 2015-03-31 12:16:47 -07:00
Jingning Han
fa4289522e Merge "Allow block skip coding option in RTC mode" 2015-03-31 12:16:36 -07:00
Jingning Han
1638d7dc96 Merge "Fix 8x8 Hadamard SSE2 implementation" 2015-03-31 12:16:27 -07:00
Alex Converse
9670d766ab Merge "VP9E_GET_ACTIVE_MAP API function." 2015-03-31 11:52:56 -07:00
Jingning Han
531468a07a Tuning SATD rate calculation for speed
This commit allows the encoder to check the eob per transform
block to decide how to compute the SATD rate cost. If the entire
block is quantized to zero, there is no need to add anything; if
only the DC coefficient is non-zero, add its absolute value;
otherwise, sum over the block. This reduces the CPU cycles spent
on vp9_satd_sse2 to one third.

Change-Id: I0d56044b793b286efc0875fafc0b8bf2d2047e32
2015-03-31 11:02:20 -07:00
hui su
d4f2f1dd5b Merge "Move vp9_coef_con_tree to common/" 2015-03-31 10:51:10 -07:00
Jingning Han
014fa45298 Use aligned copy in 8x8 Hadamard transform SSE2
This reduces the 8x8 Hadamard transform cycles by 20%.

Change-Id: If34c5e02f3afa42244c6efabe121f7cf5d2df41b
2015-03-31 10:21:52 -07:00
Jingning Han
db5ec37edc Merge "Enable 16x16 Hadamard transform in SATD based mode decision" 2015-03-31 09:55:41 -07:00
Jingning Han
8c5670bb6f Merge "Use SATD based mode decision for block sizes below 16x16" 2015-03-31 09:47:47 -07:00
Jingning Han
ebe1be9186 Allow block skip coding option in RTC mode
When the estimated rate-distortion cost of skip coding mode is
lower than that of sending quantized coefficients, allow the
encoder to drop these coefficients. This improves the compression
performance of speed -6 by 0.268% and makes the encoding speed
slightly faster.

Change-Id: Idff2d7ba59f27ead33dd5a0e9f68746ed3c2ab68
2015-03-31 09:32:53 -07:00
hui su
302e24cb3e Move vp9_coef_con_tree to common/
This tree should be defined in common/, as it is needed for
both encoder and decoder.

Change-Id: I4f5cbc80025cf2ced14182c98f7c82dc7d0f87db
2015-03-31 09:20:46 -07:00
Marco
385ca8f741 Set postproc flags in decoder_get_frame.
The postproc settings were not set in decoder_get_frame().

Change-Id: I20d23de3ea18f6df061a53d691d4095d5c62532a
2015-03-30 16:15:57 -07:00
Jingning Han
9b99eb2e12 Merge "Reuse inter prediction pixel block for Hadamard transform" 2015-03-30 16:09:38 -07:00
Jingning Han
34a996ac1e Fix 8x8 Hadamard SSE2 implementation
This commit fixes the SSE2 version 8x8 Hadamard transform
alignment and makes it consistent with the C version.

Change-Id: I1304e5f97e0e5ef2d798fe38081609c39f5bfe74
2015-03-30 15:54:08 -07:00
Jingning Han
26d3d3af6a Enable 16x16 Hadamard transform in SATD based mode decision
This commit replaces the 16x16 2D-DCT transform with Hadamard
transform for RTC coding mode. It reduces the CPU cycles cost
on 16x16 transform by 5X. Overall it makes the speed -6 encoding
speed 1.5% faster without compromise on compression performance.

Change-Id: If6c993831dc4c678d841edc804ff395ed37f2a1b
2015-03-30 15:43:31 -07:00
Jingning Han
f0ac5aaa08 Merge "Hadamard transform based coding mode decision process" 2015-03-30 15:43:15 -07:00
Jingning Han
b4b5af6acd Use SATD based mode decision for block sizes below 16x16
This commit makes the encoder to select between SATD/variance as
metric for mode decision. It also allows to account chroma
component costs for mode decision as well. The overall encoding
time increase as compared to variance based mode selection is about
15% for speed -6. The compression performance is on average 2.2%
better than variance based approach, with about 5% compression
performance gains for hard clips (e.g., jimredvga, nikas720p, and
mmmoving) at lower bit-rate range.

Change-Id: I4d04a31d36f4fcb3f5f491dacd6e7fe44cb9d815
2015-03-30 15:20:07 -07:00
Jingning Han
8a927a1b7a Reuse inter prediction pixel block for Hadamard transform
It saves one unnecessary motion compensated prediction constructed
by using 8-tap filter.

Change-Id: I101215131e6f38621d5935885f94cc74de6a5377
2015-03-30 15:04:33 -07:00
Jingning Han
8c411f74e0 Hadamard transform based coding mode decision process
This commit uses Hadamard transform based rate-distortion cost
estimate for rtc coding mode decision. It improves the compression
performance of speed -6 for many hard clips at lower bit-rates.
For example, 5.5% for jimredvga, 6.7% for mmmoving, 6.1% for
niklas720p. This will introduce extra encoding cycle costs at
this point.

Change-Id: Iaf70634fa2417a705ee29f2456175b981db3d375
2015-03-30 14:46:05 -07:00
Vignesh Venkatasubramanian
1f05b19e69 webmdec: Fix read_frame return value for calls after EOS
webm_read_frame assumes that it won't be called once end of file
is reached. But for frame parallel mode that turns out to be not
true. this patch fixes that behavior by checking for EOS and
returning the appropriate value for subsequent calls.

Change-Id: Ie2fddbe00493a0f96c4172c67be1eb719f0fe8ed
2015-03-30 12:58:26 -07:00
Alex Converse
bf7def9a43 Merge "Simplify skip check." 2015-03-30 11:31:45 -07:00
jackychen
b38b32a794 Merge "vp9_postproc.c: eliminate -Wshadow build warnings." 2015-03-30 10:29:39 -07:00
jackychen
68610ae568 vp9_postproc.c: eliminate -Wshadow build warnings.
Change-Id: I6df525a9ad1ae3cfbba8710d21db8fee76e64dbb
2015-03-27 20:27:30 -07:00
Marco
fa20a60f0d Speed 5: use non-rd mode for key frame coding.
Metrics on RTC set go down by ~1.5% on average.
Key frame encoding time goes down by factor of ~5.

Change-Id: Ia83acc55848613870e5ac6efe7f3d904d877febb
2015-03-27 16:19:26 -07:00
hkuang
0c85718954 Merge "Fix the issue that --limit is not working in --frame-parallel mode." 2015-03-27 10:12:45 -07:00
Adrian Grange
553792cee2 Merge "Remove 8-bit array in HBD" 2015-03-26 16:31:27 -07:00
Adrian Grange
300d428ecd Merge "Replace heap with stack memory allocation" 2015-03-26 16:31:06 -07:00
Adrian Grange
9931110971 Merge "Fix use of scaling in joint motion search" 2015-03-26 16:30:35 -07:00
hkuang
ffafcd6281 Fix the issue that --limit is not working in --frame-parallel mode.
The reason is due to early break out before outputting all the frames inside
decoder.

Change-Id: I4a138fba08d12935c39bd7602c95f8c18b474e29
2015-03-26 15:36:22 -07:00
Johann
46ce6954cc Remove duplicate code from merge
Change-Id: I5e2a1270001b7e29f3f198d57ea40e1efccef367
2015-03-26 14:56:24 -07:00
Adrian Grange
ad18b2b641 Remove 8-bit array in HBD
Creating both 8- and 16-bit arrays and then only using one
of them is wasteful.

Change-Id: Ic5b397c283efaff7bcfff2d2413838ba3e065561
2015-03-25 15:37:03 -07:00
Adrian Grange
65df3d138a Replace heap with stack memory allocation
Replaced the dynamic memory allocation of the
second_pred buffer with an allocation on the stack.

Change-Id: I2716c46b71e8587714ca5733a99eca2c68419b23
2015-03-25 15:36:43 -07:00
Adrian Grange
8d8d7bfde5 Fix use of scaling in joint motion search
To enable us to the scale-invariant motion estimation
code during mode selection, each of the reference
buffers is scaled to match the size of the frame
being encoded.

This fix ensures that a unit scaling factor is used in
this case rather than the one calculated assuming that
the reference frame is not scaled.

Change-Id: Id9a5c85dad402f3a7cc7ea9f30f204edad080ebf
2015-03-25 15:35:29 -07:00
Johann
ba13ff8501 Parall -> Parallel
Change-Id: I565fef382fa17a00d5ae54e980ef14d9f0ad4f55
2015-03-25 12:45:36 -07:00
James Zern
e865be95bf Merge "fix static analysis warnings related to CHECK_MEM_ERROR" 2015-03-24 23:56:04 -07:00
Parag Salasakar
84ec68d21a mips msa configuration patch for MIPS SIMD Arch (MSA) P5600 and I6400
For P5600:
CROSS=$MTI/bin/mips-mti-linux-gnu- CFLAGS='-EL' CXXFLAGS='-EL' LDFLAGS='-EL'\
 ../configure --target=mips32-linux-gcc --cpu=p5600 --enable-msa

For I6400:
CROSS=$IMG/bin/mips-img-linux-gnu- CFLAGS='-EL' CXXFLAGS='-EL' LDFLAGS='-EL'\
 ../configure --target=mips64-linux-gcc --cpu=i6400 --enable-msa

Change-Id: Id25f721ea1f1991d5116e04dba713aebd7378f05
2015-03-24 15:18:38 -07:00
paulwilkins
ab788c5380 Merge "Enable group adaptive max q by default." 2015-03-24 15:00:12 -07:00
Alex Converse
4dcb839607 VP9E_GET_ACTIVE_MAP API function.
This is useful when aq mode 3 (cyclic refresh) reactivates segments for refresh.

Change-Id: I3ad1d9410b899ede393d82bb8db14e2da4d84eca
2015-03-24 11:19:47 -07:00
Alex Converse
a1e20ec58f Refactor fast loop filter code to handle 444.
Change-Id: I921b1ebabdf617049f8fa26fbe462c3ff115c1ce
2015-03-24 11:17:50 -07:00
Yaowu Xu
c77d4dcb35 Merge "vp9_pred_mv(): misc fixes and optimizations" 2015-03-24 10:36:51 -07:00
Alex Converse
02697e35dc Merge "A tiny cyclic refresh / active map fix." 2015-03-24 09:43:24 -07:00
paulwilkins
8ea7bafdaa Merge "Revised rd adjustment for variance." 2015-03-24 03:12:56 -07:00
paulwilkins
c0b71cf82f Merge "Experimental rd bias based on source vs recon variance." 2015-03-24 03:12:41 -07:00
Johann
bb5a39c1a7 Prepare Release Candidate for libvpx v1.4.0
Change-Id: I9ffd30c88a5e40c555bde1f5efcf8a3c9ffcf5ff
2015-03-23 23:54:52 -07:00
Alex Converse
31f1563a92 A tiny cyclic refresh / active map fix.
Change-Id: I198727461455c8c198a0c892d02ed3cb1673aa50
2015-03-23 18:51:00 -07:00
James Zern
19b4dead25 vp8cx.h: vpx/vpx_encoder.h -> ./vpx_encoder.h
this matches the other includes and simplifies include paths in builds
from source

(cherry picked from commit 7999c07697)

Change-Id: I344902c84f688ef93c9f3a53e7c06c30db49d8d3
2015-03-23 17:21:27 -07:00
James Zern
7cc3e70394 Merge "vp8cx.h: vpx/vpx_encoder.h -> ./vpx_encoder.h" 2015-03-23 17:19:52 -07:00
hkuang
9f4f98fdbd Merge "Optimize the intra frame decode to skip some unnecessary copy." 2015-03-23 16:50:37 -07:00
hkuang
cd1d40ff5d Merge "Safely free all the frame buffers after all the workers finish the work." 2015-03-23 16:50:15 -07:00
James Zern
7999c07697 vp8cx.h: vpx/vpx_encoder.h -> ./vpx_encoder.h
this matches the other includes and simplifies include paths in builds
from source

Change-Id: I344902c84f688ef93c9f3a53e7c06c30db49d8d3
2015-03-23 16:07:21 -07:00
Alex Converse
b7605a9d70 Simplify skip check.
SEG_LVL_SKIP implies skip. This is enforced by skip = write_skip().

Change-Id: I61c79581c9c53deae36685c2bcf388cb4d8827d3
2015-03-23 10:53:31 -07:00
hkuang
85107641a4 Optimize the intra frame decode to skip some unnecessary copy.
This speeds up a normal YT style 1080P clip decode by ~1% on nexus 7.

Change-Id: Ied7fa0d8bc941b2adb4db9382f549ee4d5654f3a
2015-03-23 10:11:49 -07:00
Alex Converse
f7bcce91af Merge "Don't apply active map on key frames." 2015-03-23 10:04:39 -07:00
Alex Converse
03177cb7fa Merge "Set loop filter level to zero on inactive segment." 2015-03-23 10:04:29 -07:00
paulwilkins
691ec45b4e Enable group adaptive max q by default.
Set the GF group adaptive max Q compile flag to 1 by default.

This change has a quite big visual impact in some clips and also
contributes to tighter rate control.

For short test clips that have consistent content the impact is
quite small on metrics but for more varied long form clips there is
a drop in overal psnr but a sharp rise in average psnr caused by
greater expenditure on some easier sections and tighter rate clipping
in hard sections.

In chunck'ed encodes some of the effect will already be present due
to the independent rate control in each chunk but this change takes
the control down to a smaller scale.

yt hd +10.67%, - 3.77%, -1.56%
yt +9.654%, - 3.6%, - 1.82%
std hd +0.25%, -0.85%, -0.42%
derf +0.25%, - 1.1%. - 0.87%

Change-Id: Ibbc39b800d99d053939f4c6712d715124082843e
2015-03-23 15:57:09 +00:00
Yaowu Xu
9fd8abc541 vp9_pred_mv(): misc fixes and optimizations
1. skip near if it is same as nearest
2. correct rounding for converting mv to fullpel position
3. update pred_mv_sad after new mv search.

Overall .1%~.25% compression gains on rtc set for speed 5, 6, 7, 8.

Change-Id: Ic300ca53f7da18073771f1bb993c58cde9deee89
2015-03-20 17:17:04 -07:00
Alex Converse
6d6ef8eb3c Don't apply active map on key frames.
This allows applciations to be KF oblivious.

Change-Id: Ic02712eae6ad8d6b3eaec26548299d24ca0d5cc0
2015-03-20 14:57:24 -07:00
James Zern
fef91c9040 vp[89]_cx_iface.c: remove obsolete ABI checks
Change-Id: I49a7017e8adc18ff03d748cb328814a8a3e1bcf6
2015-03-20 14:50:14 -07:00
Alex Converse
e032fc7b9e Set loop filter level to zero on inactive segment.
Change-Id: I6022a79351882a72a219aee13563bf21bcd70383
2015-03-20 14:43:06 -07:00
Adrian Grange
fc05897619 Merge "Restore first ref frame pointer to the correct value" 2015-03-20 07:49:54 -07:00
paulwilkins
7e234b9228 Revised rd adjustment for variance.
Revised adjustment for rd based on source complexity.
Two cases:

1) Bias against low variance intra predictors
when the actual source variance is higher.

2) When the source variance is very low to give a slight
bias against predictors that might introduce false texture
or features.

The impact on metrics of this change across the test sets is
small and mixed.

derf -0.073%, -0.049%, -0.291%
std hd -0.093%, -0.1%, -0.557%
yt  +0.186%, +0.04%, - 0.074%
ythd +0.625%, + 0.563%, +0.584%

Medium to strong psycho-visual improvements in some
problem clips.

This feature and intra weight on GF group length now
turned on by default.

Change-Id: Idefc8b633a7b7bc56c42dbe19f6b2f872d73851e
2015-03-20 11:59:39 +00:00
paulwilkins
9a1ce7be7d Experimental rd bias based on source vs recon variance.
This experiment biases the rd decision based on the impact
a mode decision has on the relative spatial complexity of the
reconstruction vs the source.

The aim is to better retain a semblance of texture even if it
is slightly misaligned / wrong, rather than use a simple rd
measure that tends to favor use of a flat predictor if a perfect
match can't be found.

This improves the appearance of texture and visual quality
on specific test clips but is hidden under a flag and currently
off by default pending visual quality testing on a wider Yt set.

Change-Id: Idf6e754a8949bf39ed9d314c6f2daaa20c888aad
2015-03-20 11:57:36 +00:00
James Zern
094a0faf88 Merge "enable test/vp9_encoder_parms_get_to_decoder" 2015-03-19 23:36:55 -07:00
James Zern
933fe4e397 Merge "put spatial svc behind an ABI check" 2015-03-19 23:36:40 -07:00
James Zern
748a4fd638 Merge changes I42fa121b,Id30076ce
* changes:
  vpx/vpx_codec.h: bump ABI version
  vpx/vpx_encoder.h: bump ABI version
2015-03-19 23:33:53 -07:00
Adrian Grange
12d946df89 Restore first ref frame pointer to the correct value
The joint_motion_search function alternates prediction
between two reference frames. In order to reuse existing
code, a pointer to the appropriate reference frame is
written into xd->plane[0].pre[0], that the motion
estimation code assumes points to the reference frame.

If this first reference frame was scaled then the
pointer was incorrectly being reset to point to the
unscaled reference frame rather than the scaled
version.

Change-Id: I76f73a8d8f4f15c1f3a5e7e08a35140cdb7886ab
2015-03-19 16:17:31 -07:00
Adrian Grange
b708f3b9ec Merge "Move joint_motion_search & delete function prototype" 2015-03-19 16:08:54 -07:00
James Zern
0e890082e2 Merge "external_frame_buffer_test: quiet static analysis warnings" 2015-03-19 15:43:40 -07:00
Adrian Grange
53c9ebe609 Move joint_motion_search & delete function prototype
Change-Id: I7fb3a78ed0e0bc940d8b4a57c470302f8369782f
2015-03-19 14:28:52 -07:00
Yunqing Wang
d6a2e29028 vp8: fix a bug in the internal PSNR calculation
While CONFIG_INTERNAL_STATS=1, PSNR is calculated while encoding.
The aligned width/height were used mistakenly in the calculation.
This patch fixed it, and used the orignal image width/height.

Change-Id: Iad5334f8693af761b71ebb78f2587db8a3404ecf
2015-03-19 12:56:25 -07:00
James Zern
954a7aecfe enable test/vp9_encoder_parms_get_to_decoder
the TODO around CONFIG_SPATIAL_SVC has been resolved by changing the
CONFIG_* checks to use an ABI based check

Change-Id: If2638baf361b863186177a453beec9af9231e69e
2015-03-19 12:29:22 -07:00
James Zern
18613408a3 put spatial svc behind an ABI check
this removes the CONFIG_* checks from public headers, but means
'--enable-experimental --enable-spatial-svc' builds will fail without a
local change to the ABI in vpx_encoder.h. this should be all right for
testing this experiment.

Change-Id: Ief55e7b9d1e8332cfce990275e04c29b30af0c4a
2015-03-19 12:29:16 -07:00
hkuang
b88dac8938 Safely free all the frame buffers after all the workers finish the work.
Issue: 978

Change-Id: Ia7aa809095008f6819a44d7ecb0329def79b1117
2015-03-19 12:21:00 -07:00
Jingning Han
067fc49996 Merge "Speed up non-rd mode decision search" 2015-03-19 09:18:10 -07:00
Jingning Han
411bbce470 Merge "Fix an ioc warning in vp9_pick_inter_mode" 2015-03-19 09:17:25 -07:00
Marco
fc2da4c5ba Merge "Adjustments to aq-mode=3." 2015-03-19 09:01:17 -07:00
James Zern
e4aa19a81d vpx/vpx_codec.h: bump ABI version
missed in updates for high bitdepth, xma removal, others

Change-Id: I42fa121b3bb080e8275f555b923cd9cb418db8a1
2015-03-18 20:08:30 -07:00
James Zern
1ca2e4e3b2 vpx/vpx_encoder.h: bump ABI version
missed in updates for high bitdepth, others

Change-Id: Id30076ce09beb361b5e1ff0ac99e3ae1ad4f987e
2015-03-18 20:05:06 -07:00
James Zern
6f23d40582 Merge "vp9_resize_plane: quiet some static analysis warnings" 2015-03-18 19:39:48 -07:00
James Zern
c664f16182 Merge changes Ie5a24275,Ib72946a8,I532b882b
* changes:
  vp9_fdct8x8_quant_ssse3: quiet a static analysis warning
  vp9_fdct8x8_quant_sse2: quiet a static analysis warning
  vp9_mv_pred: quiet a static analysis warning
2015-03-18 19:38:49 -07:00
Alex Converse
748843712f Merge "Fix external resize memory issues." 2015-03-18 16:04:30 -07:00
James Zern
b373301e1f external_frame_buffer_test: quiet static analysis warnings
add explicit returns in cases where ASSERT_* can't be used due to the
function returning a value; retain the EXPECT_* for reporting purposes.

Change-Id: I1f514728537fee42a99277d3aba538e832d3b65b
2015-03-18 14:37:20 -07:00
James Zern
3ab1c0227a fix static analysis warnings related to CHECK_MEM_ERROR
mark vpx_internal_error as noreturn under the analyzer

Change-Id: If214a0e740aab9b82cc04f4492eb77a7a07ef7ab
2015-03-18 14:35:49 -07:00
James Zern
c4367b9b51 vp9_resize_plane: quiet some static analysis warnings
document resolution assumptions with a few asserts

Change-Id: Ia4ab738fd3e0a1ba0ed30a57facd2658c2c1fd60
2015-03-18 14:34:30 -07:00
James Zern
388add965f vp9_fdct8x8_quant_ssse3: quiet a static analysis warning
add an assert to validate 'in' array size

Change-Id: Ie5a24275c066d9dd59714f6104510abbd4850dc5
2015-03-18 14:33:43 -07:00
James Zern
198b039e2a vp9_fdct8x8_quant_sse2: quiet a static analysis warning
add an assert to validate 'in' array size

Change-Id: Ib72946a86f34e1ce8a69954e8e3e4fe1a0f18a91
2015-03-18 14:33:04 -07:00
James Zern
428369293d vp9_mv_pred: quiet a static analysis warning
add an assert to validate pred_mv array size

Change-Id: I532b882b71e2baff3ac76e07ed133ec5a11bd0fc
2015-03-18 14:31:58 -07:00
Johann
5edd076bd2 Merge changes Icc7da602,Id166bd8a
* changes:
  Remove last remnants of obj_int_extract
  Initialize "corrupted" to zero
2015-03-18 14:02:19 -07:00
Marco
71e6ed7bd1 Adjustments to aq-mode=3.
Factor in segment#2 and skip blocks into the postencode estimated bits,
and increase somewhat the aggressiveness of the refresh.

PSNR/SSIM Metrics on RTC set go up by ~0.8/0.5%.

Change-Id: I5d4e7cb00a3aefb25d18c88b6b24118b72dc5d51
2015-03-18 12:06:16 -07:00
Jingning Han
83cbe22623 Speed up non-rd mode decision search
This commit makes the encoder to explicitly calculate the SAD
associated with the LAST_FRAME motion vector and compare it to
that of the GOLDEN_FRAME given by integral projection motion
estimation. It skips the expensive sub-pixel motion search over
GOLDEN_FRAME when the LAST_FRAME can provide fairly good motion
compensated prediction quality.

For dark720p speed -6 single thread goes from
33304 b/f, 40.070 dB, 18156 ms ->
33319 b/f, 40.061 dB, 17611 ms

Change-Id: I01bc94b9b598075567a392111046b97a9bc30efe
2015-03-18 12:04:58 -07:00
Adrian Grange
83288c7af8 Order header files alphabetically
Change-Id: I3e275544bff478849c1b5f3dcd5de950ee330d14
2015-03-18 11:18:08 -07:00
Johann
08acc349b3 Remove last remnants of obj_int_extract
Change-Id: Icc7da6027763b5ed7cbfe70ffe271103ead59fe1
2015-03-18 11:06:53 -07:00
Johann
5370c6f1a5 Initialize "corrupted" to zero
Because the call to vpx_codec_control at line 928 is now guarded by
!frame_parallel, 'corrupted' may not be set.

Change-Id: Id166bd8a8cdb5e5120fca1640011a3545f6e178a
2015-03-18 11:01:28 -07:00
Frank Galligan
8a192ce7ef Merge "Add protection for codec interface name change." 2015-03-18 09:51:07 -07:00
Jingning Han
4640a0c480 Merge "Fix the C version of column vector projection" 2015-03-17 22:53:49 -07:00
Jingning Han
c932584f0f Fix the C version of column vector projection
Make the C and SSE2 versions consistent.

Change-Id: I03c405d22a36bd1a97480efb96dc5af230667424
2015-03-17 18:50:53 -07:00
Marco
e52109158a Update to variance partition.
Use force_split to constrain the partition selection.
This is used because in the top-down approach to variance partition,
a block size may be selected even though one of its subblocks may have
high variance.

In this patch the selection of the 64x64 block size will only
be allowed if the variance of all the 32x32 subblocks are also below the threshold.

Stil testing, but some visual improvement for areas near slow moving boundary
can be seen. Metrics for RTC set increase by about ~0.5%.

Change-Id: Iab3e7b19bf70f534236f7a43fd873895a2bb261d
2015-03-17 17:02:47 -07:00
Yunqing Wang
45e8e4a01f Merge "Refactor set vbp thresholds function" 2015-03-17 16:05:53 -07:00
Adrian Grange
5016e59e8b Merge "Remove unused ZBIN_BOOST macros" 2015-03-17 15:13:12 -07:00
Frank Galligan
6a4e85a1d6 Add protection for codec interface name change.
Change-Id: I9101cb1132aa580fc32fd47e8ac9d91d5b09e963
2015-03-17 13:46:22 -07:00
Yunqing Wang
c0423abf00 Refactor set vbp thresholds function
Code refactoring.

Change-Id: I73b6fcc0444155ee46c1efa5253c1d608c6439cb
2015-03-17 12:23:32 -07:00
Adrian Grange
ed6824e449 Remove unused ZBIN_BOOST macros
Change-Id: I5169155b20ea3676a6ce58ec77d6aeba07db29d9
2015-03-17 11:53:58 -07:00
Jingning Han
ee41141466 Fix an ioc warning in vp9_pick_inter_mode
Shut off all the metric checks for golden reference frame, if we
decide that it is unlikely to be selected for reference.

Change-Id: Ie457cc1fd43935584403b4982659aed80fb9909c
2015-03-17 10:13:44 -07:00
hkuang
1f841c3218 Add frame parallel decode option to vpxdec.
Change-Id: I0ba02d501d65a2f219fa1bb87b8eb81f7e6ab332
2015-03-16 18:38:49 -07:00
Yaowu Xu
de3097aa23 Merge "Remove duplicate clamping" 2015-03-16 16:56:10 -07:00
Jingning Han
adaffcc010 Merge "Remove ineffective newmv skip checking from vp9_pick_inter_mode" 2015-03-16 16:43:43 -07:00
Jingning Han
4e8daaf960 Merge "Simplify prediction filter search in rtc coding mode" 2015-03-16 16:43:26 -07:00
Jingning Han
82231beced Merge "Refactor column integral projection computation" 2015-03-16 16:43:11 -07:00
Yaowu Xu
3119c24658 Merge "change the order of inter modes evaluated" 2015-03-16 16:14:34 -07:00
Alex Converse
6126afe62e Fix external resize memory issues.
These were uncovered by the chromoting perftest.

Change-Id: Ia5a90fd1718ff757c1484decf3861295260e6722
2015-03-16 15:56:26 -07:00
Yaowu Xu
4611f24797 Remove duplicate clamping
The mvs are clamped in the vp9_find_best_ref_mvs() already.

Change-Id: I9bea5e35aef6007466fe7fca4bc2dc5c17e74222
2015-03-16 15:19:37 -07:00
Jingning Han
c852200f51 Remove ineffective newmv skip checking from vp9_pick_inter_mode
Change-Id: I41ee684cf113a7b5edf280183e51cb08b2e93cc4
2015-03-16 15:06:27 -07:00
Jingning Han
981bb84882 Simplify prediction filter search in rtc coding mode
Reduce unnecessary fetch from MB_MODE_INFO.

Change-Id: Iff89b76d5e2774c00a564e902913a633fa2e1ea9
2015-03-16 14:54:00 -07:00
Yaowu Xu
f2d682fc10 change the order of inter modes evaluated
Change-Id: I10c1ad23b110cf92cb026e895039c215c47abfd0
2015-03-16 12:49:30 -07:00
James Zern
c651f82a36 Merge changes I67890f52,I33c72799
* changes:
  usage.dox: fix encoder/decoder subpage list indent
  usage.dox: fix doxygen warnings in 1.8.x
2015-03-16 12:28:46 -07:00
Jingning Han
2cfddec332 Refactor column integral projection computation
Move the scaling factor outside column projection. This avoids
repeated calculation of the same scaling factor. Profiling shows
that the percentage of vp9_int_pro_col_sse2 of overall cycles
goes from 2.29% down to 1.88%.

Change-Id: I5ac4e324ab2d7f33ba2de66dd2a12e04e04dfd66
2015-03-16 12:07:15 -07:00
Jingning Han
09e0b38a86 Merge "Fix indent in choose_partitioning" 2015-03-16 11:52:12 -07:00
Jingning Han
7cf383d17f Fix indent in choose_partitioning
Change-Id: I4039f8ac75a9cfcc4d07abd0619d1379bb10fe51
2015-03-16 11:01:00 -07:00
Yaowu Xu
51d529a578 vp9_pick_inter_mode(): minor optimizations
1. remove duplicate initialization to mbmi->interp_filter.
2. move mv clamping into ref_frame loop instead of mode checking loop.
3. move the check if last frame is same as golden frame earlier to
avoid initialization of Golden reference related variables.

Change-Id: Idf2d05e19e94a24f69cc289687869fc71d2ff289
2015-03-16 10:08:02 -07:00
Jingning Han
1f9b2b77ad Merge "Fix choose_partitioning threshold setup for speed -5" 2015-03-15 09:04:07 -07:00
Jingning Han
b03cf9317a Fix 1-step refinement search table
Change-Id: I32f0bcb40c6e7ba63bfae487739ededd0b6b2dde
2015-03-14 10:52:11 -07:00
James Zern
ea74c1d78b usage.dox: fix encoder/decoder subpage list indent
use \li to separate the list items contained in conditionals. this
avoids the encode page becoming a sub-item of decode; likely a problem
in <1.8.3.
+ fix encoder conditional, spelling error
+ correct encode page name to match decode 'Encoding'

Change-Id: I67890f52bed8e708bad63fb8819a074e0beff2ca
2015-03-13 18:53:00 -07:00
James Zern
6809ecc820 usage.dox: fix doxygen warnings in 1.8.x
use \li to denote list items with \if.

fixes the following likely visible in <1.8.3:
usage.dox: warning: Invalid list item found
usage.dox: warning: End of list marker found without any preceding list items

Change-Id: I33c72799edf9f8866596ac8f79247050b8c75681
2015-03-13 18:49:03 -07:00
Jingning Han
1f00a9b9d5 Fix choose_partitioning threshold setup for speed -5
The compression performance of speed -5 is on average 12.6% better
than speed -6. At lower bit-rates, the gains are typically 20% or
more. For 2-thread encoding, the speed -5 takes about 1.6x time of
speed -6.

Change-Id: If7a73464a24d33e8f49b9533b51ec51c8da7fc80
2015-03-13 17:01:56 -07:00
Yaowu Xu
0e6459cafa Merge "Fix comments for vpx_codec_enc_config_default()" 2015-03-13 15:56:56 -07:00
Yaowu Xu
a562e90b9b Fix comments for vpx_codec_enc_config_default()
This makes clear that for end-usage, only 0 is supported currently.

Change-Id: I99795807c20df1d71b3c803e8d5f3b36583dcc85
2015-03-13 15:41:01 -07:00
Yaowu Xu
98c58e24f7 Merge "Provide information on codec controls" 2015-03-13 15:39:07 -07:00
Frank Galligan
8e2799e215 Merge "Set default encode test driver to 1 column and 1 thread." 2015-03-13 15:07:16 -07:00
Marco
87999b1c2e Merge "Fix crash with vp9 denoiser on." 2015-03-13 14:31:40 -07:00
Jingning Han
6cceed09cf Merge "Use sdx4df to do 1-step refinement" 2015-03-13 12:57:49 -07:00
Yaowu Xu
268f10669a Provide information on codec controls
The commit updates the comments in vp8cx.h to make it clear which
codec support each of codec control functions.

Change-Id: Ibf876e289d4325bbb61ce19311da60d384624c2f
2015-03-13 11:56:35 -07:00
Marco
e38066a74d Fix crash with vp9 denoiser on.
Crash occured on very first key frame, because denoiser
temporal function was beng entered.

Updated denoiser unittest to set cpu_used from first frame,
and verified fix fixes the crash.

Change-Id: I3be1124b52846fbbe7248d2c3d6136e086c80bc1
2015-03-13 11:10:02 -07:00
Marco
deaf661f45 Merge "Lower bitrate threshold below which cyclic refresh is turned off." 2015-03-13 10:31:35 -07:00
Alex Converse
f8df916931 Merge "Reconcile active_map and cyclic refresh" 2015-03-13 10:20:15 -07:00
Jingning Han
688c99a706 Merge "Reset src buffer only once in vp9_int_pro_motion_estimation" 2015-03-13 09:56:00 -07:00
Jingning Han
1b3499ae8b Merge "Reduce the number of full block SAD calls" 2015-03-13 09:55:52 -07:00
Jingning Han
cce7020f2c Use sdx4df to do 1-step refinement
Change-Id: Ie0c3ef3ae3aedf049b1a296de607730b79c12672
2015-03-13 09:53:15 -07:00
Marco
62a3f53997 Lower bitrate threshold below which cyclic refresh is turned off.
Change-Id: Ib54ab11adf8178eec74f65388a89c8f912c7869a
2015-03-13 09:42:45 -07:00
paulwilkins
b6749aa3a7 Merge "Shorten GF/arf interval in hard scenes." 2015-03-13 08:45:52 -07:00
Frank Galligan
89df6d1ab0 Set default encode test driver to 1 column and 1 thread.
Change-Id: I70ee538609cefad76b8ce9b225bbf8d8447aff23
2015-03-13 08:37:10 -07:00
Yaowu Xu
5784b9074a Merge changes Ic54c88ec,I6f120b65
* changes:
  Added comment for vp9 only codec controls
  Rename a vp9 only control with vp9e prefix
2015-03-12 21:27:04 -07:00
Jingning Han
ba29125f7b Reset src buffer only once in vp9_int_pro_motion_estimation
Change-Id: I5c96b6a25f9df60da65b7af7c92a921b611746e3
2015-03-12 18:50:53 -07:00
Yaowu Xu
1aa75c65cc Merge "vp9_pick_inter_mode(): Use single loop to evaluate inter modes" 2015-03-12 18:43:23 -07:00
Yaowu Xu
5dd146cb26 Added comment for vp9 only codec controls
Comments are updated to reflect that these controls apply to VP9 only,
thereby, to insure the document produced by doxygent to reflect the
same fact too.

Change-Id: Ic54c88ec066aa0ec4552d43dd4a7016e1f810f42
2015-03-12 18:37:44 -07:00
Yaowu Xu
416529069b Rename a vp9 only control with vp9e prefix
Also updated comments and doc to make it clear that the control is
supported in VP9 only.

Change-Id: I6f120b65135fc1185695e9e3dc29fbe0d430824b
2015-03-12 18:33:47 -07:00
Jingning Han
427cdf0a41 Reduce the number of full block SAD calls
This commit uses a 6-point 1-step refine motion search in the
integral projection based full pixel motion estimation, to replace
the current 9-point search.

It reduces runtime cost of speed -6 on some noisy clips, e.g.,
dark720p single thread
33314 b/f, 40.076 dB, 18231 ms ->
33307 b/f, 40.067 dB, 17768 ms

The compression performance for rtc set remains unchanged.

Change-Id: I194ea5a9ce52e5a10baeee36338633adc22f764c
2015-03-12 18:30:57 -07:00
Yunqing Wang
769e6567e9 Merge "Minorly modify model_rd_for_sb_y function" 2015-03-12 17:16:48 -07:00
Jingning Han
7a9d8f1efe Merge "Fix fdct8x8_quant ssse3 overflow issue" 2015-03-12 16:43:09 -07:00
Alex Converse
1bfacd3529 Reconcile active_map and cyclic refresh
Change-Id: Id7f8654aeeb20caa402bc822521b1d72c658f4f9
2015-03-12 16:19:49 -07:00
Yaowu Xu
2b368097c8 vp9_pick_inter_mode(): Use single loop to evaluate inter modes
This commit changes to use single loop to evaluate all inter modes.
There is no impact on compression quality and speed, but allow future
experiment with the order of modes evaluated.

Change-Id: I71696ce1014cbe127e25e98710d835987f5ecc09
2015-03-12 16:14:29 -07:00
Yunqing Wang
5d677c97eb Minorly modify model_rd_for_sb_y function
Added a skip_dc check. If skip_dc = 1, we could eliminate calling
of vp9_model_rd_from_var_lapndz(). This gave slight PSNR & SSIM
gain(<0.1%), and no speed change.

Change-Id: If5ca733366148c86b98e196a00cc890f50e9a3e5
2015-03-12 14:04:14 -07:00
Jingning Han
fcb96b3afd Fix fdct8x8_quant ssse3 overflow issue
This resolves webm issue 968.

Change-Id: Ieb363129b1e135a561141c68211d413226aba754
2015-03-12 12:43:19 -07:00
Deb Mukherjee
791bf5657f Merge "Some rate control adjustments to control overshoot" 2015-03-12 11:10:59 -07:00
Jingning Han
1ff15fbffe Merge "Prevent integer overflow in choose_partitioning" 2015-03-12 09:24:02 -07:00
Jingning Han
90ea10ec91 Merge "Remove unnecessary speed feature checking" 2015-03-12 09:23:51 -07:00
Jingning Han
594890a534 Merge "Apply fast motion search to golden reference frame" 2015-03-12 09:23:41 -07:00
Jingning Han
8fdddd5c01 Merge "Refactor to remove GLOBAL_MOTION" 2015-03-12 09:23:31 -07:00
Yaowu Xu
73508be364 Fix a typo introduced in #94401aff
This fixes all test vector failures

Change-Id: Ie1a9fe0f023f7a0c7e89eb55df1b40ff65302adc
2015-03-12 08:01:08 -07:00
Marco
0adc58037a Merge "Fix visual studio build failure." 2015-03-11 17:19:47 -07:00
Jingning Han
238b6be24b Prevent integer overflow in choose_partitioning
Re-arrange the multiplication and right shift operations to avoid
integer overflow in choose_partitioning.

Change-Id: Ib4005cafb410a67c1960486471d75b6ebe38c4e0
2015-03-11 16:31:42 -07:00
hkuang
4a691aa209 Merge "Refactor the block decode code to make it simpler." 2015-03-11 16:19:14 -07:00
Marco
a291b0b4a3 Fix visual studio build failure.
Change-Id: Ifeb14f945d0f0300eb7b21b38e5720ac1c11a6cf
2015-03-11 16:12:39 -07:00
Jingning Han
313c28f8b8 Remove unnecessary speed feature checking
This commit removes the pred_mv_sad comparison from rtc motion
search, given that a stronger comparison has been done at the
mode search level to eliminate unlikely selected reference frames.

Change-Id: I49b8d24b2174303066fd8eff2102c0648f2869df
2015-03-11 16:11:40 -07:00
Adrian Grange
39d20c6ac3 Merge "Clamp rate correction factor after scaling it" 2015-03-11 16:09:49 -07:00
Jingning Han
54eda13f8d Apply fast motion search to golden reference frame
This commit enables the rtc coding mode to run integral projection
based motion search for golden reference frame. It improves the
speed -6 compression performance by 1.1% on average, 3.46% for
jimred_vga, 6.46% for tacomascmvvga, and 0.5% for vidyo clips. The
speed -6 is about 6% slower.

Change-Id: I0fe402ad2edf0149d0349ad304ab9b2abdf0c804
2015-03-11 16:03:49 -07:00
Jingning Han
1ca4d51b2e Refactor to remove GLOBAL_MOTION
Make the vp9_int_pro_motion_estimation() function return zero
motion vector if high bit depth is turned on, instead of removing
it from compiled codes.

Change-Id: Ia48f010eb590b2d517d5678c394110b326a1a95e
2015-03-11 15:53:15 -07:00
Marco
a250ebf8b8 vpx_temporal_svc_encoder: Update some default settings.
Set flags=0 if layering_mode=0, and set static_thresh=1.

Change-Id: Id9874923b23966a2b1d0e83965add7d5c9d26d16
2015-03-11 14:09:49 -07:00
hkuang
94401aff5c Refactor the block decode code to make it simpler.
Change-Id: I0f983cb821ad7ec6fbefe7895cb8124a8fa39df6
2015-03-11 11:37:16 -07:00
Yaowu Xu
dc902fedb2 Merge "Separate rd_thresh adaption by ref_frame" 2015-03-11 10:41:20 -07:00
Adrian Grange
42a89eb8cc Clamp rate correction factor after scaling it
Added clamp on the rate correction factor after
it has been scaled.

Change-Id: I5d4b46a101987b43c5bcfd7e0bd1b7b4d53640a4
2015-03-11 09:08:15 -07:00
paulwilkins
b29c48b03c Shorten GF/arf interval in hard scenes.
This patch accounts in the first pass stats for blocks that
while not coded as intra, are complex and have an intra error /
best error ratio below a threshold.

The modification shortens the GF arf interval for a particular
class of content that contains a lot of blocks matching the
above criteria. (In one short problem test sequence the average
interval dropped from about 14-15 to 10-11)

The change results in small net gains in metrics results for the
Yt(~0.2%) and yt-hd (~0.5%) sets and is approximately neutral
for the other test sets.

The change is currently shielded by a flag and off by default
pending verification that it does not cause other regressions
in tests on a wider YT test set.

Change-Id: I6b803daa6a4ac09a6f428fb3a18be1ecedd974b7
2015-03-11 14:15:23 +00:00
Yaowu Xu
d549aa3b17 Separate rd_thresh adaption by ref_frame
Only update the rd_thresh factors for modes sharing same reference
frame. This helps overall compression of 6 and 7 by .13% and .19%
respectively without any noticeable speed difference.

Change-Id: Idb3a3879512c5d7d0880034516079949290690c5
2015-03-10 19:06:52 -07:00
Deb Mukherjee
0308e2ee6d Some rate control adjustments to control overshoot
Some rate control adjustments to control overshoot
in the constrained quality mode.

Change-Id: I8907b9a883642d779009d0a138adfa6ba67e7f41
2015-03-10 17:25:10 -07:00
Marco
340260585c Merge "Modify update golden reference update under aq-mode=3 mode." 2015-03-10 11:48:10 -07:00
Marco
fb31aa09e2 Modify update golden reference update under aq-mode=3 mode.
For non-SVC 1 pass CBR: make the GF update interval a multiple of the
cyclic refresh period, and use encoding stats to prevent GF update at certain times.

Change-Id: I4c44cacc2f70f1d27391a47644837e1eaa065017
2015-03-10 10:54:00 -07:00
Yunqing Wang
3e637a70da Merge "Accumulate tx_totals counters in multi-threaded encoder" 2015-03-10 10:52:55 -07:00
Yaowu Xu
12943e722d Merge "Enable using Golden reference in choose_partition()" 2015-03-10 10:48:52 -07:00
paulwilkins
4b01a2d350 Merge "Allow q adjustment for VPX_CQ and VPX_CBR." 2015-03-10 10:45:02 -07:00
Yunqing Wang
f0cf9719d0 Accumulate tx_totals counters in multi-threaded encoder
Tx_totals counters weren't handled correctly in multi-thread
case, which caused the mismatch while encoding using threads > 1.
This patch fixed that.

Change-Id: Ice9b0386f57175fb92a0bdcd5042686a3106246a
2015-03-10 10:02:49 -07:00
Adrian Grange
78df712216 Fix vp9_compute_qdelta_by_rate loop behavior
The return value from vp9_compute_qdelta_by_rate, which is
a delta value for the quantizer, could never be 0 if
(qindex == rc->worst_quality).

This occurs because target_index was setup unconditionally
in the loop and yet the loop counter stopped at
(rc->worst_quality - 1).

Change-Id: I6b59cd9b5811ff33357e71cd7d814c5e53d291f2
2015-03-10 09:14:54 -07:00
Yaowu Xu
059a473b35 Enable using Golden reference in choose_partition()
Choose_partition uses only the last frame as reference frame in making
partition decision, this commit adds the check on how well Golden
frame with (0,0) predicts the current block, and uses GF(0,0) as
basis for partition decision if it produces better prediction.

The commit improves rtc speed 6 and 7 encoding by 0.14% and 0.19%
respectively.

Change-Id: I156acf925bd6e0b586d48155d1940d27270a3915
2015-03-10 08:57:28 -07:00
Frank Galligan
6eaca27df2 Refactor read_intra_frame_mode_info
Change-Id: I56b0614154408e8ec613784b2007374df00fbf17
2015-03-09 16:25:01 -07:00
Alex Converse
066ed601a5 Merge "Don't waste time partitioning skip superblocks." 2015-03-09 13:02:16 -07:00
Jingning Han
9708f9d66a Merge "Skip golden ref frame check when it is same as last ref frame" 2015-03-09 12:27:19 -07:00
Jingning Han
6245a91e0b Skip golden ref frame check when it is same as last ref frame
When golden reference frame is refreshed, the next frame has both
its last and golden reference frames point to the same reference
frame in real-time coding mode. Experiments suggest that using
two separate reference frames for frames right after golden refresh
frame does not provide further compression performance advantage.
This commit hence retains the current encoder implementation and
shuts off the mode search over golden reference frame in this case.

It makes the encoder run slightly faster at no coding performance
change.

Change-Id: I1561f7799253a10e675d05c63c1749fe9e85b472
2015-03-09 11:14:55 -07:00
Alex Converse
06b59299c8 Don't waste time partitioning skip superblocks.
Force 64x64 partitioning when a whole superblock is SEGMENT_LVL_SKIP. This
drops encode times of screens mostly at rest by 20%.

Change-Id: Ieba554b0b8a0c1679aae784a8bd11f038ab942c3
2015-03-09 11:02:05 -07:00
paulwilkins
2cff9c4efe Allow q adjustment for VPX_CQ and VPX_CBR.
Adjustment previously only enabled in VBR mode.

This patch allows adjustment of min and max q for CBR
and adjustment of max q only for CQ mode.

Change-Id: Id5e583f3d50453cd544fc57249acacd946457482
2015-03-09 17:13:55 +00:00
Marco
5d676d560f Add aq-mode=3 to ethread test.
Change-Id: I619a2be502f1d2eb0ae746f7fcb465d19ddae048
2015-03-09 09:48:39 -07:00
Yunqing Wang
969dd8f128 Merge "vp9_ethread: fix me consts initialization to support aq_mode=3 encoding" 2015-03-09 09:42:12 -07:00
Jingning Han
d2b6a4cc80 Merge "Move pred_mv assign outside integral projection motion search" 2015-03-09 09:34:26 -07:00
Deb Mukherjee
a437f7b980 Merge "Reduce default overshoot/undershoot params to 25" 2015-03-09 09:21:35 -07:00
Yunqing Wang
c4fb2d7cc7 Merge "Modify the setting of transform skip flags in non-rd mode" 2015-03-09 08:35:57 -07:00
Yunqing Wang
6e0ec0b2d9 vp9_ethread: fix me consts initialization to support aq_mode=3 encoding
While turning on "--aq_mode=3", the quantizers are updated by each
thread. Fixed the me consts initialization function to make sure
that the correct thread data are updated.

Change-Id: Ied27bb7bae76fc3fa2cda4f8c35ac0b46271bef4
2015-03-06 16:31:46 -08:00
Johann
b12f531cc5 Merge "Cherry pick libyuv VS fix" 2015-03-06 16:04:59 -08:00
Johann
bdb46b2957 Cherry pick libyuv VS fix
Change-Id: I1f2e077af87d29b07eaf7acaec8d955e00da9333
2015-03-06 13:00:01 -08:00
hkuang
9d44fd6bc5 Remove some unnecessary code in thread context copy.
Change-Id: Iddf098e1bae9c10fc2f325f84156f50a0bd0055a
2015-03-06 10:29:15 -08:00
Hangyu Kuang
a1ef75bb63 Merge "Only wait for previous frame's motion vector if needed." 2015-03-06 10:27:26 -08:00
Marco
274af39eae Merge "Set the threads/tile_columns in vpx_temporal_svc_encoder." 2015-03-06 10:00:18 -08:00
Marco
c76ebffdcc Set the threads/tile_columns in vpx_temporal_svc_encoder.
Change-Id: I794e8b64f26ebe68d7f18c3a11cb7c80e1cd3110
2015-03-06 09:53:55 -08:00
Yunqing Wang
268f260d64 Modify the setting of transform skip flags in non-rd mode
While searching for the best mode in non-rd case, SSE of
a partition block is calculated and the transform size is set.
This patch rewrites the skip checking conditions based on
transform size instead of partition size to be more precise.

Small gains were seen in rtc set borg test (speed 6).
AVG PSNR: 0.087%, overall PSNR: 0.073%, SSIM: 0.146%.
No noticeable speed change.

Change-Id: I5603ca5339c784dfa02263f4005988ccd8c32f6e
2015-03-06 09:22:00 -08:00
Yaowu Xu
0f37601fd7 Merge changes I1b972c94,I9c897d32
* changes:
  Prevent invalid memory access
  Use correct bsize for uv
2015-03-06 07:27:59 -08:00
Hangyu Kuang
d5fa786b4f Only wait for previous frame's motion vector if needed.
Change-Id: Iecce685a33b64844446c0009f21bc85566d7469f
2015-03-05 16:09:44 -08:00
Yaowu Xu
8cbeb7cf36 Prevent invalid memory access
Change-Id: I1b972c945274254d896d772d859840b2f8211b4f
2015-03-05 14:57:11 -08:00
hkuang
915d5c12d3 Merge "Fix a tsan error bug in frame parallel decode." 2015-03-05 14:55:27 -08:00
Alex Converse
feda5d244c Merge changes I219c287b,I6adee670
* changes:
  Call encoder control before running ethread test.
  Don't copy thread data for the main thread.
2015-03-05 14:43:42 -08:00
Alex Converse
b21e361f8d Merge "Fix misleading indentation." 2015-03-05 14:43:38 -08:00
Alex Converse
587a0b3ef9 Call encoder control before running ethread test.
The first value of video->frame() is 15 because of the source range used.

Change-Id: I219c287b500fa376160d6dcfb937092e577ec959
2015-03-05 14:22:27 -08:00
Deb Mukherjee
7a386d83eb Reduce default overshoot/undershoot params to 25
Reducing these values from 100 makes rate control tighter by
default.

Change-Id: I979409c93e6f19e128898f08ad581bf67eb0f824
2015-03-05 14:00:03 -08:00
Frank Galligan
627f8fb676 Merge "Use 8 threads by default for VP9 encodes" 2015-03-05 13:58:26 -08:00
Frank Galligan
26f4e7dc04 Merge "VP9: turn on tile-columns and frame-parallel-mode by default" 2015-03-05 13:58:21 -08:00
Alex Converse
ad01d275e9 Merge "Don't inline cost_coeffs." 2015-03-05 13:54:44 -08:00
Adrian Grange
6e3be5c3b6 Merge "Fix valgrind memcpy memory overlaps warning" 2015-03-05 12:52:57 -08:00
Alex Converse
2eb113d00a Don't inline cost_coeffs.
It was tiny when it was orginally marked INLINE. Forcing this function
to be inlined prevents the compiler from inlining its much smaller
callers.

No measurable speed impact, 28320 byte smaller libvpx.a

Change-Id: I6bf4c917157d15cbadb3cd3e20a9e82d35dc7d6f
2015-03-05 12:39:02 -08:00
Alex Converse
56cc37c642 Fix misleading indentation.
Change-Id: Ic82b039a3d42f9aa01b85a3a69facfaa84b43a53
2015-03-05 12:10:56 -08:00
Alex Converse
71d5a59c6d Don't copy thread data for the main thread.
Change-Id: I6adee6704cacfeae0ed0b217a91095457d1be74a
2015-03-05 12:10:56 -08:00
Jingning Han
fda0410822 Move pred_mv assign outside integral projection motion search
Change-Id: I040b066fdce08e2f05115a22ea808715aa147779
2015-03-05 11:44:10 -08:00
Jingning Han
87bf5203af Merge "Move integral projection motion search to vp9_mcomp.c" 2015-03-05 09:25:16 -08:00
Yaowu Xu
b573fef76d Use correct bsize for uv
Change-Id: I9c897d32af6c3a956bb6f424a74c12737727038a
2015-03-05 08:20:35 -08:00
Johann
42eb97eb91 Declare function used by 'once' with 'void' parameters
Visual Studio is exceptionally picky about this:
vp9_reconintra.c(900): warning C4113: 'void (__cdecl *)()' differs in
parameter lists from 'void (__cdecl *)(void)'
[.build-x86_64-win64-vs10\vpx.vcxproj]

Change-Id: I564c7415f4608fd962be8c699d6133a996b545f7
2015-03-04 15:34:55 -08:00
hkuang
c45b9564b9 Merge "Fix variable shadowing." 2015-03-04 14:23:01 -08:00
Adrian Grange
4b546583c4 Merge "Small rationalization of code in vp9_first_pass" 2015-03-04 12:49:58 -08:00
hkuang
31fae6ac08 Fix variable shadowing.
Change-Id: I287c61ad4aa85654aef3c871a62131bcd0d891ac
2015-03-04 11:40:20 -08:00
hkuang
2f06f5087e Merge "Remove unnecessary loopfilter init." 2015-03-04 11:27:58 -08:00
Adrian Grange
a34a042615 Merge "Make encoder buffer allocation dynamic" 2015-03-04 10:54:10 -08:00
Adrian Grange
fed9e1fee9 Small rationalization of code in vp9_first_pass
Change-Id: I87cc0e038171c60a957298827e312fead500f7fb
2015-03-04 10:49:03 -08:00
Jingning Han
50c06052e9 Merge "Use SAD value to set chroma cost flag" 2015-03-04 10:47:56 -08:00
Jingning Han
2deecdd5cb Move integral projection motion search to vp9_mcomp.c
Make it a general purpose fast motion estimation function, to be
used in the mode search process.

Change-Id: Ib354cb0e664dc61c30c0b2314297835ee75b157a
2015-03-04 10:30:15 -08:00
Jingning Han
7d8061a44a Use SAD value to set chroma cost flag
This saves an extra 64x64 variance calculation and replaces two
32x32 variance functions with sad functions. The compression
performance change is unnoticeable.

Change-Id: I6d33868695664ec73b56c42945162ae61c484856
2015-03-04 09:46:39 -08:00
Jingning Han
0fe8304d0b Merge "Properly handle the boundary blocks for integral projection search" 2015-03-04 09:01:33 -08:00
Adrian Grange
3807dd82ab Make encoder buffer allocation dynamic
Frame buffers are now allocated dynamically on-demand.

Entries in the reference frame map, cm->ref_frame_map,
may now be set to -1 (INVALID_IDX) to indicate that
there is not a valid reference buffer in that "slot".

All slots in the reference frame map are now initialized
to the empty state (-1) and each buffer is initialized
to have a reference count of 0.

Change-Id: Id1afe98de98db4ae8b2dfefed7889c3b28c68582
2015-03-04 07:58:32 -08:00
Deb Mukherjee
87d1a488ed Merge "dc quantizer fix for 32x32 transforms" 2015-03-03 23:23:44 -08:00
Jingning Han
540318d3f8 Merge "Scale the normalization factor depending on the block size" 2015-03-03 19:04:34 -08:00
Frank Galligan
93a0189936 Use 8 threads by default for VP9 encodes
BUG=https://code.google.com/p/webm/issues/detail?id=964

Change-Id: I70679d0f139b8e0962f7e19eb56b34060953e9b0
2015-03-03 17:05:17 -08:00
Jingning Han
e5fe165840 Properly handle the boundary blocks for integral projection search
Use rectangular block size for integral projection motion estimation
if the the 64x64 block has over half block outside the frame. This
avoids the issue that the motion information of these blocks is
dominated by the extended pixels, instead of the pixels of interest.

Change-Id: I22f4d2bb7f6a20db9b3f5e2e5463a7f4b9d1b737
2015-03-03 16:15:12 -08:00
Deb Mukherjee
6910e92d04 dc quantizer fix for 32x32 transforms
The rounding factor needs to be scaled down by a factor of 2.
Also, the quantized and dequantized coefficients are memset to 0
when dc quantizer is used.

Change-Id: Ifa68bab02addbf1b83d249c5b4cbd5cda796b1cf
2015-03-03 15:58:27 -08:00
Yunqing Wang
6e5115e12e Merge "fix a race condition caused by intra function pointer initialization" 2015-03-03 15:47:06 -08:00
Yaowu Xu
767d63d076 Merge "Adapt color sensitiviy threshold to luma signal energy" 2015-03-03 15:33:55 -08:00
Adrian Grange
852f62fde5 Fix valgrind memcpy memory overlaps warning
Change-Id: Id0bb162b48b891c5c849f0411ef2ac0aa4bbe261
2015-03-03 15:06:34 -08:00
hkuang
a723f5ecd1 Fix a tsan error bug in frame parallel decode.
A frame may be waiting for an out of border pixel from another
frame. A frame's row progress variable is set to -1 when start being decoded
and another frame may be waiting for -2 row pixel from this frame.
In this case, vp9_frameworker_wait will return directly and skip the waiting
which leads to tsan error between threads.

Change-Id: Id16604915fb598b823e34393f696e3aa46fb6422
2015-03-03 12:58:25 -08:00
Jingning Han
a521008201 Scale the normalization factor depending on the block size
Change-Id: I0a26994bf65ea224e496b09af2ce71e1a4210433
2015-03-03 11:29:46 -08:00
Frank Galligan
f5c36a5ced VP9: turn on tile-columns and frame-parallel-mode by default
Most of the current decoders use tile-based multithreading. Also
most of the current decoders need frame_parallel_decoding_mode
turned on to enable multithreaded decoding. tile-columns is
limited by resolution, so setting to max (6) is fine.

BUG=https://code.google.com/p/webm/issues/detail?id=963

Change-Id: I6e7ac3485d96bf0c69e06706cbb326dd38be0020
2015-03-03 11:20:11 -08:00
Yaowu Xu
47ac3ea0bb Adapt color sensitiviy threshold to luma signal energy
Instead using only a fixed threshold, this commit adapts the threshold
for color sensitivity decision to luma signal energy: chroma channel's
sse is at least 1/6 of that in luma for color sensitivity flag to be
set to active.

This recoups a large portion of the speed loss due to accounting for
chroma component costs in RTC mode decision.

Change-Id: Ie01f747f6037dba6a1d1ed3e10b71a0ef1abc42c
2015-03-03 11:15:13 -08:00
hkuang
f9420b45e5 Remove unnecessary loopfilter init.
Loopfilters are init in vp9_decode_frame.

Change-Id: I4fbf6286b9b231451452e4ef3c19877a7b9a6768
2015-03-03 10:40:39 -08:00
Yunqing Wang
55639c383b fix a race condition caused by intra function pointer initialization
This patch fixed webm issue 962.
(https://code.google.com/p/webm/issues/detail?id=962)
The data races occurred when an encoder and a decoder were created
at the same time, and the function pointers were initialized twice.

Change-Id: I8851b753c4b4ad4767d6eea781b61f0ac9abb44b
2015-03-03 09:58:37 -08:00
Johann
6cf7b3b240 Merge "libyuv: update to r1305" 2015-03-03 09:20:02 -08:00
James Zern
40f177ab3e ResizeCspTest: request PSNR packets
without VPX_CODEC_USE_PSNR they're only generated by default with
--enable-internal-stats

Change-Id: I9a5a8874a3aa4bde39ae09a4101ed5616c83c9a1
2015-03-02 18:54:22 -08:00
Johann
223bf29307 libyuv: update to r1305
MIPS build fixes

https://code.google.com/p/webm/issues/detail?id=957

Change-Id: I9d53900af36d783c369b5dff27a7479cb94fd16b
2015-03-02 15:19:31 -08:00
Jingning Han
1790d45252 Use variance metric for integral projection vector match
This commit replaces the SAD with variance as metric for the
integral projection vector match. It improves the search accuracy
in the presence of slight light change. The average speed -6
compression performance for rtc set is improved by 1.7%. No speed
changes are observed for the test clips.

Change-Id: I71c1d27e42de2aa429fb3564e6549bba1c7d6d4d
2015-03-01 10:42:56 -08:00
Jingning Han
f4e0eb17e8 Merge "Fix source frame border extension" 2015-02-27 18:19:18 -08:00
Jingning Han
fe85fabbac Fix source frame border extension
This commit fixes an issue in source frame border extension. It
causes certain frame resolution such as 640x480 to have a portion
of the right/bottom extension filled by zeros, which misleads
motion search and degrades transform coding performance when large
block size is used.

This fix improves the speed 2 compression performance of a few
yt sequence, typically ranging from 1% - 2%, up to 5% at median
to low bit-rate.

Change-Id: Id6b09a5695d9e7651c6dfbc2c6a72288b08af7fb
2015-02-27 15:48:01 -08:00
Adrian Grange
94bba48525 Merge "Fix calc_highbd_psnr" 2015-02-27 15:42:08 -08:00
Alex Converse
2b2fc812f1 Merge "Make SVC compatible with external resize." 2015-02-27 14:37:48 -08:00
Adrian Grange
54293ee3c7 Fix calc_highbd_psnr
Should use the crop dimensions of the frame rather
than the extended size.

Change-Id: I49ed041a46ff0753d43e074020857b7ff2f95e17
2015-02-27 14:05:02 -08:00
Marco
2b0ed0842f Merge "Fix arithmetic overflow warnings." 2015-02-27 11:53:57 -08:00
James Zern
dfc888f1f8 Merge "use LC_ALL=C to sort libvpx_*srcs.txt" 2015-02-27 10:59:59 -08:00
Jingning Han
89ee460ee4 Merge "Refactor integral projection based motion estimation" 2015-02-27 09:49:30 -08:00
Jingning Han
c4cb8059ff Merge "Fix high bit-depth loop-filter sse2 compiling issue - part 4" 2015-02-27 09:49:10 -08:00
Jingning Han
43bb97f7d0 Merge "Fix high bit-depth loop-filter sse2 compiling issue - part 3" 2015-02-27 09:49:00 -08:00
Jingning Han
4800b0e80d Merge "Fix high bit-depth loop-filter sse2 compiling issue - part 2" 2015-02-27 09:48:51 -08:00
Jingning Han
47431f6c1e Merge "Fix high bit-depth loop-filter sse2 compiling issue - part 1" 2015-02-27 09:48:39 -08:00
James Zern
8ef6dadbbe test-data.mk: fix perf test data dependency
both the encode and decode perf tests require niklas_1280_720_30.yuv
broken since:
28eebf3 Merge "tests: add a shorter 720p test clip"
7839d03 tests: add a shorter 720p test clip

Change-Id: I51ebbf7261832e25d8f2c1da5c7df5c2e47f748e
2015-02-26 23:14:54 -08:00
James Zern
0f96f02b94 use LC_ALL=C to sort libvpx_*srcs.txt
Change-Id: I387da141ebade4fc4d2f3c0a2b6aa5aaea091c0c
2015-02-26 20:48:40 -08:00
James Zern
099049efb3 tools_common.sh: use $$ in VPX_TEST_OUTPUT_DIR
a bit simpler than invoking awk for rand()

Change-Id: I36ac474708f7bf0157ae59b882c2a9f69b0aaf41
2015-02-26 18:30:24 -08:00
James Zern
f1e0183c81 Merge "tools_common.sh: add directory name to error output" 2015-02-26 15:54:41 -08:00
Marco
c3f7bb16b4 Fix arithmetic overflow warnings.
Change-Id: Ib85b5bc135aa0907a76b8c74faafe577e27d014f
2015-02-26 15:27:21 -08:00
Jingning Han
8ec22296b3 Fix high bit-depth loop-filter sse2 compiling issue - part 3
Change-Id: Idb14b9a285f8098126f967c5e2750221d6a58f69
2015-02-26 15:21:22 -08:00
Yaowu Xu
776a6cfd9e Merge "Fix the encoder to support profile change" 2015-02-26 15:13:28 -08:00
Yaowu Xu
d973fbb1de Merge "Correct parameter order in a function call" 2015-02-26 15:13:06 -08:00
James Zern
28eebf3e36 Merge "tests: add a shorter 720p test clip" 2015-02-26 14:51:44 -08:00
Jingning Han
73a00d3219 Refactor integral projection based motion estimation
Support variable block size integral projection based motion
estimation.

Change-Id: Iee6d65e44df4480aa13fb7b84b9c91914b89caa1
2015-02-26 14:48:59 -08:00
James Zern
2ebe0aee11 tools_common.sh: add directory name to error output
+ add a helper function to reduce the duplication

this is a bit clearer when the environment variable is set, but the
directory is missing

Change-Id: I08f9b56122b5741bb40a5f795f7f82f5b49f1047
2015-02-26 12:57:30 -08:00
Jingning Han
14ff1cb74a Fix high bit-depth loop-filter sse2 compiling issue - part 2
Change-Id: I6728b69bb3dff1daa64ff7142f691e80a089f1c4
2015-02-26 12:41:19 -08:00
Yaowu Xu
754bbcfdc8 Fix the encoder to support profile change
Change-Id: Iefb928ad1174e274409facfb44f80265ff0f7683
2015-02-26 11:41:01 -08:00
Yaowu Xu
387bb8bed7 Correct parameter order in a function call
Change-Id: Ibd87db1c4371edcbe193d39df2fdc07d3842c21a
2015-02-26 11:39:57 -08:00
paulwilkins
e2b4ef1313 Merge "Account for rate error in GF group Q calculation." 2015-02-26 08:20:08 -08:00
James Zern
7839d0382a tests: add a shorter 720p test clip
niklas_1280_720_30.y4m 60 frames @ 30fps
only a small number of frames are being used; this reduces the test data
download size in non-perf-test cases by >500M.
retain niklas_1280_720_30.yuv for encode+decode perf tests

Change-Id: I56b3433104acd462f952a9554280de5a3ec0b6d2
2015-02-25 19:12:03 -08:00
Alex Converse
6ea83fdfcb Make SVC compatible with external resize.
Fixes https://code.google.com/p/webm/issues/detail?id=943

Change-Id: I6177bf6ab6b31a22d2652732f579b8aed3f28887
2015-02-25 14:05:51 -08:00
Jingning Han
3e1d14a6ce Merge "Motion compensated reference refinement" 2015-02-25 12:33:09 -08:00
Jingning Han
4c5a4efc38 Merge "Re-distribute hierarchical vector match pattern" 2015-02-25 10:33:25 -08:00
Jingning Han
b7050c0be3 Motion compensated reference refinement
This commit applies one-step refinement search to the resulting
motion vector of the integral projectiion based motion estimation,
per 64x64 block. It improves the coding performance of speed -6.

pedestrian 1080p 500 kbps
51735 b/f, 36.794 dB, 16044 ms ->
51382 b/f, 36.793 dB, 16282 ms

cloud 1080p 500 kbps
24081 b/f, 37.988 dB, 14016 ms ->
23597 b/f, 38.076 dB, 12774 ms

vidyo1 720p 1000 kbps
16552 b/f, 40.514 dB, 8279 ms ->
16553 b/f, 40.543 dB, 8510 ms

The rtc set compression performance is improved by 0.5%.

Change-Id: I3d09bea2caf58b2a4f3b38aa26fffafcbe9a2c17
2015-02-25 10:32:09 -08:00
Yaowu Xu
bcdac7b4be Merge "Fix a trivial memory leak" 2015-02-25 10:26:44 -08:00
Yunqing Wang
419ff1352e Merge "Fix ssse3 quantize_fp functions while skip=1" 2015-02-25 10:10:10 -08:00
Jingning Han
2080e4b206 Fix high bit-depth loop-filter sse2 compiling issue - part 1
The intrinsic statement _mm_subs_epi16() should take immediate.
Feeding variable as its input argument will cause compile failure
in older version gcc.

Change-Id: I6a71efcc8d3b16b84715e0a9bcfa818494eea3f4
2015-02-25 09:59:50 -08:00
Jingning Han
0f57d0a682 Merge "Fix fwd transform sse2 build issue on older gcc version" 2015-02-25 09:32:00 -08:00
Jingning Han
e47033319d Fix fwd transform sse2 build issue on older gcc version
Change-Id: I3e0e53d129552babf29e6c5d047483733983973c
2015-02-24 23:25:21 -08:00
James Zern
044bfa3949 Merge "vp9_loopfilter: quiet integer constant size warnings" 2015-02-24 19:09:32 -08:00
Hanno Böck
b5d0a20170 Fix a trivial memory leak
Change-Id: I1108d720bb3b30586b128dd01ce608e1e62b1756
2015-02-24 16:06:52 -08:00
Jingning Han
5b87f1bb5a Fix high bit-depth loop-filter sse2 compiling issue - part 4
Change-Id: I39f56f60425836f2e1ec07da71edd4810a4c78bb
2015-02-24 14:50:30 -08:00
Jingning Han
f87e315e1e Re-distribute hierarchical vector match pattern
This commit modifies the hierarchical vector match patter. It
avoids repeated SAD computation at same points. The function
vp9_vector_sad_sse2 is called 12 times per 64x64 block, instead
of 15 times as before. The effective coverage remains the same.

Change-Id: I91ad9d27d40db8963c907d02af84e10702136994
2015-02-24 11:48:38 -08:00
James Zern
279d350f0b vp9_loopfilter: quiet integer constant size warnings
mark uint64_t constants with 'ULL'

Change-Id: I7648e161b4004fba35e1fa7ab79e34cc19e39716
2015-02-24 11:13:16 -08:00
Yunqing Wang
58e0159c80 Fix ssse3 quantize_fp functions while skip=1
In ssse3 functions, DEFINE_ARGS macro hard codes qcoeff and dqcoeff
to r3 and r4. If skip is 1, qcoeff and dqcoeff need to be loaded
from the stack, which doesn't work because of the above definitions.
Currently, skip=1 case is not used in the encoder. This patch fixed
the issue, so it can be turned on later.

Change-Id: I998d696b1a7a85dca2b3bcee790b21c21e039147
2015-02-24 10:37:05 -08:00
Yaowu Xu
6cf3031286 fix the propagation of color space info in decoder
This addresses the issue #960

Change-Id: Iddf45b4bd4f53cb0ddfd879e800a071cd843b915
2015-02-23 13:01:14 -08:00
paulwilkins
8d7f53f04c Account for rate error in GF group Q calculation.
When GF group adaptive maxQ is enabled this patch accounts
somewhat for accumulated error in the rate control.

This improves accuracy quite a bit on many clips especially
when there is  overshoot.

Examples when the overshoot and undershoot command line
parameters are set to 100:

Hall @ 1200 overshoot is reduced from 67-24%.
Akiyo @ 400 undershoot is reduced from 28%-15%.

Setting a lower value for undershoot or overshoot still
reduces the error further.

Impact on metrics is mixed with some gains in average psnr
but generally a little lower (e.g. 0.5%) on overall and ssim.

The GF group adaptation is still off by default in this patch.
Compared to with the head, enabling this mode now gives
big average psnr gains on the YT sets (e.g. YT_HD >11.2%),
a drop in overall PSNR (YT-HD 3.9%) and a smaller drop or
neutral for SSIM.

Change-Id: If4b32cd0740d3fb941317b374f9c2951954eee90
2015-02-23 10:57:27 +00:00
Adrian Grange
44adb8e283 Merge "Remove redundant test" 2015-02-20 16:13:55 -08:00
Marco
c9f660d895 Merge "Remove a few unneccessary multiplications in denoiser." 2015-02-20 14:42:02 -08:00
Marco
8f84fbe756 Remove a few unneccessary multiplications in denoiser.
Change-Id: I3edbb7cc67203fbbf32c6fd4a08015ca9d9ed53e
2015-02-20 11:55:11 -08:00
Hangyu Kuang
8724d31d12 Move dequant table from VP9_COMMON to VP9_COMP as decoder
does not need it any more.

This reduces VP9_COMMON size from 25776 bytes to 17584 bytes(~31%).

Change-Id: Ic5daea732ccefb6d512b048af7983f0efe08589b
2015-02-20 11:12:42 -08:00
Marco
a1b402e71c Merge "Adjustments to cyclic refresh (aq-mode=3)." 2015-02-20 09:55:05 -08:00
Jingning Han
6728655422 Merge "Add high bit depth support to rtc sub8x8 block coding" 2015-02-20 09:35:18 -08:00
Marco
0187f4b411 Adjustments to cyclic refresh (aq-mode=3).
Target higher delta-qp for big blocks with zero motion,
and for segment#1: avoid 64x64 partition size and force 8x8 tx size.

Metrics on RTC set mostly positive: SSIM up by ~4%, PSRN by ~1.5%.
Doesn't seem to be any change in speed.

Change-Id: I1f68fa3c4f62dab3b90cc58041f05ebb048ae5ac
2015-02-20 08:47:59 -08:00
Jingning Han
6f4245894a Add high bit depth support to rtc sub8x8 block coding
This commit adds proper buffer handle to support high bit depth
in rtc sub8x8 block coding.

Change-Id: Ibaf8a2160194121aec9ca68b8094817fed9ccaea
2015-02-20 08:36:33 -08:00
Hangyu Kuang
a28a8cb726 Merge "Optimize the dequantization process on decoder side." 2015-02-20 08:23:54 -08:00
Adrian Grange
f03627347e Merge "Fix control string in firstpass stats fprintf" 2015-02-19 16:36:43 -08:00
Hangyu Kuang
bdd249be31 Optimize the dequantization process on decoder side.
Change-Id: I00621ff7165bbe86a18794b4a816976c9effaf78
2015-02-19 15:43:15 -08:00
Yunqing Wang
5e57729601 Merge "Improve skip_txfm thresholds in the non-rd mode selection" 2015-02-19 15:31:02 -08:00
Adrian Grange
2ae314fe3a Fix control string in firstpass stats fprintf
20 items in the control string but only 19 arguments.

Change-Id: I51dab9aa1c58c653b52395005a9cb41f09feb484
2015-02-19 15:18:30 -08:00
Jingning Han
216b171d63 Merge "Integral projection based motion estimation" 2015-02-19 15:08:11 -08:00
Yunqing Wang
81fc5bf81c Improve skip_txfm thresholds in the non-rd mode selection
Modified the thresholds of deciding whether or not to skip
the transforms in model_rd_for_sb_y(). Used zbin[] instead
of dequant[] to be more precise. Also, modified the checking
coditions.

Rtc set borg test results (at speed 6) showed:
average PSNR gain: 0.138%, overall PSNR gain: 0.158%,
and SSIM gain: 0.177%.

The data rate test was modified slightly as suggested by
Marco.

Change-Id: Ieaf633ab77f4838cb3c45cf69065b29d55f8ae6c
2015-02-19 14:30:46 -08:00
Jingning Han
ed2dc59c1b Integral projection based motion estimation
This commit introduces a new block match motion estimation
using integral projection measurement. The 2-D block and the nearby
region is projected onto the horizontal and vertical 1-D vectors,
respectively. It then runs vector match, instead of block match,
over the two separate 1-D vectors to locate the motion compensated
reference block.

This process is run per 64x64 block to align the reference before
choosing partitioning in speed 6. The overall CPU cycle cost due
to this additional 64x64 block match (SSE2 version) takes around 2%
at low bit-rate rtc speed 6. When strong motion activities exist in
the video sequence, it substantially improves the partition
selection accuracy, thereby achieving better compression performance
and lower CPU cycles.

The experiments were tested in RTC speed -6 setting:
cloud 1080p 500 kbps
17006 b/f, 37.086 dB, 5386 ms ->
16669 b/f, 37.970 dB, 5085 ms (>0.9dB gain and 6% faster)

pedestrian_area 1080p 500 kbps
53537 b/f, 36.771 dB, 18706 ms ->
51897 b/f, 36.792 dB, 18585 ms (4% bit-rate savings)

blue_sky 1080p 500 kbps
70214 b/f, 33.600 dB, 13979 ms ->
53885 b/f, 33.645 dB, 10878 ms (30% bit-rate savings, 25% faster)

jimred 400 kbps
13380 b/f, 36.014 dB, 5723 ms ->
13377 b/f, 36.087 dB, 5831 ms  (2% bit-rate savings, 2% slower)

Change-Id: Iffdb6ea5b16b77016bfa3dd3904d284168ae649c
2015-02-19 13:47:19 -08:00
Jingning Han
83559e7357 Fix a check condition in nonrd_pick_partition
Change-Id: Ic92fb4b16948f745c218351b24fdafecf9abce3a
2015-02-19 09:54:55 -08:00
hkuang
02bd4edc2a Merge "Fix the frame parallel invalid file test failure on ARM." 2015-02-18 14:09:28 -08:00
James Zern
d93fe856b9 Merge "test_vector_test: fix build with --disable-(vp8|vp9)" 2015-02-17 14:05:32 -08:00
hkuang
2fa9e9e227 Fix the frame parallel invalid file test failure on ARM.
There is a corner case that when a frame is corrupted, the following
inter frame decode worker will miss the previous failure. To solve
this problem, a need_resync flag needs to be added to master thread
to keep control of that.

Change-Id: Iea9309b2562e7b59a83dd6b720607410286c90a6
2015-02-17 09:43:34 -08:00
James Zern
0dd591bedd loop_filter_rows_mt: remove dependency on 'last_height'
using this to control reallocation would miss a change if the function
were not called for every frame.
fixes potential memory corruption by the subsequent memset

Change-Id: I4c6bb6ab68803104fc824c7e27cc2f9b2cf53e33
2015-02-13 19:11:23 -08:00
James Zern
5b9dacd297 test_vector_test: fix build with --disable-(vp8|vp9)
use VP[89]_INSTANTIATE_TEST_CASE case when possible to disable the tests if
the codec is unavailable.
broken since:
be6aead Try again to merge branch 'frame-parallel' into master branch.

Change-Id: I8d81c5ba3b951f82be94bfaed6be194e4289baec
2015-02-13 18:52:25 -08:00
Yaowu Xu
c5718a7aa3 Merge "Fix an encoder/decode mismatch bug" 2015-02-13 16:40:41 -08:00
Yaowu Xu
4bc7f4828f Fix an encoder/decode mismatch bug
This commit prevent the encoder to update last_frame_type when a frame
is dropped in the encoder. Prior to this fix, if there is a dropped
frame immediatedly after a key frame, decoder would have the value of
last_frame_type as key frame, different from encoder as the dropped
frame in encoder would have updated the value to an inter frame. This
leads to different probability update in encoder and decoder, thereby
encoder/decoder mismatch.

This fixes issue #941

Change-Id: I27115224b138bec43ae3916c016574f5740822b0
2015-02-13 15:45:47 -08:00
Marco
d4761cff36 Merge "Replace some operations with shift in encoder_breakout." 2015-02-13 15:28:49 -08:00
Adrian Grange
4a03baa2f6 Merge "Improve readability: move return statements" 2015-02-13 15:28:01 -08:00
Adrian Grange
d240180022 Remove redundant test
Change-Id: I11e4fd8dcd44b0475f3bff0545a035feb223ce55
2015-02-13 14:57:14 -08:00
Marco
b1940bf5fe Replace some operations with shift in encoder_breakout.
Replaced a divide by 9 with 8, so some very small difference,
but otherwise no change in behavior.

Change-Id: I1079ae3c41e0789ff0bc6fa9940a238b6bca0f5b
2015-02-13 10:45:19 -08:00
Adrian Grange
1cfbc86e38 Merge "Add VP9 decoder control to get frame size" 2015-02-13 10:20:14 -08:00
Adrian Grange
e31516a08f Improve readability: move return statements
Change-Id: I18428d0a93084f78ec136d9019f10466326c67e5
2015-02-13 09:46:13 -08:00
Adrian Grange
cf54b88043 Add VP9 decoder control to get frame size
Adds a control function that allows the caller to get
the size of the current frame.

Change-Id: Iddfdedc0f3aa9aa46119f87d294681c82f275c9f
2015-02-13 09:09:49 -08:00
Marco
48fd2e41cd Merge "vpx_temporal_svc_encoder: Adjust default qp-max setting for vp9." 2015-02-13 08:11:31 -08:00
Jingning Han
e69c79e19a Merge "Fix ioc issue in block_rd_txfm" 2015-02-12 15:07:41 -08:00
Jingning Han
5041aa0fbe Fix ioc issue in block_rd_txfm
Force 64-bit precision in the intermediate steps.

Change-Id: I666113d9adcef8975da201d5aa1a13b783d09594
2015-02-12 12:51:39 -08:00
Marco
87a6175d6e vpx_temporal_svc_encoder: Adjust default qp-max setting for vp9.
Change-Id: Iada495f05193a1f645a5405ad792931f4d9113ab
2015-02-12 12:40:02 -08:00
Adrian Grange
04412d68bd Merge "Add missing initializer to VP8 codec interface" 2015-02-12 12:40:02 -08:00
hkuang
aa5c8b757d Merge "Remove unnecessary border extension when frame size change." 2015-02-12 12:00:32 -08:00
Marco
cc7d981de1 Merge "Add skin detection." 2015-02-12 11:12:27 -08:00
Adrian Grange
f29961dbd7 Add missing initializer to VP8 codec interface
Change-Id: Ia164ba03fb732e9c9e520e4aa2d75b7eadff6165
2015-02-12 09:53:52 -08:00
Jingning Han
f4c29ae9ea Merge "Update partition rate cost in rtc speed 5" 2015-02-12 09:14:49 -08:00
Jingning Han
ee83243daa Merge "Add mode cost to sub8x8 block mode decision in rtc coding" 2015-02-12 09:14:29 -08:00
Adrian Grange
24a6dbd853 Merge "Add cast to convert double to int" 2015-02-12 07:02:54 -08:00
Marco
56435bb7b6 Add skin detection.
Simple skin detection, from vp8; works reasonable on most of the
RTC clips, but could miss sometimes.

Added debug flag to write out skin map over source input.

Change-Id: I2caea7592f1c459047aac46627eeb24a94946464
2015-02-11 17:47:17 -08:00
Yunqing Wang
238707ab4c Merge "Make vp9_print_modes_and_motion_vectors() work" 2015-02-11 16:58:52 -08:00
James Zern
d8ed558c99 Merge "vp9_thread: prefer pthread.h if available" 2015-02-11 16:50:07 -08:00
James Zern
a139f3f6fc Merge "vp9_highbd_tm_predictor_16x16: fix win64" 2015-02-11 16:49:53 -08:00
Adrian Grange
053625e4cd Add cast to convert double to int
Change-Id: I7f63c2940256a5dadf9a29a853809290dd9e98ed
2015-02-11 15:59:48 -08:00
Jingning Han
e665c8f2c9 Add mode cost to sub8x8 block mode decision in rtc coding
This commit allows the encoder to properly account for the mode
cost in sub8x8 non-RD mode decision.

Change-Id: I2951960d20e37ed08e372ee0c7044935b2b9b899
2015-02-11 14:43:02 -08:00
Jingning Han
c9725813db Merge "Account for inter prediction filter rate cost in rtc mode selection" 2015-02-11 14:42:44 -08:00
Jingning Han
532cb435f8 Merge "Add ref frame rate cost to non-RD mode decision" 2015-02-11 14:36:48 -08:00
Jingning Han
7a4e0b2265 Update partition rate cost in rtc speed 5
The block partition rate cost should be updated when recursive
partition search is needed.

Change-Id: I7bc5ad1fc2cbd3577dee7f7e8da111a2742bdeb9
2015-02-11 12:48:29 -08:00
Jingning Han
41b7f76db1 Account for inter prediction filter rate cost in rtc mode selection
Add the rate cost on inter prediction filter type to the overall
rate-distortion cost in vp9_pick_mode_inter.

Change-Id: I72c34017adf5220cadb3962694ee5404469fc673
2015-02-11 12:17:29 -08:00
Jingning Han
4ce70e8847 Add ref frame rate cost to non-RD mode decision
This commit adds a heuristic rate cost of reference frame to the
non-RD mode decision. It improves the compression performance of
speed -6 by 0.31% and speed -5 by 0.69%.

Change-Id: If7f3b45519d49b2cb640bcb7316a254efc8be446
2015-02-11 11:08:10 -08:00
James Zern
923cc0bf51 vp9_highbd_tm_predictor_16x16: fix win64
by saving xmm8; cglobal's xmm reg arg is 0-based

Change-Id: Ic8426ec9ac59ab4478716aa812452a6406794dcb
2015-02-10 19:34:12 -08:00
Yaowu Xu
fc99636f1b Add --color-space to vpxenc
This enbale the encoder to set color space information for the input
video, so it is then coded in the output bitstream.

Change-Id: Ife03deab3c762425ccd27c4c190902c4d94a76f4
2015-02-10 16:37:21 -08:00
Yunqing Wang
f37788eaf6 Make vp9_print_modes_and_motion_vectors() work
MODE_INFO struct was modified, and vp9_print_modes_and_motion_vectors()
didn't work anymore. This patch modified vp9_debugmodes.c so that
this function works again for debug usage.

Change-Id: I293fae0295235deb2529a460a274caf7c045ac1a
2015-02-10 16:37:02 -08:00
Yaowu Xu
ee5d79995e Move computation up to frame level
This is to avoid redo the same calculation repeatly, and also allow
easier adjustments for further experiments.

This commit shall have no effect on quality/compression.

Change-Id: I4460acf5c808ff5518da18d21e002c5da58af857
2015-02-10 15:41:52 -08:00
hkuang
bf3cb25019 Remove unnecessary border extension when frame size change.
This border extension is not needed with on-demond border extension.

Change-Id: I8501b37f5f756dc7e874cef4c1cfdbfa9a16112a
2015-02-10 14:55:27 -08:00
James Zern
d167a1aeee vp9_thread: prefer pthread.h if available
this avoids conflicts with recent versions of mingw-w64 (tested g++
4.8.2) and the unit tests

Change-Id: Ic41ea31eebe0e3e712ed5e657f37d8cad6712088
2015-02-10 12:47:14 -08:00
Adrian Grange
2d924161c7 Merge "Auto-adaptive encoder frame resizing logic" 2015-02-10 12:16:55 -08:00
Jingning Han
f0eea5be2a Merge "Fix block partition size in fill_mode_info_sb" 2015-02-10 10:49:03 -08:00
Adrian Grange
23ebacdb81 Auto-adaptive encoder frame resizing logic
Note: This feature is still in development.

Add an option for the encoder to decide the resolution
at which to encode each frame.

Each KF/GF/ARF goup is tested to see if it would be
better encoded at a lower resolution. At present, each
KF/GF/ARF is coded first at full-size and if the coded
size exceeds a threshold (twice target data rate) at
the maximum active Q then the entire group is encoded
at lower resolution.

This feature is enabled in vpxenc by setting:
  --resize-allowed=1

In addition, if the vpxenc command line also specifies
valid frame dimensions using:
  --resize-width=XXXX & --resize_height=YYYY
then *all* frames will be encoded at this resolution.

Change-Id: I13f341e0a82512f9e84e144e0f3b5aed8a65402b
2015-02-10 09:59:32 -08:00
Yunqing Wang
84b813aa42 Merge "Make encoder and decoder share common thread function" 2015-02-10 09:06:41 -08:00
Yunqing Wang
d3a37731c2 Merge "Rename loopfilter_thread files to thread_common files" 2015-02-10 09:06:23 -08:00
Jingning Han
ebb4c9e8e7 Fix block partition size in fill_mode_info_sb
This commit fixes the sub block partition size used in
fill_mode_info_sb. Previous implementation effectively disabled
the rectangular block sizes. This commit resolved this issue.

Change-Id: Ic1c383ab0a9a2e7d59e85b388093f1f1f94d1e7f
2015-02-10 08:39:32 -08:00
James Zern
4409a4bcfb Merge "configure: add --(disable|enable)-dependency-tracking" 2015-02-10 00:00:24 -08:00
Yaowu Xu
f18b714e93 Merge "Add two constant definitions" 2015-02-09 17:00:55 -08:00
James Zern
aaccf6566d configure: add --(disable|enable)-dependency-tracking
defaults to enabled. when disabled skips dependency file (.d) generation
allowing for faster one-time builds.

Change-Id: I2d7d7f905f1663315b8eb2b2e81fffb6fcb15829
2015-02-09 16:38:49 -08:00
Yaowu Xu
03bc5a3aa9 Add two constant definitions
This fixes compiler errors for vs 2008.

Change-Id: Ifaabb1c5e74fe6ede6dacf66ec3f634fecb556fd
2015-02-09 16:26:53 -08:00
hkuang
1cdb5439e7 Merge "Set the maximum decode threads to be 8." 2015-02-09 16:25:20 -08:00
Yunqing Wang
07eb8c8da3 Merge "Fix high bit depth assembly function bugs" 2015-02-09 15:30:36 -08:00
hkuang
dd88f48296 Set the maximum decode threads to be 8.
This will fix the frame parallel decode hang on windows
due to not enough semaphores.

This will also make the frame parallel decode safer as
the number of frame buffers could only support maximum
8 threads.

Change-Id: Id9ef50692819dcbebbd74a0aabffbfb3f39a4309
2015-02-09 10:38:41 -08:00
hkuang
67b61c7ace Fix jenkins unit test failure due to "uninitialised value".
Change-Id: Ief6b526486bc729dcb787358bc0b781f278bdc66
2015-02-07 15:13:45 -08:00
Yaowu Xu
dd27307cac Prevent VP8 encoding crash
This commit changes the value of highbitdepth flag to avoid conflict
with vp8 refresh_last_frame flag.

Change-Id: Idcff2cf44f0a200bd935b326f785c0cf32d7228a
2015-02-06 16:32:48 -08:00
James Zern
aa6db39a17 Merge "vpxdec: correct file op error messages" 2015-02-06 14:40:52 -08:00
Yaowu Xu
6a078a21be Merge "Correct the miscalculation in uv dimensions" 2015-02-06 13:54:44 -08:00
Yaowu Xu
4bca73b609 Correct the miscalculation in uv dimensions
The calculation of required extension used in HBD case was wrong due
to rounding for UV when y dimension is odd. This commit replace the
computation with correct version.

This fixes a crash caused by writting beyond buffer boundary.

Change-Id: Ic7c9afeb7388cd1341ec4974a611dacfb74ac6b6
2015-02-06 12:19:32 -08:00
Yunqing Wang
4ae092c660 Make encoder and decoder share common thread function
Moved vp9_accumulate_frame_counts to vp9_thread_common.c to
eliminate the duplicate code.

Change-Id: I9cf506d729603c8bf1494b4c86a3b7d47af1917a
2015-02-06 11:45:51 -08:00
Jingning Han
ba933b90c6 Merge "Re-arrange inter mode search order in RTC coding flow" 2015-02-06 10:11:33 -08:00
Yunqing Wang
41063137c3 Rename loopfilter_thread files to thread_common files
Renames the files to allow more common thread code to
be moved to vp9/common.

Change-Id: I7386e64e221086e3cdc087e79812f993c423413b
2015-02-06 10:03:31 -08:00
Yaowu Xu
8b5e665098 Merge "Replace repeated check with single variable" 2015-02-06 09:17:59 -08:00
Jingning Han
b2762a8853 Re-arrange inter mode search order in RTC coding flow
This commit makes the ZEROMV mode first in the search order to
ensure that the zero mv is always checked in the RTC coding mode.
It improves the average speed -6 compression performance by 0.3%
in both PSNR and SSIM at no visible speed change.

Change-Id: I465a7e59f4e20cd84fee3f02ced6f98036945949
2015-02-06 08:52:52 -08:00
James Zern
519b9141ad Merge "vp9: fix segfault w/corrupt data post frame-parallel merge" 2015-02-06 00:28:10 -08:00
James Zern
6b993f076e vpxdec: correct file op error messages
- use fatal() consistently
- correct wording in output file open failure message

Change-Id: I4dafe03c6eece6df53375f72adf0d5964e211c9a
2015-02-05 21:08:19 -08:00
James Zern
a5a5b115b1 Merge "Revert "Add vp9_highbitdepth info in configure --help"" 2015-02-05 14:09:01 -08:00
hkuang
1c396f3f8e Merge "Fix a thread lost bug in frame parallel decode." 2015-02-05 14:07:35 -08:00
Marco
dc4cdf9517 Merge "vpx_temporal_svc_encoder: change default setting for static threshold." 2015-02-05 13:01:40 -08:00
James Zern
137fd2db45 Revert "Add vp9_highbitdepth info in configure --help"
This reverts commit a6715a7558.

Removes a duplicate entry; this was previously added by:
14e37cf Add help info for --enable-vp9-highbitdepth

Change-Id: I61408e782232821ef6ed84775b5c79d172ba7f2d
2015-02-05 12:54:49 -08:00
hkuang
65f046e29f Merge "Mute the harmless tsan error in frame parallel decode." 2015-02-05 12:44:04 -08:00
James Zern
3be948d84b Merge "configure: enable x86inc for all intel platforms" 2015-02-05 12:18:24 -08:00
James Zern
0261fb4c4f vp9: fix segfault w/corrupt data post frame-parallel merge
cm->frame_bufs[].idx values were made consistent in:
61c5e94 Use -1 consistently as invalid buffer idx
update the initialization in swap_frame_buffers() to match.
additionally:
  - remove some shadowed variables in the former and marked them volatile

Change-Id: Ie3f9636c405bd822112bb56bd22d28024ae98909
2015-02-05 12:11:40 -08:00
Marco
ef6d6ec285 vpx_temporal_svc_encoder: change default setting for static threshold.
Change-Id: Ie45c8344df9415173eae7aa20384ea8ecb05d07a
2015-02-05 12:07:31 -08:00
Yunqing Wang
789ae447f8 Fix high bit depth assembly function bugs
The high bit depth build failed while building for 32bit target.
The bugs were in vp9_highbd_subpel_variance.asm and
vp9_highbd_sad4d_sse2.asm functions. This patch fixed the bugs,
and made 32bit build work.

Change-Id: Idc8e5e1b7965bb70d4afba140c6583c5d9666b75
2015-02-05 11:24:03 -08:00
James Zern
769fe6e2b3 configure: enable x86inc for all intel platforms
there are no known issues since:
10d5e09 Fix issues in 32bit PIC enabled build

related issues: #808, #924

Change-Id: I80454f95fe6b4ce630fdd434d740ce8b0d42951b
2015-02-04 19:16:12 -08:00
Tom Finegan
7467936340 Merge "Xcode: Fix includes in examples." 2015-02-04 17:33:41 -08:00
Tom Finegan
9e96bdc733 Xcode: Fix includes in examples.
The current file's directory, ".", is treated much more literally
when building libvpx examples with Xcode than it is with make, and
clang cannot find common include files included via "./" when those
files actually reside one directory up in the tree.

Change-Id: I5f66a026282e35d80248ca4052ebb882b859172e
2015-02-04 16:11:57 -08:00
Yaowu Xu
c905c42ad8 Remove unnecessary initialization
loop_filter_level is always reset in loop_filter_frame() later in
encoder.

Change-Id: I608e03d905a6b23e7d5025ca747e4784c665007e
2015-02-04 13:56:16 -08:00
Yaowu Xu
581aee001e Move tx_mode decision logic into select_tx_mode()
Change-Id: I7f8f78c33eb3f33344b029a27bda320f4d68c577
2015-02-04 13:54:49 -08:00
Yaowu Xu
19451e6d67 Replace repeated check with single variable
Change-Id: I2f6a669bf7c6d9796388ad3f3fa3fc942635c215
2015-02-04 12:59:14 -08:00
Yaowu Xu
a844a778c7 Merge "Adjust partitioning threshold based rtc speed" 2015-02-04 12:52:03 -08:00
Yaowu Xu
3bc0c6576f Merge "Move calls to avoid unnecessary operations" 2015-02-04 12:51:16 -08:00
hkuang
41e376e494 Mute the harmless tsan error in frame parallel decode.
Change-Id: I52565fd90461221f89134997a0782cb1b681df01
2015-02-04 12:39:35 -08:00
Jingning Han
1221641914 Merge "Unify luma and chroma inter predictors in choose_partitioning" 2015-02-04 12:09:21 -08:00
Jingning Han
fb2bac4001 Merge "Save an extra call for setup_pred_plane function" 2015-02-04 12:09:14 -08:00
Jingning Han
ce819d74dc Merge "Account for chroma component costs in RTC mode decision" 2015-02-04 12:09:01 -08:00
Yaowu Xu
bdfb5f986e Adjust partitioning threshold based rtc speed
On rtc set:
speed 7 quality improves about 0.5%
speed 8 quality improves about 1.0%

Encoding time for speed 7 changes from 67804ms to 65889ms
Encoding time for speed 8 changes from 58659ms to 56808ms

Change-Id: Iabcfb53012fc1b9f3326cdbc167e5758b8c7ad30
2015-02-04 11:28:39 -08:00
hkuang
b104b84058 Fix a thread lost bug in frame parallel decode.
After syncing the frame worker thread, avaiable thread count should
increase by 1 even the worker thread does not have displayable frame
to output.

Change-Id: I9eeb87720fed82dfe38555286833ff88e8a8e746
2015-02-04 11:07:02 -08:00
Jingning Han
1b9082ec6b Unify luma and chroma inter predictors in choose_partitioning
Change-Id: I8bfc80f4fffb0892e93d3326394a52d1ee3c0f37
2015-02-04 10:02:57 -08:00
Jingning Han
4ccfc7d517 Save an extra call for setup_pred_plane function
Reuse the yv12_mb array to fetch the buffer pointers/strides
corresponding to the current reference frame.

Change-Id: I5276b7494158b2cccef15213be2dc189e9036851
2015-02-04 09:47:14 -08:00
Jingning Han
0c6d3a03e1 Account for chroma component costs in RTC mode decision
This commit allows the encoder to account for additional chroma
plane costs in the mode decision process, if the current block
potentially contains significant color change. It improves the
visual quality at very low bit-rates.

The compression performance of dark720p is improved by 12.39% in
speed 6. For jimred at 150 kbps, the PSNR of V component (red)
increased by 0.2 dB, at the expense of about 5% increase in
encoding time. Note that for sequences where the chroma components
are fairly consistent, the encoding time increase is negligible.

On average the rtc set compression performance is improved by
1.172% in PSNR and 1.920% in SSIM.

Change-Id: Ia55b24ef23a25304f7ec9958fbf07fd6e658505c
2015-02-04 09:45:14 -08:00
Yunqing Wang
b3b7645a2f vp9_dthread: remove frame_parallel_decoding_mode requirement
This patch continues the work to remove frame_parallel_decoding_mode
requirement in VP9 multi-threaded tile decoder. In order to do that,
the frame counts associated to each thread need to be accumulated
together after the frame is decoded.

Change-Id: Idba1a756cedfed3c154aef52ed82c8da3bbf9e0c
2015-02-04 09:16:41 -08:00
Johann
3a5d40608e Merge "Remove unnecessary pointer check" 2015-02-03 17:12:56 -08:00
Yaowu Xu
02537ebbe4 Move calls to avoid unnecessary operations
Change-Id: I236f7f75ab9a4511d1b52a6a67299b0e844a103e
2015-02-03 17:01:37 -08:00
Yaowu Xu
cb411108a3 Merge "adjust rtc setting and threshold" 2015-02-03 15:13:52 -08:00
Johann
a367c9766d Merge "Use correct buffer size in vp8 subpixel variance" 2015-02-03 13:52:14 -08:00
hkuang
70554a21f1 Merge "Remove duplicate code." 2015-02-03 13:37:48 -08:00
Jim Bankoski
d7783cae95 Merge "make low bitrates a lot less blocky" 2015-02-03 13:25:06 -08:00
Johann
ba18609502 Remove unnecessary pointer check
The original implementation had the following comment:
// Ignore mv costing if mvsadcost is NULL

However the current implementation does not allow for this.
If x exists then nmvsadcost must not be null.

This removes the only warning from -Wpointer-bool-conversion

https://code.google.com/p/webm/issues/detail?id=894

Change-Id: I1a2cee340d7972d41e1bbbe1ec8dfbe917667085
2015-02-03 13:03:46 -08:00
Jingning Han
894f0fbd3b Merge "Assign 2nd ref frame in choose_partitioning" 2015-02-03 12:25:18 -08:00
Johann
51945a5400 Merge "Fail when only an old nasm is found" 2015-02-03 11:19:24 -08:00
Jingning Han
ca9c352fc3 Assign 2nd ref frame in choose_partitioning
Avoid the use of uninitialized second reference frame for fetching
reference block.

Change-Id: I9983a0daea829700b3270dc8bf2bcc6d6ea36652
2015-02-03 11:17:51 -08:00
Yunqing Wang
f5b3631621 Merge "vp9_dthread: pass frame counts to decoder functions" 2015-02-03 10:52:02 -08:00
Yaowu Xu
9a664917b0 Merge "Add mutex initialization in encoder" 2015-02-03 10:36:42 -08:00
Yaowu Xu
a6b3e01a27 Add mutex initialization in encoder
This resolves the encoder crashes on windows.

Change-Id: I159d79014cf9279751e403936ce1f84482ae82da
2015-02-03 09:53:08 -08:00
Johann
421043340a Merge "Ensure the error-concealment code is available" 2015-02-03 09:40:12 -08:00
Yunqing Wang
85a9bc04d4 vp9_dthread: pass frame counts to decoder functions
The current multi-threaded tile decoder requires that the videoes
are encoded with frame_parallel_decoding_mode = 1. This requirement
is not necessary, and is better to be removed. This patch includes
the first part of the work.

Change-Id: Ic7695fb3cfe13f9022582c9f0edd2aa6e2e36d28
2015-02-03 09:39:15 -08:00
Johann
eabb793f3b Use correct buffer size in vp8 subpixel variance
In vp8_sub_pixel_variance8x8_neon the temp2 buffer is only initialized
to kHeight8 * kWidth8. However, in the case that xoffset != 0 and
yoffset == 0, var_filter_block2d_bil_w8 is called with output_width
kHeight8PlusOne.

Thanks to cmugurel for diagnosing and yulius for the patch.

Change-Id: Ib71ffd96ffad963c92b8b7ca23f303942785b8e0
https://code.google.com/p/webrtc/issues/detail?id=4190
2015-02-03 09:11:05 -08:00
Johann
852829c315 Fail when only an old nasm is found
Apple ships version 0.98 of nasm through at least XCode 6. It is
incompatible with the assembly in libvpx.

https://code.google.com/p/webm/issues/detail?id=772

Change-Id: I33245a76f50a8224fe6fafa3cce9991f953fdcc8
2015-02-03 08:55:00 -08:00
Jim Bankoski
9f1cf2c8cf make low bitrates a lot less blocky
Remove loop filter skip at speed 7+ because of bad visual artifacts and
up the postprocessing.

Change-Id: Ibdd0bac71aaee232d2bb2e14462733c51517768d
2015-02-03 06:45:56 -08:00
Yaowu Xu
65a1a3e85d adjust rtc setting and threshold
1. Adjusted the threshold for coef update computation based on counts
of tx used, avoid coef update computation when count is low (<20)
2. Move sf->lpf_pick = LPF_PICK_MINIMAL_LPF to speed 8.

Change-Id: I02b44309e40fcdbf135c7934ae067a3f42502d30
2015-02-02 17:43:46 -08:00
hkuang
4ed539f22e Merge "Fix a bug from merging frame parallel branch into master." 2015-02-02 17:08:42 -08:00
hkuang
94a459522e Fix a bug from merging frame parallel branch into master.
The merge did not merge the fix for issue #850.

Change-Id: I0dc1377dbfcb9497fb01a13d4f78ac65bff5eb33
2015-02-02 16:01:17 -08:00
Johann
5085f8d2a4 Merge "Require webm when explicitly requested" 2015-02-02 13:13:04 -08:00
Alex Converse
a79db92c07 Merge "Allow larger encoder configurations." 2015-02-02 12:05:56 -08:00
Johann
b50e518ab6 Require webm when explicitly requested
https://code.google.com/p/webm/issues/detail?id=906

Change-Id: I72841078ff81152d21d84ccf4d5548e757685a6d
2015-02-02 08:35:56 -08:00
Adrian Grange
fd354b2e1e Merge "Abort if firstpass file does not exist" 2015-02-02 08:11:14 -08:00
Yaowu Xu
80e729f601 Merge "Optimize coef update" 2015-02-01 20:08:29 -08:00
hkuang
be6aeadaf4 Try again to merge branch 'frame-parallel' into master branch.
In frame parallel decode, libvpx decoder decodes several frames on all
cpus in parallel fashion. If not being flushed, it will only return frame
when all the cpus are busy. If getting flushed, it will return all the
frames in the decoder. Compare with current serial decode mode in which
libvpx decoder is idle between decode calls, libvpx decoder is busy
between decode calls.

Current frame parallel decode will only speed up the decoding for frame
parallel encoded videos. For non frame parallel encoded videos, frame
parallel decode is slower than serial decode due to lack of loopfilter
worker thread.

There are still some known issues that need to be addressed. For example:
decode frame parallel videos with segmentation enabled is not right sometimes.

* frame-parallel:
  Add error handling for frame parallel decode and unit test for that.
  Fix a bug in frame parallel decode and add a unit test for that.
  Add two test vectors to test frame parallel decode.
  Add key frame seeking to webmdec and webm_video_source.
  Implement frame parallel decode for VP9.
  Increase the thread test range to cover 5, 6, 7, 8 threads.
  Fix a bug in adding frame parallel unit test.
  Add VP9 frame-parallel unit test.
  Manually pick "Make the api behavior conform to api spec." from master branch.
  Move vp9_dec_build_inter_predictors_* to decoder folder.
  Add segmentation map array for current and last frame segmentation.
  Include the right header for VP9 worker thread.
  Move vp9_thread.* to common.
  ctrl_get_reference does not need user_priv.
  Seperate the frame buffers from VP9 encoder/decoder structure.
  Revert "Revert "Revert "Revert 3 patches from Hangyu to get Chrome to build:"""
 Conflicts:
       test/codec_factory.h
       test/decode_test_driver.cc
       test/decode_test_driver.h
       test/invalid_file_test.cc
       test/test-data.sha1
       test/test.mk
       test/test_vectors.cc
       vp8/vp8_dx_iface.c
       vp9/common/vp9_alloccommon.c
       vp9/common/vp9_entropymode.c
       vp9/common/vp9_loopfilter_thread.c
       vp9/common/vp9_loopfilter_thread.h
       vp9/common/vp9_mvref_common.c
       vp9/common/vp9_onyxc_int.h
       vp9/common/vp9_reconinter.c
       vp9/decoder/vp9_decodeframe.c
       vp9/decoder/vp9_decodeframe.h
       vp9/decoder/vp9_decodemv.c
       vp9/decoder/vp9_decoder.c
       vp9/decoder/vp9_decoder.h
       vp9/encoder/vp9_encoder.c
       vp9/encoder/vp9_pickmode.c
       vp9/encoder/vp9_rdopt.c
       vp9/vp9_cx_iface.c
       vp9/vp9_dx_iface.c

This reverts commit a18da9760a.

Change-Id: I361442ffec1586d036ea2e0ee97ce4f077585f02
2015-01-30 21:00:13 -08:00
James Zern
f6c2a6c5d6 vp9: rename 'near' parameters
+ nearest for consistency

near is a reserved word in windows builds so using it as a parameter
name may cause build failures with some configurations

Change-Id: Iddf1d4ecdb39843f14e95dbfd9dca55f07f81403
2015-01-30 15:52:24 -08:00
Jingning Han
f1ab5c1021 Merge "Format fixes in vp9_rd_pick_inter_mode_sb/sub8x8" 2015-01-30 15:49:14 -08:00
James Zern
d2493313ae Merge "configure: echo --(disable|enable)-* cmdline options" 2015-01-30 13:16:02 -08:00
Johann
1c5e16bec7 Merge "Explicitly include vp8_rtcd.h" 2015-01-30 11:19:28 -08:00
Adrian Grange
f92c0b1688 Abort if firstpass file does not exist
This fixes a crash if the firstpass file does not
exist when doing a two-pass encode.

Change-Id: I3a1a95d68d57125c63123d6208af7537f5a689a0
2015-01-30 10:42:29 -08:00
Yaowu Xu
45971abd1d Optimize coef update
1. move the check of search method of USE_TX_8X8 up one level to
avoid operations of build_tree_distributions()
2. count tx used and avoid computaton for coef udpate when one size
is not used at all.

Change-Id: Ia3e54a2588aa531c41377a1bfaa64385d04a592c
2015-01-30 10:16:40 -08:00
Yunqing Wang
cc7fac39d5 Enable use_x86inc for 32bit pic enabled Darwin target
The previous patch "Fix issues in 32bit PIC enabled build" fixed
the x86inc.asm for macho32. Now we can enable use_x86inc while
building libvpx for 32bit pic enabled Darwin target, which makes
the encoder a lot faster(>2X) in this case by turning on the
existing optimizations.

Change-Id: I5f5c7add428d73f50c935c48d0a70aed2b1eb7af
2015-01-29 16:47:06 -08:00
Yunqing Wang
3b3e299650 Merge "Fix issues in 32bit PIC enabled build" 2015-01-29 16:41:25 -08:00
Alex Converse
797a2556eb Allow larger encoder configurations.
Allow changing colorspace in the encoder and increasing frame size.

Change-Id: I8e7c3b891af29ce420a15beb4f6f9c250245b2bb
2015-01-29 15:07:40 -08:00
Paul Wilkins
68340a3470 Merge "Change to update of rate control factors." 2015-01-29 13:50:52 -08:00
Johann
04168d41cb Explicitly include vp8_rtcd.h
When referencing RTCD functions make sure the relevant
header file is included.

Change-Id: Ia0d7112d4aff9b4d8fa94648f0702371b7484031
https://code.google.com/p/webm/issues/detail?id=937
2015-01-29 09:59:16 -08:00
Marco
a80dd52b6e Merge "Fix to vp9 denoiser." 2015-01-29 09:10:30 -08:00
James Zern
ef7f33b93b configure: echo --(disable|enable)-* cmdline options
gives a better summary of what is enabled / disabled outside of the
automatic toolchain options.

fixes issue #936

Change-Id: I1bf27593a5512713aab1473cb606c58cf3084d62
2015-01-28 20:30:51 -08:00
Paul Wilkins
f752da8ce2 Change to update of rate control factors.
Remove damping parameter and use the damping
formula introduced by Yaowu Xu in all cases.

Change-Id: I18db7e0d0f262d5140102f259ab07821d374d285
2015-01-28 15:44:53 -08:00
Yaowu Xu
ff99a3c750 Simplify update_coef_probs()
1. reduce the size of temporaray arrays on stack
2. avoid build_tree_distribution for tx size that is not used at all.

Change-Id: I0f8d7124e16a3789d3c15ad24cf02c1c12789e2c
2015-01-28 15:12:42 -08:00
Marco
c0923d4d3a Fix to vp9 denoiser.
Prevent from using wrong mv for denoiser motion compensation.

Change-Id: Ifa0f9daabdbdab0900d3c17304059fe0d15de914
2015-01-28 12:07:27 -08:00
hkuang
e8c42fb0bd Remove duplicate code.
(issue #934).

Change-Id: Ic8adaaff87aae0b33d9b508f160b48e0ccdaaf4c
2015-01-28 12:00:34 -08:00
Alex Converse
c29c613400 Merge "vp8enc: Prevent out of bounds memory access." 2015-01-28 11:22:36 -08:00
Frank Galligan
d1e6b8231a Merge "Add vp9_sad32x32x4d_neon Neon intrinsic function." 2015-01-28 10:35:50 -08:00
Frank Galligan
eb12d880ab Merge "Add vp9_sad16x16x4d_neon Neon intrinsic function." 2015-01-27 23:01:44 -08:00
Frank Galligan
80a3a07929 Merge "Add vp9_sad64x64x4d_neon Neon intrinsic function." 2015-01-27 23:01:15 -08:00
Yunqing Wang
10d5e09c87 Fix issues in 32bit PIC enabled build
This patch was to fix issue 924:
https://code.google.com/p/webm/issues/detail?id=924

The SECTION_RODATA macro was modified to support macho32 format.
The sub-pixel functions were modified to pass in 2 more parameters
to handle the global offsets for PIC build.

Change-Id: I3bfcd336bcae945edf300bca4ab40376a2628cd4
2015-01-27 22:20:21 -08:00
Alex Converse
581731a95f vp8enc: Prevent out of bounds memory access.
Prevent out of bounds access when attempting to increase frame size

Change-Id: I710c40c692802a72963c9680c2125da17f9060a9
2015-01-27 16:44:31 -08:00
Yaowu Xu
fe2439703d Merge "move clear_system_state() call before using double" 2015-01-27 12:42:13 -08:00
Johann
89e07be395 Merge "Fix discovery of Darwin SDKs" 2015-01-27 10:49:26 -08:00
Frank Galligan
e3167f7fbf Add vp9_sad32x32x4d_neon Neon intrinsic function.
On Nexus 7 speed -6 saw ~18% increase in perf.

Tested on Nexus 7, built with ndk r10d, gcc 4.9.

BUG=https://code.google.com/p/webm/issues/detail?id=908

Change-Id: I70ccdea0326750552ed946fb004507d6efe02d5c
2015-01-27 08:54:00 -08:00
Frank Galligan
9f574d0316 Add vp9_sad16x16x4d_neon Neon intrinsic function.
On Nexus 7 speed -6 saw ~15% increase in perf.

Tested on Nexus 7, built with ndk r10d, gcc 4.9.

BUG=https://code.google.com/p/webm/issues/detail?id=908

Change-Id: I4b2006b644c488f42bf06d8a22ef0e6120a96bf9
2015-01-27 08:42:17 -08:00
Frank Galligan
54fa956715 Add vp9_sad64x64x4d_neon Neon intrinsic function.
On Nexus 7 speed -6 saw ~30% increase in perf.

Tested on Nexus 7, built with ndk r10d, gcc 4.9.

BUG=https://code.google.com/p/webm/issues/detail?id=908

Change-Id: Id12af7d1883243c23e6692e898aea82299633d58
2015-01-27 08:33:40 -08:00
Marco
1c4a84c6e9 Merge "aq-mode=3: Update to allow for refresh on modes other than zero-mv." 2015-01-26 19:47:13 -08:00
Lawrence Velázquez
ad314c1689 Fix discovery of Darwin SDKs
The current method doesn't work with Xcode 4 and up, since they no
longer have a $DEVELOPER_DIR/SDKs directory. Using xcrun and xcodebuild
works all the way back to Xcode 3 on OS X 10.6 Snow Leopard, if not
earlier.

Change-Id: I7126f2fb4a8f1d6e46f921e70bbd090f00ce3d36
2015-01-26 21:44:02 -05:00
Yaowu Xu
645b7cdf03 move clear_system_state() call before using double
Floating point is used in vp9_convert_qindex_to_q(), so sometime unit
test ActiveMapTest would cause run time error without properly call
to clear_system_state to reset register status.

Change-Id: I181e9395148c44a6ca8b97d6e109bd4a152143c6
2015-01-26 18:41:50 -08:00
Paul Wilkins
d231ce4fde Merge "Adjust active maxq for GF groups." 2015-01-26 18:19:09 -08:00
Yaowu Xu
d987dc4fdb Merge "Fix MSVC warnings on conversion from int64 to int" 2015-01-26 16:52:30 -08:00
Marco
3f1af6e85e aq-mode=3: Update to allow for refresh on modes other than zero-mv.
Add distortion threshold condition to refresh state of a coding block,
and allow for qp adjustment also for some intra modes and non-zero motion modes.

Also some code cleanup (remove unused variables/code).

Change-Id: I735fa2b28bc64f60e0323976b82510577b074203
2015-01-26 16:44:25 -08:00
Tom Finegan
e7ef8ecefd Merge "iosbuild.sh: Increase build speed." 2015-01-26 15:10:18 -08:00
Paul Wilkins
fd070220ff Adjust active maxq for GF groups.
Currently disabled by default: enabled using
#define GROUP_ADAPTIVE_MAXQ

In this patch the active max Q is adjusted for each GF
group based on the vbr bit allocation and raw first pass
group error.

This will tend to give a lower q for easy sections
and a higher value for very hard sections. As such it is
expected to improve quality in some of the easier
sections where quality issues have been reported.

This change tends to hurt overall psnr but help
average psnr. SSIM also shows a small gain.

Average results for derf, yt, std-hd and yt-hd test sets were
as follows (%change for average psnr, overal psnr and ssim):-

derf +0.291, - 0.252, -0.021
yt +6.466, -1.436, +0.552
std-hd +0.490, +0.014, +0.380
yt-hd +5.565, - 1.573, +0.099

Change-Id: Icc015499cebbf2a45054a05e8e31f3dfb43f944a
2015-01-26 14:55:36 -08:00
Yaowu Xu
6d16f6c14c Fix MSVC warnings on conversion from int64 to int
Change-Id: I7e96509ffa36899fcd2935749927a1e8aac8d025
2015-01-26 10:54:06 -08:00
Frank Galligan
9f6eba419a Add Neon intrinsic vp9_fdct8x8_quant_neon
On Nexus 7 speed -5 got ~2%, -6 got ~15%, -7 and -8 got ~30%
increase in perf.

Tested on Nexus 7, built with ndk r10d, gcc 4.9.

Change-Id: I83246d63b96674d170098a572fa4fe28a05aaf51
2015-01-24 22:49:50 -08:00
Yaowu Xu
643c75d90b Merge "Replace divide with look-up" 2015-01-23 21:12:18 -08:00
James Zern
4ed1bda7af x86: correct OSXSAVE + AVX bit check
the result should have both bits set; previously this was converted from
webp incorrectly and resulted in a boolean check...

Change-Id: I2a7c7f2b491945f3a536ab4fca02247eccc892b8
2015-01-23 18:06:04 -08:00
Jingning Han
9bdc0ae2b2 Format fixes in vp9_rd_pick_inter_mode_sb/sub8x8
Add parentheses to bit operations.

Change-Id: I095d601f0631d055adc4b3a8fde70c9cbae9e749
2015-01-23 11:48:58 -08:00
JackyChen
65f60f8e8c Merge "SSE2 code for the filter in MFQE." 2015-01-23 11:08:16 -08:00
Adrian Grange
0e2e2c2652 Merge "Remove elevate_newmv_thresh from SPEED_FEATURES (unused)" 2015-01-23 09:57:03 -08:00
Yaowu Xu
eda179764f Replace divide with look-up
This commit replaces an integer divide with a table-lookup. It is
to improve decoding speed, and at the same time, to reduce possible
complications with a bug in AMD Family 12h processors:

"665 Integer Divide Instruction May Cause Unpredictable Behavior"

Change-Id: I678b707a538798a923850bac467e66e847e6def7
2015-01-23 09:02:07 -08:00
Johann
3e466cea98 Merge "Revert "Merge branch 'frame-parallel' to enable frame parallel decode in master branch."" 2015-01-23 08:43:15 -08:00
Johann
a18da9760a Revert "Merge branch 'frame-parallel' to enable frame parallel decode in master branch."
This reverts commit bde04ce503

Change-Id: I053dae04c761b04a36dc239558503905a14d2470
2015-01-23 08:42:02 -08:00
James Zern
880ca0ecad Merge "workaround stack bashing by asm on 32-bit OpenBSD" 2015-01-22 20:04:07 -08:00
hkuang
0b6e35a90d Merge branch 'master' of ssh://gerrit.chromium.org:29418/webm/libvpx
* 'master' of ssh://gerrit.chromium.org:29418/webm/libvpx:
  Add libvpx build targets for OS X 10.10 Yosemite.
2015-01-22 18:19:04 -08:00
hkuang
bde04ce503 Merge branch 'frame-parallel' to enable frame parallel decode in master branch.
In frame parallel decode, libvpx decoder decodes several frames on all
cpus in parallel fashion. If not being flushed, it will only return frame
when all the cpus are busy. If getting flushed, it will return all the
frames in the decoder. Compare with current serial decode mode in which
libvpx decoder is idle between decode calls, libvpx decoder is busy
between decode calls. VP9 frame parallel decode is >30% faster than serial
decode with tile parallel threading which will makes devices play 1080P
VP9 videos more easily.

* frame-parallel:
  Add error handling for frame parallel decode and unit test for that.
  Fix a bug in frame parallel decode and add a unit test for that.
  Add two test vectors to test frame parallel decode.
  Add key frame seeking to webmdec and webm_video_source.
  Implement frame parallel decode for VP9.
  Increase the thread test range to cover 5, 6, 7, 8 threads.
  Fix a bug in adding frame parallel unit test.
  Add VP9 frame-parallel unit test.
  Manually pick "Make the api behavior conform to api spec." from master branch.
  Move vp9_dec_build_inter_predictors_* to decoder folder.
  Add segmentation map array for current and last frame segmentation.
  Include the right header for VP9 worker thread.
  Move vp9_thread.* to common.
  ctrl_get_reference does not need user_priv.
  Seperate the frame buffers from VP9 encoder/decoder structure.
  Revert "Revert "Revert "Revert 3 patches from Hangyu to get Chrome to build:"""

 Conflicts:
       test/codec_factory.h
       test/decode_test_driver.cc
       test/decode_test_driver.h
       test/invalid_file_test.cc
       test/test-data.sha1
       test/test.mk
       test/test_vectors.cc
       vp8/vp8_dx_iface.c
       vp9/common/vp9_alloccommon.c
       vp9/common/vp9_entropymode.c
       vp9/common/vp9_loopfilter_thread.c
       vp9/common/vp9_loopfilter_thread.h
       vp9/common/vp9_mvref_common.c
       vp9/common/vp9_onyxc_int.h
       vp9/common/vp9_reconinter.c
       vp9/decoder/vp9_decodeframe.c
       vp9/decoder/vp9_decodeframe.h
       vp9/decoder/vp9_decodemv.c
       vp9/decoder/vp9_decoder.c
       vp9/decoder/vp9_decoder.h
       vp9/encoder/vp9_encoder.c
       vp9/encoder/vp9_pickmode.c
       vp9/encoder/vp9_rdopt.c
       vp9/vp9_cx_iface.c
       vp9/vp9_dx_iface.c

Change-Id: Ib92eb35851c172d0624970e312ed515054e5ca64
2015-01-22 18:18:53 -08:00
Johann
8cfe9607d9 Merge "Add libvpx build targets for OS X 10.10 Yosemite." 2015-01-22 18:11:21 -08:00
Adrian Grange
527e073163 Remove elevate_newmv_thresh from SPEED_FEATURES (unused)
Change-Id: I78ef7f89586a329787f6bc4c58ec83af210989a3
2015-01-22 16:12:50 -08:00
Lawrence Velázquez
4fe4c2834f Add libvpx build targets for OS X 10.10 Yosemite.
Change-Id: I5baa4405e0b52fd3b6f312bd2dc94b19e6ff3da7
2015-01-22 15:33:53 -08:00
Tom Finegan
1387f4dedf iosbuild.sh: Increase build speed.
Disable more stuff to speed up the build, and log default configure
args in verbose mode.

Change-Id: I40e55fc5e8d2bff0262e1d6bd4a40ee2c10d2b6d
2015-01-22 15:19:07 -08:00
Marco
0dccb6277c Modify variance partition selection for low resolutions.
For low spatial resolutions: bias partittion selection to smaller block sizes,
and base the variance computation on 4x4 down-sampling.

Also move the threshold computations into the choose_partitioning,
so they are computed once for each sb block.

On low-res clips (RTC_derf) PSNR/SSIMetrics increase by about 4-5%.
No change for resolutions above CIF.

Change-Id: I93f8ff742c8044786977bb6e31dcf8efda6dd1b0
2015-01-22 15:16:55 -08:00
Paul Wilkins
cf3202132f Merge "Bug when last group before forced key frame is short." 2015-01-22 08:28:19 -08:00
Paul Wilkins
0bff1efc2b Bug when last group before forced key frame is short.
Just before a forced key frame we often get a foreshortened
arf/gf group. In such a case, we do not want to update
rc->last_boosted_qindex, which is used to define the Q range
for the forced key frame itself.

This gives a small average metrics gain for the YT and YT-HD sets
(eg. YT SSIM +0.141%).

Change-Id: Ie06698bc4f249e87183b8f8fb27ff8f3fde216d9
2015-01-21 15:25:57 -08:00
JackyChen
cd0830f452 Merge "Fix compile error in Chromium building." 2015-01-21 14:52:32 -08:00
Alex Converse
aaa31a3164 Merge "Allow external resize via vpx_codec_enc_config_set" 2015-01-21 13:59:34 -08:00
JackyChen
25a19b48ff Fix compile error in Chromium building.
The comparison of address in the condition is not necessary, since
they will constantly be non-null.

Change-Id: Id0b0075283f5af65215d5761a8160a4cb2a15c9b
2015-01-21 12:59:25 -08:00
James Zern
13458362af Merge "fix AVX & AVX2 detection" 2015-01-21 12:59:07 -08:00
Alex Converse
910ca857df Allow external resize via vpx_codec_enc_config_set
Change-Id: I3d324e2baa4de2d266c5f7ca7b635b62372e90a7
2015-01-21 11:33:06 -08:00
Yaowu Xu
c97d435243 Merge "Replace "colorspace" with "color_space"" 2015-01-21 08:58:09 -08:00
Frank Galligan
469ff48d7b Merge "Add Neon intrinsics for vp9_avg_8x8_neon" 2015-01-20 14:38:39 -08:00
Yunqing Wang
79b88cc2a5 Merge "Add non420 code in multi-threaded loopfilter" 2015-01-20 11:45:03 -08:00
Yaowu Xu
eceedbff2a Merge "Fix obvious misses in doxygen mainpage" 2015-01-20 11:27:52 -08:00
Yunqing Wang
6d7b7abf52 Add non420 code in multi-threaded loopfilter
Added non420 part back to make it consistent with single
thread code in vp9_loopfilter.c.

Change-Id: I8ca255d73bffebae294d2627d6655eafe535cb90
2015-01-20 09:31:47 -08:00
Yunqing Wang
7b232717af Merge "vp9_ethread: add parallel loopfilter" 2015-01-20 09:27:08 -08:00
Yaowu Xu
cb749125e3 Merge "Add vp9_highbitdepth info in configure --help" 2015-01-20 08:55:16 -08:00
JackyChen
09673deba9 SSE2 code for the filter in MFQE.
The SSE2 code is from VP8 MFQE, reuse it in VP9. No change on VP8
side. In our testing, we achieve 2X speed by adopting this change.

Change-Id: Ib2b14144ae57c892005c1c4b84e3379d02e56716
2015-01-18 16:07:59 -08:00
Frank Galligan
cc2da09d42 Fix variance Neon intrinsics > 32x32
The 16 bit sum vector was overflowing.

Change-Id: I0fdf38e832ee99457ec8680a92691a6175ff8c3f
2015-01-17 10:31:48 -08:00
Yunqing Wang
e76eaf05b1 vp9_ethread: add parallel loopfilter
1. Added row-based loopfilter in encoder;
2. Moved common multi-threaded loopfilter functions from decoder
   to common;
3. Merged multi-threaded loopfilter code, and made encoder/
   decoder call same function to reduce code duplication.

Encoder tests showed that 1% - 2% speedup was seen for good-quality
2-pass mode(at speed 3); 1% - 3% speedup using 2 threads and 4% - 6%
speedup using 4 threads were seen for real-time mode(at speed 7).

Change-Id: I8a4ac51c2ad9bab9fa7b864e90743931c53ec1c4
2015-01-16 17:19:27 -08:00
Jingning Han
0220255fa0 Merge "Fix frame buffer swap in denoiser" 2015-01-16 16:58:37 -08:00
Minghai Shang
31614c7fdb Merge "[two pass temporal svc]Fix crash issue in transcoder app caused by last fix." 2015-01-16 15:00:20 -08:00
Jingning Han
dfda5cebc7 Fix frame buffer swap in denoiser
This commit fixes a bug in denoiser reference frame buffer swap,
which disables frame buffer update.

Change-Id: I39a9427180fd18f9692602064ad821f7af4714c0
2015-01-16 12:29:58 -08:00
Yaowu Xu
a6715a7558 Add vp9_highbitdepth info in configure --help
Change-Id: I89497a483117fc472be3a836070109498258140d
2015-01-16 11:27:07 -08:00
James Zern
7e515c4637 fix AVX & AVX2 detection
fixes issue #790 which resulted in a SIGILL on OpenBSD

code is mostly from libwebp, based on the following:

https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family

Change-Id: Ida7c1a18261e98c05ed9c662068140be407ec107
2015-01-15 23:16:25 -08:00
Yaowu Xu
bc5d3fae5c Replace "colorspace" with "color_space"
This is to make the usage of the variable name consistent across
the code base.

Change-Id: I698739e55841c59358d1c6e5cc97c96088772943
2015-01-15 17:58:47 -08:00
Minghai Shang
220bc3a013 [two pass temporal svc]Fix crash issue in transcoder app caused by last fix.
Change-Id: I78ecc8ec3fa3ba5f69bb23813e68a5255d0534e1
2015-01-15 16:59:54 -08:00
Frank Galligan
6e7e1cf32f Add Neon intrinsics for vp9_avg_8x8_neon
On Nexus 7 speed -5, -6, -7, and -8 saw about a 1% increase
in perf for 480p. Speeds -5, -6, -7, and -8 saw about a 1.5%
increase in perf for 720p.

Tested on Nexus 7, built with ndk r10d, gcc 4.9.

Change-Id: Ibf17ebfd952a6aec941719bd8306df8ec4574bee
2015-01-15 15:32:40 -08:00
Yaowu Xu
f5bbe244aa Fix obvious misses in doxygen mainpage
Change-Id: I0537769904f0853c9299b36a91391f289acf442c
2015-01-15 15:12:27 -08:00
Yaowu Xu
1be4267ec2 Fix color_space enum comments for doxygen
Change-Id: I14f1708908a0b68b7f4c8e039dbec138c14c5ae4
2015-01-15 13:40:16 -08:00
Yaowu Xu
7ef157ccce Fix doxygen warning with usage.dox
Change-Id: I3ee8974a66f186fb0eb15b1078a3c7b9cbf5ec80
2015-01-15 11:42:04 -08:00
Yaowu Xu
1b7391a3a4 Remove obsolete doxygen tags
Change-Id: I38a42ed1d0be4fbfce6c9f3f5d021055107933d7
2015-01-15 10:46:37 -08:00
Yaowu Xu
199951bd61 Merge "Fix comments for doxygen" 2015-01-15 10:46:20 -08:00
Yunqing Wang
d3ccb3fe2e Merge "Align thread data in vp9_ethread" 2015-01-15 09:21:31 -08:00
Yaowu Xu
9ace4f9e99 Fix comments for doxygen
Change-Id: Iaad3dc3cdd25275939b475706eb7d136a5a10174
2015-01-15 09:12:58 -08:00
James Zern
0373dbf5a5 workaround stack bashing by asm on 32-bit OpenBSD
like Darwin, disable x86inc with 32-bit PIC/shared library builds;
avoids stack smashing done by vp9_subpixel_*

workaround for issue #808

Change-Id: I3f2f16bd91822c8e8dad0242b5dcfb0e621aea97
2015-01-14 23:25:02 -08:00
Yaowu Xu
5ca96f9d60 Merge "Clarify purpose of VP9_INVERT_TILE_DECODE_ORDER" 2015-01-14 20:25:18 -08:00
Yaowu Xu
05d19e06d0 Merge "Add comments for two SVC related controls" 2015-01-14 17:53:49 -08:00
Yaowu Xu
81194188a1 Merge "Add comments for two SVC related controls" 2015-01-14 17:53:42 -08:00
Yaowu Xu
6fc72673b3 Merge "Add comments for control VP9E_SET_TUNE_CONTENT" 2015-01-14 16:28:57 -08:00
Yaowu Xu
f3c9272edc Merge "Add comments for VP9E_SET_FRAME_PERIODIC_BOOST" 2015-01-14 16:28:41 -08:00
Yaowu Xu
6f4d29c58c Clarify purpose of VP9_INVERT_TILE_DECODE_ORDER
Change-Id: I1eb98f4576994c5c9fa5ba748d85cd186910ee4f
2015-01-14 16:26:14 -08:00
Yunqing Wang
99b99831e4 Align thread data in vp9_ethread
On some platforms, such as 32bit Windows and 32bit Mac, the allocated
memory isn't aligned automatically. The thread data is aligned to
ensure the correct access in SIMD code.

Change-Id: I1108c145fe982ddbd3d9324952758297120e4806
2015-01-14 15:51:56 -08:00
Yaowu Xu
f7fd03f996 Merge "Fix comments for encoder controls" 2015-01-14 15:32:35 -08:00
Yaowu Xu
829a01dbb7 Merge "Add encoder control for setting color space" 2015-01-14 14:14:34 -08:00
Frank Galligan
c7d6c0c5a8 Merge "Switch remaining Neon variance functions to shifts" 2015-01-14 12:17:42 -08:00
Frank Galligan
68224a6e87 Merge "Add 64x64 sub_pel_variance Neon function" 2015-01-14 12:17:20 -08:00
Yaowu Xu
3ca15a8be6 Add comments for two SVC related controls
VP9E_SET_SVC
VP9E_SET_SVC_PARAMETERS

Change-Id: Ie32ffad48b6b53c5a2c44c42ec655bfedf8d2903
2015-01-14 12:02:46 -08:00
Yaowu Xu
193ca4b744 Add comments for two SVC related controls
VP9E_GET_SVC_LAYER_ID
VP9E_REGISTER_CX_CALLBACK

Change-Id: I92060bde1a4830268c8e07190d4ee4c37bc05334
2015-01-14 11:48:29 -08:00
Yaowu Xu
dc08b20405 Add comments for control VP9E_SET_TUNE_CONTENT
Change-Id: If1fb5d9f1545cb9753eeda22e699b1ab778452b4
2015-01-14 11:17:09 -08:00
Yaowu Xu
4ab39e13ea Add comments for VP9E_SET_FRAME_PERIODIC_BOOST
Change-Id: Id6decd0024b87da82d85d62ec2f4bdff416faa39
2015-01-14 11:11:53 -08:00
Yaowu Xu
87c436fbe2 Fix comments for encoder controls
This commit added coments for the following encoder controls:
VP9E_SET_LOSSLESS
VP9E_SET_TILE_COLUMNS
VP9E_SET_TILE_ROWS
VP9E_SET_FRAME_PARALLEL_DECODING
VP9E_SET_AQ_MODE

Change-Id: I2f75afd9cce01394f202b8e25f36bf763be0ddeb
2015-01-14 10:54:59 -08:00
Yaowu Xu
e94b415c34 Add encoder control for setting color space
This commit adds encoder side control for vp9 to set color space info
in the output compressed bitstream.

It also amends the "vp9_encoder_params_get_to_decoder" test to verify
the correct color space information is passed from the encoder end to
decoder end.

Change-Id: Ibf5fba2edcb2a8dc37557f6fae5c7816efa52650
2015-01-14 10:17:14 -08:00
Yaowu Xu
afae733eed Merge "Enable decoder to pass through color space info" 2015-01-14 10:04:15 -08:00
Frank Galligan
ec1d8387e1 Add 64x64 sub_pel_variance Neon function
On Nexus 7 speed -5, -6, -7, and -8 saw about a 15% increase
in perf for 480p. Speeds -5, -6, -7, and -8 saw about a 10%
increase in perf for 720p.

Tested on Nexus 7, built with ndk r10d, gcc 4.9.

Change-Id: I2fa5315845e3021c9a6e2ea47e52e68b398d8334
2015-01-14 08:36:24 -08:00
Frank Galligan
588f74f8a6 Switch remaining Neon variance functions to shifts
Saves 5 instructions on 8x8 and 16x16 and 8 instructions
on 32x32, when compiled with 4.9.

Change-Id: Id3da613a36a9d27d8c5169c59ba45d247c920c6c
2015-01-14 07:22:49 -08:00
Frank Galligan
bd3dbc588c Merge "Add 64x variance Neon functions" 2015-01-13 22:38:58 -08:00
Minghai Shang
a14415d171 [twopass temporal svc] Fix decoding error on seek.
Don't put small empty frame in front of a key frame. We will
put key frame flag in webm container if there's a visible key
frame. But there will be decoding error when we seek to here
if we put the small empty frame, which will be inter frame,
in front of it.

Change-Id: Id50c2c1fd31da0405ff6faa7375cc2f49c55402d
2015-01-13 15:44:22 -08:00
Yaowu Xu
6b223fcb58 Enable decoder to pass through color space info
This commit added a field to vpx_image_t for indicating color space,
the field is also added to YUV_BUFFER_CONFIG. This allows the color
space information pass through the decoder from input stream to the
output buffer.

The commit also updated compare_img() function with added verification
of matching color space to ensure the color space information to be
correctly passed from encode to decoder in compressed vp9 streams.

Change-Id: I412776ec83defd8a09d76759aeb057b8fa690371
2015-01-13 15:13:19 -08:00
Frank Galligan
74d40cd507 Add 64x variance Neon functions
Add optimized Neon functions of:
vp9_variance32x64
vp9_variance64x32
vp9_variance64x64

On Nexus 7 speed -5 and -6 saw about a 4% increase in perf.
Speeds -7 and -8 saw about a 6% increase in perf.
Tested on Nexus 7, built with ndk r10d, gcc 4.9.

Change-Id: I5a81f13c9897eb927fa39662530f5524a0f768fa
2015-01-13 15:08:13 -08:00
Yaowu Xu
6f6fbf9175 Merge "Added plumbing for setting color space" 2015-01-13 09:20:13 -08:00
JackyChen
0337bae9b3 Merge "Unit test for turning VP8 denoiser on/off periodically." 2015-01-12 17:33:34 -08:00
Marco
2c6d9c574f vp8: Fix to crash in pick_inter.
Added unittest that triggers the crash without this fix.

Issue: https://code.google.com/p/webm/issues/detail?id=911

Change-Id: If5208ceb210c821891675fdf3d9951ab83d52ae6
2015-01-12 11:53:26 -08:00
Yaowu Xu
fe3f21099f Merge "Fix comments and color format" 2015-01-11 14:01:36 -08:00
JackyChen
7cb111b148 Unit test for turning VP8 denoiser on/off periodically.
Change-Id: Id537d1126f25c0218adcfb4d6ee641ee81a2169a
2015-01-09 14:51:06 -08:00
Yaowu Xu
ce52b0f8d3 Added plumbing for setting color space
Change-Id: If64052cc6e404abc8a64a889f42930d14fad21d3
2015-01-09 10:54:25 -08:00
Yaowu Xu
ecbca31a1d Fix comments and color format
Replaced "color space" with "color format" in comments where color
sampling format is concerned, so to differentiate from the concept
defined in COLOR_SPACE.

Change-Id: I8c935034c166b24307a99352dab1686531276bb8
2015-01-09 10:36:43 -08:00
Paul Wilkins
ccffe318ff Merge "Use 64 bit to accumulate frame sse." 2015-01-09 06:05:11 -08:00
Jingning Han
ae537c151b Merge "Refactor mc reference block fetch in denoiser" 2015-01-08 17:56:53 -08:00
James Zern
4d6838627d Merge "vp9: add per-tile longjmp error handling" 2015-01-08 15:53:37 -08:00
James Zern
44b55dada8 Merge "vp9: fix -Wclobbered (longjmp + local variables)" 2015-01-08 15:53:02 -08:00
Jingning Han
a1daf009be Merge "Use lookup table to find pixel numbers in block" 2015-01-08 13:58:35 -08:00
Johann
00bbe342c2 Merge "Disable vp9 _8_ loopfilters" 2015-01-08 12:47:52 -08:00
Jingning Han
a0be730eae Refactor mc reference block fetch in denoiser
This commit refactors the motion compensated reference block fetch
process in denoiser. It skips the stage that generates motion
compensated reference block if denoiser decides to use copy block
mode. For high motion clips, this could speed up the denoising
process by about 10%.

Change-Id: I8ef4fa5fe766a8c4529119b9ec01faefb3d4ef53
2015-01-08 12:43:08 -08:00
Jingning Han
e3f0b19f3f Use lookup table to find pixel numbers in block
This could save one multiplication in each threshold funtion
called by the denoiser per block.

Change-Id: I35f437e09999f0a087180878ef7805f0d86e5819
2015-01-08 12:32:28 -08:00
Jingning Han
e535ad5067 Merge "Refactor denoiser frame buffer update" 2015-01-08 11:16:14 -08:00
Jingning Han
97dc782635 Merge "Initalize zeromv_sse and newmv_sse in vp9_pick_inter_mode" 2015-01-08 10:55:03 -08:00
Jingning Han
f1866a5792 Merge "Use vp9_convolve_copy in denoiser output" 2015-01-08 09:59:10 -08:00
hkuang
9130e7ad2e Merge "Remove unnecessary init_macroblockd." 2015-01-08 09:15:32 -08:00
Zoe Liu
ce274c5ced Merge "Removed redundant local variables in the forward hybrid transforms." 2015-01-08 02:32:15 -08:00
JackyChen
ea9c949729 Merge "Unit test for turning VP9 denoiser on/off periodically." 2015-01-07 23:36:16 -08:00
Jingning Han
ea061a885d Refactor denoiser frame buffer update
Use frame buffer pointer swap instead of memcpy when possible.
These two CLs make the denoiser when running on vidyo1 720p at
speed -6 over 10% faster.

Change-Id: I64fe8a2422cafca6787a50c7f4dfb961191c0a9d
2015-01-07 18:33:13 -08:00
JackyChen
e82a3b245e Unit test for turning VP9 denoiser on/off periodically.
Change-Id: Ifd2813e8ccd8af189a8dc89b24efb6a5681714c7
2015-01-07 18:26:41 -08:00
Jingning Han
29a5deb40c Use vp9_convolve_copy in denoiser output
Replace copy_block with vp9_convolve_copy for speed performance
improvement.

Change-Id: I3a08c4d01dff2253b6ee573efd02f65ccdc1b5a5
2015-01-07 18:23:17 -08:00
Zoe Liu
4cf636a60e Removed redundant local variables in the forward hybrid transforms.
Change-Id: I60f7ccbbc8dc624134e325bdce6042bc183075b6
2015-01-07 16:38:29 -08:00
Yaowu Xu
01eec75858 Merge "Refactor calculation of tile_cols" 2015-01-07 16:24:57 -08:00
Jingning Han
08055b639a Merge "Always check and free denoiser buffer memory space" 2015-01-07 15:54:06 -08:00
Jingning Han
e42b3ee765 Initalize zeromv_sse and newmv_sse in vp9_pick_inter_mode
These two parameters are used to control the denoiser cut-off
thresholds. They should be properly initialized when starting
mode search of a given block.

Change-Id: Iba8a25487026a0dbe0d350c347d7e4e4e237b637
2015-01-07 15:32:41 -08:00
JackyChen
1883c940b9 Merge "Use qdiff to adjust the threshold of sad and variance in MFQE." 2015-01-07 14:57:46 -08:00
Yaowu Xu
e9cf9b7dfe Refactor calculation of tile_cols
Change-Id: I2c38ea2bcf6d221a0b6b2fb9be4cebbee21006a3
2015-01-07 14:28:59 -08:00
Jingning Han
b208439b5a Merge "Fix best ref frame rd cost update in sub8x8 non-RD mode search" 2015-01-07 14:06:55 -08:00
Jingning Han
3e41563f33 Merge "Format fix in vp9_pick_inter_mode_sub8x8" 2015-01-07 14:06:06 -08:00
Jingning Han
802b798f67 Fix best ref frame rd cost update in sub8x8 non-RD mode search
This fixes the issue that sub8x8 inter blocks always end up
with GOLDEN_FRAME.

Change-Id: Id0c25cbb9c2003f43b4dff8fb1572512c246e077
2015-01-07 12:00:02 -08:00
Jingning Han
c3fd9bbdaf Format fix in vp9_pick_inter_mode_sub8x8
Replace ref_frame++ with ++ref_frame.

Change-Id: Ic39793081156c314bf1b85d5ab76def97f3bff52
2015-01-07 11:50:36 -08:00
Jingning Han
59f29f5e3f Merge "Fix denoiser chroma component initialization" 2015-01-07 11:30:15 -08:00
Jingning Han
9a0e694182 Merge "Skip duplicate denoiser frame buffer allocation" 2015-01-07 11:30:07 -08:00
Jingning Han
21039452c9 Merge "Turn denoiser sensitivity on starting from kf in unit test" 2015-01-07 11:29:54 -08:00
Johann
d12f1f907d Merge "Rearrange loopfilter functions" 2015-01-07 11:07:54 -08:00
Johann
3b8d4458bb Merge "Add missing tests for neon _16_ filters" 2015-01-07 11:07:12 -08:00
Deb Mukherjee
ba93f0a201 Merge "Moves inter mode count updates to update_stats" 2015-01-07 09:38:32 -08:00
JackyChen
60cf5cf7b2 Use qdiff to adjust the threshold of sad and variance in MFQE.
When qdiff is larger, the sad/variance threshold should also be
higher which indicates a more aggressive action on MFQE.

Change-Id: I44c5c93572805458d4f87fdc7619cc9d8a522185
2015-01-07 09:07:10 -08:00
Jingning Han
ce08006951 Always check and free denoiser buffer memory space
The vp9_denoiser_free() function will internally check if the
buffer pointers are NULL. This commit makes the encoder always
call vp9_denoiser_free() after finishing encoding. It protects the
case where noise_sensitivity_level is changed during encoding
process and happen to be turned off towards the end of sequence,
which could result memory space allocated to denoiser not being
released.

Change-Id: Ie20dc2f2e6e5fb6333fbab3356bc153978a6a0f8
2015-01-07 08:50:13 -08:00
Jingning Han
2fb9b635bb Fix denoiser chroma component initialization
Use the correct frame size and stride value for chroma components
when setting the initial values. These control parameters are
assigned when the denoiser buffer was allocated and initialized.

Change-Id: Ia6318194c7738aff540bcbd34f77f0dac46221a1
2015-01-07 08:49:59 -08:00
Jingning Han
27582e573b Skip duplicate denoiser frame buffer allocation
Allocate the frame buffer allocation for denoiser once during the
encoder initialization. This avoids allocating frame buffer
multiple times and overwriting the buffer pointer without proper
releasing.

Change-Id: I9b3baa6283449d86fd164534d344c036bb035700
2015-01-07 08:49:04 -08:00
Paul Wilkins
a3c1a9b419 Use 64 bit to accumulate frame sse.
When testing frame sse to choose a loop filter value and
when checking ambient error in kf Q selection, use 64 bit
values for accumulating the sse, to avoid risk of overflow
for large image formats.

Change-Id: I03765d16c843d0ade61a45b0cd46312472697e57
2015-01-07 14:13:16 +00:00
Johann
377b6682f9 Disable vp9 _8_ loopfilters
Investigating https://code.google.com/p/chromium/issues/detail?id=443839

Change-Id: Ibb7485d835c5aa5e1d40f31715596ba8d208eedb
2015-01-06 19:26:11 -08:00
Johann
b1ba4cc394 Rearrange loopfilter functions
Separate functions and rename files. This will make it easier to disable
some functions later to help work around a compiler issue in chromium.

Change-Id: I7f30e109f77c4cd22e2eda7bd006672f090c1dc5
2015-01-06 19:26:11 -08:00
Johann
fca0037e3b Add missing tests for neon _16_ filters
Change-Id: I47174884efa257f331a369410a2fa7440368250b
2015-01-06 19:26:11 -08:00
Yaowu Xu
7ba6a676f5 Merge "Use -1 consistently as invalid buffer idx" 2015-01-06 17:31:13 -08:00
Deb Mukherjee
e7570493b8 Moves inter mode count updates to update_stats
This makes the inter_mode counts update consistent with other symbols.
Also, forward updates should work corerctly now.

Change-Id: Id98be26fd08875162e644bb8f1de6f0918f85396
2015-01-06 16:40:45 -08:00
Yaowu Xu
61c5e94e22 Use -1 consistently as invalid buffer idx
Instead of mixed use of both -1 and INT_MAX.

This also fixes a vp9 fuzzing test failure.

Change-Id: I950ea94b44ec7cdb5232773bee30b104e342f52a
2015-01-06 15:59:03 -08:00
Deb Mukherjee
0c2ee67ad6 Merge "Enable coefficient range checking for 10-/12-bit" 2015-01-06 14:59:08 -08:00
Frank Galligan
238c4fa74e Fix encode perf test.
JSON was missing a comma.

Change-Id: I7e6b6251b17bc4e74b0197a449ef0313255997e7
2015-01-06 11:12:44 -08:00
Jingning Han
5b860e1251 Turn denoiser sensitivity on starting from kf in unit test
The denoiser sensitivity level should be set to 1 starting from
key frame. The internal function of denoiser should make the
temporal denoising operations cut off in key frame coding.

Change-Id: Id3e704a73e98e4ea801284a2cbbab2ea9c371d23
2015-01-06 10:08:43 -08:00
Yaowu Xu
0979dbb37b Merge "Fix compiler warnigns for msvc2013" 2015-01-06 08:01:47 -08:00
Yaowu Xu
4e00f56cd6 Merge "Return error on wrong sync code" 2015-01-06 08:01:40 -08:00
Yaowu Xu
262f66e6ed Merge "Properly validate data size" 2015-01-06 08:01:30 -08:00
Paul Wilkins
a88e4e64b1 Merge "Deleted unused #define" 2015-01-06 04:18:20 -08:00
Deb Mukherjee
0ce2a27e9b Enable coefficient range checking for 10-/12-bit
Also fixes a broken build with --enable-coefficient-range-checking
configuration option.

Change-Id: Icc536f53088e8cec59dfb8f635668555fdb9125e
2015-01-06 02:40:51 -08:00
Yaowu Xu
9c061ef506 Properly validate data size
With "show_existing_frame" frames:
Minimum data size for profile 0 and 1 is 1 byte (8bits)
Minimum data size for profile 2 and 3 is 2 bytes (9bits)

Otherwise:
Minimum data size is 8 bytes.

This resolves the VP9 failure in fuzzing test build #56.

Change-Id: I146d9d37688f535dd68d24aacc76d464ccffdf04
2015-01-05 17:34:31 -08:00
Yaowu Xu
364b92dc88 Fix compiler warnigns for msvc2013
Change-Id: I1e32bf8f6872a6fb7e9cabe86483e94805e2f790
2015-01-05 17:31:19 -08:00
Yaowu Xu
4fcf726a0e Return error on wrong sync code
Not initialize codec stream info

This fixes vp8 fuzzing issue reported at build #56

Change-Id: I307ac839b4f4bda3a02a551019c0d688dba19c86
2015-01-05 17:19:32 -08:00
Jingning Han
1da0402eff Merge "Fix denoised video output function" 2015-01-05 15:28:29 -08:00
JackyChen
fe23539d58 Adopt weighted averaging in MFQE.
By using weighted averaging in the calculation of the frames to be
displayed, we get an average gain of more than 1 db for key frames
whose base qp are 20 higher than non-key frames.

Change-Id: I7bcb2e7b9c6420ea3f73f33204d18b072dffd17c
2015-01-05 11:38:42 -08:00
Jingning Han
21c0306187 Fix denoised video output function
This commit fixes the buffer alignment control in denoised video
output function. The encoder is now able to properly store the
denoised input video into provided file when enabled.

Change-Id: I258e272c8d4a9b52592e16d6d09976c6f5c21728
2015-01-03 21:39:32 -08:00
Jingning Han
2fe1bfa5ad Merge "Remove redundant local variable for segment_id" 2015-01-02 14:48:27 -08:00
Yaowu Xu
14e37cf917 Add help info for --enable-vp9-highbitdepth
This fixes issue# 903.

Change-Id: I649d8584898a93681073e1ac1b444ff66e240050
2015-01-02 12:36:57 -08:00
Jingning Han
5516fdd8d0 Remove redundant local variable for segment_id
Use mbmi->segment_id directly in vp9_pick_inter_mode. The value is
set outside this function, hence no need to assign it again.

Change-Id: I3d63cdd2e4fadf62ccdefada638b00d979eb3741
2015-01-02 12:25:14 -08:00
Jingning Han
0d2d3321af Merge "Add bsize check condition in nonrd_use_partition" 2015-01-02 11:50:57 -08:00
Jingning Han
5486db185c Add bsize check condition in nonrd_use_partition
Check if block size is below 8x8 for rectangular block coding. It
is added to support 4x8 and 8x4 block coding for RTC mode.

Change-Id: I760b328f45b98ae48adc45ed5a39fb643cd8aebd
2015-01-02 10:12:37 -08:00
Jingning Han
59cfaa538e Merge "Use less tmp motion vectors in vp9_pick_inter_mode_sub8x8" 2015-01-02 10:00:45 -08:00
Jingning Han
5c31fd5c6d Merge "Enable sub8x8 inter block search for RTC coding mode" 2015-01-02 10:00:35 -08:00
hkuang
aa5563cd41 Remove unnecessary init_macroblockd.
macroblockd are init again inside decode_tiles and decode_tiles_mt.

Change-Id: I1f42837864f095c319cdb24cec7d6aa6a3a4da50
2014-12-30 15:23:52 -08:00
Jingning Han
2baccb18a0 Use less tmp motion vectors in vp9_pick_inter_mode_sub8x8
This commit simplifies the reference motion vector part for sub8x8
block coding in RTC mode and reduces the required local variables.

Change-Id: I470d1482092563b68af22404dc1f497e7457b0a8
2014-12-30 13:16:12 -08:00
Yaowu Xu
32d88c2209 Properly set size based on actual buffer layout
VP9FrameSizeTestsLarge.OneByOneVideo has been causing a failure in
jenkins libvpx__unit_tests-valgrind_long for "using of uninitialized
memory", the root cause was that the input image for this test was
not initialized with proper size, therefore plan U and V were not
initialized at all.

This commit fixes the size initialization, and resolves the issue.

Change-Id: Ic4dd1542b7bb0cb260a1e0aeeb505db21ae5edc8
2014-12-30 09:20:36 -08:00
Jingning Han
f5d574c566 Merge "Set ref frame scaling factor in RTC inter mode decision" 2014-12-29 14:20:22 -08:00
Jim Bankoski
cc30751516 Merge "WIP: Remove giant value cost table" 2014-12-29 11:24:42 -08:00
Jingning Han
dad89d5ca1 Enable sub8x8 inter block search for RTC coding mode
This commit enables sub8x8 inter block coding for RTC mode. The
use of sub8x8 blocks can be turned on by allowing
choose_partitioning function to select 4x4/4x8/8x4 block sizes.

Change-Id: Ifbf1fb3888fe4c094fc85158ac3aa89867d8494a
2014-12-24 17:40:31 -08:00
Jim Bankoski
b3c66f8a2f WIP: Remove giant value cost table
Change-Id: Iabe8a8868a747626c24bb13f1796f4c7827af367
2014-12-23 15:06:17 -08:00
Jingning Han
eb1795f643 Set ref frame scaling factor in RTC inter mode decision
Properly set the corresponding scaling factor of the reference
frame in the non-RD mode decision process. This allows the mode
search process to account for the scaled reference frame when
selecting coding mode.

Change-Id: I9d41bff6931c98e5a82b413e37ac5e6e14b93b23
2014-12-23 09:33:58 -08:00
James Zern
59d63e610a vp9: fix -Wclobbered (longjmp + local variables)
Local variables used at the setjmp() site need to be marked volatile.
Relevant excerpt from the 'man longjmp':

===============
The values of automatic variables are unspecified after a call to
longjmp() if they meet all the following criteria:
·  they are local to the function that made the corresponding setjmp(3) call;
·  their values are changed between the calls to setjmp(3) and longjmp(); and
·  they are not declared as volatile.
===============

Change-Id: I093e6eeeedbf5f781d202248ca701ba2c29d3064
2014-12-23 11:44:11 -05:00
Jim Bankoski
8619274ea3 assert that the write writes the whole packet
As a side effect this should avoid an unsigned signed failure in
jenkins.

Change-Id: I8e6a9c3dbd4252d37e6325f95fc80e49ce4cc59e
2014-12-23 08:35:26 -08:00
Jim Bankoski
4e04fa6dea Merge "make vp9_coef_encodings const" 2014-12-22 15:05:25 -08:00
Jim Bankoski
fc954c7c03 Merge "remove static initializers for partition tree" 2014-12-22 13:49:57 -08:00
Jim Bankoski
d6d431c476 Merge "Revert "Revert "Removal of legacy zbin_extra / zbin_oq_value.""" 2014-12-22 13:43:56 -08:00
Jim Bankoski
fba0ead543 Merge "Tokenization without huge tables." 2014-12-22 13:36:38 -08:00
Jim Bankoski
a5f7d78a06 make vp9_coef_encodings const
Change-Id: I28a3d342a4a4b23e02a0f47bb8037c4403f71d61
2014-12-22 13:35:56 -08:00
Jim Bankoski
6121dd89ff Merge "convert extra bit cat structure to const statics" 2014-12-22 12:53:50 -08:00
Frank Galligan
1f0c4991d6 Merge "Add multithread encodes to the encode perf test" 2014-12-22 11:37:24 -08:00
Jingning Han
d0f2377027 Revert "Revert "Removal of legacy zbin_extra / zbin_oq_value.""
This reverts commit 9946ee23e0.

Fix the ssse3 asm function.

Change-Id: I07f77a63aa98087626e45c4e87aa5dcafc0b0b07
2014-12-22 10:09:25 -08:00
Jim Bankoski
4b8c6d96ec Tokenization without huge tables.
Change-Id: Iff528c4b7528cc70320343b3a7ce07a92b024dfd
2014-12-22 08:42:52 -08:00
Jim Bankoski
17ee87b46c convert extra bit cat structure to const statics
Change-Id: Idb257e78dab2339ab1f41c3c82e537bc23e90b65
2014-12-22 06:57:50 -08:00
Jim Bankoski
f4eab151c5 Revert "remove vp8 unused uvstride parm in simple loop filter"
This reverts commit 392a2c43c7

Failing nexus build tests:
http://build.chromium.org/p/client.libvpx/builders/Nexus%207%20Builder/builds/224

Change-Id: I95ae2c894b70cef9c757334fcab7fdeca9003e9c
2014-12-21 21:35:07 -08:00
Jim Bankoski
9152537f3e Merge "Resolve several style issues in decode_perf_test" 2014-12-21 16:50:00 -08:00
Jim Bankoski
2c5dc477bf Merge "remove vp8 unused uvstride parm in simple loop filter" 2014-12-21 16:49:45 -08:00
Jim Bankoski
4276eac294 Resolve several style issues in decode_perf_test
This allows us to track decode speed for new encodes so that we catch
problems like an encode change that makes decode really slow.

Change-Id: I7210196415c4e53d455e9c81246d9fb324913a06
2014-12-19 15:53:59 -08:00
Frank Galligan
d80d94498c Add multithread encodes to the encode perf test
Encode the files with 1, 2, and 4 threads.

Explicitly turn on error resilient and frame parallel
decoding and turn off altref frames.

Change-Id: I02b66f72b7d35c666c3ba685b33015508e440209
2014-12-19 15:21:40 -08:00
Jim Bankoski
3d94b9bf24 Merge "resolve visual studio warnings around initializers" 2014-12-19 15:18:04 -08:00
Jim Bankoski
dd4275e498 resolve visual studio warnings around initializers
Change-Id: Id2ad4fb24242f7ca8fa7a152f0889fded4113613
2014-12-19 12:38:25 -08:00
Yunqing Wang
3a3c71aaa5 Merge "vp9_ethread: add the multi-threaded encoder unit tests" 2014-12-19 12:33:27 -08:00
James Zern
129a2bda2b Merge "vpxdec: ignore GET_FRAME_CORRUPTED error w/--keep-going" 2014-12-19 11:51:19 -08:00
James Zern
953dd1894d vp9: add per-tile longjmp error handling
this avoids longjmp'ing from another thread on error which will cause
undesired behavior

Change-Id: Ic9074ed8cc4243944bf2539d6e482f213f4e8c86
2014-12-19 11:50:04 -08:00
Jingning Han
1b5d612b5d Merge "Add a guard on intra mode skip control for RTC mode" 2014-12-19 11:03:00 -08:00
Jingning Han
9c93307c10 Merge "Remove ARF mode entries from THR_MODES array in non-RD mode" 2014-12-19 11:02:51 -08:00
Jingning Han
cb01baa0fa Merge "Rework mode search threshold update for RTC coding mode" 2014-12-19 11:02:40 -08:00
Jingning Han
a8e6d4d041 Merge "Properly store the tx_size of selected intra mode" 2014-12-19 11:02:37 -08:00
Frank Galligan
2258e28f7e Merge "Fix including test file twice." 2014-12-19 10:31:30 -08:00
Frank Galligan
bc8b0ada3a Merge "Fix encode perf test" 2014-12-19 08:11:36 -08:00
Paul Wilkins
9946ee23e0 Revert "Removal of legacy zbin_extra / zbin_oq_value."
This reverts commit e9b586e21b.

Change-Id: I5b36e6727da6c05278d97e2c37b80c109f79bed4
2014-12-19 15:02:58 +00:00
Paul Wilkins
8ac3f9adaa Merge "Removal of legacy zbin_extra / zbin_oq_value." 2014-12-19 03:37:02 -08:00
James Zern
b32ba09d35 Merge "make vp9 encoder static initializers thread safe" 2014-12-18 18:48:30 -08:00
James Zern
1c69be6e75 Merge "tests/examples.sh: skip env. check for filtered tests" 2014-12-18 18:36:49 -08:00
Johann
39a74e19fb Ensure the error-concealment code is available
When it's configured, make sure it can be configured. When it's not,
make sure it fails.

Change-Id: I857d4b8014547ddbad70395f17e58d5838bd142f
2014-12-18 17:36:58 -08:00
Yunqing Wang
7c2c2bea96 vp9_ethread: add the multi-threaded encoder unit tests
The unit tests for VP9 multi-threaded encoder are added, which
carry out tests for all three modes(i.e. kTwoPassGood, kOnePassGood
and kRealTime), and speeds ranging from 1 to 8. A 1280x720 test
clip is used, which is encoded into multiple tiles. The number of
threads is num_of_tiles.

Change-Id: I04419eeca145ad841c9c527603668239a82e7fbd
2014-12-18 16:37:38 -08:00
Frank Galligan
675ec943db Fix including test file twice.
The test file niklas_1280_720_30.yuv may be included twice.

Change-Id: I44512073e9e430a8e10fbce5afd62041e0edea17
2014-12-18 16:03:27 -08:00
Jim Bankoski
cd60930814 make vp9 encoder static initializers thread safe
Change-Id: If2d0888d13ebe52bc7c3b16f16319408a86ab6de
2014-12-18 15:50:46 -08:00
Frank Galligan
0f3d388685 Fix encode perf test
The accepted range changed to -8..8.
BUG:https://code.google.com/p/webm/issues/detail?id=901

Change-Id: I53ac80b58f4819b82c76db61db5dc476f821191f
2014-12-18 15:19:21 -08:00
Jingning Han
6ec0ef6691 Add a guard on intra mode skip control for RTC mode
This commit adds a guard condition to the intra mode test skip
control in RTC coding mode. If all inter modes are skipped, force
the encoder to check intra mode. It avoids situations where the
encoder processes without properly assigning required mode
information.

Change-Id: Ibb349fee997d6584ce901d08b06e8df3ca9c01b1
2014-12-18 12:00:27 -08:00
Paul Wilkins
e9b586e21b Removal of legacy zbin_extra / zbin_oq_value.
zbin extra / zbin_oq_value was widely passed around,
hence removal touches a lot of code.

Change-Id: Idc94359735b60c38a160e4385ae09d5ca8b6b8e5
2014-12-18 16:49:11 +00:00
Paul Wilkins
60e9b731cf Remove mode dependent zbin boost.
Initial patch to remove get_zbin_mode_boost() and
cpi->zbin_mode_boost.

For now sets a dummy value of 0 for zbin extra pending
a further clean up patch.

Change-Id: I64a1e1eca2d39baa8ffb0871b515a0be05c9a6af
2014-12-18 16:45:52 +00:00
Paul Wilkins
2e39817f5e Merge "Improve motion detection for low complexity regions." 2014-12-18 08:38:21 -08:00
James Zern
fcbf3e45ff vpxdec: ignore GET_FRAME_CORRUPTED error w/--keep-going
this function may return an error if no frame is available; --keep-going
is meant to test decoder resilience, so simply warn in this case.

Change-Id: I6e6aed3e78eca21cca80d7d8a06a1a244685ba29
2014-12-17 19:20:00 -08:00
James Zern
84eca07c61 tests/examples.sh: skip env. check for filtered tests
Change-Id: Ide670b00ae3ecd9e18f394905341bf793349f247
2014-12-17 19:02:00 -08:00
hkuang
b7166143d0 Let YUV plane share the same dqcoeff buffer.
Remove unnecessary dqcoeff from macroblockd which reduce macroblockd
size by 16384 bytes.

Change-Id: Ia379a703b4fee81c8fd4698b52488a85a90c9bc2
2014-12-17 18:29:07 -08:00
Jingning Han
dd0602e01c Remove ARF mode entries from THR_MODES array in non-RD mode
The alternate reference frame is disabled in non-RD mode. No need
to keep the related entries in the THR_MODES array.

Change-Id: I53386f4bb1c6284f582801f27246c5edf55bc24b
2014-12-17 17:13:15 -08:00
Yaowu Xu
09b9a59fb5 Merge "Corrected value range of --cpu-used for vp9" 2014-12-17 17:12:14 -08:00
Jingning Han
455514a683 Rework mode search threshold update for RTC coding mode
In RTC coding mode, the alternate reference frame modes and compound
inter prediction modes are disabled. This commit reworks the
related mode search threshold update process to skip interacting
with these coding modes. It provides about 1.5% speed-up for speed
-6 on average.

vidyo1
16551 b/f, 40.451 dB, 6261 ms -> 16550 b/f, 40.459 dB, 6190 ms

nik720p
33316 b/f, 38.795 dB, 6335 ms -> 33310 b/f, 38.798 dB, 6237 ms

mmmoving
33265 b/f, 41.055 dB, 7176 ms -> 33267 b/f, 41.064 dB, 7084 ms

dark720
33329 b/f, 39.729 dB, 11235 ms -> 33331 b/f, 39.733 dB, 10731 ms

Change-Id: If2a4090a371cd28f579be219c013b972d7d9b97f
2014-12-17 15:56:01 -08:00
Yaowu Xu
a16f075375 Corrected value range of --cpu-used for vp9
This commit removes undefined value options of cpu-used for VP9 and
changed vpxenc prompt to reflect the usable range of [-8,8]

Change-Id: Ib80fef3dbb6ec9aabac45ed13e8ab6fbaf94f55e
2014-12-17 15:18:01 -08:00
JackyChen
9bc7974552 Merge "Add rectangle block support for MFQE." 2014-12-17 15:10:02 -08:00
Deb Mukherjee
4dd5b88535 Merge "Enhance the end to end psnr tests" 2014-12-17 13:49:13 -08:00
Deb Mukherjee
b62064f338 Enhance the end to end psnr tests
Includes more speed settings and also real-time mode now.

Change-Id: I71c77c4a2471d715c61cc30db092aa053cf012e1
2014-12-17 12:00:20 -08:00
Jim Bankoski
fd96deb06c remove static initializers for partition tree
Could have problem with 2 encoders.

Change-Id: I92d326933c00fee688f77b54acf467ca5a8516bc
see: https://code.google.com/p/webm/issues/detail?id=900&thanks=900&ts=1418843841
2014-12-17 11:41:06 -08:00
Yunqing Wang
28c9bed70c Merge "Improve the libvpx encoder test driver" 2014-12-17 10:06:33 -08:00
JackyChen
021e244a51 Merge "Use bit_depth in VP9Common as the flag of highbit." 2014-12-17 09:30:32 -08:00
Jingning Han
56a8bc54a6 Properly store the tx_size of selected intra mode
Use a temporary variable to store the transform size associated
with the best intra mode and restore the mode_info if the overall
best mode is intra mode.

Change-Id: I2606e0061ad32f91b095462902b1eb734b128eea
2014-12-17 09:25:14 -08:00
Jingning Han
00d2211929 Merge "Remove reset mode_info array per frame" 2014-12-17 09:24:44 -08:00
Jingning Han
cc8a11d8a1 Merge "Set second ref frame to be NONE in key frame coding" 2014-12-17 09:24:39 -08:00
Yunqing Wang
3666478195 Improve the libvpx encoder test driver
The encoder initialization is called in EncodeFrame(). Therefore,
in the unit tests, the set control is done when video->frame() is 1.
This didn't cause problem since current tests mainly test lag_frame
> 0 case, or no encoding option that needs to allocate memory before
1st frame is used. If use lag_frame = 0 and encoding multiple tiles,
the unit tests crash. The issue is fixed by doing the initialization
before encoding frames.

Change-Id: I43102048f88448bcf27e9c60e0ec06c176b02e5c
2014-12-17 08:49:46 -08:00
Paul Wilkins
b76312124d Deleted unused #define
FAST_MOTION_MV_THRESH no longer referenced.

Change-Id: Idee6ee5a59ba330904c42b20c9ec35b6fc16f7a2
2014-12-17 14:59:22 +00:00
JackyChen
b363cedcd1 Use bit_depth in VP9Common as the flag of highbit.
Change-Id: I881aefbe68f9c10bb4629a2a5ee1e42a225d5ab7
2014-12-16 21:45:01 -08:00
James Yu
aeeaa67987 VP9 common for ARMv8 by using NEON intrinsics 15
Re-write
- vp9_lpf_horizontal_4_dual_neon
in vp9_loopfilter_16_neon.c

Change-Id: Ie14f63d352f9564ad01db3939a61d91cf6d21a31
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-16 20:00:26 -08:00
Johann
ebc1951c7c Merge "Use defines for inline and __builtin_prefetch" 2014-12-16 18:04:04 -08:00
Jingning Han
200d93545e Merge "Fix intra mode update process in vp9_pick_inter_mode" 2014-12-16 17:04:04 -08:00
JackyChen
9931070094 Add rectangle block support for MFQE.
Only for the rectangle blocks larger than 16X16, SAD and Variance are
still based on the internal square blocks.

Change-Id: I3754da1b0254147313f86a0140dbf4f980f06a5a
2014-12-16 16:35:54 -08:00
Johann
4f7060a431 Merge "VP9 common for ARMv8 by using NEON intrinsics 16" 2014-12-16 16:15:48 -08:00
Johann
9022ba3cb9 Merge "Allow building multi-res encoder with --shared" 2014-12-16 15:54:36 -08:00
Johann
5eb9bfa4e3 Merge "Silence -Werror=unused-parameter" 2014-12-16 15:54:29 -08:00
Jingning Han
ccdc448b70 Remove reset mode_info array per frame
The mode_info array was unnecessarily reset to zero every frame
when error resilient mode turned on, given that the mode info
values per block will be assigned during mode search stage.

This commit removes this reset operation. It reduces the runtime
cost on memset operation to 1/3. The overall speed -6 runtime is
reduced by 2%.

Change-Id: I32ecb73338d8995cc0c5147de09357364f13d45b
2014-12-16 15:54:24 -08:00
Jingning Han
01613aa753 Set second ref frame to be NONE in key frame coding
This commit explicitly set the second reference frame type to be
NONE in key frame coding mode. This fixes a subtle dependency of
reference motion vector used by next inter frame on mode_info
reset before key frame coding.

Change-Id: I5ff0359753fdc9992b0bfe889490f7a32d7d5f6a
2014-12-16 15:49:58 -08:00
Johann
2fdbf70d40 Use defines for inline and __builtin_prefetch
These were established for compatibility. Make sure to use them.

Most frequently they manifest as issues on Visual Studio builds.

Change-Id: I39d764d2eb341b999d7a6132cb44b2acfc511160
2014-12-16 15:21:19 -08:00
Frank Galligan
5fdd0f1fe0 Merge "Revert "Revert "Add support for setting byte alignment.""" 2014-12-16 15:14:17 -08:00
James Yu
aa8dd897c1 VP9 common for ARMv8 by using NEON intrinsics 16
Add vp9_reconintra_neon.c
- vp9_v_predictor_4x4_neon
- vp9_v_predictor_8x8_neon
- vp9_v_predictor_16x16_neon
- vp9_v_predictor_32x32_neon
- vp9_h_predictor_4x4_neon
- vp9_h_predictor_8x8_neon
- vp9_h_predictor_16x16_neon
- vp9_h_predictor_32x32_neon
- vp9_tm_predictor_4x4_neon
- vp9_tm_predictor_8x8_neon
- vp9_tm_predictor_16x16_neon
- vp9_tm_predictor_32x32_neon

Change-Id: Ib5d54a4766a1b5127169045659974f33aa98376d
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-16 12:57:52 -08:00
Johann
73261850fe Allow building multi-res encoder with --shared
Export vpx_codec_enc_init_multi_ver so the vp8 multi res encoder example
can see it when building shared.

Change-Id: Ic5222b1b6d949f39c7e50c3bc58fb76bece2a3f1
2014-12-16 12:47:53 -08:00
Johann
80b344dec5 Silence -Werror=unused-parameter
Cast away remaining issues so that new ones don't get lost in the noise.

Change-Id: Iacd6999b0686ce80f9835730d68db6382690fa92
2014-12-16 12:47:08 -08:00
James Zern
2a64ed9b70 Merge "rtcd: handle armv7s architecture" 2014-12-16 12:22:55 -08:00
James Yu
ba05a4c640 VP9 common for ARMv8 by using NEON intrinsics 19
Delete vp9_dc_only_idct_add_neon.c

The function was merged with vp9_short_idct4x4_1_add (later
vp9_idct4x4_1_add) in d2de1ca and should have been deleted then.

Change-Id: Ie58ba3dd9dc7330a8f1238dd7dd71c9ed4639b94
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-16 11:14:12 -08:00
JackyChen
603cdcfce5 Merge "Fixed MFQE crash issue for highbit depth." 2014-12-16 11:12:03 -08:00
JackyChen
e7bad92689 Fixed MFQE crash issue for highbit depth.
Check the flags, no MFQE for highbit now. Will add highbit support
latter.

Change-Id: I548c27593e0f47ab7f4c92b45f14fb037dc86591
2014-12-16 10:07:38 -08:00
Jingning Han
581c8dbd33 Merge "Initialize best_tx_size with invalid value" 2014-12-16 10:01:03 -08:00
Yaowu Xu
b60ae45f36 Merge "Prevent decoder from using uninitialized entropy context." 2014-12-16 09:30:24 -08:00
Jingning Han
b47f9c5802 Merge "Use right shift to replace division in vp9_pick_inter_mode" 2014-12-16 09:26:51 -08:00
Paul Wilkins
b6c75c5a8d Improve motion detection for low complexity regions.
Where there is very subtle motion, especially when combined
with low spatial complexity, the codec sometimes fails to quickly
pick up the ambient motion field.

Once it has been established though the field propagates well using
Nearest and Near MV.

This patch looks specifically at the case where the Nearest and Near
have not been established as non zero vectors and in this case
discounts the cost of searching for a new vector in the rd code.

This will almost certainly have some implications in terms of encode
speed but it should be possible to mitigate the impact in a subsequent
using first pass stats and the local spatial complexity.

Average results for test sets approximately neutral.

Change-Id: I44a29e20f11f7ab10f8c93ffbdc50183d9801524
2014-12-16 17:22:54 +00:00
Debargha Mukherjee
4ebdb4a1b9 Merge "Fix for crash in highbitdepth rt mode" 2014-12-16 06:41:54 -08:00
Jim Bankoski
abc5a66770 Merge "Fix the comments." 2014-12-16 06:25:01 -08:00
Peter de Rivaz
e3d19bfc63 Fix for crash in highbitdepth rt mode
Change 72141 introduced a new use of vp9_avg_4x4.
This call needs to switch to using vp9_highbd_avg_4x4
when performing high bitdepth encodes.

Change-Id: I6a8ba4b62f8a75d0a917b365a55245e2f0438ea1
2014-12-16 10:55:49 +00:00
James Zern
a2fed22b6c Merge "iosbuild.sh: allow for out of tree builds" 2014-12-15 22:04:46 -08:00
James Zern
0e94f3cf06 iosbuild.sh: allow for out of tree builds
Change-Id: Id89ed4a4153dd6e02380c4b8ae8ad6c1f8d21944
2014-12-15 18:41:46 -08:00
James Zern
6ea881cc12 rtcd: handle armv7s architecture
quiets build warnings about implicit (armv6) function declarations

Change-Id: I896a5ef3e367e5bb92777a60d34003eb3a040997
2014-12-15 18:39:51 -08:00
Jingning Han
df3e3ab6ff Fix intra mode update process in vp9_pick_inter_mode
When multiple intra modes are tested, the previous mode info
update process may overwrite the selected best intra mode and make
the final selection use an inter mode. This commit fixes this
issue by moving the mode_info reset outside the intra mode search
loop.

Change-Id: I15ed4288a6b3cb0832104a5e6d5d9a25cd1a5b2b
2014-12-15 17:52:09 -08:00
Johann
1d059fa23e Merge "VP9 common for ARMv8 by using NEON intrinsics 06" 2014-12-15 14:49:33 -08:00
Johann
37ea1e1218 Merge "VP9 common for ARMv8 by using NEON intrinsics 05" 2014-12-15 14:48:53 -08:00
Jingning Han
5c93dca3d3 Merge "Simplify rate-distortion modeling function" 2014-12-15 14:37:19 -08:00
Jingning Han
c2c7596fc7 Initialize best_tx_size with invalid value
If vp9_pick_inter_mode works properly, it should at least check
one coding mode and hence get best_tx_size assigned a valid value.
There is no need to initialize best_tx_size with a legitimate
value before starting the mode search.

Change-Id: Ic0496cd89672ea9c2c512a9bd1da952190af9cba
2014-12-15 12:58:34 -08:00
Jingning Han
83e2c62aba Use right shift to replace division in vp9_pick_inter_mode
Make the variable reduction_fac log2 based and explicitly use
right shift when computing intra_cost_penalty.

Change-Id: I208f1fb879a02debb3b3fc64f9fd06260dcf1c86
2014-12-15 12:48:07 -08:00
Frank Galligan
c4f7079ad4 Revert "Revert "Add support for setting byte alignment.""
This reverts commit 91471d6aad.

Fixes the compile issues if post_proc is enabled.

Change-Id: Ib40a15ce2c194f9b5adfa65a17ab01ddf60f5a59
2014-12-15 12:20:37 -08:00
James Yu
4f856cd7fa VP9 common for ARMv8 by using NEON intrinsics 06
Add vp9_iht8x8_add_neon.c
- vp9_iht8x8_64_add_neon

The assembly did not previously implement tx_type 0
BUG=716

Change-Id: Icfc99dd24f3d59047f9184a7d0c761ba7e3de934
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-15 12:18:06 -08:00
James Yu
6b71013277 VP9 common for ARMv8 by using NEON intrinsics 05
Add vp9_iht4x4_add_neon.c
- vp9_iht4x4_16_add_neon

The assembly did not previously implement tx_type 0
BUG=715

Change-Id: I60034d1568de034edba45c5cdd13f3d87dbc73b6
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-15 12:16:19 -08:00
James Zern
8d558f2ca5 Merge "vp9/MACROBLOCKD: reorder struct members" 2014-12-15 11:54:51 -08:00
Jingning Han
eefe869291 Simplify rate-distortion modeling function
Use left shift to replace one multiplication. The computation
outcome remains identical.

Change-Id: I1e1737af0a245de0d2a2bde10f0c171477199fc1
2014-12-15 11:51:16 -08:00
Paul Wilkins
91471d6aad Revert "Add support for setting byte alignment."
Fails to compile. Bad calls to vp9_alloc_frame_buffer
and vp9_realloc_frame_buffer in postproc.c

This reverts commit 399823b6f5.

Change-Id: I29f0e173f8e185d3a303cfdb17813e1eccb51e3a
2014-12-15 11:54:13 +00:00
hkuang
d4426d5876 Merge "Fix a bug that break the vp8 fragment decoder." 2014-12-13 09:56:55 -08:00
James Zern
d356dce759 iosbuild: add success/failure output
Change-Id: I84492f68752321f0266141666e2672ed2da5f509
2014-12-12 19:45:15 -08:00
James Zern
c58c579ec4 vp9/MACROBLOCKD: reorder struct members
improves locality of reference

Change-Id: I0639b98bf38879f918173b3a1b25dd93090e88b4
2014-12-12 18:01:24 -08:00
hkuang
9353607ac8 Fix a bug that break the vp8 fragment decoder.
(issue #882).

Change-Id: I2ca7f96d390c4eaec0473c50cb01b903d0bd3ee6
2014-12-12 16:44:14 -08:00
James Zern
089086bc25 Merge "Optimize bit_read_buffer." 2014-12-12 16:29:42 -08:00
Tom Finegan
b3345f462f Merge "vpxdec: Rename the libyuv scale wrapper." 2014-12-12 16:14:57 -08:00
Tom Finegan
53a0ed84ac Merge "iosbuild.sh: Add targets argument." 2014-12-12 16:14:12 -08:00
Frank Galligan
9c2601eb68 Merge "Add support for setting byte alignment." 2014-12-12 15:47:11 -08:00
hkuang
3cecce916b Optimize bit_read_buffer.
Change-Id: Iee43c34909deec9787b29c1c33672213b9f049df
2014-12-12 14:38:12 -08:00
James Zern
89ee8923a8 Merge "Remove redundant loads on 1d16_v8 filter." 2014-12-12 14:32:52 -08:00
James Zern
f82d7fd854 Merge "Remove redundant loads on 1d8_v8 filter." 2014-12-12 14:32:26 -08:00
James Zern
4d40a046da Merge "vp9: move encoder-only member from common" 2014-12-12 14:28:55 -08:00
James Zern
0c0a57b94d Merge "don't set INLINE to 'always_inline'" 2014-12-12 14:28:20 -08:00
James Zern
2bf4b4852f Merge changes Id6421838,I37499329
* changes:
  vp9: make postproc members depend on CONFIG_VP9_POSTPROC
  vp9_postproc: remove redundant CONFIG_* checks
2014-12-12 14:27:56 -08:00
Marco
7f59cff53d Merge "Allow for 4x4 prediction blocks for key frame, speed 6." 2014-12-12 14:27:31 -08:00
James Zern
5ccff43292 Merge "vp9_loopfilter_mmx: remove some unused tables" 2014-12-12 14:25:53 -08:00
James Zern
3aecec084b Merge "x86_abi_support: set LIBVPX_RAND w/vp9-postproc" 2014-12-12 14:25:30 -08:00
Tom Finegan
bc74a2f33b iosbuild.sh: Add targets argument.
Allows override of default target list. Also added missing usage info
for --extra-configure-args, and removed last vestiges of armv6 support.

Change-Id: Ic0f14fffa0cbaea1bed371d38ff65e035bbe3273
2014-12-12 13:53:58 -08:00
Frank Galligan
399823b6f5 Add support for setting byte alignment.
Add support for setting byte alignment on the Y, U, and V plane of the
reference buffers. The byte alignment must be a power of 2, from 32 to
1024. A value of 0 sets legacy alignment.

Change-Id: I7c1399622f7aa68e123646369216b32047dda73d
2014-12-12 13:34:36 -08:00
James Zern
6d1a63a02a Merge "Remove unnecessary dqcoeff memset." 2014-12-12 12:16:32 -08:00
Tom Finegan
8ef2ce8664 vpxdec: Rename the libyuv scale wrapper.
The other name was misleading: We do not export scaling support from
libvpx via vpx_im{g,age}*.

Change-Id: I8acb4ea0301f08c9bab557a4063ea35d147b4631
2014-12-12 11:58:53 -08:00
Frank Galligan
6a24dbd71f Remove redundant loads on 1d16_v8 filter.
This CL showed about a 3% gain in performance on some systems.

Change-Id: Id27e7e0b8e69068aa364e67859436da852669250
2014-12-12 11:48:47 -08:00
Frank Galligan
44ee777905 Remove redundant loads on 1d8_v8 filter.
This CL showed a modest gain in performance on some systems.

Change-Id: Iad636a89a1a9804ab7a0dea302bf2c6a4d1653a4
2014-12-12 11:34:24 -08:00
James Zern
5fe9a5c649 don't set INLINE to 'always_inline'
INLINE is used quite widely in vp9, this change improves performance
1-2% on most modern platforms.

Change-Id: I8a9974aab89fa588ea4923cc7eaf6199e344a528
2014-12-12 11:18:00 -08:00
James Zern
72ece1308b vp9: move encoder-only member from common
allow_comp_inter_inter VP9_COMMON -> VP9_COMP

Change-Id: I6d9dc25d1cdd7e2ab62f5be69cd9fa883d21dbb6
2014-12-12 11:17:44 -08:00
James Zern
ef06de33fe vp9: make postproc members depend on CONFIG_VP9_POSTPROC
Change-Id: Id64218386968cee3132269e4a0572650f20fd980
2014-12-12 11:17:17 -08:00
James Zern
890f7bedf3 vp9_postproc: remove redundant CONFIG_* checks
the entire module is wrapped in CONFIG_VP9_POSTPROC which is forcibly
enabled with CONFIG_INTERNAL_STATS

+ a similar change in vp9_alloccommon.c

Change-Id: I374993297a9fba5bef2f0b71f984eba42f0995a3
2014-12-12 11:17:16 -08:00
James Zern
d456ccbc9d vp9_loopfilter_mmx: remove some unused tables
Change-Id: I964d25cc91c8e4864d73b142d9c7a1b39cb6cfbb
2014-12-12 11:16:24 -08:00
Jim Bankoski
d916b0f22f Merge "vp9_dx_iface.c uses CONFIG_VP9_POSTPROC but config.h not included" 2014-12-12 11:10:17 -08:00
Jim Bankoski
cf6a5c8759 Merge "Adds a test to make sure encoder parms get to decoder." 2014-12-12 11:10:08 -08:00
James Zern
d5484f109e x86_abi_support: set LIBVPX_RAND w/vp9-postproc
set LIBVPX_RAND with --enable-vp9-postproc, previously only the vp8
config was checked. this fixes the build with --disable-postproc.

Change-Id: Ia61baded6aa0e44d6443ae4a3c85915f1054f053
2014-12-12 11:07:29 -08:00
Jingning Han
3e0793b80b Merge "Fix PICK_MODE_CONTEXT index in non-RD coding mode" 2014-12-12 09:16:01 -08:00
Jim Bankoski
c67859f737 vp9_dx_iface.c uses CONFIG_VP9_POSTPROC but config.h not included
Change-Id: Id316b3786214bf1028992968955da917e3f2d4a3
2014-12-12 08:42:36 -08:00
Jim Bankoski
18d323606d Fix test to call clear system state in convolve_test.
Assembly tests should clear system state, as we have no
expectation of proper system state in between test runs..

Change-Id: I0f591996c1f17ef2a5a8572a6b445f757223a144
2014-12-12 06:18:56 -08:00
Jim Bankoski
a0d9a9dd51 Adds a test to make sure encoder parms get to decoder.
This is meant as a framework for testing that encode parms make it
through to the decoder.

Change-Id: Idb86ee3668b45b4e73c23c6e4daef94b0650b786
2014-12-11 17:34:32 -08:00
Jingning Han
e2c2a65695 Fix PICK_MODE_CONTEXT index in non-RD coding mode
This commit fixes a bug in the PICK_MODE_CONTEXT index for
horizontal partition case. The compression performance change
is less than 0.01% level, since most blocks are selected to
use square block size in RTC coding mode.

Change-Id: I67effc18ae8795fccdd82a55f4efc609fa5cb3e1
2014-12-11 17:21:24 -08:00
JackyChen
3425d6c83e Merge "Multiframe Quality Enhancement(MFQE) in VP9." 2014-12-11 16:24:08 -08:00
Marco
7e99cd2a9b Allow for 4x4 prediction blocks for key frame, speed 6.
For key frame under variance source partition: 4x4 prediction blocks
may be selected when variance of 8x8 block is very high (threshold is set fairly high for now).

Testing on some RTC clips shows this helps to reduce some ringing artifacts on key frame.
Encoded key frame size increases about ~10%. Key frame PSNR increases about ~0.1-0.2dB.

Change-Id: I56e203fac32ea6ef69897fb3ea269c59cb50d174
2014-12-11 15:36:16 -08:00
Jingning Han
811c74cdfa Merge "Replace division with bit shift in choose_partitioning" 2014-12-11 13:30:03 -08:00
Deb Mukherjee
847636fe88 Merge "Re-enable 8x8 fdct/fht tests by changing tolerance" 2014-12-11 12:29:06 -08:00
Debargha Mukherjee
dd33c656da Merge "Corrected optimization of 8x8 DCT code" 2014-12-11 12:28:45 -08:00
hkuang
3c7a06c3cc Remove unnecessary dqcoeff memset.
dqcoeff is set to be 0 on initialization. And set back to 0 after being
used everytime.

Change-Id: I32b8e149bba40a8d707849f737a8e49a691f319c
2014-12-11 12:27:25 -08:00
Jingning Han
d9892e846f Merge "Refactor choose_partitioning computing scheme" 2014-12-11 11:14:07 -08:00
Jingning Han
d5c396a902 Replace division with bit shift in choose_partitioning
This commit explicitly uses the bit shift operation instead of
division for computing block variance.

Change-Id: Id19c0ff27dd1d1ae4aceee6657e1aad0d406bd74
2014-12-11 11:06:57 -08:00
Alexander Voronov
6c6a97814f Prevent decoder from using uninitialized entropy context.
If decoding starts with intra-only frame, there is a possibility
of using uninitialized entropy context, what leads to undefined
behavior.

Change-Id: Icbb64b5b1bd1e5de2a4bfa2884e56bc0a20840af
2014-12-11 20:44:19 +03:00
Peter de Rivaz
5c22224e9e 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
(cherry picked from commit fd05fb0c21)
2014-12-11 09:42:57 -08:00
Jingning Han
377d2f027a Refactor choose_partitioning computing scheme
This commit refactors the choose_partitioning function. It removes
redundant memset calls and makes the encoder to calculate
variance value per block only when it is needed. It reduces the
average runtime cost of choose_partitioning by 60%. Overall it
reduces speed -6 runtime by 2-5%.

Change-Id: I951922c50d901d0fff77a3bafc45992179bacef9
2014-12-11 09:33:40 -08:00
JackyChen
7ac3e3c1d6 Multiframe Quality Enhancement(MFQE) in VP9.
It is the first version of MFQE in VP9. There are a few TODOs included
in this version.
Usage: Add flag --enable-vp9-postproc to config the project.
In decoder, use flag --mfqe in the command line to enable
MFQE in postproc.
Note: Need to have key frame with low quality to see the effect of this
new patch. In my experiment, I fixed the qindex to 200 in key frame.

Change-Id: I021f9ce4616ed3574c81e48d968662994b56a396
2014-12-11 09:19:39 -08:00
Johann
26a0721268 Enable neon idct tests for intrinsics
Change-Id: I45d4a22f3ecb9af172e37c95f168805e492c5493
2014-12-10 18:20:04 -08:00
James Yu
3f7c12dab9 VP9 common for ARMv8 by using NEON intrinsics 18
Add vp9_idct32x32_add_neon.c
- vp9_idct32x32_1024_add_neon

Change-Id: Ic598b772c28bd3487a8ead7a4598a66b25f9b00f
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 18:20:04 -08:00
James Yu
3cfed4bf76 VP9 common for ARMv8 by using NEON intrinsics 14
Add vp9_idct16x16_add_neon.c
- vp9_idct16x16_256_add_neon_pass1
- vp9_idct16x16_256_add_neon_pass2
- vp9_idct16x16_10_add_neon_pass1
- vp9_idct16x16_10_add_neon_pass2

Change-Id: I54d25b54a36f4371760f54e4036693aaea40a5de
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 18:19:54 -08:00
James Yu
ce76aeb00d VP9 common for ARMv8 by using NEON intrinsics 13
Add vp9_idct8x8_add_neon.c
- vp9_idct8x8_64_add_neon
- vp9_idct8x8_10_add_neon

Change-Id: I6ee7b4496765aa36ed52990f2ef73e9f24459610
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 14:56:54 -08:00
James Yu
8c25f4af6a VP9 common for ARMv8 by using NEON intrinsics 12
Add vp9_idct4x4_add_neon.c
- vp9_idct4x4_16_add_neon

Change-Id: I011a96b10f1992dbd52246019ce05bae7ca8ea4f
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 14:49:59 -08:00
James Yu
420f58f2d2 VP9 common for ARMv8 by using NEON intrinsics 11
Add vp9_idct16x16_1_add_neon.c
- vp9_idct16x16_1_add_neon

Change-Id: I7c6524024ad4cb4e66aa38f1c887e733503c39df
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 13:06:58 -08:00
James Yu
030ca4d0e5 VP9 common for ARMv8 by using NEON intrinsics 10
Add vp9_idct32x32_1_add_neon.c
- vp9_idct32x32_1_add_neon

Change-Id: If9ffe9a857228f5c67f61dc2b428b40965816eda
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 13:04:29 -08:00
James Yu
2772b45ac0 VP9 common for ARMv8 by using NEON intrinsics 09
Add vp9_idct8x8_1_add_neon.c
- vp9_idct8x8_1_add_neon

Change-Id: I9d23e01fa96013febbf64db6c76c6c955f14e3ff
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 12:52:33 -08:00
James Yu
9114f0afdb VP9 common for ARMv8 by using NEON intrinsics 08
Add vp9_idct4x4_1_add_neon.c
- vp9_idct4x4_1_add_neon

Change-Id: Ieab9af107dbd07a4f9503bc945890c90faccb8ac
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-10 12:49:28 -08:00
Johann
2d8f581330 Merge "VP9 common for ARMv8 by using NEON intrinsics 07" 2014-12-10 11:40:46 -08:00
Johann
913d0adbaf Merge "VP9 common for ARMv8 by using NEON intrinsics 04" 2014-12-10 11:40:29 -08:00
Paul Wilkins
65cfb808d0 Merge "Substantial restructuring of AQ mode 2." 2014-12-10 10:44:27 -08:00
Jingning Han
ad19724f1a Merge "Use use_prev_frame_mvs flag for ref mv search branch" 2014-12-10 09:25:12 -08:00
Jingning Han
6fc289b9c0 Merge "Refactor update_state_rt" 2014-12-10 09:25:05 -08:00
Jingning Han
8bd88a3c83 Merge "Make RTC coding flow support sub8x8 in key frame coding" 2014-12-10 09:24:56 -08:00
Jingning Han
4cda7a1a9a Merge "Cosmetic naming change" 2014-12-10 09:05:34 -08:00
Jingning Han
fb3cc0ed57 Merge "Take out redundant setting of mode_info from set_block_size" 2014-12-10 09:05:26 -08:00
Jingning Han
161f636809 Merge "Remove unused rd cost calculation from nonrd_use_partition" 2014-12-10 09:05:18 -08:00
Jim Bankoski
d01c7e3544 Merge changes I92251a8b,I5d23a685
* changes:
  Adds a decode perf test that builds a new file.
  Make the decoder Cfg available to encoder tests..
2014-12-10 06:42:08 -08:00
James Yu
01fc6f51e0 VP9 common for ARMv8 by using NEON intrinsics 07
Add vp9_convolve8_neon.c
- vp9_convolve8_horiz_neon
- vp9_convolve8_vert_neon

Change-Id: I0bdd99ff72d275223fe211ac7243c25a5a60cf87
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-09 20:03:07 -08:00
James Yu
893534a996 VP9 common for ARMv8 by using NEON intrinsics 04
Add vp9_convolve8_avg_neon.c
- vp9_convolve8_avg_horiz_neon
- vp9_convolve8_avg_vert_neon

Change-Id: I617971e37b02186fec5aca181f4f9622050ea2df
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-09 20:03:07 -08:00
James Yu
d12757f5c6 VP9 common for ARMv8 by using NEON intrinsics 03
Add vp9_copy_neon.c
- vp9_convolve_copy_neon

Change-Id: I291fc5423d06240876411bbceab03eae5ef585be
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-09 20:02:46 -08:00
Scott LaVarnway
617382a2e3 VP9 common for ARMv8 by using NEON intrinsics 02
Add vp9_avg_neon.c
- vp9_convolve_avg_neon

Change-Id: Id2c9d5bcfa37cff1a16417aba1656ff07bdf10fd
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-09 19:00:21 -08:00
James Zern
10252275f8 Merge "Fix clang ioc warning due to NULL src_mi pointer." 2014-12-09 18:31:46 -08:00
Jingning Han
0cac834b5a Use use_prev_frame_mvs flag for ref mv search branch
Replace error_resilient flag with use_prev_frame_mvs in
vp9_pick_inter_mode reference motion vector search selection.
This effectively turns off the simplified ref mv search in the
settings of frame resizing, even if error-resilient mode is off.

Change-Id: I7fed814ee7bc0cb419a03b846e0fc2de46ba7686
2014-12-09 18:18:40 -08:00
Johann
65247d8f59 Merge "Add convolve_copy and convolve_avg to the test" 2014-12-09 16:51:35 -08:00
Jingning Han
e728678c50 Refactor update_state_rt
Update the frame motion vector only if previous frame motion vector
is needed for next frame reference motion vector.

Change-Id: Ica50f9d7b46ad4f815bba0d9e30f5546df29546f
2014-12-09 15:35:49 -08:00
hkuang
4eee74d6ed Fix clang ioc warning due to NULL src_mi pointer.
The warning only happens in VP9 encoder's first pass due to src_mi
is not set up yet. But it will not fail the encoder as left_mi and
above_mi are not used in the first_pass and they will be set up again
in the second pass.

Change-Id: I12dffcd5fb1002b2b2dabb083c8726650e4b5f08
2014-12-09 14:32:48 -08:00
Johann
5810f1b4cd Merge "VP9 common for ARMv8 by using NEON intrinsics 01" 2014-12-09 13:41:49 -08:00
Johann
1c3594c334 Add convolve_copy and convolve_avg to the test
Change-Id: Ic9438031282e63e627550f7e4cdeda36e43e647b
2014-12-09 12:56:38 -08:00
Johann
09b7ad42e7 Merge "Disable neon assembly when neon is disabled" 2014-12-09 12:47:12 -08:00
Jim Bankoski
c2638bd80a Adds a decode perf test that builds a new file.
This allows us to track decode speed for new encodes so that we catch
problems like an encode change that makes decode really slow.

Change-Id: I92251a8b1f710b241f66e1042413df1b71b76038
2014-12-09 12:44:45 -08:00
James Yu
5b098b1825 VP9 common for ARMv8 by using NEON intrinsics 01
Add vp9_loopfilter_neon.c
- vp9_lpf_horizontal_4_neon
- vp9_lpf_vertical_4_neon
- vp9_lpf_horizontal_8_neon
- vp9_lpf_vertical_8_neon

Change-Id: I97a0d7b399a431c21ee77396be3d5f5a1f7ebccb
Signed-off-by: James Yu <james.yu@linaro.org>
2014-12-09 12:26:56 -08:00
Jingning Han
225cdef665 Make RTC coding flow support sub8x8 in key frame coding
This commit enables the use of sub8x8 blocks in RTC key frame
encoding. It requires the block size to be preset and will decide
the coding mode and encode the bit-stream.

Change-Id: I35aaf8ee2d4d6085432410c7963f339f85a2c19b
2014-12-09 11:34:58 -08:00
Johann
e577098079 Disable neon assembly when neon is disabled
Change-Id: Idde266cd7287bb6bee016c90efeafa67550f94c6
2014-12-09 10:46:32 -08:00
Jingning Han
4bacaab46d Cosmetic naming change
Rename set_modeinfo_offsets as set_mode_info_offsets, to be more
consistent with naming convention.

Change-Id: I68ca1f36c4a78127d9439a50c1506a2afd07927d
2014-12-09 10:32:04 -08:00
Jingning Han
f051a7beab Take out redundant setting of mode_info from set_block_size
The later encoding process will take the top-left block's
mode_info for pre-determined block size.

Change-Id: I76a90f9ce7f3b2dbc2975b52442114e461c465b5
2014-12-09 10:27:18 -08:00
hkuang
3dfdfd5c86 Merge "Clean up the logic of handling corrupted frame." 2014-12-09 10:23:18 -08:00
Paul Wilkins
e68c8dcfd2 Substantial restructuring of AQ mode 2.
The restructure moves the decision into the rd pick
modes loop and makes a decision based at the 16x16
block level instead of only the 64x64 level.

This gives finer granularity and better visual results
on the clips I have tested. Metrics results are worse
than the old AQ2 especially for PSNR and this mode
now falls between AQ0 and AQ1 in terms of visual
impact and metrics results.

Further tuning of this to follow.

It should be noted that if there are multiple iterations
of the recode loop the segment for a MB could change
in each loop if the previous loop causes a change in the
complexity / variance bin of the block. Also where a block
gets a delta Q this will alter the rd multiplier for this block
in subsequent recode iterations and frames where the
segmentation is applied.

Change-Id: I20256c125daa14734c16f7cc9aefab656ab808f7
2014-12-09 15:10:52 +00:00
Jingning Han
1395ded2a7 Remove unused rd cost calculation from nonrd_use_partition
The per block rd cost calculation is not needed when partition
size is preset.

Change-Id: Ie5575248bbffb584e908aa13097f697ace6ec747
2014-12-08 18:45:19 -08:00
Johann
547cb14e15 Merge "Extend x32 check by also checking for __x86_64__." 2014-12-08 14:52:31 -08:00
Yunqing Wang
cddbdeabd0 Merge "SSSE3 Optimization for Atom processors using new instruction selection and ordering" 2014-12-08 13:34:54 -08:00
James Zern
c38d0490b3 Merge "Changes to assembler for NASM on mac." 2014-12-08 12:55:06 -08:00
hkuang
81e5cb86d3 Fix the comments.
Change-Id: I9789476865a1b24dad54115d8f7edb4fed780b90
2014-12-08 12:44:09 -08:00
hkuang
d05cf10fe7 Add error handling for frame parallel decode and unit test for that.
Change-Id: I6e309e11f1641618d2424b7a2c0fe744b8974dec
2014-12-08 12:30:19 -08:00
levytamar82
8f9d94ec17 SSSE3 Optimization for Atom processors using new instruction selection and ordering
The function vp9_filter_block1d16_h8_ssse3 uses the PSHUFB instruction which has a 3 cycle latency and slows execution when done in blocks of 5 or more on Atom processors.
By replacing the PSHUFB instructions with other more efficient single cycle instructions (PUNPCKLBW + PUNPCHBW + PALIGNR) performance can be improved.
In the original code, the PSHUBF uses every byte and is consecutively copied.
This is done more efficiently by PUNPCKLBW and PUNPCHBW, using PALIGNR to concatenate the intermediate result and then shift right the next consecutive 16 bytes for the final result.

For example:
filter = 0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8
Reg = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
REG1 = PUNPCKLBW Reg, Reg = 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7
REG2 = PUNPCHBW Reg, Reg = 8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15
PALIGNR REG2, REG1, 1 = 0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8

This optimization improved the function performance by 23% and produced a 3% user level gain on 1080p content on Atom processors.
There was no observed performance impact on Core processors (expected).

Change-Id: I3cec701158993d95ed23ff04516942b5a4a461c0
2014-12-08 13:11:01 -07:00
hkuang
f925e5ce0f Merge "Improve the performance by caching the left_mi and right_mi in macroblockd." 2014-12-08 10:24:17 -08:00
Paul Wilkins
127f65531b Merge "Use average mb energy from first pass in AQ2 test." 2014-12-08 09:01:39 -08:00
Frank Galligan
0f8e8330eb Merge "Fix potential integer overflow." 2014-12-07 21:37:39 -08:00
Jim Bankoski
be7a285820 Make the decoder Cfg available to encoder tests..
Adds decoder config as a changeable parameter to unit tests, and
changes end to end test to use commonly used parameters to enable
base test of tiles encoding and frame parallel decoding.

Change-Id: I5d23a6857303b4d68b92b15c3f2f04a1bcb4c2bb
2014-12-07 11:28:51 -08:00
James Zern
da464c483f Merge "vp9 asserts: fix compile warning" 2014-12-05 21:09:42 -08:00
James Zern
0e00dbae02 Merge "fix building with --disable-spatial-resampling" 2014-12-05 20:36:44 -08:00
James Zern
0e8cc9a82f fix building with --disable-spatial-resampling
vpx_scale.c is only used by the vp8 encoder when spatial resampling is
enabled.

Change-Id: If3d3ad81e9ee6e0b59f8c040b9624ef52598fe03
2014-12-05 19:08:36 -08:00
James Zern
3db785facc Merge "vp9: fix frame-parallel encoding" 2014-12-05 19:00:48 -08:00
Deb Mukherjee
0d367474d0 Merge "Some internal-stats, vp9-highbitdepth bug fixes" 2014-12-05 17:49:52 -08:00
James Zern
6db81fd629 vp9: fix frame-parallel encoding
the flag in the header wasn't being set based on the encoder
configuration in non-intra only mode

broken since:
fbc2fbf Adding oxcf temp variable.

Change-Id: Ib4cff9901889824bc4e68d7f0f6deb1e41df2f53
2014-12-05 17:44:46 -08:00
Jingning Han
bd6bfb93b0 Merge "Remove redundant rdcost reset" 2014-12-05 17:35:07 -08:00
Jingning Han
296afb9440 Merge "Fix a motion search skip condition in vp9_pick_inter_mode" 2014-12-05 17:35:04 -08:00
Jingning Han
3d8d1e374e Merge "Remove redundant MB_MODE_INFO reset from vp9_pick_mode_inter" 2014-12-05 16:59:50 -08:00
hkuang
382f86f945 Improve the performance by caching the left_mi and right_mi in macroblockd.
This improve the deocde performance by ~2% on Nexus 7 2013.

Change-Id: Ie9c4ba0371a149eb7fddc687a6a291c17298d6c3
2014-12-05 16:25:42 -08:00
James Zern
616b3a810f vp9 asserts: fix compile warning
string literal to int within an assert

Change-Id: I76a173f96b9add5bf27c3f5ad5d72c6f30e51629
2014-12-05 16:20:42 -08:00
Jingning Han
17bedc54f5 Remove redundant rdcost reset
The initial reset of this_rdc in vp9_pick_inter_mode is not needed,
since it will be re-assign when used.

Change-Id: Ic0e12d741cbab292fc214c1eabb48b129af7839b
2014-12-05 16:06:17 -08:00
Jingning Han
eadffb2d6e Fix a motion search skip condition in vp9_pick_inter_mode
Compare the current best mode rate-distortion cost with the skip
threshold to decide if performing motion search.

Change-Id: Ia071824f8dd3b7db485f424692a485a2da6a1a9f
2014-12-05 15:58:36 -08:00
Jingning Han
732d57c2b5 Remove redundant MB_MODE_INFO reset from vp9_pick_mode_inter
Change-Id: I0222f7abc61202f4a83b117bbfb042ada6304562
2014-12-05 15:51:11 -08:00
hkuang
eaa6deee5b Merge "Merge set_prev_mi function into encoder function." 2014-12-05 15:12:50 -08:00
Deb Mukherjee
37448d3e1f Some internal-stats, vp9-highbitdepth bug fixes
Change-Id: I0363d98f6f6558a43276aec48f27dca37c93f5ad
2014-12-05 13:40:50 -08:00
Jingning Han
6ae829088f Merge "Remove redundant vp9_zero in choose_partitioning" 2014-12-05 11:47:58 -08:00
Jingning Han
69a9dc5cd3 Merge "Enable conditional skip path in rd_pick_intra_sby_mode" 2014-12-05 11:25:30 -08:00
Jingning Han
62c7356098 Merge "Use hybrid RD and non-RD coding flow for key frame coding" 2014-12-05 11:25:19 -08:00
Jingning Han
9d88b30854 Remove redundant vp9_zero in choose_partitioning
It makes the overall speed -6 about 2% faster with no compression
performance change.

Change-Id: I680a967b421caa2c5a5cdb821311c4726a2df45a
2014-12-05 10:39:39 -08:00
Jingning Han
74ded4863e Enable conditional skip path in rd_pick_intra_sby_mode
These speed-up features for key frame coding are only turned on
in the settings of hybrid non-RD and RD mode decision. It provides
about 20% speed-up to the hybrid key frame coding at the expense
of certain compression performance loss. For vidyo1, the key frame
coding statistics are changed
9838F, 35.020 dB, 61677 us -> 9920F, 34.834 dB, 47556 us

Overall rtc set compression performance is down by -0.257%.

Change-Id: I0025447fda26bb7855e982955642b5f55d71b51f
2014-12-05 09:36:09 -08:00
Jingning Han
07711e9b27 Use hybrid RD and non-RD coding flow for key frame coding
When block size is below 16x16, the encoder swap from non-RD to
RD mode for key frame coding. This largely brough back the key
frame compression performance. For vidyo1 at 1000 kbps, the key
frame coding statistics are changed

9978F, 34.183 dB, 36807 us -> 9838F, 35.020 dB, 61677 us

As compared to the full RD case
7187F, 34.930 dB, 214470 us

The overall rtc set coding performance (single key frame setting)
is improved by 1.5%.

Change-Id: I78a4ecf025d7b24ec911e85be94e01da05e77878
2014-12-05 09:35:27 -08:00
Yunqing Wang
a3a4a34c60 Merge "vp9_ethread: the tile-based multi-threaded encoder" 2014-12-05 08:23:49 -08:00
Frank Galligan
4c4d7261e4 Fix potential integer overflow.
ioc found a potential integer overflow in the rate control.

This is related to https://code.google.com/p/webm/issues/detail?id=821

Change-Id: Ib6c4acd6e964972f932fce7490592eb134f2b7ea
2014-12-05 08:02:12 -08:00
Paul Wilkins
bb6e47c1c9 Merge "Increase strength of AQ1." 2014-12-05 04:11:43 -08:00
Debargha Mukherjee
15cf55b3ca Merge "Use the RTC optimizations when in high bitdepth mode." 2014-12-04 19:22:27 -08:00
Deb Mukherjee
1fe643cf03 Re-enable 8x8 fdct/fht tests by changing tolerance
Increases tolerance for tests to ensure the fdct tests pass after
random number range change.

Change-Id: I5b622099e850f91a14b903d10cf14685f4dd3c2b
2014-12-04 16:46:06 -08:00
James Zern
b43c27ab6e Merge "vp9_reader: reorder struct members" 2014-12-04 16:08:08 -08:00
Debargha Mukherjee
4bfde1071e Merge "Corrected the renaming of CONFIG_VP9_HIGH ro CONFIG_VP9_HIGHBITDEPTH." 2014-12-04 15:52:35 -08:00
Peter de Rivaz
a306bd8274 Use the RTC optimizations when in high bitdepth mode.
Change 72193 made the encoder behave differently
when configured with and without high bitdepth.
This change means the same algorithm is used for both.

Change-Id: I707a44a94afca773a9e0c2f7ebeeea83030257c5
2014-12-04 15:48:42 -08:00
James Zern
dd26b9a6d0 Merge "Loop filter test fix" 2014-12-04 15:14:20 -08:00
hkuang
dde819599b Clean up the logic of handling corrupted frame.
No more checking of corrupted reference frame as we skip
decoding any non-intra frame in case of frame corrupted.

Change-Id: I77d41bbb02fc5f61972740e2d411441eb6a17073
2014-12-04 15:07:59 -08:00
hkuang
62de07c8c6 Merge set_prev_mi function into encoder function.
Change-Id: Ifcf2efbb232ea4cabcdebbe77e0820d121e4a6da
2014-12-04 14:44:23 -08:00
Yunqing Wang
eba9c762a1 vp9_ethread: the tile-based multi-threaded encoder
Currently, VP9 supports column-tile encoding, which allows a frame
to be encoded in multiple column tiles independently. The number of
column tiles are set by encoder option "--tile-columns". This
provides a way to encode a frame in parallel.

Based on previous set of patches, this patch implemented the tile-
based multi-threaded encoder. Each thread processes one or more
tiles.

Usage:
For HD clips:
--tile-columns=2 --threads=1/2/3/4

While using 4 threads, tests showed that the encoder achieved
2.3X - 2.5X speedup at good-quality speed 3, and 2X speedup at
realtime speed 5.

Change-Id: Ied987f8f2618b1283a8643ad255e88341733c9d4
2014-12-04 11:21:34 -08:00
Deb Mukherjee
4f860dba78 Merge "Fixes a missing highbitdepth convolve call bug" 2014-12-04 11:19:59 -08:00
Adrian Grange
9065da983f Merge "Free motion vector array before re-allocating" 2014-12-04 07:08:37 -08:00
Peter de Rivaz
f610f88be4 Corrected the renaming of CONFIG_VP9_HIGH ro CONFIG_VP9_HIGHBITDEPTH.
Change 71789 renamed CONFIG_VP9_HIGH to CONFIG_VP9_HIGHBITDEPTH.
However, one use of CONFIG_VP9_HIGH was missed.

Change-Id: I0ebb9c71380c6d810a25708d15471abf9533e695
2014-12-04 11:01:46 +00:00
Deb Mukherjee
072ed17d1e Loop filter test fix
Related to fixing random number range.

Change-Id: I84d004600e1f6918badf08d08da421b4e8cc4826
2014-12-04 01:26:06 -08:00
Marco
7cb7588b1e Merge "Various updates to vp8." 2014-12-03 18:12:47 -08:00
James Zern
33e61df7d7 Merge "acm_random: provide full range for Rand16()" 2014-12-03 18:05:36 -08:00
Tom Finegan
7339681ee9 Merge "sse2 visual studio build fix" 2014-12-03 18:05:03 -08:00
Deb Mukherjee
70d9dbd818 Fixes a missing highbitdepth convolve call bug
Bug was introduced in https://gerrit.chromium.org/gerrit/#/c/72122/

Change-Id: Idb500ea619a30e7bc50e22fb8ee03be5282f41db
2014-12-03 17:48:50 -08:00
James Zern
615230b810 acm_random: provide full range for Rand16()
the gtest implementation used only returns values between 0 and 2^31-1

+ temporarily disable some tests in fdct8x8_test which misbehave with the
  new range

Change-Id: I45381076f0bea3317cc6728305890e4fd2f2facd
2014-12-03 16:59:40 -08:00
James Zern
276ab21562 Merge "acm_random: provide full range for Rand8()" 2014-12-03 16:58:42 -08:00
Adrian Grange
b56451f488 Merge "Use memset for initialization to 0" 2014-12-03 16:50:39 -08:00
Deb Mukherjee
6615706af2 sse2 visual studio build fix
Change-Id: Id8c8c3be882bcd92afea3ccec6ebdf3f208d28ef
2014-12-03 16:35:26 -08:00
Adrian Grange
979ee6e4c9 Free motion vector array before re-allocating
Change-Id: I0c39136d67e1e83020d61f86b062a04182ec9b00
2014-12-03 16:07:32 -08:00
Marco
fb20a07c36 Merge "Increase delta-qp for aq=3 mode, after key frame." 2014-12-03 16:03:06 -08:00
Marco
af898b56bb Various updates to vp8.
Change-Id: Icc7a816491897107764e4c936288e9000e6319b8
2014-12-03 16:01:28 -08:00
Jingning Han
3665f194fa Merge "Fix indent in source_var_based_partition_search_method" 2014-12-03 15:43:40 -08:00
Adrian Grange
73caef0500 Use memset for initialization to 0
Change-Id: I714ca22b5d51016bf8b035cf457616c707257641
2014-12-03 15:22:02 -08:00
James Zern
d5937cd268 Merge "vp9: sync threads after a longjmp" 2014-12-03 14:30:55 -08:00
Dim Temp
134384dd80 Extend x32 check by also checking for __x86_64__.
Currently, the configure script checks for x32 by testing just the
__ILP32__ define.  However, on "plain" i386, __ILP32__ can also be
defined, for example by clang 3.5.0 and higher.  (That gcc does not
define it there, is another issue, but not for this tracker.)

Therefore, extend the check by also checking for __x86_64__, which will
also be defined for x32.

BUG=887

Change-Id: I90ac1d6843caff0416e1dd360c0be3dbaa85c2ae
2014-12-03 13:51:58 -08:00
Marco
a047e7cdf8 Increase delta-qp for aq=3 mode, after key frame.
For a few refresh periods after key frame, use large qp-delta
to increase quality ramp-up.

Change-Id: Ib5a150fb2dfa6bafd0d4e6b5d28dfd0724b61319
2014-12-03 13:04:45 -08:00
James Zern
306319387b acm_random: provide full range for Rand8()
the gtest implementation used only returns values between 0 and 2^31-1

+ temporarily disable some tests in lpf_8_test which misbehave with the
  new range

Change-Id: I8a026680c4b8c12dc14d4f24c33edb2315963114
2014-12-03 12:56:05 -08:00
Jingning Han
17176cd452 Fix indent in source_var_based_partition_search_method
Change-Id: I6e5e0571d6967b9b992966336715e35bb97f187e
2014-12-03 12:37:36 -08:00
Jingning Han
8f3db5f22e Merge "Remove unused ONE_LOOP entry from speed feature" 2014-12-03 11:34:42 -08:00
Jingning Han
228ec17ff2 Merge "Rework coeff probability model update for rtc coding" 2014-12-03 11:34:35 -08:00
Marco
8fd3f9a2fb Enable non-rd mode coding on key frame, for speed 6.
For key frame at speed 6: enable the non-rd mode selection in speed setting
and use the (non-rd) variance_based partition.

Adjust some logic/thresholds in variance partition selection for key frame only (no change to delta frames),
mainly to bias to selecting smaller prediction blocks, and also set max tx size of 16x16.

Loss in key frame quality (~0.6-0.7dB) compared to rd coding,
but speeds up key frame encoding by at least 6x.
Average PNSR/SSIM metrics over RTC clips go down by ~1-2% for speed 6.

Change-Id: Ie4845e0127e876337b9c105aa37e93b286193405
2014-12-03 09:18:08 -08:00
Jingning Han
a8d8c0f633 Remove unused ONE_LOOP entry from speed feature
Change-Id: I56ead0ebc2491144c4e79e5859b05e126176702c
2014-12-03 09:17:08 -08:00
Jingning Han
8fe50191c6 Rework coeff probability model update for rtc coding
This commit reworks the ONE_LOOP_REDUCED coefficient probability
model update process. It allows model update for every coefficient
across the spectrum at a coarser resolution, instead of performing
precise update only for certain subset of probability models.

The overall runtime remains nearly same (<1% change) for speed -6.
The compression performance is improved by 7.5% in PSNR for speed
-5 and 4.57% for speed -6, respectively.

Change-Id: Ifb17136382ee7e39a9f34ff4a4f09a753125c8d1
2014-12-03 09:15:25 -08:00
James Zern
6f7ab01451 vp9: sync threads after a longjmp
Synchronize all threads immediately as a subsequent decode call may
cause a resize invalidating some allocations.

fixes one aspect of crbug.com/437655

Change-Id: Ie993b62c2756478543206ddbe43ec6268d90a470
2014-12-02 16:51:27 -08:00
Debargha Mukherjee
99874f55fb Merge "Reinsert macro to fix issue 884." 2014-12-02 15:32:24 -08:00
Deb Mukherjee
1fbe0c7615 Merge "Fix a warning related to VPX_EFLAG_FORCE_KF check" 2014-12-02 14:03:55 -08:00
Peter de Rivaz
2c886953d1 Reinsert macro to fix issue 884.
Change 72056 unfolded some macro definitions,
but lost some alternative behaviour required for
high bitdepth encodes.
This causes the encoder to crash, see issue 884.

Change-Id: I8ce4d73c9fe0a3c10ccb86fba210fabc8b2f0ccc
2014-12-02 13:45:26 -08:00
Debargha Mukherjee
dcb29c1406 Merge "Added high bitdepth sse2 transform functions" 2014-12-02 12:29:21 -08:00
Deb Mukherjee
02941b0df2 Fix a warning related to VPX_EFLAG_FORCE_KF check
Fixes a warning in chrome build.

Change-Id: I8fa0fd3e7ba1aecf89e5f79ce94cd64ed6a9567c
2014-12-02 11:35:52 -08:00
Peter de Rivaz
7e40a55ef9 Added high bitdepth sse2 transform functions
Also removes some spurious changes in common/vp9_blockd.h which
was introduced by a rebase issue between nextgen and master branches.

Change-Id: If359f0e9a71bca9c2ba685a87a355873536bb282
(cherry picked from commit 005d80cd05)
(cherry picked from commit 08d2f54800)
(cherry picked from commit 4230c2306c)
2014-12-02 11:16:24 -08:00
Jingning Han
bf758b6afa Enforce error resilient mode on in temporal svc real-time mode
This commit makes the codec automatically turn on error resilient
mode when using real-time mode for temporal scalable coding. It
fixes an enc/dec mismatch issue and re-enables the corresponding
unit test.

Change-Id: Ie1f7134e9a78ddd43e9b1555b3ee991c8a3afd0d
2014-12-02 10:53:01 -08:00
Marco Paniconi
03e267155b Merge "Cyclic refresh: factor segment delta-q into rate control." 2014-12-02 09:14:48 -08:00
Paul Wilkins
00e3626e13 Use average mb energy from first pass in AQ2 test.
AQ2 modified to use mb_av_energy in defining variance
thresholds used alongside complexity when defining the
segment to be used for an SB64.

Slight improvements in metrics (ssim and PSNR).

Change-Id: Idb9cb73f7d9c4f7118cd7e84ac77b0f25cacbf81
2014-12-02 16:07:30 +00:00
Jingning Han
aabedc8807 Merge "Turn off temporal svc unit test in RTC setting" 2014-12-01 17:35:11 -08:00
Marco Paniconi
83fd18977f Cyclic refresh: factor segment delta-q into rate control.
Incorporate segment delta-q into estimated bits.
This generally improves the rate control under cyclic refresh (aq=3) mode.

Change-Id: I1dc60fb230e7d08357fae18909d8ed27bf58e037
2014-12-01 16:56:43 -08:00
Jingning Han
65d6320cf8 Turn off temporal svc unit test in RTC setting
A hidden enc/dec mismatch bug was accidentally triggered by
https://gerrit.chromium.org/gerrit/#/c/72247/
Adaptively adjust mode test kick-off thresholds in RTC coding

This commit temporarily turns off the broken unit tests to avoid
blocking other CLs while fixing.

Change-Id: I0a0f195030321190ce10879cd833187680576367
2014-12-01 15:14:47 -08:00
Jingning Han
f59cb45e90 Merge "Remove repeated search_type_check_frequency assign" 2014-12-01 14:02:10 -08:00
Yunqing Wang
7af927e324 Merge "vp9_ethread: calculate and save the tok starting address for tiles" 2014-12-01 12:49:03 -08:00
Johann
661802b61d Remove default cortex-a8 tuning.
Probably not even the dominant platform the library is being built for.
Add --cpu= option description to help. The option already exists.

Don't allow passing just --cpu as a no-op.

BUG=826

Change-Id: Iaa3f4f693ec78b18927b159b480daafeba0549c0
2014-12-01 11:08:59 -08:00
Paul Wilkins
0d3d6e0e31 Increase strength of AQ1.
This patch greatly increase the strength of AQ1.

Visual tests show strong gains on many clips but their is a big
hit on psnr.

SSIM is more mixed with some winners and losers.

Change-Id: Idaa5d3b41d8576096bfa000b62bc531c3d8bf6a1
2014-11-27 10:53:37 +00:00
Marco
e0b3e213c6 temporal_svc encoder: Change default setting for layering_mode = 0.
Change-Id: I5f723ada144d0bd82ee700ef28a4916fd64ba5e4
2014-11-26 11:13:23 -08:00
Yaowu Xu
10f62d071c Merge "Separate rate_correction_factor for boosted GFs" 2014-11-26 07:56:43 -08:00
Jingning Han
a6df0cbcca Remove repeated search_type_check_frequency assign
This parameter is initialized as 50. No need to re-assign the
same value in speed -6.

Change-Id: I8735a5593412df2fdcee53ae45c8ebd1c3d792e7
2014-11-25 18:36:41 -08:00
Yunqing Wang
0993bef7e9 vp9_ethread: calculate and save the tok starting address for tiles
Each tile's tok starting address is calculated before the encoding
process. These addresses are stored so that the same calculation
won't be done again in packing bit stream.

Change-Id: I0a3be0301f002260c19a850303f2f73ebc47aa50
2014-11-25 17:19:35 -08:00
James Zern
31bb7a2570 Merge "tests: enable resize_test for vp8" 2014-11-25 15:12:41 -08:00
Yaowu Xu
e4234b3f8b Separate rate_correction_factor for boosted GFs
When the golden frame is boosted, the rate correction factor is not
correlated well with other inter frames even in CBR mode. This commit
changes to use GF specific rate_correction_factor when gf_cbr_boost
is greater than 20%.

Change-Id: I6312c1564387bcacc11f4c5e8a9cfdc781b5c3ab
2014-11-25 14:32:07 -08:00
Johann
ee30dd000c Remove unfreed memory in quantize_test.cc
vp8_config doesn't need to be on the stack. Just use a local copy.

Change-Id: Ia241b1d87fd9422556d957f3ea43ad71eb5c414a
2014-11-25 12:48:51 -08:00
Jingning Han
a04ed98482 Cosmetic change in vp9_pick_inter_mode
Change-Id: Ic072585ebffdb36982ed7b8b9f875ca6c1c656c4
2014-11-25 09:42:57 -08:00
Jingning Han
92a7cfc8bf Adaptively adjust mode test kick-off thresholds in RTC coding
This commit allows the encoder to increase the mode test kick-off
thresholds if the previous best mode renders all zero quantized
coefficients, thereby saving motion search runs when possible.
The compression performance of speed -5 and -6 is down by -0.446%
and 0.591%, respectively. The runtime of speed -6 is improved by
10% for many test clips.

vidyo1, 1000 kbps
16578 b/f, 40.316 dB, 7873 ms -> 16575 b/f, 40.262 dB, 7126 ms

nik720p, 1000 kbps
33311 b/f, 38.651 dB, 7263 ms -> 33304 b/f, 38.629 dB, 6865 ms

dark720p, 1000 kbps
33331 b/f, 39.718 dB, 13596 ms -> 33324 b/f, 39.651 dB, 12000 ms

mmoving, 1000 kbps
33263 b/f, 40.983 dB, 7566 ms -> 33259 b/f, 40.978 dB, 7531 ms

Change-Id: I7591617ff113e91125ec32c9b853e257fbc41d90
2014-11-25 09:42:08 -08:00
Jingning Han
30104207fd Merge "Rework forward txfm/quantization skip system in RTC coding mode" 2014-11-25 09:33:57 -08:00
Jingning Han
6912c44135 Merge "Remove redundant intra mode penalty from vp9_pick_inter_mode" 2014-11-24 22:13:44 -08:00
James Zern
e1f55e0441 vp9_reader: reorder struct members
improves locality of reference

Change-Id: Ia4d55bb8c98e479528d88303fa35e8c74fbf939d
2014-11-24 22:10:39 -08:00
Yunqing Wang
edbd61e136 vp9_ethread: modify VP9_COMP structure
This patch modified struct VP9_COMP. Created a struct ThreadData
to include data that need to be copied for each thread. In
multiple thread case, one thread processes one tile. all threads
share one copy of VP9_COMP,
(refer to VP9_COMP *cpi in the code)
but each thread has its own copy of ThreadData,
(refer to ThreadData *td in the code).
Therefore, within the scope of encode_tiles(), both cpi and td
need to be passed as function parameters.

In single thread case, the FRAME_COUNTS pointer in ThreadData
points to "counts" in VP9_COMMON.

Change-Id: Ib37908b2d8e2c0f4f9c18f38017df5ce60e8b13e
2014-11-24 17:57:38 -08:00
Alex Converse
60ef6c0735 Merge "Fix a tautological assert." 2014-11-24 16:36:53 -08:00
Alex Converse
0496d11486 Fix a tautological assert.
Change-Id: I90ad08823e1d038384536fa9f458caadc2c87f38
2014-11-24 15:01:01 -08:00
Jingning Han
25be81e2dd Remove redundant intra mode penalty from vp9_pick_inter_mode
The intra mode penalty is covered by intra_cost_penalty. This
commit removes the other intra cost threshold, provided that the
constant 50 is negligible in normal rate-distortion cost.

Change-Id: I9b8b7483c43b9a41741622e7057def1f7d51bb72
2014-11-24 14:55:59 -08:00
Jingning Han
e6fb9c0b0b Merge "Key frame non-RD mode decision process" 2014-11-24 13:21:56 -08:00
Debargha Mukherjee
e9d9f1adab Merge "Refactored idct routines and headers" 2014-11-24 12:47:03 -08:00
James Zern
3726d45d5b Merge "sad_test: initialize bit_depth_ in all cases" 2014-11-24 12:26:15 -08:00
John Stark
71379b87df Changes to assembler for NASM on mac.
fixes non-Apple nasm part of issue #755

Change-Id: I11955d270c4ee55e3c00e99f568de01b95e7ea9a
2014-11-24 12:00:50 -08:00
Peter de Rivaz
3a8c43a479 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
(cherry picked from commit 454342d4e7)
2014-11-24 09:57:40 -08:00
Jingning Han
2fbdfd2c66 Key frame non-RD mode decision process
This commit makes a non-RD coding mode decision process for key
frame coding. It can be optionally turned on in speed -6 and above.

Change-Id: I0847258b392877a0210b4768bef88ebc9ad009b5
2014-11-24 09:04:28 -08:00
Marco
681d5e9024 Merge "Only allow for cyclic refresh (aq=3 mode) for base layer." 2014-11-24 07:46:36 -08:00
Johann
dfdfb2d0ff Merge "Indent build/make/configure.sh" 2014-11-22 13:14:56 -08:00
James Zern
65d7fa7169 sad_test: initialize bit_depth_ in all cases
previously 'bit_depth_', which is later used to calculate 'mask_', would
be left uninitialized in non-high-bitdepth builds

Change-Id: Ia72035f4645baf3bb0f191504f491b934cdf1e0e
2014-11-22 12:12:59 -08:00
Paul Wilkins
2232c3e34b Merge "Fix some minor nits." 2014-11-21 17:39:43 -08:00
Johann
7efb302af9 Indent build/make/configure.sh
Whitespace changes only.

Change-Id: I92eef49db1798bc69ec003fca69995fea560d6fa
2014-11-21 17:32:08 -08:00
Debargha Mukherjee
02355a4abf Merge "Added highbitdepth sse2 acceleration for quantize" 2014-11-21 16:08:47 -08:00
Paul Wilkins
d28e9ed452 Merge changes Ie077edd0,Id31a74fc
* changes:
  Remove rate component adjustment for AQ1
  Switch AQ1 segment basis from q ratio to rate ratio.
2014-11-21 15:38:32 -08:00
Paul Wilkins
771259fe10 Merge "Add adaptive midpoint for AQ1." 2014-11-21 15:26:18 -08:00
Paul Wilkins
6dbf83d082 Merge "Add variance restriction to AQ2." 2014-11-21 15:25:43 -08:00
Marco
53c3f2ca4d Only allow for cyclic refresh (aq=3 mode) for base layer.
Condition existed for temporal case, added it for spatial as well.
Issue: https://code.google.com/p/webm/issues/detail?id=878.

Change-Id: I38339207f9a94924f5568a081eabe64f867a686d
2014-11-21 14:47:32 -08:00
Paul Wilkins
ea494c0e76 Fix some minor nits.
Change-Id: Ib8810d431fa20a2c78e0caaa28eb2c99903e60fb
2014-11-21 14:13:59 -08:00
Paul Wilkins
a867bb538b Merge "Further AQ1 clean up." 2014-11-21 12:58:03 -08:00
Jingning Han
7428cebe4f Rework forward txfm/quantization skip system in RTC coding mode
This commit allows more aggressive decision to skip forward
transform and quantization for luma component in RTC coding mode.
The chroma components remains going through the normal coding
routine, since they are not included in the non-RD mode search
process.

It reduces the runtime cost by 2% - 10%. In speed -6,
vidyo1 1000 kbps
16576 b/f, 40.281 dB, 8402 ms -> 16576 b/f, 40.323 dB, 7764 ms

nik720p 1000 kbps
33337 b/f, 38.622 dB, 7473 ms -> 33299 b/f, 38.660 dB, 7314 ms

dark720p 1000 kbps
33330 b/f, 39.785 dB, 13505 ms -> 33325 b/f, 39.714 dB, 13105 ms

The compression performance of speed -6 is improved by 0.44% in
PSNR and 1.31% in SSIM.

Change-Id: Iae9e3738de6255babea734e5897f29118bebc6d7
2014-11-21 12:46:40 -08:00
Paul Wilkins
b87c51ce55 Merge "Initial AQ1 restructuring." 2014-11-21 12:10:03 -08:00
James Zern
508b345b44 Merge "vp9_thread_test: fix 'had_error' assignment" 2014-11-21 11:35:59 -08:00
Alex Converse
590ba7f75d Merge "Allow DC/H/V/TM on screen content." 2014-11-21 09:38:39 -08:00
Alex Converse
3d544bd66a Merge "Drop special inter mode selection for screen content." 2014-11-21 09:38:02 -08:00
Johann
130b151e09 Merge "Remove armv5te target" 2014-11-21 08:55:22 -08:00
Paul Wilkins
f5209d7e01 Remove rate component adjustment for AQ1
In AQ1 a rate adjustment was applied for blocks coded with a
deltaq. This tends to skew the partition selection and cause
rate overshoot.

For example, consider a 64x64 super block where some but not all
sub blocks are in a low q segment and some are in a high q segment.
The choice of Q when considering large partition and transform sizes
is defined by the lowest sub block segment id (currently this implies the
lowest Q). If some parts of the larger partition are very hard this will
cause a high rate component.

The correct behavior here is for the rd code to discard the large partition
choice and break down to sub blocks where some have low and some
have high Q.  However the rate correction factor above mask the high
cost of coding at a larger partition size.

Change-Id: Ie077edd0b1b43c094898f481df772ea280b35960
2014-11-21 08:51:58 -08:00
Paul Wilkins
1663eff7f8 Switch AQ1 segment basis from q ratio to rate ratio.
In defining the Q deltas for segments in AQ1 use a rate
ratio rather than a q ratio.

Change-Id: Id31a74fcf2b7e55437e42a51c21b3cbcb57028d4
2014-11-21 08:50:57 -08:00
Paul Wilkins
fc47c5d653 Add adaptive midpoint for AQ1.
Make the midpoint variance used in AQ mode 1 segmentation
depend on the overall complexity of the frame in two pass.

Change-Id: I452814ec57f7a32352e41bb250e78066abe952dd
2014-11-20 18:37:34 -08:00
Johann
08ad7e4db5 Correctly initialize "ones" value in neon quantize
By using 0xff for a short it was not setting the high bits. When
comparing the output with vtst to find non-zero elements it was skipping
vaules which had no low bits set such as -512 / 0xFE00.

Using -8191 as the first element of coeff will generate this condition.

BUG=883

Change-Id: Ia1e10fb809d1e7866f28c56769fe703e6231a657
2014-11-20 18:34:45 -08:00
Alex Converse
bc1b3d8412 Allow DC/H/V/TM on screen content.
6.3% better compression
less than 1% compression time increase

Change-Id: Ie83c059436e54c09de9e7c87e06e0a6d40dc38fe
2014-11-20 18:04:57 -08:00
Alex Converse
722e9d611b Drop special inter mode selection for screen content.
Better mode selection was implemented for all content.

Change-Id: I479778ed21d3968892f4dce396c83733583f4f23
2014-11-20 18:04:57 -08:00
Johann
eafa0d0ce7 Remove armv5te target
All the assembly code has been removed, the tests no longer check for
the target, and android and chrome do not use the targets.

Change-Id: I193993f7b2b0bd6478453402f573ce3606e04e8d
2014-11-20 17:08:11 -08:00
Yunqing Wang
72522dbc86 Merge "vp9_ethread: move filter_cache out of RD_OPT struct" 2014-11-20 16:51:31 -08:00
Paul Wilkins
d031237999 Add variance restriction to AQ2.
Add an additional restriction to bit/complexity based
segmentation based on spatial variance.

Only lower Q when both the number of bits spent
in the initial encoding pass and the spatial complexity are
below a threshold. This will prevent the low Q segments
being used just because there is a surfeit of bits.

Small metrics gains especially opsnr.
derf ~0.2% std-hd ~0.3%

Change-Id: I6a8496d466d673f9b0e2b2ca6304ea7b6d8e1cce
2014-11-20 16:23:35 -08:00
Paul Wilkins
3d1e8c9a85 Further AQ1 clean up.
Further patch to restructure AQ mode 1.

Change-Id: I566452a033d047a49a40441a7be24690ea69412d
2014-11-20 16:00:51 -08:00
Paul Wilkins
6a760d483d Initial AQ1 restructuring.
This is the first of a series of patches to restructure and
improve AQ mode 1 (variance based AQ).

Change-Id: Idcf693131a3ea2459dcfd957a54a65b971fa4a2a
2014-11-20 15:50:15 -08:00
Paul Wilkins
b74eeb8675 Merge "Fix bug in calculating number of mbs with scaling." 2014-11-20 15:45:41 -08:00
James Zern
a37607bc8c tests: enable resize_test for vp8
this was incorrectly set in test.mk by
93ffd37 Enable and fix resize_test for VP9

the test is now available when using --disable-vp9

Change-Id: I6acf44b0de647b34812ef5e18fd96447cdf9b25d
2014-11-20 14:34:40 -08:00
James Zern
ec8c25ca2a Merge "sad_test: fix vp8-only build" 2014-11-20 14:18:37 -08:00
James Zern
a0d1582d65 vp9_thread_test: fix 'had_error' assignment
worker hooks return false on error, fix the assignment in Execute() used
in the TestSerialInterface test

Change-Id: I93c2e45f270330ae6d35a3a303411c4ee0f31337
2014-11-20 14:16:28 -08:00
Yunqing Wang
54ba65a63e Merge "vp9_ethread: move max/min partition size to mb struct" 2014-11-20 14:00:37 -08:00
Yunqing Wang
379334c2d8 vp9_ethread: move filter_cache out of RD_OPT struct
Similar to mask_filter, the filter_cache in RD_OPT struct can be
moved out, and declared as a local variable since it is only
used in pick_inter_mode functions.

Change-Id: I412b99cca82bade07ac912064ec03dd1de6b2c17
2014-11-20 13:44:16 -08:00
Yunqing Wang
0b71fdbf80 Merge "vp9_ethread: change mask_filter to a local variable" 2014-11-20 13:02:55 -08:00
Yunqing Wang
bdaa3eaf43 Merge "Revert "vp9_ethread: include a pointer to mb in VP9_COMP"" 2014-11-20 12:27:34 -08:00
Paul Wilkins
5e5da2e963 Fix bug in calculating number of mbs with scaling.
Correct calculation of number of mbs in two pass code when
frame resizing is enabled. Always use initial number of mbs if
scaling is enabled, as this is what was used in the first pass.

Change-Id: I49a4280ab5a8b1000efcc157a449a081cbb6d410
2014-11-20 12:24:43 -08:00
Yunqing Wang
b0efddd8e6 vp9_ethread: change mask_filter to a local variable
The mask_filter in RD_OPT struct is used to record rd result in
filter decision. It is only used in pick_inter_mode functions,
and is removed from the struct and declared as a local variable.

Change-Id: I3c95c8632ba7241591ce00ef2ef5677b5e297d7b
2014-11-20 09:41:49 -08:00
Yunqing Wang
ad7586a9e1 vp9_ethread: move max/min partition size to mb struct
The max_partition_size and max_partition_size are set at the
beginning while setting speed features, and then adjusted at
SB level. Moving them to mb struct ensures there is a local
copy for each thread.

Change-Id: I7dd08dc918d9f772fcd718bbd6533e0787720ad4
2014-11-20 09:24:50 -08:00
Jingning Han
5db4b77789 Merge "Enable ssse3 version of vp9_fdct8x8_quant" 2014-11-20 09:06:39 -08:00
Yunqing Wang
70c9d2983b Revert "vp9_ethread: include a pointer to mb in VP9_COMP"
This reverts commit 6906d218dd.

Another way will be used to handle mb struct.

Change-Id: Ic1111a46b2b1ee00f8f9e3fcd4cf3eb6030b2dc4
2014-11-20 08:31:12 -08:00
Peter de Rivaz
a7b2d09f36 Added highbitdepth sse2 acceleration for quantize
Also includes block error.

(This patch is mostly cherry picked from
commit db7192e0b0)

Change-Id: Idef18f90b111a0d0c9546543d3347e551908fd78
2014-11-19 23:55:19 -08:00
Deb Mukherjee
f94c7a8f35 Merge "Changes SvcContext_t to SvcContext" 2014-11-19 23:22:18 -08:00
Jingning Han
c42715b721 Enable ssse3 version of vp9_fdct8x8_quant
It improves the speed performance of vp9_fdct8x8_quant_sse2 by
about 5%.

Change-Id: I74b093ba4d81df64caf71ac7693f3d917f673097
2014-11-19 22:14:19 -08:00
James Zern
16d2696978 sad_test: fix vp8-only build
ROUND_POWER_OF_TWO() is defined in vp9 headers currently, avoid it in
non-high-bitdepth code

Change-Id: Ic28b8f95ef7964800475ee8b35be5f9cea9afab6
2014-11-19 19:18:25 -08:00
Yaowu Xu
21db24efcb Add a reset to rc tracking for dropped frames
VP9/DatarateTestVP9Large.ChangingDropFrameThresh/[34] fails post the
merge of commit#ffa06b37. This commit adds reset of rc tracking info
when frame is dropped, and fixes the causes of the bad interaction
between the tests and the previous commit.

Change-Id: I848acfd9fcb336359662274325190f94aac76eae
2014-11-19 15:32:11 -08:00
Jingning Han
bf63652d34 Merge "Combine fdct8x8 and quantization process" 2014-11-19 11:17:44 -08:00
Jingning Han
ce77a7bcb0 Merge "Add sse2 version for vp9_quantize_fp" 2014-11-19 11:17:36 -08:00
Jingning Han
c6908fd5f7 Combine fdct8x8 and quantization process
This commit reworks the forward transform and quantization process
for 8x8 block coding. It combines the two operations in a single
function to save a store/load stage of the original transform
coefficients. Overall the speed -6 is slightly faster (around 1%
range). The compression performance of speed -6 is improved by
3.4%.

Change-Id: Id6628daef123f3e4649248735ec2ad7423629387
2014-11-18 18:10:56 -08:00
Yaowu Xu
587f0cd39d Merge "Prevent severe rate control errors in CBR mode" 2014-11-18 16:56:06 -08:00
Deb Mukherjee
4c12046a7d Changes SvcContext_t to SvcContext
Fixes a borg build.

Change-Id: I8cb510577e8d8bbc7a2e64f9e1bdfe883f49cb61
2014-11-18 12:27:12 -08:00
Marco
3c715863da Merge "Modify active_worst_quality setting for one pass CBR." 2014-11-18 11:22:18 -08:00
Yaowu Xu
550707b9e1 Merge "change to call vp9_refining_search_sad() directly" 2014-11-18 09:14:02 -08:00
Yaowu Xu
ffa06b3708 Prevent severe rate control errors in CBR mode
In rare cases, the interaction between rate correction factor and Q
choices may cause severe oscillating frame sizes that are way off
target bandwidth. This commit adds tracking of rate control results
for last two frames, and use the information to prevent oscillating
Q choices.

Change-Id: I9a6d125a15652b9bcac0e1fec6d7a1aedc4ed97e
2014-11-18 09:05:57 -08:00
Jingning Han
2d3cc8ea2b Add sse2 version for vp9_quantize_fp
vp9_quantize_fp is the quantization process used by rtc coding
mode. This commit adds a sse2 implementation of it. The
implementation is modified based on vp9_quantize_b_sse2. No speed
difference from ssse3 version.

Change-Id: I24949c5b27df160b4f35117d28858d269454e64a
2014-11-18 09:01:41 -08:00
Jingning Han
13a999de8e Merge "Add empty pointer check to pred buffering in rtc coding mode" 2014-11-17 17:40:54 -08:00
Marco
b660f723b4 Modify active_worst_quality setting for one pass CBR.
Current setting had active_worst_quality set too high (close to worst_quality)
for first frame(s) following first key frame. This changes that to be somewhat
more aggressive in allowing active_worst_quality to be lower following key frame.

Also remove the 4/5 reduction in active_worst for key frame as
this should be set by the user qp_max setting.

Change-Id: I0530b3ddcc85c00e3eb7568de1b14a31206c4a4c
2014-11-17 11:46:49 -08:00
Yaowu Xu
1687c47bfd change to call vp9_refining_search_sad() directly
The function pointer in compressor instance does not change, so this
commit changes to call the function directly.

Change-Id: I9c9c460e3475711c384b74c9842f0b4f3d037cc5
2014-11-17 11:30:17 -08:00
Jingning Han
a62c87fb04 Add empty pointer check to pred buffering in rtc coding mode
This commit adds a check condition to the prediction buffering
operation used in the rtc coding mode. This resolves a unit test
warning in example/vpx_tsvc_encoder_vp9_mode_7.

Change-Id: I9fd50d5956948b73b53bd8fc5a16ee66aff61995
2014-11-17 11:24:07 -08:00
Yunqing Wang
4539c496bc Merge "Code cleanup: remove unused members in RD_OPT" 2014-11-17 09:10:28 -08:00
Yunqing Wang
3f4a93baf2 Merge "vp9_ethread: combine encoder counts in separate struct" 2014-11-17 08:57:38 -08:00
Debargha Mukherjee
c3a9056df4 Merge "Added sse2 acceleration for highbitdepth variance" 2014-11-14 21:11:27 -08:00
James Zern
75c2c84bb5 Merge "Visual studio build fix using explicit cast" 2014-11-14 20:26:28 -08:00
Yunqing Wang
87ae6d73d4 Code cleanup: remove unused members in RD_OPT
These 2 members in RD_OPT were moved to TileDataEnc struct
already, and therefore were removed here.

Change-Id: I22fee3b67f96e473a58e194a7edc76dbd48bfa04
2014-11-14 16:33:25 -08:00
Yunqing Wang
d0b547c676 vp9_ethread: combine encoder counts in separate struct
Several frame counters in encoder are updated at SB level. Combine
those counters and put them in a separate struct, which allows us
to allocate one copy for each thread.

Change-Id: I00366296a13c0ada4d8fa12f5e07728388b6cab7
2014-11-14 16:09:22 -08:00
Peter de Rivaz
48032bfcdb Added sse2 acceleration for highbitdepth variance
Change-Id: I446bdf3a405e4e9d2aa633d6281d66ea0cdfd79f
(cherry picked from commit d7422b2b1e)
(cherry picked from commit 6d741e4d76)
2014-11-14 15:18:53 -08:00
Deb Mukherjee
00c385f17a Visual studio build fix using explicit cast
Change-Id: If74510370723e497f4f33d988b8b398124edf69b
2014-11-14 15:12:01 -08:00
Yunqing Wang
035acac008 Merge "vp9_ethread: include a pointer to mb in VP9_COMP" 2014-11-14 15:11:47 -08:00
Yunqing Wang
6906d218dd vp9_ethread: include a pointer to mb in VP9_COMP
Modified VP9_COMP struct to include MACROBLOCK *mb. This change
makes it feasible in multi-thread case to allocate a mb for each
thread.

Change-Id: I624d6d1aa9c132362200753e5d90b581b1738d6e
2014-11-14 12:31:06 -08:00
Marco
f7168490b6 Merge "Add more rate control stats to vpx_temporal_svc_encoder." 2014-11-14 11:36:05 -08:00
hkuang
a9a20a1040 Fix a bug in frame parallel decode and add a unit test for that.
A flush bug is discovered during putting frame parallel decoder
into Android. This test will expose that bug.

Change-Id: Ia047f27972f4da0471649f79f1f91e7695297473
2014-11-14 10:16:34 -08:00
Marco
b64359110b Add more rate control stats to vpx_temporal_svc_encoder.
Average and variance of actual encoding bitrate over fixed short-time window.

Change-Id: Icc3d6d93792c81e1fb9fd3b56008bf47a503b204
2014-11-14 08:51:31 -08:00
Yunqing Wang
807885b5e0 Merge "vp9_ethread: modify the cyclic refresh struct" 2014-11-13 18:35:01 -08:00
Yaowu Xu
e4e85ad4a8 Merge "adapt the adjustment limit for rate correction factor in RTC mode" 2014-11-13 15:50:30 -08:00
Yunqing Wang
8ee605f188 vp9_ethread: modify the cyclic refresh struct
Two members in struct CYCLIC_REFRESH
  int64_t projected_rate_sb;
  int64_t projected_dist_sb;
are updated at the superblock level, which makes them shared data
in the multi-thread situation, and requires extra work to handle
them. However, those values are updated and used immediately, and
therefore can be removed. This patch cleaned up the code and
removed the two members.

Change-Id: I2c6ee4552bf49fb63ce590cdb47f9723974fffb1
2014-11-13 15:05:46 -08:00
Adrian Grange
35de9db312 Merge "Prepare for dynamic frame resizing in the recode loop" 2014-11-13 15:01:49 -08:00
Paul Wilkins
20517e0627 Merge "Fix 32 bit build emms problem." 2014-11-13 15:00:41 -08:00
Johann
134bc822c8 Merge "Revert "Fix SSSE3 partial_idct_test detection"" 2014-11-13 14:49:22 -08:00
Jingning Han
aeff1f7ec2 Merge "Use reconstructed pixels for intra prediction" 2014-11-13 13:59:02 -08:00
Jingning Han
6efafda738 Merge "Refactor nonrd_use_partition coding process" 2014-11-13 13:58:21 -08:00
Adrian Grange
0d085ebc0a Prepare for dynamic frame resizing in the recode loop
Prepare for the introduction of frame-size change
logic into the recode loop.

Separated the speed dependent features into
separate static and dynamic parts, the latter being
those features that are dependent on the frame size.

Change-Id: Ia693e28c5cf069a1a7bf12e49ecf83e440e1d313
2014-11-13 11:41:20 -08:00
Paul Wilkins
b9c4f9a7db Fix 32 bit build emms problem.
Add extra vp9_clear_system_state() calls to fix
double / mmx issue introduced into first pass
code for 32 bit builds.

Change-Id: I84cd2986b80d83650a091ab25c43755efeb82e03
2014-11-13 11:33:55 -08:00
James Zern
8da5088da1 Revert "Fix SSSE3 partial_idct_test detection"
This reverts commit 7d07f512cd.

this breaks visual studio builds:
'#' : invalid character : possibly the result of a macro expansion

Change-Id: I77170d549afb71e75a878fa0f6acd204fe8d9e67
2014-11-13 11:32:02 -08:00
Yaowu Xu
9f79259e54 adapt the adjustment limit for rate correction factor in RTC mode
Rate correction factor is used to correct the estimated rate for any
given quantizer, and feeds into rate control for quantizer selection.
We make use of the actual bits used to calculate this rate correction
factor with an adjustment limit to prevent over-adjustment.

This commit adapts the adjustment limit to the difference between the
estimated bits and the actual bits, allows the adjustment limit to vary
between 0.125 (when estimate is close to actual) and 0.625 (when there
is >10X factor off between estimated and actual bits). By doing this,
the commit appears to have largely corrected two observed issues:
1. Adjustment is too slow when the actual bits used is way off from
estimate due to the small adjustment limit.
2. Extreme oscillating quantizer choices due to the feedback loop.

Change-Id: I4ee148d2c9d26d173b6c48011313ddb07ce2d7d6
2014-11-13 11:26:52 -08:00
Deb Mukherjee
7621a19aa5 Merge "Vidyo: Turn off keyframes in higher spatial layers" 2014-11-13 03:27:11 -08:00
Debargha Mukherjee
002172efd6 Merge "Added highbitdepth sse2 SAD acceleration and tests" 2014-11-12 21:20:34 -08:00
Marco
c7d26ccaca Remove vp9_temporal_denoising from experimental list.
Change-Id: I7a941c0efbb5912aa97348da6fd1aba28df4482a
2014-11-12 17:39:35 -08:00
Peter de Rivaz
7eee487c00 Added highbitdepth sse2 SAD acceleration and tests
Change-Id: I1a74a1b032b198793ef9cc526327987f7799125f
(cherry picked from commit b1a6f6b9cb)
2014-11-12 14:25:45 -08:00
Johann
64b3739bf1 Merge "Fix SSSE3 partial_idct_test detection" 2014-11-12 12:20:36 -08:00
Yaowu Xu
8e112d9586 Merge "Use normal rate_correction_factor for gf in CBR mode" 2014-11-12 08:00:26 -08:00
Deb Mukherjee
48a7627316 Vidyo: Turn off keyframes in higher spatial layers
Change-Id: Icdd5e71cd6a2b59bc4b3b972af9e4d4a36821792
2014-11-11 16:09:07 -08:00
Deb Mukherjee
c7a905ca3d Merge "Vidyo: Support for one-pass rc-enabled SVC encoder" 2014-11-11 16:03:11 -08:00
Jingning Han
e717d22b63 Use reconstructed pixels for intra prediction
This commit makes the speed -6 and above use the reconstructed
boundary pixels for precise intra prediction. This allows more
intra prediction modes to be tested in the non-RD coding process.

Enabling horizontal and vertical intra prediction modes can
improve the speed -6 compression performance for rtc set
by 0.331%.

Change-Id: I3a99f9d12c6af54de2bdbf28c76eab8e0905f744
2014-11-11 10:04:43 -08:00
Paul Wilkins
4999505472 Merge "AQ1 - remove first pass weights." 2014-11-11 09:17:33 -08:00
Yaowu Xu
f2b978e895 Use normal rate_correction_factor for gf in CBR mode
I0c5f010 changed to allow update golden reference buffer in CBR mode,
this commit changes the use of rate_correction_factor for those frames
to be aligned with the new usage. This commit attempts to solve two
issues:

a. Initialization of rate correction factor for Golden Frame
Prior to this patch, even the regular inter frame has been update
the rate correction factor based on content and encoding results,
the first golden frame would still use the ininitialized value
that can be way off.

b. Allowing rate correction factor update to be slightly faster
Prior to this patch, when the rate correction factor is off, the
update to the factor is too slow, the factor could not get close
to a semi-correct value even after many frames.

The commit helps all clips in psnr/ssim metric, but especially to
a few clip in RTC set that rate correction was way off. For example
thaloundeskmtgvga gained about .5dB for both overall/average psnr.

Change-Id: I0be5c41691be57891d824505348b64be87fa3545
2014-11-10 16:55:13 -08:00
Deb Mukherjee
0ba1542f12 Vidyo: Support for one-pass rc-enabled SVC encoder
Adds support for one-pass rc-enabled SVC encoder with callbacks for
getting per-layer packets.
- the callback function registration is implemented as an encoder
control function.
- if the callback function is not registered, the old way of
aggregating packets with superframe will take effect.
- one more control function “VP9E_GET_SVC_LAYER_ID” has been
implemented to get the temporal/spatial id from the encoder
within the callback. This can be used to get the ids to put on RTP
packet.

Change-Id: I1a90e00135dde65da128b758e6c00b57299a111a
2014-11-10 16:08:58 -08:00
Deb Mukherjee
130c6d7455 Merge "Iadst transforms to use internal low precision" 2014-11-10 15:39:46 -08:00
Johann
18366964b1 Merge "Remove asm offset dependencies" 2014-11-10 10:22:09 -08:00
Alex Converse
d8362a3887 Merge "Fix LAST SKIP when considering GOLDEN" 2014-11-07 16:21:37 -08:00
Deb Mukherjee
cc57c5e4af Iadst transforms to use internal low precision
Change-Id: I266777d40c300bc53b45b205144520b85b0d6e58
(cherry picked from commit a1b726117f)
2014-11-07 14:19:45 -08:00
Deb Mukherjee
27dce0f324 Test name changes to use SSE/SSE2 exactly
Change-Id: I3b5a478d198868c2796366f0ac59d0e2036308b8
2014-11-07 13:44:19 -08:00
Alex Converse
ce9ba97a9d Fix LAST SKIP when considering GOLDEN
Change-Id: I39d9f13fa34984ee9dad0c4f303ef672635f420e
2014-11-07 13:44:17 -08:00
hkuang
165db2343a Merge "Add two test vectors to test frame parallel decode." into frame_parallel 2014-11-07 10:06:35 -08:00
Paul Wilkins
08d86bc904 Merge "Add intra complexity and brightness weight to first pass." 2014-11-07 09:22:12 -08:00
Yaowu Xu
98492c1091 Merge "Change the use of a reserved color space entry" 2014-11-07 06:24:59 -08:00
Paul Wilkins
31b6d7c1eb AQ1 - remove first pass weights.
Removed redundant weighting function tied for AQ1 from first
pass code.

Improvment in baseline AQ1 results:-
Derf  opsnr +0.142% SSIm +0.258%
YT  opsnr +0.173% SSIm +0.3%

Change-Id: I16ef91caf2d7f302cd5940cc5e2626d48ebcb212
2014-11-07 14:11:29 +00:00
Yaowu Xu
af3519a385 Change the use of a reserved color space entry
This commit rename a reserved color space entry to BT_2020, it intends
to provide support for VP9 bitstream to pass along the color space
type defined in BT.2020(Rec.2020)

please note this entry does not have any effect on encoding/decoding
behavior, but allow applications to the pass the information along
from encoding end to decoding end.

Change-Id: I4678520e89141ea5e8900f7bd1c0e95b710b7091
2014-11-06 19:14:21 -08:00
Jingning Han
754b05a4de Refactor nonrd_use_partition coding process
This commit integrates the non-RD mode decision process and the
encoding process into a single recursion scheme.

Change-Id: I6a7e72a0b84d567554801ebbe01ec75d54c1f77d
2014-11-06 17:00:48 -08:00
hkuang
f2fe530e15 Add two test vectors to test frame parallel decode.
The added vectors are mainly used to test the output cache
mechanism in frame parallel decode.

Change-Id: I3d413d060daa5abf72358f6350bd1d16d71adc5a
2014-11-06 16:28:35 -08:00
Johann
6eec73a747 Remove asm offset dependencies
The obj_int_extract code is no longer worth maintaining. It creates
significant issues when adapting for different build systems and no
longer offers as significant of a performance benefit due to
improvements in intrinsics.

Source files will remain until the various third-party builds are updated.

The neon fast quantizer has been moved to intrinsics. The armv6 version
has been removed because so few remaining targets require it.

Compilers and processors have improved significantly since the
pack_tokens code was written. The assembly is no longer faster than the
C code.

pack_tokens were the only optimizations for the armv5te targets so the targets
will be removed after the test infrastructure has been updated.

BUG=710

Change-Id: Ic785b167cd9f95eeff31c7c76b7b736c07fb30eb
2014-11-06 16:00:01 -08:00
hkuang
ad693e1ff5 Add key frame seeking to webmdec and webm_video_source.
This is for the frame parallel's pause/seek/resume unit test.

Change-Id: Ie235f86ca5f3d525896222766f6d610e6682fd76
2014-11-06 13:51:08 -08:00
Yunqing Wang
bf44117d5f Merge "Modify the frame context memory deallocation" 2014-11-06 13:08:57 -08:00
Jingning Han
417e754f56 Merge "Remove unused is_background function" 2014-11-06 12:03:15 -08:00
Jingning Han
e97f404e52 Merge "Rework cut-off decisions in cyclic refresh aq mode" 2014-11-06 12:03:07 -08:00
Yunqing Wang
1228433430 Modify the frame context memory deallocation
This patch was to fix the vpxdec fuzzing3 test failure. When an
error occurs, setjmp() is invoked, which calls the decoder
removing routine. In multiple thread situation, other threads
could try to access the frame context memory that is already
deallocated, thus causing a segfault.

An invalid unit test was added for this issue.

Change-Id: Ida7442154f3d89759483f0f4fe0324041fffb952
2014-11-06 11:34:19 -08:00
Paul Wilkins
5e935126a6 Add intra complexity and brightness weight to first pass.
The aim of this patch is to apply a positive weighting to
frames that have a significant number of blocks that are
of low spatial complexity and are dark. The rationale behind
this is that artifacts tend to be more visible in such frames.

In this patch the weight is only applied in regard to the distribution
of bits between frames. Hence if all the frames share similar
characteristics (as is the case for most of our short test clips) there
will be little or no net effect.

However, the effect can be seen on some longer form test content.

For example Tears of steel baseline test:
2323.09 Kbit/s opsnr 39.915 ssim 74.729
With this patch:-
2213.34 Kbit/s opsnr 39.963 ssim 74.808
(Sligtly better metrics and about 5% smaller)

The weighting may well need some further tuning along side changes
to the aq modes.

Change-Id: Ieced379bca03938166ab87b2b97f55d94948904c
2014-11-06 10:45:00 +00:00
Jingning Han
10da059b52 Remove unused is_background function
Change-Id: Ia540eac5f066ae95280c2f898370eddf0110c279
2014-11-05 21:19:23 -08:00
Jingning Han
caaf63b2c4 Rework cut-off decisions in cyclic refresh aq mode
This commit removes the cyclic aq mode dependency on
in_static_area and reworks the corresponding cut-off thresholds.
It improves the compression performance of speed -5 by 1.47% in
PSNR and 2.07% in SSIM, and the compression performance of speed
-6 by 3.10% in PSNR and 5.25% in SSIM. Speed wise, about 1% faster
in both settings at high bit-rates.

Change-Id: I1ffc775afdc047964448d9dff5751491ba4ff4a9
2014-11-05 21:17:09 -08:00
hkuang
e8860693ea Merge "Totally remove prev_mi in VP9 decoder." 2014-11-05 17:48:47 -08:00
hkuang
4cc7c5a17f Totally remove prev_mi in VP9 decoder.
This will save the memory and improve the decode speed due to
removing unnecessary memset of big prev_mi array for
all the key frames.

Decoding a all key frames 1080p video shows speed improve around 2%.

Change-Id: I6284a445c1291056e3c15135c3c20d502f791c10
2014-11-05 16:14:30 -08:00
Yaowu Xu
7e491de1c4 Merge "Fix visual studio 2013 compiler warnings" 2014-11-05 15:34:13 -08:00
Johann
92440e82fd Merge "vp8 quantize is now in intrinsics, not asm" 2014-11-05 14:05:26 -08:00
Yaowu Xu
2c4fee17bc Fix visual studio 2013 compiler warnings
For configured with --enable-vp9-highbitdepth

Change-Id: I2b181519d7192f8d7a241ad5760c3578255f24e6
2014-11-05 13:47:28 -08:00
Hui Su
2c95a3f374 Merge "Simplify interface of write_selected_tx_size and read_tx_size" 2014-11-05 13:33:09 -08:00
Johann
7d07f512cd Fix SSSE3 partial_idct_test detection
The test filter is not a prefix matcher. It requires test type to
contain no more than the optimization type. In this example, SSSE3_64
fails to match and the test is not skipped even when SSSE3 is not
available.

Change-Id: Ia74229a167c88da4e6da169012a7a77d438c3f75
2014-11-05 12:58:08 -08:00
Johann
d1b64deef4 vp8 quantize is now in intrinsics, not asm
Change-Id: Ie106c5335c9ba5aac81e23150e7026fb6ea6196e
2014-11-05 12:28:07 -08:00
Jingning Han
a7889cac9a Merge "Skip ref frame mode search conditioned on predicted mv residuals" 2014-11-05 12:04:10 -08:00
James Zern
df1b0cafd6 quantize_test: delete QuantizePair related tests
functions were removed in:
2134eb2 Remove pair quantization

fixes ARM build

Change-Id: I634de50c2752408381d70afb0f5088b61052853c
2014-11-05 13:11:34 +01:00
Johann
c4b3625393 Merge "Remove pair quantization" 2014-11-04 16:29:19 -08:00
Johann
412eaaf090 Merge "vp8 quantization -> intrinsics" 2014-11-04 16:28:46 -08:00
Hui Su
709c634b84 Simplify interface of write_selected_tx_size and read_tx_size
Change-Id: Ia2b2a895deefaaf7b34bf26df86add56dbab082c
2014-11-04 16:11:50 -08:00
Minghai Shang
9f9e30d7bf Merge "[spatial svc] Make spatial svc working for one pass rate control" 2014-11-04 15:57:16 -08:00
hkuang
825e270d01 Merge "Fix the memory leak due to missing free frame_mvs." 2014-11-04 14:43:47 -08:00
Johann
0593ce390d Merge "Avoid divide-by-zero in vp8 initialization" 2014-11-04 14:28:45 -08:00
hkuang
23da920a8e Fix the memory leak due to missing free frame_mvs.
Change-Id: I2ceee7341d906259002c0ea31ea009ae32c04bfd
2014-11-04 13:28:31 -08:00
Johann
b4957234af Avoid divide-by-zero in vp8 initialization
Check that the numerator is not zero. If it is, guess 30fps.

Fixes a clang IOC error in the quantize test. It's very unlikely for
this to occur in the wild because the setup in the quantize test is very
nonstandard.

Change-Id: Icdab7b81d4e168d3423e14db20787f960052e0c3
2014-11-04 12:52:10 -08:00
Minghai Shang
86c36a504d [spatial svc] Make spatial svc working for one pass rate control
Change-Id: Ibd9114485c3d747f9d148f64f706bf873ea473ac
2014-11-04 11:46:48 -08:00
Johann
dae280d537 Align structures in quantize test
MACROBLOCKD structures require alignment.

This fixes an issue caught by clang IOC.

Change-Id: Ibb5bcc122f531b4302a87e1144e4feaf46c1de64
2014-11-04 10:49:59 -08:00
Johann
9c6ce43df6 Add some indirection to the quantize test
Visual Studio and XCode require the address of the functions be passed.

Change-Id: Id39cab8e50061fdc6ac6018371a3a158c713e14b
2014-11-04 10:48:32 -08:00
Jingning Han
1e753387c8 Merge "Refactor sub-pixel motion search unit" 2014-11-04 09:11:15 -08:00
Jingning Han
1434f7695b Skip ref frame mode search conditioned on predicted mv residuals
This commit makes the RTC coding mode to conditionally skip the
reference frame mode search, when the predicted motion vector of
the current reference frame gives more than two times sum of
absolute difference compared to that of other reference frames.

It reduces the runtim by 1% - 4% for speed -5 and -6. The average
compression performance is improved by about 0.1% in both settings.

It is of particular benefit to light change scenarios. The
compression performance of test clip mmmovingvga.y4m is improved by
6.39% and 15.69% at high bit rates for speed -5 and -6, respectively.

Speed -5
vidyo1 16555 b/f, 40.818 dB, 12422 ms ->
       16552 b/f, 40.804 dB, 12100 ms

nik    33211 b/f, 39.138 dB, 11341 ms ->
       33228 b/f, 39.139 dB, 11023 ms

mmmoving 33263 b/f, 40.935 dB, 13508 ms ->
         33256 b/f, 41.068 dB, 12861 ms

Speed -6
vidyo1 16541 b/f, 40.227 dB, 8437 ms ->
       16540 b/f, 40.220 dB, 8216 ms

nik    33272 b/f, 38.399 dB, 7610 ms ->
       33267 b/f, 38.414 dB, 7490 ms

mmmoving 33255 b/f, 40.555 dB, 7523 ms ->
         33257 b/f, 40.975 dB, 7493 ms

Change-Id: Id2aef76ef74a3cba5e9a82a83b792144948c6a91
2014-11-04 09:10:19 -08:00
Yunqing Wang
6d90a9d289 Merge "WORKAROUND FIX FOR GCC4.9.1" 2014-11-03 16:56:38 -08:00
Johann
6bab322d49 Merge "vp8 quantize test" 2014-11-03 15:45:21 -08:00
Marco
343acaa8f2 Merge "Allow disable of refresh golden for more than 1 layer encoding." 2014-11-03 14:38:05 -08:00
Johann
53b68de565 vp8 quantize test
Test for Regular, Fast and Pair quantization

Change-Id: I0a26c164afe632db869099402189826c0d43f9a2
2014-11-03 14:15:34 -08:00
Jingning Han
e083f6bd08 Refactor sub-pixel motion search unit
This commit unfolds the legacy macro definitions used in the
sub-pixel motion search and refactors the operational flow for
later optimizations.

Change-Id: I3e3f770cad961d03d1a6eb0b2a0186cc77eaf2b8
2014-11-03 09:02:57 -08:00
Jingning Han
0ca5908ff6 Merge "Fix the THR_MODES array used in vp9_pick_inter_mode" 2014-11-03 08:46:42 -08:00
Yaowu Xu
2fe893c94f Merge "Fix speed 7 and speed 12 for rt" 2014-11-03 08:02:58 -08:00
Marco
d6b688375f Allow disable of refresh golden for more than 1 layer encoding.
The current logic was allowing for disabling golden refresh only
for two pass svc encoding. This change disables it as long as
more than 1 layer encoding is used (for example temporal layers under 1pass CBR).

Change-Id: I4dc5204a7ad365c821ec7963e93b59da82e1826b
2014-11-02 22:24:00 -08:00
Jingning Han
7e119e2946 Fix the THR_MODES array used in vp9_pick_inter_mode
Fix the alignment of entries fo intra prediction modes.

Change-Id: Ie32ad87cf90694efd591a4b1cc29c916c4cd56f7
2014-11-02 12:25:57 -08:00
levytamar82
86175a5788 WORKAROUND FIX FOR GCC4.9.1
In the function mb_lpf_horizontal_edge_w_avx2_16 the usage of the intrinsic
_mm256_cvtepu8_epi16 cause a compiler bug in gcc 4.9.1.
until it will be fixed I created a workaround that create the up convert by
using broadcast128+shuffle.
The bug was reported here:
https://code.google.com/p/webm/issues/detail?id=867

Change-Id: I73452e6806f42e0fadcde96b804ea3afa7eeb351
2014-11-01 11:27:28 -07:00
Yaowu Xu
0271ff7775 Fix speed 7 and speed 12 for rt
A recent change has introduced big quality drops for speed 7 and 12
for --rt mode. The change reverted the big drop and improved quality
by 9.5% for speed 7 and 13.4% for speed 12.

Change-Id: I07b82e3bb6002a73af486a083458c88877bdad01
2014-10-31 17:29:02 -07:00
hkuang
55577431ae Bind motion vectors with frame buffer structure.
This will save a lot of memory for decoder due to removing of prev_mi,
but prev_mi is still needed in encoder. So this will increase a little bit
memory for encoder.

Change-Id: I24b2f1a423ebffa55a9bd2fcee1077dac995b2ed
2014-10-31 17:01:08 -07:00
Johann
2134eb2f05 Remove pair quantization
The intrinsics version of the pair quant is slower than running it
individually.

Change-Id: I7b4ea8599d4aab04be0a5a0c59b8b29a7fc283f4
2014-10-31 13:42:55 -07:00
Johann
7ae75c3d52 vp8 quantization -> intrinsics
Use intrinsics for neon quantization. Slight loss (<5%) of performance
compared to the assembly. Roughly 10x faster on arm64 because that was
running C code before.

Change-Id: I7cf5242d8f29b7eab5bca6a1c20c89c9fc9ca66d
2014-10-31 13:42:13 -07:00
Jingning Han
1c84e73ebd Merge "Fix mode index use case in vp9_pick_inter_mode" 2014-10-31 08:55:40 -07:00
Jingning Han
61966b1d10 Merge "Refactor vp9_update_rd_thresh_fact" 2014-10-31 08:55:28 -07:00
Jingning Han
1cffea9fb7 Merge "Rework pred pixel buffer system in non-RD coding mode" 2014-10-31 08:55:24 -07:00
Jingning Han
64348d9f8d Fix mode index use case in vp9_pick_inter_mode
This improves coding performance of speed -5 and -6 by 0.6%,
respectively.

Change-Id: Ic5a7746a88c73285f0b14333d35dc16b02152c25
2014-10-30 11:10:06 -07:00
Jingning Han
f7b46d8c5e Refactor vp9_update_rd_thresh_fact
Reduce the scope of function parameters.

Change-Id: Ifef2cfb559908a97498ffdbd6ea53da1cd45a73c
2014-10-30 11:09:40 -07:00
Jingning Han
7bea8c59f9 Rework pred pixel buffer system in non-RD coding mode
This commit makes the inter prediction buffer system to support
hybrid partition search. It reduces the runtime of speed -5 by
about 3%. No compression performance change.

vidyo1 720p 1000 kbps
11831 ms -> 11497 ms

nik 720p 1000 kbps
10919 ms -> 10645 ms

Change-Id: I5b2da747c6395c253cd074d3907f5402e1840c36
2014-10-30 11:08:35 -07:00
Hui Su
d478d2df37 Merge "Move the definition of switchable filter numbers into enum INTERP_FILTER; Modify the macro ADD_MV_REF_LIST and IF_DIFF_REF_FRAME_ADD_MV." 2014-10-30 11:05:04 -07:00
Hui Su
66906da066 Merge "Combine vp9_encode_block_intra and encode_block_intra" 2014-10-30 11:02:31 -07:00
Yunqing Wang
7ceddede06 Merge "Remove unused speed feature" 2014-10-29 19:00:32 -07:00
Marco
cccfe5629e Merge "Addd error resilience test for temporal layers." 2014-10-29 18:23:13 -07:00
Yunqing Wang
aed48c786a Remove unused speed feature
Partition_check was unused and removed.

Change-Id: I15ec9162d86dc61f04c09229c498629878ed7155
2014-10-29 17:05:04 -07:00
Marco
8fd5525191 Addd error resilience test for temporal layers.
Test for successful decoding when dropping enhancement layer frames.

Change-Id: Id3ae6e5676894f352680973e52352dc5d98bbf55
2014-10-29 16:47:56 -07:00
Jingning Han
afa31ab9b8 Merge "Enable mode search threshold update in non-RD coding mode" 2014-10-29 12:42:22 -07:00
Jingning Han
9349a28e80 Enable mode search threshold update in non-RD coding mode
Adaptively adjust the mode thresholds after each mode search round
to skip checking less likely selected modes. Local tests indicate
5% - 10% speed-up in speed -5 and -6. Average coding performance
loss is -1.055%.

speed -5
vidyo1 720p 1000 kbps
16533 b/f, 40.851 dB, 12607 ms -> 16556 b/f, 40.796 dB, 11831 ms

nik 720p 1000 kbps
33229 b/f, 39.127 dB, 11468 ms -> 33235 b/f, 39.131 dB, 10919 ms

speed -6
vidyo1 720p 1000 kbps
16549 b/f, 40.268 dB, 10138 ms -> 16538 b/f, 40.212 dB, 8456 ms

nik 720p 1000 kbps
33271 b/f, 38.433 dB,  7886 ms -> 33279 b/f, 38.416 dB, 7843 ms

Change-Id: I2c2963f1ce4ed9c1cf233b5b2c880b682e1c1e8b
2014-10-29 10:55:34 -07:00
Adrian Grange
4074099ed8 Simplify vp9_set_rd_speed_thresholds_sub8x8
Change-Id: I4bf0f9a38697f5aea564a47afd7f02bb8b2888b6
2014-10-29 09:09:46 -07:00
Hui Su
0928da3b6e Combine vp9_encode_block_intra and encode_block_intra
Change-Id: I79091fb677b64892ecca2fb466fde14602d8cdfc
2014-10-28 18:57:01 -07:00
Jingning Han
982dab6050 Merge "Use zero motion vector in choose_partitioning" 2014-10-28 12:00:13 -07:00
JackyChen
50e5c30536 Merge "vp9_denoiser_sse2: refactor the code." 2014-10-28 11:06:05 -07:00
Yaowu Xu
7d7b43b9af Merge "Allow update of golden refernce buffer in CBR mode" 2014-10-28 10:48:02 -07:00
JackyChen
99a8dac4de vp9_denoiser_sse2: refactor the code.
Combined vp9_denoiser_8xM_sse2 and vp9_denoiser_4xM_sse2 into one
function vp9_denoiser_NxM_sse2_small and passed the bitexact testing.
Changed the name of the function vp9_denoiser_64_32_16xM_sse2 to
vp9_denoiser_NxM_sse2_big.

Change-Id: Ib22478df585994dd347ebae04202c0b701e7f451
2014-10-28 09:36:58 -07:00
Yaowu Xu
2a506e33b4 Merge "Add a new control of golden frame boost in CBR mode" 2014-10-28 09:32:58 -07:00
Yaowu Xu
e5cd51880e Allow update of golden refernce buffer in CBR mode
This commit changes to allow the usage of golden reference frame in
VP9 CBR mode to improve quality. VP9 supports potentially up to 8
reference buffers, it has reference buffers available for this
purpose. This was not possible in VP8 as golden and alt-ref buffers
were used for temporal scalability purpose in CBR mode in WebRTC.

For frames that update golden frame, there can be a quality boost.
The amount of allowed bitrate boost can be controlled via parameter
rc_max_inter_bitrate_pct. The inital value of the boost ratior is
currently based on over_shoot_pct. Further experiments will work
out the adaption of this boost value.

Change-Id: I0c5f010c8fd8b7b598f69779c1b30e5b2ac30a4d
2014-10-28 09:31:10 -07:00
Paul Wilkins
422d7bc918 Relax maximum Q for extreme overshoot.
Added code to relax the active maximum Q in response
to extreme local overshoot to reduce bandwidth peaks.

The impact is small in metrics terms, but it this helps reduce
bandwidth spikes and overall overshoot in a number of
clips in our tests sets (especially the YT test set).

In particular this should help prevent very big spikes where a clip
is mainly easy but has a short hard section. In such a case a choice
of maximum Q for the clip as a whole may allow us to hit the overall
target rate but give some extreme spikes. The chunked encoding in YT
mitigates this problem but it can show up where a longer clip is
coded as a single chunk.

Change-Id: I213d09950ccb8489d10adf00fda1e53235b39203
2014-10-28 13:03:06 +00:00
Jingning Han
07436abb86 Use zero motion vector in choose_partitioning
The zero motion vector was effectively used in the subsampled pixel
based variance calculation. This commit makes it directly use zero
mv to generate prediction.

Change-Id: Ica83dc843e9f8da2f89c3ef451e50f16214c0def
2014-10-27 19:38:43 -07:00
Jingning Han
d56b3eb0cf Refactor encoder tile data structure
Make the common tile info as one element in the encoder tile data
struct.

Change-Id: I8c474b4ba67ee3e2c86ab164f353ff71ea9992be
2014-10-27 19:37:13 -07:00
Yaowu Xu
03a60b78db Add a new control of golden frame boost in CBR mode
0 means that golden boost is off, and uses average frame target rate,
a non-zero number means the percentage of boost over average frame
bitrate is given initially to golden frames in CBR mode.

Change-Id: If4334fe2cc424b65ae0cce27f71b5561bf1e577d
2014-10-27 13:55:18 -07:00
Jingning Han
192010d218 Refactor rtc coding mode to support tile encoding
Use per tile threshold in the prediction mode search process.

Change-Id: I6c74ee5a3b069bb4281002dfe51310911a0756c0
2014-10-27 09:53:46 -07:00
Yaowu Xu
aa2af3ff6e Merge "Add a new control of max bitrate for inter frame" 2014-10-27 08:11:54 -07:00
Jingning Han
ac53c41e64 Merge "Tile based adaptive mode search in RD loop" 2014-10-24 18:44:52 -07:00
James Zern
01900edc40 Merge changes I8a9c9019,Ic7b2faa3,I44d42a50,I3f3a3924,I10747b32,I31b49c9e
* changes:
  add vp9_loop_filter_data_reset
  move LFWorkerData allocation to VP9LfSync
  vp9_loop_filter_frame_mt: remove pbi dependency
  vp9_loop_filter_frame_mt: pass planes directly
  vp9_loop_filter_frame_mt: pass VP9LfSync directly
  vp9: store TileWorkerData allocations separately
2014-10-24 11:43:51 -07:00
Yaowu Xu
636099f7b6 Add a new control of max bitrate for inter frame
Change-Id: I205de3611622cff7f751ea8baf9f82784581730a
2014-10-24 10:19:28 -07:00
Jingning Han
eee201c221 Tile based adaptive mode search in RD loop
Make the spatially adaptive mode search in rate-distortion
optimization loop inter tile independent. Experiments suggest that
this does not significantly change the coding staticstics.

Single tile, speed 3:
pedestrian_area 1080p 1500 kbps
59192 b/f, 40.611 dB, 101689 ms

blue_sky 1080p 1500 kbps
58505 b/f, 36.347 dB, 62458 ms

mobile_cal 720p 1000 kbps
13335 b/f, 35.646 dB, 45655 ms

as compared to 4 column tiles, speed 3:
pedestrian_area 1080p 1500 kbps
59329 b/f, 40.597 dB, 101917 ms

blue_sky 1080p 1500 kbps
58712 b/f, 36.320 dB, 62693 ms

mobile_cal 720p 1000 kbps
13191 b/f, 35.485 dB, 45319 ms

Change-Id: I35c6e1e0a859fece8f4145dec28623cbc6a12325
2014-10-24 10:00:27 -07:00
Marco
fe2fd37bb2 vp8: Updates to noise level estimate.
-Use full bandwidth (when temporal layers is on) for checking switching.
-Normalize metric wrt num_blocks.
-Rounding fix to update of average noise level metric.
-Make default internal denoiser mode == kDenoiserOnYUV (in denoiser set_parameters()).
-Adjust some thresholds.

Change-Id: Ib827512b25a7bf1f66c76d3045f3a68ce56b1cd2
2014-10-24 09:36:18 -07:00
Paul Wilkins
60d192db04 Merge "Enable dual arf with constant q." 2014-10-24 05:51:25 -07:00
Paul Wilkins
3758650c98 Merge "Move frame re-sizing into the recode loop" 2014-10-24 05:50:39 -07:00
Adrian Grange
65753eeb8a Move frame re-sizing into the recode loop
The point at which frames are scaled to their
coded dimensions is moved into the re-code loop.

This is in preparation for a further patch that
will add logic into the re-code loop to reduce
the coded frame size if the encoder is struggling
to hit the target data rate at the native frame
size.

Change-Id: Ie4131f5ec6fb93148879f6ce96123296442bf2d1
2014-10-23 16:20:57 -07:00
Tom Finegan
feb4be8552 Merge "build/make/iosbuild.sh: Remove armv6 support." 2014-10-23 14:20:06 -07:00
Yaowu Xu
86777f2e1e Merge "Move filter_ref initialization" 2014-10-23 11:20:22 -07:00
James Zern
01483677e5 add vp9_loop_filter_data_reset
Change-Id: I8a9c9019242ec10fa499a78db322221bf96a0275
2014-10-23 19:43:48 +02:00
Yaowu Xu
065809d286 Move filter_ref initialization
To outside the loop to avoid repeating the operations.

Change-Id: I66c1986e98ce0d7594caad3d3b45de655b299bff
2014-10-23 08:27:25 -07:00
Paul Wilkins
8fc3ab774f Enable dual arf with constant q.
Add second level arf Q adjustment when using dual arfs
in constant Q mode.

Previously in constant Q mode enabling dual arf hurt by ~5%
but with this change the average benefit is ~1-1.5% with some
mid range data points up ~10%.

Note however that it still hurts on some clips including
some very low motion show content.

Change-Id: I5b7789a2f42a6127d9e801cc010c20a7113bdd9b
2014-10-23 13:19:31 +01:00
Paul Wilkins
9363425daa Merge "Initialization bug for multi arf." 2014-10-23 02:02:48 -07:00
Jingning Han
41a17f4457 Merge "Allow checking zeromv mode in vp9_pick_inter_mode" 2014-10-22 18:46:20 -07:00
Yunqing Wang
330a6b2756 Merge "vp9_ethread: allocate frame contexts outside VP9_COMMON struct" 2014-10-22 17:10:39 -07:00
Tom Finegan
12e295d056 build/make/iosbuild.sh: Remove armv6 support.
Apple no longer supports armv6 targets in Xcode or iOS.

Change-Id: Ia7aa496afe62162c43c004530324406486c9a052
2014-10-22 16:26:14 -07:00
Frank Galligan
f271bed671 Merge "Fix Neon convolve profiling" 2014-10-22 15:50:36 -07:00
Yunqing Wang
7c7e4d4eb8 vp9_ethread: allocate frame contexts outside VP9_COMMON struct
This patch allocated frame contexts outside VP9_COMMON. This allows
multiple threads to share the same copy of frame contexts, and
reduces the overhead. It also guarantees the correct update of
these contexts during bitstream packing. This patch doesn't change
encoding result.

Change-Id: Ic181a2460b891d1d587278a6d02d8057b9dbd353
2014-10-22 15:03:12 -07:00
Yaowu Xu
7c48a295ae Merge "Fix a subtle issue in re-use inter_pred" 2014-10-22 14:53:06 -07:00
Jingning Han
08cdd006e1 Allow checking zeromv mode in vp9_pick_inter_mode
This improves the compression performance of speed -5 by 0.6%. The
speed impact is less than 1%.

Change-Id: Ie77daa561976dfc8b479061e1221bdf428eb0c3b
2014-10-22 14:47:15 -07:00
JackyChen
897500b9ba Merge "vp9_denoiser_sse2.c: improve code style." 2014-10-22 13:52:03 -07:00
Yaowu Xu
3f79359e0a Fix a subtle issue in re-use inter_pred
The initialization of this_mode_pred does not work when the ref_frame
loop ever goes beyond LAST_FRAME. This commit fixes the subtle issue
and allows potentially expanding the loop to test GOLDEN_FRAME.

Change-Id: Ibbd427a22160d1d9eacb8ed0c87f88d6cef9c0f3
2014-10-22 12:06:27 -07:00
JackyChen
5cba6516aa vp9_denoiser_sse2.c: improve code style.
denoiser_sse2.c: fix typos in comment.

Change-Id: Ic0fb102331b0e533c058da3cab1fbc30de9a0070
2014-10-22 10:55:54 -07:00
Frank Galligan
95a568b3a8 Fix Neon convolve profiling
When profiling, gprof can't distinguish between matching labels in
different files.

Change-Id: I56770df212ed314a0d8568071fa8157624ef1e8f
2014-10-22 10:51:53 -07:00
Paul Wilkins
7cd6330ef3 Initialization bug for multi arf.
Moved erroneous reset of cpi->multi_arf_last_grp_enabled.

Change-Id: Ibb0b96f6ed1d5eeb575a3b1c798e0fe2ee651d06
2014-10-22 18:51:07 +01:00
Hangyu Kuang
9ce3a7d76c Implement frame parallel decode for VP9.
Using 4 threads, frame parallel decode is ~3x faster than single thread
decode and around 30% faster than tile parallel decode for frame parallel
encoded video on both Android and desktop with 4 threads. Decode speed is
scalable to threads too which means decode could be even faster with more threads.

Change-Id: Ia0a549aaa3e83b5a17b31d8299aa496ea4f21e3e
2014-10-22 10:50:58 -07:00
Marco
d166be653e vp8: Update to computation of noise level.
Avoid unneeded computation of mse in process_denoise.

Change-Id: I3a538178f2d138750d0c38ea4dd05dbbc2b7df41
2014-10-22 10:38:24 -07:00
Hui Su
8947b18fa3 Move the definition of switchable filter numbers into enum
INTERP_FILTER; Modify the macro ADD_MV_REF_LIST and
IF_DIFF_REF_FRAME_ADD_MV.

Change-Id: Ic36c9eb6ccb8ec324d991f7241e42b40b60b1dcb
2014-10-21 15:41:37 -07:00
James Zern
e9b8810b4d move LFWorkerData allocation to VP9LfSync
this removes an assumption that worker->data1 would be pointing to a
TileWorkerData allocation.
additionally, within the multi-threaded loopfilter pass VP9LfSync as a
parameter to the worker hook, removing the need for a shadow pointer in
LFWorkerData.

Change-Id: Ic7b2faa34e3eb59dbcb8a7c67f333448fa047c88
2014-10-16 18:55:46 +02:00
James Zern
175c870efa vp9_loop_filter_frame_mt: remove pbi dependency
Change-Id: I44d42a5098305a2d050ce8ff3c76baf7798c48af
2014-10-16 18:55:44 +02:00
James Zern
69f11d2b9d vp9_loop_filter_frame_mt: pass planes directly
one less dependency on pbi

Change-Id: I3f3a392416d3523f4aea6682c3965885baf85197
2014-10-16 18:54:10 +02:00
James Zern
eb3fdfba09 vp9_loop_filter_frame_mt: pass VP9LfSync directly
a step towards removing the pbi dependency

Change-Id: I10747b325e81c172f5e67031ea5159159fc26e91
2014-10-16 17:27:57 +02:00
James Zern
ff3ae42d8c vp9: store TileWorkerData allocations separately
move them from VP9Worker::data[12] to allow the structure to be reused a
bit more naturally by the multi-threaded loopfilter.

Change-Id: I31b49c9e93ca744fd7f6d6ed8696671188fb2c1d
2014-10-16 17:27:57 +02:00
hkuang
4d0d78424b Increase the thread test range to cover 5, 6, 7, 8 threads.
Change-Id: Id25c294720551bb5153987d8758668befaa57929
2014-09-05 17:11:30 -07:00
hkuang
5106e4dfa8 Fix a bug in adding frame parallel unit test.
There are two CreateDecoder functions and decode_test_driver is not
calling the right function now. This bug is discovered during really
enable the frame parallel flag inside libvpx. This bug does not affect
any existing unit test though.

Change-Id: Icd9633c4b66d50e422a09c4310ff791082878936
2014-08-18 11:16:15 -07:00
hkuang
02410659cd Merge "Add VP9 frame-parallel unit test." into frame_parallel 2014-08-14 14:55:09 -07:00
hkuang
a3ef7d5a50 Add VP9 frame-parallel unit test.
Make sure VP9 frame-parallel decode passes all the standard
test vectors. Only test running with 2,3,4 threads now.

Also refactor the video decode test driver to support passing
in decode flags which is used to enable frame-parallel decode.

Change-Id: I6a712464232c2e13681634951c7e176312522e1e
2014-08-14 13:06:26 -07:00
hkuang
48c5d470e7 Manually pick "Make the api behavior conform to api spec." from
master branch.

Change-Id: I7323ec4cf8b8b7841e37f2bf90548cefa9de9795
2014-08-07 15:15:46 -07:00
hkuang
44395a21da Move vp9_dec_build_inter_predictors_* to decoder folder.
Change-Id: Ibe9fa28440cc79ba9f3504d78c7dca7bb01a23e1
2014-07-28 11:09:11 -07:00
hkuang
7eca086707 Add segmentation map array for current and last frame segmentation.
The original implementation only allocates one segmentation map and this
works fine for serial decode. But for frame parallel decode,  each thread
need to have its own segmentation map and the last frame segmentation map
should be provided from last frame decoding thread.

After finishing decoding a frame, thread need to serve the old segmentation
map that associate with the previous decoded frame. The thread also need to
use another segmentation map for decoding the current frame.

Change-Id: I442ddff36b5de9cb8a7eb59e225744c78f4492d8
2014-07-28 10:44:02 -07:00
hkuang
4c08120ca0 Merge "Include the right header for VP9 worker thread." into frame_parallel 2014-07-14 16:09:16 -07:00
hkuang
294b849796 Include the right header for VP9 worker thread.
pthread.h is not supported in windows. vp9_thread.h includes
the emulation layer for pthread in windows.

Change-Id: I2b1c8ec299928472faca7ebeea998170c9f4d744
2014-07-14 16:03:38 -07:00
hkuang
3cffa0c74e Move vp9_thread.* to common.
Prepare for frame parallel decoding, the reference count buffers
need to be protected by mutex. Move vp9_thread.* to common
folder so that those buffers could use cross-platform mutex
from vp9_thread.*.

(cherry picked from commit 337e8015c9)

Change-Id: I0587a08447925f4554d7788686a31483c2ae3f37
2014-07-11 15:24:31 -07:00
hkuang
10aa23f751 ctrl_get_reference does not need user_priv.
The relationship of the user private data at runtime
is not preserved from decode() to this call which may
occur at an unknown point in the future

Change-Id: Ia7eb25365c805147614574c3af87aedbe0305fc6
2014-07-02 19:28:38 -07:00
hkuang
28a794f680 Seperate the frame buffers from VP9 encoder/decoder structure.
Prepare for frame parallel decoding, the frame buffers must be
separated from the encoder and decoder structure, while the encoder
and decoder will hold the pointer of the BufferPool.

Change-Id: I172c78f876e41fb5aea11be5f632adadf2a6f466
2014-07-02 15:34:20 -07:00
hkuang
bf58d1725c Revert "Revert "Revert "Revert 3 patches from Hangyu to get Chrome to build:"""
This reverts commit 749e0c7b28.

Change-Id: I0c63a152baf94d38496dd925a40040366153bf4f
2014-07-02 14:57:39 -07:00
Jim Bankoski
392a2c43c7 remove vp8 unused uvstride parm in simple loop filter
Change-Id: I35fac6c0db327ef81852f326a93878b57cb2def4
2014-05-27 16:36:17 -07:00
665 changed files with 80594 additions and 113751 deletions

1
.gitignore vendored
View File

@@ -44,7 +44,6 @@
/ivfenc.dox
/libvpx.so*
/libvpx.ver
/obj_int_extract
/samples.dox
/test_libvpx
/vp8_api1_migration.dox

View File

@@ -1,18 +1,26 @@
Adrian Grange <agrange@google.com>
Alex Converse <aconverse@google.com> <alex.converse@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>
Jim Bankoski <jimbankoski@google.com>
John Koleszar <jkoleszar@google.com>
Johann Koenig <johannkoenig@google.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>
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>
Paul Wilkins <paulwilkins@google.com>
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
Ralph Giles <giles@xiph.org> <giles@mozilla.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>
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
Tom Finegan <tomfinegan@google.com>
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>

29
AUTHORS
View File

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

View File

@@ -1,3 +1,31 @@
xxxx-yy-zz v1.4.0 "Changes for next release"
vpxenc is changed to use VP9 by default.
Encoder controls added for 1 pass SVC.
Decoder control to toggle on/off loopfilter.
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"
This release introduces the VP9 codec in a backward-compatible way.
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
counterclaim in a lawsuit) alleging that any of these implementations of WebM
or any code incorporated within any of these implementations of WebM
constitutes direct or contributory patent infringement, or inducement of
constitute direct or contributory patent infringement, or inducement of
patent infringement, then any patent rights granted to you under this License
for these implementations of WebM shall terminate as of the date such
litigation is filed.

20
README
View File

@@ -1,4 +1,4 @@
README - 30 May 2014
README - 23 March 2015
Welcome to the WebM VP8/VP9 Codec SDK!
@@ -47,10 +47,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
--help output of the configure script. As of this writing, the list of
available targets is:
armv5te-android-gcc
armv5te-linux-rvct
armv5te-linux-gcc
armv5te-none-rvct
armv6-darwin-gcc
armv6-linux-rvct
armv6-linux-gcc
@@ -66,12 +62,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
armv7s-darwin-gcc
mips32-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
x86-android-gcc
x86-darwin8-gcc
@@ -82,6 +72,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86-darwin11-gcc
x86-darwin12-gcc
x86-darwin13-gcc
x86-darwin14-gcc
x86-iphonesimulator-gcc
x86-linux-gcc
x86-linux-icc
@@ -99,6 +90,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86_64-darwin11-gcc
x86_64-darwin12-gcc
x86_64-darwin13-gcc
x86_64-darwin14-gcc
x86_64-iphonesimulator-gcc
x86_64-linux-gcc
x86_64-linux-icc
@@ -109,12 +101,6 @@ COMPILING THE APPLICATIONS/LIBRARIES:
x86_64-win64-vs10
x86_64-win64-vs11
x86_64-win64-vs12
universal-darwin8-gcc
universal-darwin9-gcc
universal-darwin10-gcc
universal-darwin11-gcc
universal-darwin12-gcc
universal-darwin13-gcc
generic-gnu
The generic-gnu target, in conjunction with the CROSS environment variable,

4
args.c
View File

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

View File

@@ -1,18 +0,0 @@
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.
# To change to building armeabi, run ./libvpx/configure again, but with
# --target=arm5te-android-gcc and modify the Application.mk file to
# --target=armv6-android-gcc and modify the Application.mk file to
# set APP_ABI := armeabi
#
# Running ndk-build will build libvpx and include it in your project.
@@ -60,7 +60,7 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
include $(CONFIG_DIR)libs-armv7-android-gcc.mk
LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),armeabi)
include $(CONFIG_DIR)libs-armv5te-android-gcc.mk
include $(CONFIG_DIR)libs-armv6-android-gcc.mk
LOCAL_ARM_MODE := arm
else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
include $(CONFIG_DIR)libs-armv8-android-gcc.mk
@@ -91,51 +91,8 @@ LOCAL_CFLAGS := -O3
# like x86inc.asm and x86_abi_support.asm
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
$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm $(ASM_CNV_OFFSETS_DEPEND)
$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm
@mkdir -p $(dir $@)
@$(CONFIG_DIR)$(ASM_CONVERSION) <$< > $@
@@ -201,13 +158,12 @@ LOCAL_CFLAGS += \
LOCAL_MODULE := libvpx
LOCAL_LDLIBS := -llog
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
LOCAL_STATIC_LIBRARIES := cpufeatures
endif
# Add a dependency to force generation of the RTCD files.
define rtcd_dep_template
ifeq ($(CONFIG_VP8), yes)
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp8_rtcd.h
endif
@@ -215,31 +171,26 @@ ifeq ($(CONFIG_VP9), yes)
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp9_rtcd.h
endif
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_scale_rtcd.h
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_dsp_rtcd.h
ifeq ($(TARGET_ARCH_ABI),x86)
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_config.asm
endif
endef
$(eval $(call rtcd_dep_template))
.PHONY: clean
clean:
@echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]"
@$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS)
@$(RM) $(patsubst %.asm, %.*, $(ASM_CNV_OFFSETS_DEPEND))
@$(RM) -r $(ASM_CNV_PATH)
@$(RM) $(CLEAN-OBJS)
include $(BUILD_SHARED_LIBRARY)
ifeq ($(HAVE_NEON), yes)
$(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))
ifeq ($(ENABLE_SHARED),1)
include $(BUILD_SHARED_LIBRARY)
else
include $(BUILD_STATIC_LIBRARY)
endif
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)

View File

@@ -22,8 +22,10 @@ clean:: .DEFAULT
exampletest: .DEFAULT
install:: .DEFAULT
test:: .DEFAULT
test-no-data-check:: .DEFAULT
testdata:: .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
@@ -56,13 +58,10 @@ dist:
fi
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),)
# 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
include $(target)-$(TOOLCHAIN).mk
endif
BUILD_ROOT?=.
VPATH=$(SRC_PATH_BARE)
@@ -116,6 +115,9 @@ test::
testdata::
.PHONY: 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
ifeq ($(TOOLCHAIN), x86-os2-gcc)
@@ -146,6 +148,7 @@ $(BUILD_PFX)%.c.d: %.c
$(BUILD_PFX)%.c.o: %.c
$(if $(quiet),@echo " [CC] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $<
$(BUILD_PFX)%.cc.d: %.cc
@@ -155,6 +158,7 @@ $(BUILD_PFX)%.cc.d: %.cc
$(BUILD_PFX)%.cc.o: %.cc
$(if $(quiet),@echo " [CXX] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
$(BUILD_PFX)%.cpp.d: %.cpp
@@ -164,6 +168,7 @@ $(BUILD_PFX)%.cpp.d: %.cpp
$(BUILD_PFX)%.cpp.o: %.cpp
$(if $(quiet),@echo " [CXX] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
$(BUILD_PFX)%.asm.d: %.asm
@@ -174,6 +179,7 @@ $(BUILD_PFX)%.asm.d: %.asm
$(BUILD_PFX)%.asm.o: %.asm
$(if $(quiet),@echo " [AS] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
$(BUILD_PFX)%.s.d: %.s
@@ -184,12 +190,14 @@ $(BUILD_PFX)%.s.d: %.s
$(BUILD_PFX)%.s.o: %.s
$(if $(quiet),@echo " [AS] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(AS) $(ASFLAGS) -o $@ $<
.PRECIOUS: %.c.S
%.c.S: CFLAGS += -DINLINE_ASM
$(BUILD_PFX)%.c.S: %.c
$(if $(quiet),@echo " [GEN] $@")
$(qexec)$(if $(CONFIG_DEPENDENCY_TRACKING),,mkdir -p $(dir $@))
$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
.PRECIOUS: %.asm.s
@@ -216,14 +224,6 @@ else
$(qexec)cp $< $@
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
#
@@ -315,18 +315,15 @@ $(1):
$$(filter %.o,$$^) $$(extralibs)
endef
define lipo_lib_template
$(1): $(addsuffix /$(1),$(FAT_ARCHS))
$(if $(quiet),@echo " [LIPO] $$@")
$(qexec)libtool -static -o $$@ $$?
endef
define lipo_bin_template
$(1): $(addsuffix /$(1),$(FAT_ARCHS))
$(if $(quiet),@echo " [LIPO] $$@")
$(qexec)lipo -output $$@ -create $$?
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
# for creating them.
$(1):
$(if $(quiet),@echo " [LD] $$@")
$(qexec)$$(LD) -Zdll $$(LDFLAGS) \
-o $$@ \
$$(filter %.o,$$^) $$(extralibs) $$(EXPORTS_FILE)
endef
@@ -340,9 +337,11 @@ endif
skip_deps := $(filter %clean,$(MAKECMDGOALS))
skip_deps += $(findstring testdata,$(MAKECMDGOALS))
ifeq ($(strip $(skip_deps)),)
# Older versions of make don't like -include directives with no arguments
ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),)
-include $(filter %.d,$(OBJS-yes:.o=.d))
ifeq ($(CONFIG_DEPENDENCY_TRACKING),yes)
# Older versions of make don't like -include directives with no arguments
ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),)
-include $(filter %.d,$(OBJS-yes:.o=.d))
endif
endif
endif
@@ -383,8 +382,9 @@ LIBS=$(call enabled,LIBS)
.libs: $(LIBS)
@touch $@
$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib))))
$(foreach lib,$(filter %so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib))))
$(foreach lib,$(filter %$(VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_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).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)
ifeq ($(MAKECMDGOALS),dist)
@@ -424,11 +424,7 @@ ifneq ($(call enabled,DIST-SRCS),)
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/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
# 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_apple.pl
DIST-SRCS-$(ARCH_ARM) += build/make/ads2armasm_ms.pl

File diff suppressed because it is too large Load Diff

View File

@@ -295,22 +295,7 @@ generate_vcproj() {
case "$target" in
x86*)
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)
tag Tool \
Name="VCPreBuildEventTool" \
CommandLine="call obj_int_extract.bat &quot;$src_path_bare&quot; $plat_no_ws\\\$(ConfigurationName)" \
tag Tool \
Name="VCCLCompilerTool" \
Optimization="0" \
@@ -347,11 +332,6 @@ generate_vcproj() {
case "$target" in
x86*)
case "$name" in
obj_int_extract)
tag Tool \
Name="VCLinkerTool" \
GenerateDebugInformation="true" \
;;
*)
tag Tool \
Name="VCLinkerTool" \
@@ -400,24 +380,7 @@ generate_vcproj() {
case "$target" in
x86*)
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)
tag Tool \
Name="VCPreBuildEventTool" \
CommandLine="call obj_int_extract.bat &quot;$src_path_bare&quot; $plat_no_ws\\\$(ConfigurationName)" \
tag Tool \
Name="VCCLCompilerTool" \
Optimization="2" \
@@ -456,11 +419,6 @@ generate_vcproj() {
case "$target" in
x86*)
case "$name" in
obj_int_extract)
tag Tool \
Name="VCLinkerTool" \
GenerateDebugInformation="true" \
;;
*)
tag Tool \
Name="VCLinkerTool" \

View File

@@ -262,15 +262,9 @@ case "$target" in
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} &quot;%(FullPath)&quot;"
;;
arm*)
asm_Debug_cmdline="armasm -nologo &quot;%(FullPath)&quot;"
asm_Release_cmdline="armasm -nologo &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
platforms[0]="ARM"
asm_Debug_cmdline="armasm -nologo -oldit &quot;%(FullPath)&quot;"
asm_Release_cmdline="armasm -nologo -oldit &quot;%(FullPath)&quot;"
;;
*) die "Unsupported target $target!"
;;
@@ -400,23 +394,13 @@ generate_vcxproj() {
if [ "$hostplat" == "ARM" ]; then
hostplat=Win32
fi
open_tag PreBuildEvent
tag_content Command "call obj_int_extract.bat &quot;$src_path_bare&quot; $hostplat\\\$(Configuration)"
close_tag PreBuildEvent
fi
open_tag ClCompile
if [ "$config" = "Debug" ]; then
opt=Disabled
runtime=$debug_runtime
curlibs=$debug_libs
case "$name" in
obj_int_extract)
debug=DEBUG
;;
*)
debug=_DEBUG
;;
esac
debug=_DEBUG
else
opt=MaxSpeed
runtime=$release_runtime
@@ -424,14 +408,7 @@ generate_vcxproj() {
tag_content FavorSizeOrSpeed Speed
debug=NDEBUG
fi
case "$name" in
obj_int_extract)
extradefines=";_CONSOLE"
;;
*)
extradefines=";$defines"
;;
esac
extradefines=";$defines"
tag_content Optimization $opt
tag_content AdditionalIncludeDirectories "$incs;%(AdditionalIncludeDirectories)"
tag_content PreprocessorDefinitions "WIN32;$debug;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE$extradefines;%(PreprocessorDefinitions)"
@@ -451,10 +428,6 @@ generate_vcxproj() {
case "$proj_kind" in
exe)
open_tag Link
if [ "$name" != "obj_int_extract" ]; then
tag_content AdditionalDependencies "$curlibs;%(AdditionalDependencies)"
tag_content AdditionalLibraryDirectories "$libdirs;%(AdditionalLibraryDirectories)"
fi
tag_content GenerateDebugInformation true
# Console is the default normally, but if
# AppContainerApplication is set, we need to override it.

View File

@@ -18,15 +18,19 @@ set -e
devnull='> /dev/null 2>&1'
BUILD_ROOT="_iosbuild"
CONFIGURE_ARGS="--disable-docs
--disable-examples
--disable-libyuv
--disable-unit-tests"
DIST_DIR="_dist"
FRAMEWORK_DIR="VPX.framework"
HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx"
MAKE_JOBS=1
LIBVPX_SOURCE_DIR=$(dirname "$0" | sed -e s,/build/make,,)
SCRIPT_DIR=$(dirname "$0")
LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd)
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
ORIG_PWD="$(pwd)"
TARGETS="arm64-darwin-gcc
armv6-darwin-gcc
armv7-darwin-gcc
armv7s-darwin-gcc
x86-iphonesimulator-gcc
@@ -42,8 +46,8 @@ build_target() {
mkdir "${target}"
cd "${target}"
eval "../../${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
--disable-docs ${EXTRA_CONFIGURE_ARGS} ${devnull}
eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${devnull}
export DIST_DIR
eval make -j ${MAKE_JOBS} dist ${devnull}
cd "${old_pwd}"
@@ -58,9 +62,6 @@ target_to_preproc_symbol() {
arm64-*)
echo "__aarch64__"
;;
armv6-*)
echo "__ARM_ARCH_6__"
;;
armv7-*)
echo "__ARM_ARCH_7A__"
;;
@@ -176,8 +177,13 @@ build_framework() {
# Trap function. Cleans up the subtree used to build all targets contained in
# $TARGETS.
cleanup() {
local readonly res=$?
cd "${ORIG_PWD}"
if [ $res -ne 0 ]; then
elog "build exited with error ($res)"
fi
if [ "${PRESERVE_BUILD_OUTPUT}" != "yes" ]; then
rm -rf "${BUILD_ROOT}"
fi
@@ -187,14 +193,21 @@ iosbuild_usage() {
cat << EOF
Usage: ${0##*/} [arguments]
--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.
--show-build-output: Show output from each library build.
--targets <targets>: Override default target list. Defaults:
${TARGETS}
--verbose: Output information about the environment and each stage of the
build.
EOF
}
elog() {
echo "${0##*/} failed because: $@" 1>&2
}
vlog() {
if [ "${VERBOSE}" = "yes" ]; then
echo "$@"
@@ -224,6 +237,10 @@ while [ -n "$1" ]; do
--show-build-output)
devnull=
;;
--targets)
TARGETS="$2"
shift
;;
--verbose)
VERBOSE=yes
;;
@@ -239,6 +256,7 @@ if [ "${VERBOSE}" = "yes" ]; then
cat << EOF
BUILD_ROOT=${BUILD_ROOT}
DIST_DIR=${DIST_DIR}
CONFIGURE_ARGS=${CONFIGURE_ARGS}
EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
FRAMEWORK_DIR=${FRAMEWORK_DIR}
HEADER_DIR=${HEADER_DIR}
@@ -252,3 +270,5 @@ EOF
fi
build_framework "${TARGETS}"
echo "Successfully built '${FRAMEWORK_DIR}' for:"
echo " ${TARGETS}"

View File

@@ -1,857 +0,0 @@
/*
* 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

@@ -376,17 +376,18 @@ if ($opts{arch} eq 'x86') {
@ALL_ARCHS = filter("$opts{arch}", qw/dspr2/);
last;
}
if (/HAVE_MSA=yes/) {
@ALL_ARCHS = filter("$opts{arch}", qw/msa/);
last;
}
}
close CONFIG_FILE;
mips;
} elsif ($opts{arch} eq 'armv5te') {
@ALL_ARCHS = filter(qw/edsp/);
arm;
} elsif ($opts{arch} eq 'armv6') {
@ALL_ARCHS = filter(qw/edsp media/);
@ALL_ARCHS = filter(qw/media/);
arm;
} elsif ($opts{arch} eq 'armv7') {
@ALL_ARCHS = filter(qw/edsp media neon_asm neon/);
} elsif ($opts{arch} =~ /armv7\w?/) {
@ALL_ARCHS = filter(qw/media neon_asm neon/);
@REQUIRES = filter(keys %required ? keys %required : qw/media/);
&require(@REQUIRES);
arm;

View File

@@ -1,15 +0,0 @@
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"

158
configure vendored
View File

@@ -31,15 +31,13 @@ Advanced options:
--size-limit=WxH max size to allow in the decoder
--as={yasm|nasm|auto} use specified assembler [auto, yasm preferred]
--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_debug_libs} in/exclude debug version of libraries
${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_vp9} VP9 codec support
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
${toggle_mem_tracker} track memory usage
${toggle_postproc} postprocessing
${toggle_vp9_postproc} vp9 specific postprocessing
${toggle_multithread} multithreaded encoding and decoding
@@ -57,6 +55,8 @@ Advanced options:
${toggle_postproc_visualizer} macro block / block level visualizers
${toggle_multi_res_encoding} enable multiple-resolution encoding
${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_libyuv} enable libyuv
@@ -94,10 +94,6 @@ EOF
# all_platforms is a list of all supported target platforms. Maintain
# 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-linux-rvct"
all_platforms="${all_platforms} armv6-linux-gcc"
@@ -113,12 +109,6 @@ all_platforms="${all_platforms} armv7-win32-vs12"
all_platforms="${all_platforms} armv7s-darwin-gcc"
all_platforms="${all_platforms} mips32-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} x86-android-gcc"
all_platforms="${all_platforms} x86-darwin8-gcc"
@@ -129,6 +119,7 @@ all_platforms="${all_platforms} x86-darwin10-gcc"
all_platforms="${all_platforms} x86-darwin11-gcc"
all_platforms="${all_platforms} x86-darwin12-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-linux-gcc"
all_platforms="${all_platforms} x86-linux-icc"
@@ -146,6 +137,7 @@ all_platforms="${all_platforms} x86_64-darwin10-gcc"
all_platforms="${all_platforms} x86_64-darwin11-gcc"
all_platforms="${all_platforms} x86_64-darwin12-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-linux-gcc"
all_platforms="${all_platforms} x86_64-linux-icc"
@@ -156,12 +148,6 @@ all_platforms="${all_platforms} x86_64-win64-vs9"
all_platforms="${all_platforms} x86_64-win64-vs10"
all_platforms="${all_platforms} x86_64-win64-vs11"
all_platforms="${all_platforms} x86_64-win64-vs12"
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_targets is a list of all targets that can be configured
@@ -198,6 +184,10 @@ if [ ${doxy_major:-0} -ge 1 ]; then
[ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable_feature doxygen
fi
# disable codecs when their source directory does not exist
[ -d "${source_path}/vp8" ] || disable_feature vp8
[ -d "${source_path}/vp9" ] || disable_feature vp9
# install everything except the sources, by default. sources will have
# to be enabled when doing dist builds, since that's no longer a common
# case.
@@ -207,45 +197,28 @@ enable_feature install_libs
enable_feature static
enable_feature optimizations
enable_feature fast_unaligned #allow unaligned accesses, if supported by hw
enable_feature dependency_tracking
enable_feature spatial_resampling
enable_feature multithread
enable_feature os_support
enable_feature temporal_denoising
[ -d "${source_path}/../include" ] && enable_feature alt_tree_layout
for d in vp8 vp9; do
[ -d "${source_path}/${d}" ] && disable_feature alt_tree_layout;
done
if ! enabled alt_tree_layout; then
# development environment
[ -d "${source_path}/vp8" ] && CODECS="${CODECS} vp8_encoder vp8_decoder"
[ -d "${source_path}/vp9" ] && CODECS="${CODECS} vp9_encoder vp9_decoder"
else
# customer environment
[ -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)"
CODECS="
vp8_encoder
vp8_decoder
vp9_encoder
vp9_decoder
"
CODEC_FAMILIES="
vp8
vp9
"
ARCH_LIST="
arm
mips
x86
x86_64
ppc32
ppc64
"
ARCH_EXT_LIST="
edsp
@@ -255,7 +228,7 @@ ARCH_EXT_LIST="
mips32
dspr2
msa
mips64
mmx
@@ -266,49 +239,24 @@ ARCH_EXT_LIST="
sse4_1
avx
avx2
altivec
"
HAVE_LIST="
${ARCH_EXT_LIST}
vpx_ports
stdint_h
alt_tree_layout
pthread_h
sys_mman_h
unistd_h
"
EXPERIMENT_LIST="
spatial_svc
vp9_temporal_denoising
fp_mb_stats
full_buffer_test
internal_resize
emulate_hardware
tx64x64
filterintra
ext_tx
tx_skip
supertx
copy_mode
interintra
wedge_partition
global_motion
palette
new_quant
intrabc
loop_postfilter
row_tile
new_inter
bitstream_fixes
newmvref
misc_entropy
wavelets
ext_partition
qctx_tprobs
sr_mode
multi_ref
ext_coding_unit_size
"
CONFIG_LIST="
dependency_tracking
external_build
install_docs
install_bins
@@ -326,10 +274,6 @@ CONFIG_LIST="
codec_srcs
debug_libs
fast_unaligned
mem_manager
mem_tracker
mem_checks
dequant_tokens
dc_recon
@@ -359,6 +303,7 @@ CONFIG_LIST="
encode_perf_tests
multi_res_encoding
temporal_denoising
vp9_temporal_denoising
coefficient_range_checking
vp9_highbitdepth
experimental
@@ -366,6 +311,7 @@ CONFIG_LIST="
${EXPERIMENT_LIST}
"
CMDLINE_SELECT="
dependency_tracking
external_build
extra_warnings
werror
@@ -389,7 +335,6 @@ CMDLINE_SELECT="
libc
as
size_limit
fast_unaligned
codec_srcs
debug_libs
@@ -402,7 +347,6 @@ CMDLINE_SELECT="
${CODECS}
${CODEC_FAMILIES}
static_msvcrt
mem_tracker
spatial_resampling
realtime_only
onthefly_bitpacking
@@ -418,6 +362,7 @@ CMDLINE_SELECT="
encode_perf_tests
multi_res_encoding
temporal_denoising
vp9_temporal_denoising
coefficient_range_checking
vp9_highbitdepth
experimental
@@ -474,24 +419,8 @@ post_process_cmdline() {
process_targets() {
enabled child || write_common_config_banner
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_target_config_h ${BUILD_PFX}vpx_config.h
write_common_config_targets
enabled universal && echo "FAT_ARCHS=${fat_bin_archs}" >> config.mk
# Calculate the default distribution name, based on the enabled features
cf=""
@@ -567,11 +496,11 @@ process_detect() {
# 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
# magic happens after the command line has been parsed.
if ! enabled linux; then
if ! enabled linux && ! enabled os2; then
if enabled gnu; then
echo "--enable-shared is only supported on ELF; assuming this is OK"
else
die "--enable-shared only supported on ELF for now"
die "--enable-shared only supported on ELF and OS/2 for now"
fi
fi
fi
@@ -636,30 +565,6 @@ EOF
process_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
if enabled gcc; then
enabled werror && check_add_cflags -Werror
@@ -747,7 +652,7 @@ process_toolchain() {
esac
# Other toolchain specific defaults
case $toolchain in x86*|ppc*|universal*) soft_enable postproc;; esac
case $toolchain in x86*) soft_enable postproc;; esac
if enabled postproc_visualizer; then
enabled postproc || die "postproc_visualizer requires postproc to be enabled"
@@ -811,6 +716,7 @@ CONFIGURE_ARGS="$@"
process "$@"
print_webm_license ${BUILD_PFX}vpx_config.c "/*" " */"
cat <<EOF >> ${BUILD_PFX}vpx_config.c
#include "vpx/vpx_codec.h"
static const char* const cfg = "$CONFIGURE_ARGS";
const char *vpx_codec_build_config(void) {return cfg;}
EOF

View File

@@ -35,30 +35,20 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
third_party/libyuv/source/scale_posix.cc \
third_party/libyuv/source/scale_win.cc \
LIBWEBM_COMMON_SRCS += third_party/libwebm/common/hdr_util.cc \
third_party/libwebm/common/hdr_util.h \
third_party/libwebm/common/webmids.h
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \
third_party/libwebm/mkvmuxerutil.cpp \
third_party/libwebm/mkvwriter.cpp \
third_party/libwebm/mkvmuxer.hpp \
third_party/libwebm/mkvmuxertypes.hpp \
third_party/libwebm/mkvmuxerutil.hpp \
third_party/libwebm/mkvparser.hpp \
third_party/libwebm/mkvwriter.hpp \
third_party/libwebm/webmids.hpp
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer/mkvmuxer.cc \
third_party/libwebm/mkvmuxer/mkvmuxerutil.cc \
third_party/libwebm/mkvmuxer/mkvwriter.cc \
third_party/libwebm/mkvmuxer/mkvmuxer.h \
third_party/libwebm/mkvmuxer/mkvmuxertypes.h \
third_party/libwebm/mkvmuxer/mkvmuxerutil.h \
third_party/libwebm/mkvparser/mkvparser.h \
third_party/libwebm/mkvmuxer/mkvwriter.h
LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser/mkvparser.cc \
third_party/libwebm/mkvparser/mkvreader.cc \
third_party/libwebm/mkvparser/mkvparser.h \
third_party/libwebm/mkvparser/mkvreader.h
# Add compile flags and include path for libwebm sources.
ifeq ($(CONFIG_WEBM_IO),yes)
CXXFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/libwebm
INC_PATH-yes += $(SRC_PATH_BARE)/third_party/libwebm
endif
LIBWEBM_PARSER_SRCS = third_party/libwebm/mkvparser.cpp \
third_party/libwebm/mkvreader.cpp \
third_party/libwebm/mkvparser.hpp \
third_party/libwebm/mkvreader.hpp
# List of examples to build. UTILS are tools meant for distribution
# while EXAMPLES demonstrate specific portions of the API.
@@ -66,6 +56,7 @@ UTILS-$(CONFIG_DECODERS) += vpxdec.c
vpxdec.SRCS += md5_utils.c md5_utils.h
vpxdec.SRCS += vpx_ports/mem_ops.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/vpx_integer.h
vpxdec.SRCS += args.c args.h
@@ -76,8 +67,6 @@ ifeq ($(CONFIG_LIBYUV),yes)
vpxdec.SRCS += $(LIBYUV_SRCS)
endif
ifeq ($(CONFIG_WEBM_IO),yes)
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
vpxdec.SRCS += $(LIBWEBM_MUXER_SRCS)
vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS)
vpxdec.SRCS += webmdec.cc webmdec.h
endif
@@ -92,24 +81,43 @@ vpxenc.SRCS += tools_common.c tools_common.h
vpxenc.SRCS += warnings.c warnings.h
vpxenc.SRCS += vpx_ports/mem_ops.h
vpxenc.SRCS += vpx_ports/mem_ops_aligned.h
vpxenc.SRCS += vpx_ports/msvc.h
vpxenc.SRCS += vpx_ports/vpx_timer.h
vpxenc.SRCS += vpxstats.c vpxstats.h
ifeq ($(CONFIG_LIBYUV),yes)
vpxenc.SRCS += $(LIBYUV_SRCS)
endif
ifeq ($(CONFIG_WEBM_IO),yes)
vpxenc.SRCS += $(LIBWEBM_COMMON_SRCS)
vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS)
vpxenc.SRCS += $(LIBWEBM_PARSER_SRCS)
vpxenc.SRCS += webmenc.cc webmenc.h
endif
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
vpxenc.DESCRIPTION = Full featured encoder
ifeq ($(CONFIG_SPATIAL_SVC),yes)
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_spatial_svc_encoder.c
vp9_spatial_svc_encoder.SRCS += args.c args.h
vp9_spatial_svc_encoder.SRCS += ivfenc.c ivfenc.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_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.GUID = 4A38598D-627D-4505-9C7B-D4020C84100D
vp9_spatial_svc_encoder.DESCRIPTION = VP9 Spatial SVC Encoder
endif
ifneq ($(CONFIG_SHARED),yes)
EXAMPLES-$(CONFIG_VP9_ENCODER) += resize_util.c
endif
EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c
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 += video_common.h
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.DESCRIPTION = Temporal SVC Encoder
EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
simple_decoder.GUID = D3BBF1E9-2427-450D-BBFF-B2843C1D44CC
simple_decoder.SRCS += ivfdec.h ivfdec.c
@@ -118,6 +126,7 @@ simple_decoder.SRCS += video_common.h
simple_decoder.SRCS += video_reader.h video_reader.c
simple_decoder.SRCS += vpx_ports/mem_ops.h
simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h
simple_decoder.SRCS += vpx_ports/msvc.h
simple_decoder.DESCRIPTION = Simplified decoder loop
EXAMPLES-$(CONFIG_DECODERS) += postproc.c
postproc.SRCS += ivfdec.h ivfdec.c
@@ -126,6 +135,7 @@ postproc.SRCS += video_common.h
postproc.SRCS += video_reader.h video_reader.c
postproc.SRCS += vpx_ports/mem_ops.h
postproc.SRCS += vpx_ports/mem_ops_aligned.h
postproc.SRCS += vpx_ports/msvc.h
postproc.GUID = 65E33355-F35E-4088-884D-3FD4905881D7
postproc.DESCRIPTION = Decoder postprocessor control
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
@@ -136,6 +146,7 @@ decode_to_md5.SRCS += video_common.h
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_aligned.h
decode_to_md5.SRCS += vpx_ports/msvc.h
decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42
decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum
EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
@@ -143,6 +154,7 @@ simple_encoder.SRCS += ivfenc.h ivfenc.c
simple_encoder.SRCS += tools_common.h tools_common.c
simple_encoder.SRCS += video_common.h
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.DESCRIPTION = Simplified encoder loop
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
@@ -150,6 +162,7 @@ vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
vp9_lossless_encoder.SRCS += video_common.h
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.DESCRIPTION = Simplified lossless VP9 encoder
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
@@ -157,6 +170,7 @@ twopass_encoder.SRCS += ivfenc.h ivfenc.c
twopass_encoder.SRCS += tools_common.h tools_common.c
twopass_encoder.SRCS += video_common.h
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.DESCRIPTION = Two-pass encoder loop
EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c
@@ -166,6 +180,7 @@ decode_with_drops.SRCS += video_common.h
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_aligned.h
decode_with_drops.SRCS += vpx_ports/msvc.h
decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
decode_with_drops.DESCRIPTION = Drops frames while decoding
EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c
@@ -173,6 +188,7 @@ set_maps.SRCS += ivfenc.h ivfenc.c
set_maps.SRCS += tools_common.h tools_common.c
set_maps.SRCS += video_common.h
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.DESCRIPTION = Set active and ROI maps
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
@@ -180,15 +196,10 @@ vp8cx_set_ref.SRCS += ivfenc.h ivfenc.c
vp8cx_set_ref.SRCS += tools_common.h tools_common.c
vp8cx_set_ref.SRCS += video_common.h
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.DESCRIPTION = VP8 set encoder reference frame
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9cx_set_ref.c
vp9cx_set_ref.SRCS += ivfenc.h ivfenc.c
vp9cx_set_ref.SRCS += tools_common.h tools_common.c
vp9cx_set_ref.SRCS += video_common.h
vp9cx_set_ref.SRCS += video_writer.h video_writer.c
vp9cx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55
vp9cx_set_ref.DESCRIPTION = VP9 set encoder reference frame
ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
ifeq ($(CONFIG_LIBYUV),yes)
@@ -196,6 +207,7 @@ EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.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 += 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.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de
vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding
@@ -256,14 +268,6 @@ CODEC_EXTRA_LIBS=$(sort $(call enabled,CODEC_EXTRA_LIBS))
$(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
# is handled here. The MSVS case is handled below.
NOT_MSVS = $(if $(CONFIG_MSVS),,yes)
@@ -271,24 +275,28 @@ DIST-BINS-$(NOT_MSVS) += $(addprefix bin/,$(ALL_EXAMPLES:.c=$(EXE_SFX)))
INSTALL-BINS-$(NOT_MSVS) += $(addprefix bin/,$(UTILS:.c=$(EXE_SFX)))
DIST-SRCS-yes += $(ALL_SRCS)
INSTALL-SRCS-yes += $(UTIL_SRCS)
OBJS-$(NOT_MSVS) += $(if $(BUILD_OBJS),$(call objs,$(ALL_SRCS)))
OBJS-$(NOT_MSVS) += $(call objs,$(ALL_SRCS))
BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=$(EXE_SFX)))
# Instantiate linker template for all examples.
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
SHARED_LIB_SUF=$(if $(filter darwin%,$(TGT_OS)),.dylib,.so)
ifneq ($(filter darwin%,$(TGT_OS)),)
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)
$(foreach bin,$(BINS-yes),\
$(if $(BUILD_OBJS),$(eval $(bin):\
$(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF)))\
$(if $(BUILD_OBJS),$(eval $(call linker_template,$(bin),\
$(eval $(bin):$(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF))\
$(eval $(call linker_template,$(bin),\
$(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) \
-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
# tree to locations in the source/build trees.
@@ -340,6 +348,7 @@ $(foreach proj,$(call enabled,PROJECTS),\
#
%.dox: %.c
@echo " [DOXY] $@"
@mkdir -p $(dir $@)
@echo "/*!\page example_$(@F:.dox=) $(@F:.dox=)" > $@
@echo " \includelineno $(<F)" >> $@
@echo "*/" >> $@

View File

@@ -36,9 +36,9 @@
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
#include "./md5_utils.h"
#include "./tools_common.h"
#include "./video_reader.h"
#include "../md5_utils.h"
#include "../tools_common.h"
#include "../video_reader.h"
#include "./vpx_config.h"
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;
void usage_exit() {
void usage_exit(void) {
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
exit(EXIT_FAILURE);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,292 +8,729 @@
* 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.
*/
// 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 "./vpx_config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.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/scale.h"
#include "third_party/libyuv/include/libyuv/cpu_id.h"
#include "vpx/vpx_encoder.h"
#include "vpx/vp8cx.h"
int (*read_frame_p)(FILE *f, vpx_image_t *img);
#include "./tools_common.h"
#include "./video_writer.h"
static int read_frame(FILE *f, vpx_image_t *img) {
size_t nbytes, to_read;
int res = 1;
// The input video frame is downsampled several times to generate a
// multi-level hierarchical structure. kNumEncoders is defined as the number
// of encoding levels required. For example, if the size of input video is
// 1280x720, kNumEncoders 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.
#define kNumEncoders 3
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);
to_read = img->w*img->h*3/2;
nbytes = fread(img->planes[0], 1, to_read, f);
if(nbytes != to_read) {
res = 0;
if(nbytes > 0)
printf("Warning: Read partial frame. Check your width & height!\n");
}
return res;
}
int main(int argc, char *argv[]) {
int frame_cnt = 0;
FILE *infile = NULL;
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;
static int read_frame_by_row(FILE *f, vpx_image_t *img) {
size_t nbytes, to_read;
int res = 1;
int 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.
for (plane = 0; plane < 3; plane++)
{
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;
}
unsigned char *ptr;
int w = (plane ? (1 + img->d_w) / 2 : img->d_w);
int h = (plane ? (1 + img->d_h) / 2 : img->d_h);
int r;
// Make width & height to be multiplier of 2.
if ((cfg[i].g_w) % 2)
cfg[i].g_w++;
if ((cfg[i].g_h) % 2)
cfg[i].g_h++;
}
// 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]++;
}
/* Determine the correct plane based on the image format. The for-loop
* always counts in Y,U,V order, but this may not match the order of
* the data on disk.
*/
switch (plane)
{
case 1:
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12? VPX_PLANE_V : VPX_PLANE_U];
break;
default:
case 2:
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12?VPX_PLANE_U : VPX_PLANE_V];
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");
fclose(infile);
for (r = 0; r < h; r++)
{
to_read = w;
printf("Processed %d frames.\n", frame_cnt - 1);
for (i = 0; i < kNumEncoders; ++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]);
nbytes = fread(ptr, 1, to_read, f);
if(nbytes != to_read) {
res = 0;
if(nbytes > 0)
printf("Warning: Read partial frame. Check your width & height!\n");
break;
}
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]);
ptr += img->stride[plane];
}
if (!res)
break;
}
if (vpx_codec_destroy(&codec[i]))
die_codec(&codec[i], "Failed to destroy codec");
vpx_img_free(&raw[i]);
vpx_video_writer_close(writers[i]);
}
printf("\n");
return EXIT_SUCCESS;
return res;
}
static void write_ivf_file_header(FILE *outfile,
const vpx_codec_enc_cfg_t *cfg,
int frame_cnt) {
char header[32];
if(cfg->g_pass != VPX_RC_ONE_PASS && cfg->g_pass != VPX_RC_LAST_PASS)
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/vpx_encoder.h"
#include "./tools_common.h"
#include "./video_writer.h"
#include "../tools_common.h"
#include "../video_writer.h"
static const char *exec_name;
void usage_exit() {
void usage_exit(void) {
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile> <frame>\n",
exec_name);
exit(EXIT_FAILURE);

View File

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

View File

@@ -0,0 +1,792 @@
/*
* 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.
*/
/*
* This is an example demonstrating how to implement a multi-layer
* VP9 encoding scheme based on spatial scalability for video applications
* that benefit from a scalable bitstream.
*/
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../args.h"
#include "../tools_common.h"
#include "../video_writer.h"
#include "vpx/svc_context.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "../vpxstats.h"
#define OUTPUT_RC_STATS 1
static const arg_def_t skip_frames_arg =
ARG_DEF("s", "skip-frames", 1, "input frames to skip");
static const arg_def_t frames_arg =
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 height_arg = ARG_DEF("h", "height", 1, "source height");
static const arg_def_t timebase_arg =
ARG_DEF("t", "timebase", 1, "timebase (num/den)");
static const arg_def_t bitrate_arg = ARG_DEF(
"b", "target-bitrate", 1, "encoding bitrate, in kilobits per second");
static const arg_def_t spatial_layers_arg =
ARG_DEF("sl", "spatial-layers", 1, "number of spatial SVC layers");
static const arg_def_t temporal_layers_arg =
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 =
ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes");
static const arg_def_t scale_factors_arg =
ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)");
static const arg_def_t passes_arg =
ARG_DEF("p", "passes", 1, "Number of passes (1/2)");
static const arg_def_t pass_arg =
ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)");
static const arg_def_t fpf_name_arg =
ARG_DEF(NULL, "fpf", 1, "First pass statistics file name");
static const arg_def_t min_q_arg =
ARG_DEF(NULL, "min-q", 1, "Minimum quantizer");
static const arg_def_t max_q_arg =
ARG_DEF(NULL, "max-q", 1, "Maximum quantizer");
static const arg_def_t min_bitrate_arg =
ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate");
static const arg_def_t max_bitrate_arg =
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");
#if CONFIG_VP9_HIGHBITDEPTH
static const struct arg_enum_list bitdepth_enum[] = {
{"8", VPX_BITS_8},
{"10", VPX_BITS_10},
{"12", VPX_BITS_12},
{NULL, 0}
};
static const arg_def_t bitdepth_arg =
ARG_DEF_ENUM("d", "bit-depth", 1, "Bit depth for codec 8, 10 or 12. ",
bitdepth_enum);
#endif // CONFIG_VP9_HIGHBITDEPTH
static const arg_def_t *svc_args[] = {
&frames_arg, &width_arg, &height_arg,
&timebase_arg, &bitrate_arg, &skip_frames_arg, &spatial_layers_arg,
&kf_dist_arg, &scale_factors_arg, &passes_arg, &pass_arg,
&fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg,
&max_bitrate_arg, &temporal_layers_arg, &temporal_layering_mode_arg,
&lag_in_frame_arg, &threads_arg,
#if OUTPUT_RC_STATS
&output_rc_stats_arg,
#endif
#if CONFIG_VP9_HIGHBITDEPTH
&bitdepth_arg,
#endif
&speed_arg,
&rc_end_usage_arg, NULL
};
static const uint32_t default_frames_to_skip = 0;
static const uint32_t default_frames_to_code = 60 * 60;
static const uint32_t default_width = 1920;
static const uint32_t default_height = 1080;
static const uint32_t default_timebase_num = 1;
static const uint32_t default_timebase_den = 60;
static const uint32_t default_bitrate = 1000;
static const uint32_t default_spatial_layers = 5;
static const uint32_t default_temporal_layers = 1;
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 {
const char *input_filename;
const char *output_filename;
uint32_t frames_to_code;
uint32_t frames_to_skip;
struct VpxInputContext input_ctx;
stats_io_t rc_stats;
int passes;
int pass;
} AppInput;
static const char *exec_name;
void usage_exit(void) {
fprintf(stderr, "Usage: %s <options> input_filename output_filename\n",
exec_name);
fprintf(stderr, "Options:\n");
arg_show_usage(stderr, svc_args);
exit(EXIT_FAILURE);
}
static void parse_command_line(int argc, const char **argv_,
AppInput *app_input, SvcContext *svc_ctx,
vpx_codec_enc_cfg_t *enc_cfg) {
struct arg arg = {0};
char **argv = NULL;
char **argi = NULL;
char **argj = NULL;
vpx_codec_err_t res;
int passes = 0;
int pass = 0;
const char *fpf_file_name = NULL;
unsigned int min_bitrate = 0;
unsigned int max_bitrate = 0;
char string_options[1024] = {0};
// initialize SvcContext with parameters that will be passed to vpx_svc_init
svc_ctx->log_level = SVC_LOG_DEBUG;
svc_ctx->spatial_layers = default_spatial_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
res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
if (res) {
die("Failed to get config: %s\n", vpx_codec_err_to_string(res));
}
// update enc_cfg with app default values
enc_cfg->g_w = default_width;
enc_cfg->g_h = default_height;
enc_cfg->g_timebase.num = default_timebase_num;
enc_cfg->g_timebase.den = default_timebase_den;
enc_cfg->rc_target_bitrate = default_bitrate;
enc_cfg->kf_min_dist = default_kf_dist;
enc_cfg->kf_max_dist = default_kf_dist;
enc_cfg->rc_end_usage = VPX_CQ;
// initialize AppInput with default values
app_input->frames_to_code = default_frames_to_code;
app_input->frames_to_skip = default_frames_to_skip;
// process command line options
argv = argv_dup(argc - 1, argv_ + 1);
for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
arg.argv_step = 1;
if (arg_match(&arg, &frames_arg, argi)) {
app_input->frames_to_code = arg_parse_uint(&arg);
} else if (arg_match(&arg, &width_arg, argi)) {
enc_cfg->g_w = arg_parse_uint(&arg);
} else if (arg_match(&arg, &height_arg, argi)) {
enc_cfg->g_h = arg_parse_uint(&arg);
} else if (arg_match(&arg, &timebase_arg, argi)) {
enc_cfg->g_timebase = arg_parse_rational(&arg);
} else if (arg_match(&arg, &bitrate_arg, argi)) {
enc_cfg->rc_target_bitrate = arg_parse_uint(&arg);
} else if (arg_match(&arg, &skip_frames_arg, argi)) {
app_input->frames_to_skip = arg_parse_uint(&arg);
} else if (arg_match(&arg, &spatial_layers_arg, argi)) {
svc_ctx->spatial_layers = arg_parse_uint(&arg);
} else if (arg_match(&arg, &temporal_layers_arg, argi)) {
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, &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)) {
enc_cfg->kf_min_dist = arg_parse_uint(&arg);
enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
} else if (arg_match(&arg, &scale_factors_arg, argi)) {
snprintf(string_options, sizeof(string_options), "%s scale-factors=%s",
string_options, arg.val);
} else if (arg_match(&arg, &passes_arg, argi)) {
passes = arg_parse_uint(&arg);
if (passes < 1 || passes > 2) {
die("Error: Invalid number of passes (%d)\n", passes);
}
} else if (arg_match(&arg, &pass_arg, argi)) {
pass = arg_parse_uint(&arg);
if (pass < 1 || pass > 2) {
die("Error: Invalid pass selected (%d)\n", pass);
}
} else if (arg_match(&arg, &fpf_name_arg, argi)) {
fpf_file_name = arg.val;
} else if (arg_match(&arg, &min_q_arg, argi)) {
snprintf(string_options, sizeof(string_options), "%s min-quantizers=%s",
string_options, arg.val);
} else if (arg_match(&arg, &max_q_arg, argi)) {
snprintf(string_options, sizeof(string_options), "%s max-quantizers=%s",
string_options, arg.val);
} else if (arg_match(&arg, &min_bitrate_arg, argi)) {
min_bitrate = arg_parse_uint(&arg);
} else if (arg_match(&arg, &max_bitrate_arg, argi)) {
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
} else if (arg_match(&arg, &bitdepth_arg, argi)) {
enc_cfg->g_bit_depth = arg_parse_enum_or_int(&arg);
switch (enc_cfg->g_bit_depth) {
case VPX_BITS_8:
enc_cfg->g_input_bit_depth = 8;
enc_cfg->g_profile = 0;
break;
case VPX_BITS_10:
enc_cfg->g_input_bit_depth = 10;
enc_cfg->g_profile = 2;
break;
case VPX_BITS_12:
enc_cfg->g_input_bit_depth = 12;
enc_cfg->g_profile = 2;
break;
default:
die("Error: Invalid bit depth selected (%d)\n", enc_cfg->g_bit_depth);
break;
}
#endif // CONFIG_VP9_HIGHBITDEPTH
} else {
++argj;
}
}
// There will be a space in front of the string options
if (strlen(string_options) > 0)
vpx_svc_set_options(svc_ctx, string_options + 1);
if (passes == 0 || passes == 1) {
if (pass) {
fprintf(stderr, "pass is ignored since there's only one pass\n");
}
enc_cfg->g_pass = VPX_RC_ONE_PASS;
} else {
if (pass == 0) {
die("pass must be specified when passes is 2\n");
}
if (fpf_file_name == NULL) {
die("fpf must be specified when passes is 2\n");
}
if (pass == 1) {
enc_cfg->g_pass = VPX_RC_FIRST_PASS;
if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 0)) {
fatal("Failed to open statistics store");
}
} else {
enc_cfg->g_pass = VPX_RC_LAST_PASS;
if (!stats_open_file(&app_input->rc_stats, fpf_file_name, 1)) {
fatal("Failed to open statistics store");
}
enc_cfg->rc_twopass_stats_in = stats_get(&app_input->rc_stats);
}
app_input->passes = passes;
app_input->pass = pass;
}
if (enc_cfg->rc_target_bitrate > 0) {
if (min_bitrate > 0) {
enc_cfg->rc_2pass_vbr_minsection_pct =
min_bitrate * 100 / enc_cfg->rc_target_bitrate;
}
if (max_bitrate > 0) {
enc_cfg->rc_2pass_vbr_maxsection_pct =
max_bitrate * 100 / enc_cfg->rc_target_bitrate;
}
}
// Check for unrecognized options
for (argi = argv; *argi; ++argi)
if (argi[0][0] == '-' && strlen(argi[0]) > 1)
die("Error: Unrecognized option %s\n", *argi);
if (argv[0] == NULL || argv[1] == 0) {
usage_exit();
}
app_input->input_filename = argv[0];
app_input->output_filename = argv[1];
free(argv);
if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 ||
enc_cfg->g_h % 2)
die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h);
printf(
"Codec %s\nframes: %d, skip: %d\n"
"layers: %d\n"
"width %d, height: %d,\n"
"num: %d, den: %d, bitrate: %d,\n"
"gop size: %d\n",
vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
app_input->frames_to_skip,
svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h,
enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
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
int main(int argc, const char **argv) {
AppInput app_input = {0};
VpxVideoWriter *writer = NULL;
VpxVideoInfo info = {0};
vpx_codec_ctx_t codec;
vpx_codec_enc_cfg_t enc_cfg;
SvcContext svc_ctx;
uint32_t i;
uint32_t frame_cnt = 0;
vpx_image_t raw;
vpx_codec_err_t res;
int pts = 0; /* PTS starts at 0 */
int frame_duration = 1; /* 1 timebase tick per frame */
FILE *infile = NULL;
int end_of_stream = 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;
int sl, tl;
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
double framerate = 30.0;
#endif
memset(&svc_ctx, 0, sizeof(svc_ctx));
svc_ctx.log_print = 1;
exec_name = argv[0];
parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg);
// Allocate image buffer
#if CONFIG_VP9_HIGHBITDEPTH
if (!vpx_img_alloc(&raw, enc_cfg.g_input_bit_depth == 8 ?
VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
enc_cfg.g_w, enc_cfg.g_h, 32)) {
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
}
#else
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) {
die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
if (!(infile = fopen(app_input.input_filename, "rb")))
die("Failed to open %s for reading\n", app_input.input_filename);
// Initialize codec
if (vpx_svc_init(&svc_ctx, &codec, vpx_codec_vp9_cx(), &enc_cfg) !=
VPX_CODEC_OK)
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.time_base.numerator = enc_cfg.g_timebase.num;
info.time_base.denominator = enc_cfg.g_timebase.den;
if (!(app_input.passes == 2 && app_input.pass == 1)) {
// We don't save the bitstream for the 1st pass on two pass rate control
writer = vpx_video_writer_open(app_input.output_filename, kContainerIVF,
&info);
if (!writer)
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
for (i = 0; i < app_input.frames_to_skip; ++i)
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));
// Encode frames
while (!end_of_stream) {
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *cx_pkt;
if (frame_cnt >= app_input.frames_to_code || !vpx_img_read(&raw, infile)) {
// We need one extra vpx_svc_encode call at end of stream to flush
// encoder and get remaining data
end_of_stream = 1;
}
res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw),
pts, frame_duration, svc_ctx.speed >= 5 ?
VPX_DL_REALTIME : VPX_DL_GOOD_QUALITY);
printf("%s", vpx_svc_get_message(&svc_ctx));
if (res != VPX_CODEC_OK) {
die_codec(&codec, "Failed to encode frame");
}
while ((cx_pkt = vpx_codec_get_cx_data(&codec, &iter)) != NULL) {
switch (cx_pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT: {
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,
cx_pkt->data.frame.buf,
cx_pkt->data.frame.sz,
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,
!!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY),
(int)cx_pkt->data.frame.sz, (int)cx_pkt->data.frame.pts);
++frames_received;
break;
}
case VPX_CODEC_STATS_PKT: {
stats_write(&app_input.rc_stats,
cx_pkt->data.twopass_stats.buf,
cx_pkt->data.twopass_stats.sz);
break;
}
default: {
break;
}
}
}
if (!end_of_stream) {
++frame_cnt;
pts += frame_duration;
}
}
printf("Processed %d frames\n", frame_cnt);
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 (app_input.passes == 2)
stats_close(&app_input.rc_stats, 1);
if (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
vpx_img_free(&raw);
// display average size, psnr
printf("%s", vpx_svc_dump_statistics(&svc_ctx));
vpx_svc_release(&svc_ctx);
return EXIT_SUCCESS;
}

View File

@@ -1,443 +0,0 @@
/*
* Copyright (c) 2016 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.
*/
// VP9 Set Reference Frame
// =======================
//
// This is an example demonstrating how to overwrite the VP9 encoder's
// internal reference frame. In the sample we set the last frame to the
// current frame. This technique could be used to bounce between two cameras.
//
// The decoder would also have to set the reference frame to the same value
// on the same frame, or the video will become corrupt. The 'test_decode'
// variable is set to 1 in this example that tests if the encoder and decoder
// results are matching.
//
// Usage
// -----
// This example encodes a raw video. And the last argument passed in specifies
// the frame number to update the reference frame on.
// The parameter is parsed as follows:
//
//
// Extra Variables
// ---------------
// This example maintains the frame number passed on the command line
// in the `update_frame_num` variable.
//
//
// Configuration
// -------------
//
// The reference frame is updated on the frame specified on the command
// line.
//
// Observing The Effects
// ---------------------
// The encoder and decoder results should be matching when the same reference
// frame setting operation is done in both encoder and decoder. Otherwise,
// the encoder/decoder mismatch would be seen.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vpx/vp8cx.h"
#include "vpx/vpx_decoder.h"
#include "vpx/vpx_encoder.h"
#include "./tools_common.h"
#include "./video_writer.h"
static const char *exec_name;
void usage_exit() {
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile> "
"<frame>\n",
exec_name);
exit(EXIT_FAILURE);
}
static int compare_img(const vpx_image_t *const img1,
const vpx_image_t *const img2) {
uint32_t l_w = img1->d_w;
uint32_t c_w =
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
uint32_t i;
int match = 1;
match &= (img1->fmt == img2->fmt);
match &= (img1->d_w == img2->d_w);
match &= (img1->d_h == img2->d_h);
for (i = 0; i < img1->d_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
l_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
c_w) == 0);
for (i = 0; i < c_h; ++i)
match &= (memcmp(img1->planes[VPX_PLANE_V] + i * img1->stride[VPX_PLANE_V],
img2->planes[VPX_PLANE_V] + i * img2->stride[VPX_PLANE_V],
c_w) == 0);
return match;
}
#define mmin(a, b) ((a) < (b) ? (a) : (b))
static void find_mismatch(const vpx_image_t *const img1,
const vpx_image_t *const img2,
int yloc[4], int uloc[4], int vloc[4]) {
const uint32_t bsize = 64;
const uint32_t bsizey = bsize >> img1->y_chroma_shift;
const uint32_t bsizex = bsize >> img1->x_chroma_shift;
const uint32_t c_w =
(img1->d_w + img1->x_chroma_shift) >> img1->x_chroma_shift;
const uint32_t c_h =
(img1->d_h + img1->y_chroma_shift) >> img1->y_chroma_shift;
int match = 1;
uint32_t i, j;
yloc[0] = yloc[1] = yloc[2] = yloc[3] = -1;
for (i = 0, match = 1; match && i < img1->d_h; i += bsize) {
for (j = 0; match && j < img1->d_w; j += bsize) {
int k, l;
const int si = mmin(i + bsize, img1->d_h) - i;
const int sj = mmin(j + bsize, img1->d_w) - j;
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_Y] +
(i + k) * img1->stride[VPX_PLANE_Y] + j + l) !=
*(img2->planes[VPX_PLANE_Y] +
(i + k) * img2->stride[VPX_PLANE_Y] + j + l)) {
yloc[0] = i + k;
yloc[1] = j + l;
yloc[2] = *(img1->planes[VPX_PLANE_Y] +
(i + k) * img1->stride[VPX_PLANE_Y] + j + l);
yloc[3] = *(img2->planes[VPX_PLANE_Y] +
(i + k) * img2->stride[VPX_PLANE_Y] + j + l);
match = 0;
break;
}
}
}
}
}
uloc[0] = uloc[1] = uloc[2] = uloc[3] = -1;
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
for (j = 0; match && j < c_w; j += bsizex) {
int k, l;
const int si = mmin(i + bsizey, c_h - i);
const int sj = mmin(j + bsizex, c_w - j);
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_U] +
(i + k) * img1->stride[VPX_PLANE_U] + j + l) !=
*(img2->planes[VPX_PLANE_U] +
(i + k) * img2->stride[VPX_PLANE_U] + j + l)) {
uloc[0] = i + k;
uloc[1] = j + l;
uloc[2] = *(img1->planes[VPX_PLANE_U] +
(i + k) * img1->stride[VPX_PLANE_U] + j + l);
uloc[3] = *(img2->planes[VPX_PLANE_U] +
(i + k) * img2->stride[VPX_PLANE_U] + j + l);
match = 0;
break;
}
}
}
}
}
vloc[0] = vloc[1] = vloc[2] = vloc[3] = -1;
for (i = 0, match = 1; match && i < c_h; i += bsizey) {
for (j = 0; match && j < c_w; j += bsizex) {
int k, l;
const int si = mmin(i + bsizey, c_h - i);
const int sj = mmin(j + bsizex, c_w - j);
for (k = 0; match && k < si; ++k) {
for (l = 0; match && l < sj; ++l) {
if (*(img1->planes[VPX_PLANE_V] +
(i + k) * img1->stride[VPX_PLANE_V] + j + l) !=
*(img2->planes[VPX_PLANE_V] +
(i + k) * img2->stride[VPX_PLANE_V] + j + l)) {
vloc[0] = i + k;
vloc[1] = j + l;
vloc[2] = *(img1->planes[VPX_PLANE_V] +
(i + k) * img1->stride[VPX_PLANE_V] + j + l);
vloc[3] = *(img2->planes[VPX_PLANE_V] +
(i + k) * img2->stride[VPX_PLANE_V] + j + l);
match = 0;
break;
}
}
}
}
}
}
static void testing_decode(vpx_codec_ctx_t *encoder,
vpx_codec_ctx_t *decoder,
vpx_codec_enc_cfg_t *cfg,
unsigned int frame_out,
int *mismatch_seen) {
vpx_image_t enc_img, dec_img;
struct vp9_ref_frame ref_enc, ref_dec;
if (*mismatch_seen)
return;
ref_enc.idx = 0;
ref_dec.idx = 0;
if (vpx_codec_control(encoder, VP9_GET_REFERENCE, &ref_enc))
die_codec(encoder, "Failed to get encoder reference frame");
enc_img = ref_enc.img;
if (vpx_codec_control(decoder, VP9_GET_REFERENCE, &ref_dec))
die_codec(decoder, "Failed to get decoder reference frame");
dec_img = ref_dec.img;
if (!compare_img(&enc_img, &dec_img)) {
int y[4], u[4], v[4];
*mismatch_seen = 1;
find_mismatch(&enc_img, &dec_img, y, u, v);
printf("Encode/decode mismatch on frame %d at"
" Y[%d, %d] {%d/%d},"
" U[%d, %d] {%d/%d},"
" V[%d, %d] {%d/%d}",
frame_out,
y[0], y[1], y[2], y[3],
u[0], u[1], u[2], u[3],
v[0], v[1], v[2], v[3]);
}
vpx_img_free(&enc_img);
vpx_img_free(&dec_img);
}
static int encode_frame(vpx_codec_ctx_t *ecodec,
vpx_codec_enc_cfg_t *cfg,
vpx_image_t *img,
unsigned int frame_in,
VpxVideoWriter *writer,
int test_decode,
vpx_codec_ctx_t *dcodec,
unsigned int *frame_out,
int *mismatch_seen) {
int got_pkts = 0;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt = NULL;
int got_data;
const vpx_codec_err_t res = vpx_codec_encode(ecodec, img, frame_in, 1,
0, VPX_DL_GOOD_QUALITY);
if (res != VPX_CODEC_OK)
die_codec(ecodec, "Failed to encode frame");
got_data = 0;
while ((pkt = vpx_codec_get_cx_data(ecodec, &iter)) != NULL) {
got_pkts = 1;
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const int keyframe = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
if (!(pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)) {
*frame_out += 1;
}
if (!vpx_video_writer_write_frame(writer,
pkt->data.frame.buf,
pkt->data.frame.sz,
pkt->data.frame.pts)) {
die_codec(ecodec, "Failed to write compressed frame");
}
printf(keyframe ? "K" : ".");
fflush(stdout);
got_data = 1;
// Decode 1 frame.
if (test_decode) {
if (vpx_codec_decode(dcodec, pkt->data.frame.buf,
(unsigned int)pkt->data.frame.sz, NULL, 0))
die_codec(dcodec, "Failed to decode frame.");
}
}
}
// Mismatch checking
if (got_data && test_decode) {
testing_decode(ecodec, dcodec, cfg, *frame_out, mismatch_seen);
}
return got_pkts;
}
int main(int argc, char **argv) {
FILE *infile = NULL;
// Encoder
vpx_codec_ctx_t ecodec = {0};
vpx_codec_enc_cfg_t cfg = {0};
unsigned int frame_in = 0;
vpx_image_t raw;
vpx_codec_err_t res;
VpxVideoInfo info = {0};
VpxVideoWriter *writer = NULL;
const VpxInterface *encoder = NULL;
// Test encoder/decoder mismatch.
int test_decode = 1;
// Decoder
vpx_codec_ctx_t dcodec;
unsigned int frame_out = 0;
// The frame number to set reference frame on
int update_frame_num = 0;
int mismatch_seen = 0;
const int fps = 30;
const int bitrate = 500;
const char *codec_used = "vp9";
const char *width_arg = NULL;
const char *height_arg = NULL;
const char *infile_arg = NULL;
const char *outfile_arg = NULL;
exec_name = argv[0];
if (argc != 6)
die("Invalid number of arguments");
width_arg = argv[1];
height_arg = argv[2];
infile_arg = argv[3];
outfile_arg = argv[4];
encoder = get_vpx_encoder_by_name(codec_used);
if (!encoder)
die("Unsupported codec.");
update_frame_num = atoi(argv[5]);
if (update_frame_num <= 0)
die("Couldn't parse frame number '%s'\n", argv[5]);
info.codec_fourcc = encoder->fourcc;
info.frame_width = strtol(width_arg, NULL, 0);
info.frame_height = strtol(height_arg, NULL, 0);
info.time_base.numerator = 1;
info.time_base.denominator = fps;
if (info.frame_width <= 0 ||
info.frame_height <= 0 ||
(info.frame_width % 2) != 0 ||
(info.frame_height % 2) != 0) {
die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
}
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
info.frame_height, 1)) {
die("Failed to allocate image.");
}
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res)
die_codec(&ecodec, "Failed to get default codec config.");
cfg.g_w = info.frame_width;
cfg.g_h = info.frame_height;
cfg.g_timebase.num = info.time_base.numerator;
cfg.g_timebase.den = info.time_base.denominator;
cfg.rc_target_bitrate = bitrate;
cfg.g_lag_in_frames = 25;
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
if (!writer)
die("Failed to open %s for writing.", outfile_arg);
if (!(infile = fopen(infile_arg, "rb")))
die("Failed to open %s for reading.", infile_arg);
if (vpx_codec_enc_init(&ecodec, encoder->codec_interface(), &cfg, 0))
die_codec(&ecodec, "Failed to initialize encoder");
// Disable alt_ref.
if (vpx_codec_control(&ecodec, VP8E_SET_ENABLEAUTOALTREF, 0))
die_codec(&ecodec, "Failed to set enable auto alt ref");
if (test_decode) {
const VpxInterface *decoder = get_vpx_decoder_by_name(codec_used);
if (vpx_codec_dec_init(&dcodec, decoder->codec_interface(), NULL, 0))
die_codec(&dcodec, "Failed to initialize decoder.");
}
// Encode frames.
while (vpx_img_read(&raw, infile)) {
// In VP9, the reference buffers (cm->frame_buffs[i].buf) are allocated
// while calling vpx_codec_encode(), thus, setting reference for 1st frame
// isn't supported.
if (update_frame_num > 1 && frame_out + 1 == update_frame_num) {
vpx_ref_frame_t ref;
ref.frame_type = VP8_LAST_FRAME;
ref.img = raw;
// Set reference frame in encoder.
if (vpx_codec_control(&ecodec, VP8_SET_REFERENCE, &ref))
die_codec(&ecodec, "Failed to set reference frame");
// If set_reference in decoder is commented out, the enc/dec mismatch
// would be seen.
if (test_decode) {
if (vpx_codec_control(&dcodec, VP8_SET_REFERENCE, &ref))
die_codec(&dcodec, "Failed to set reference frame");
}
}
encode_frame(&ecodec, &cfg, &raw, frame_in, writer, test_decode,
&dcodec, &frame_out, &mismatch_seen);
frame_in++;
if (mismatch_seen)
break;
}
// Flush encoder.
if (!mismatch_seen)
while (encode_frame(&ecodec, &cfg, NULL, frame_in, writer, test_decode,
&dcodec, &frame_out, &mismatch_seen)) {};
printf("\n");
fclose(infile);
printf("Processed %d frames.\n", frame_out);
if (test_decode) {
if (!mismatch_seen)
printf("Encoder/decoder results are matching.\n");
else
printf("Encoder/decoder results are NOT matching.\n");
}
if (test_decode)
if (vpx_codec_destroy(&dcodec))
die_codec(&dcodec, "Failed to destroy decoder");
vpx_img_free(&raw);
if (vpx_codec_destroy(&ecodec))
die_codec(&ecodec, "Failed to destroy encoder.");
vpx_video_writer_close(writer);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,826 @@
/*
* 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.
*/
// This is an example demonstrating how to implement a multi-layer VPx
// encoding scheme based on temporal scalability for video applications
// that benefit from a scalable bitstream.
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./vpx_config.h"
#include "../vpx_ports/vpx_timer.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "../tools_common.h"
#include "../video_writer.h"
static const char *exec_name;
void usage_exit(void) {
exit(EXIT_FAILURE);
}
// Denoiser states, for temporal denoising.
enum denoiserState {
kDenoiserOff,
kDenoiserOnYOnly,
kDenoiserOnYUV,
kDenoiserOnYUVAggressive,
kDenoiserOnAdaptive
};
static int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3};
// For rate control encoding stats.
struct RateControlMetrics {
// Number of input frames per layer.
int layer_input_frames[VPX_TS_MAX_LAYERS];
// Total (cumulative) number of encoded frames per layer.
int layer_tot_enc_frames[VPX_TS_MAX_LAYERS];
// Number of encoded non-key frames per layer.
int layer_enc_frames[VPX_TS_MAX_LAYERS];
// Framerate per layer layer (cumulative).
double layer_framerate[VPX_TS_MAX_LAYERS];
// Target average frame size per layer (per-frame-bandwidth per layer).
double layer_pfb[VPX_TS_MAX_LAYERS];
// Actual average frame size per layer.
double layer_avg_frame_size[VPX_TS_MAX_LAYERS];
// Average rate mismatch per layer (|target - actual| / target).
double layer_avg_rate_mismatch[VPX_TS_MAX_LAYERS];
// Actual encoding bitrate per layer (cumulative).
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
// sequence (i.e., first frame only). So for temporal pattern# 7
// (which has key frame for every frame on base layer), the metrics
// computation will be off/wrong.
// TODO(marpan): Update these metrics to account for multiple key frames
// in the stream.
static void set_rate_control_metrics(struct RateControlMetrics *rc,
vpx_codec_enc_cfg_t *cfg) {
unsigned int i = 0;
// 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;
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] /
rc->layer_framerate[0];
for (i = 0; i < cfg->ts_number_layers; ++i) {
if (i > 0) {
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
rc->layer_pfb[i] = 1000.0 *
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
}
rc->layer_input_frames[i] = 0;
rc->layer_enc_frames[i] = 0;
rc->layer_tot_enc_frames[i] = 0;
rc->layer_encoding_bitrate[i] = 0.0;
rc->layer_avg_frame_size[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,
vpx_codec_enc_cfg_t *cfg,
int frame_cnt) {
unsigned int i = 0;
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 %d layer(s):\n\n",
cfg->ts_number_layers);
for (i = 0; i < cfg->ts_number_layers; ++i) {
const int num_dropped = (i > 0) ?
(rc->layer_input_frames[i] - rc->layer_enc_frames[i]) :
(rc->layer_input_frames[i] - rc->layer_enc_frames[i] - 1);
tot_num_frames += rc->layer_input_frames[i];
rc->layer_encoding_bitrate[i] = 0.001 * rc->layer_framerate[i] *
rc->layer_encoding_bitrate[i] / tot_num_frames;
rc->layer_avg_frame_size[i] = rc->layer_avg_frame_size[i] /
rc->layer_enc_frames[i];
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
rc->layer_enc_frames[i];
printf("For layer#: %d \n", i);
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
rc->layer_encoding_bitrate[i]);
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
rc->layer_avg_frame_size[i]);
printf("Average rate_mismatch: %f \n", rc->layer_avg_rate_mismatch[i]);
printf("Number of input frames, encoded (non-key) frames, "
"and perc dropped frames: %d %d %f \n", rc->layer_input_frames[i],
rc->layer_enc_frames[i],
100.0 * num_dropped / rc->layer_input_frames[i]);
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)
die("Error: Number of input frames not equal to output! \n");
}
// Temporal scaling parameters:
// NOTE: The 3 prediction frames cannot be used interchangeably due to
// differences in the way they are handled throughout the code. The
// frames should be allocated to layers in the order LAST, GF, ARF.
// Other combinations work, but may produce slightly inferior results.
static void set_temporal_layer_pattern(int layering_mode,
vpx_codec_enc_cfg_t *cfg,
int *layer_flags,
int *flag_periodicity) {
switch (layering_mode) {
case 0: {
// 1-layer.
int ids[1] = {0};
cfg->ts_periodicity = 1;
*flag_periodicity = 1;
cfg->ts_number_layers = 1;
cfg->ts_rate_decimator[0] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// Update L only.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
break;
}
case 1: {
// 2-layers, 2-frame period.
int ids[2] = {0, 1};
cfg->ts_periodicity = 2;
*flag_periodicity = 2;
cfg->ts_number_layers = 2;
cfg->ts_rate_decimator[0] = 2;
cfg->ts_rate_decimator[1] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
#if 1
// 0=L, 1=GF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_REF_ARF;
#else
// 0=L, 1=GF, Intra-layer prediction disabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
#endif
break;
}
case 2: {
// 2-layers, 3-frame period.
int ids[3] = {0, 1, 1};
cfg->ts_periodicity = 3;
*flag_periodicity = 3;
cfg->ts_number_layers = 2;
cfg->ts_rate_decimator[0] = 3;
cfg->ts_rate_decimator[1] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] =
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
break;
}
case 3: {
// 3-layers, 6-frame period.
int ids[6] = {0, 2, 2, 1, 2, 2};
cfg->ts_periodicity = 6;
*flag_periodicity = 6;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 6;
cfg->ts_rate_decimator[1] = 3;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] =
layer_flags[2] =
layer_flags[4] =
layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
break;
}
case 4: {
// 3-layers, 4-frame period.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 4;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[1] =
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
break;
}
case 5: {
// 3-layers, 4-frame period.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 4;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1, disabled
// in layer 2.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] =
layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
break;
}
case 6: {
// 3-layers, 4-frame period.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 4;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] =
layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
break;
}
case 7: {
// NOTE: Probably of academic interest only.
// 5-layers, 16-frame period.
int ids[16] = {0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4};
cfg->ts_periodicity = 16;
*flag_periodicity = 16;
cfg->ts_number_layers = 5;
cfg->ts_rate_decimator[0] = 16;
cfg->ts_rate_decimator[1] = 8;
cfg->ts_rate_decimator[2] = 4;
cfg->ts_rate_decimator[3] = 2;
cfg->ts_rate_decimator[4] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
layer_flags[0] = VPX_EFLAG_FORCE_KF;
layer_flags[1] =
layer_flags[3] =
layer_flags[5] =
layer_flags[7] =
layer_flags[9] =
layer_flags[11] =
layer_flags[13] =
layer_flags[15] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[2] =
layer_flags[6] =
layer_flags[10] =
layer_flags[14] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_GF;
layer_flags[4] =
layer_flags[12] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[8] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF;
break;
}
case 8: {
// 2-layers, with sync point at first frame of layer 1.
int ids[2] = {0, 1};
cfg->ts_periodicity = 2;
*flag_periodicity = 8;
cfg->ts_number_layers = 2;
cfg->ts_rate_decimator[0] = 2;
cfg->ts_rate_decimator[1] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 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] = VPX_EFLAG_FORCE_KF | 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 9: {
// 3-layers: Sync points for layer 1 and 2 every 8 frames.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 8;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF.
layer_flags[0] = VPX_EFLAG_FORCE_KF | VP8_EFLAG_NO_REF_GF |
VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[1] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
layer_flags[3] =
layer_flags[5] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
layer_flags[4] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
layer_flags[6] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_LAST |
VP8_EFLAG_NO_UPD_ARF;
layer_flags[7] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_ENTROPY;
break;
}
case 10: {
// 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.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 8;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF.
// Layer 0: predict from L and ARF; update L and G.
layer_flags[0] = VPX_EFLAG_FORCE_KF | 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;
}
case 11:
default: {
// 3-layers structure as in case 10, but no sync/refresh points for
// layer 1 and 2.
int ids[4] = {0, 2, 1, 2};
cfg->ts_periodicity = 4;
*flag_periodicity = 8;
cfg->ts_number_layers = 3;
cfg->ts_rate_decimator[0] = 4;
cfg->ts_rate_decimator[1] = 2;
cfg->ts_rate_decimator[2] = 1;
memcpy(cfg->ts_layer_id, ids, sizeof(ids));
// 0=L, 1=GF, 2=ARF.
// Layer 0: predict from L and ARF; update L.
layer_flags[0] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
layer_flags[4] = layer_flags[0];
// Layer 1: predict from L, G, ARF; update G.
layer_flags[2] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
layer_flags[6] = layer_flags[2];
// Layer 2: predict from L, G, ARF; update none.
layer_flags[1] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ENTROPY;
layer_flags[3] = layer_flags[1];
layer_flags[5] = layer_flags[1];
layer_flags[7] = layer_flags[1];
break;
}
}
}
int main(int argc, char **argv) {
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = {NULL};
vpx_codec_ctx_t codec;
vpx_codec_enc_cfg_t cfg;
int frame_cnt = 0;
vpx_image_t raw;
vpx_codec_err_t res;
unsigned int width;
unsigned int height;
int speed;
int frame_avail;
int got_data;
int flags = 0;
unsigned int i;
int pts = 0; // PTS starts at 0.
int frame_duration = 1; // 1 timebase tick per frame.
int layering_mode = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
int flag_periodicity = 1;
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
vpx_svc_layer_id_t layer_id = {0, 0};
#else
vpx_svc_layer_id_t layer_id = {0};
#endif
const VpxInterface *encoder = NULL;
FILE *infile = NULL;
struct RateControlMetrics rc;
int64_t cx_time = 0;
const int min_args_base = 11;
#if CONFIG_VP9_HIGHBITDEPTH
vpx_bit_depth_t bit_depth = VPX_BITS_8;
int input_bit_depth = 8;
const int min_args = min_args_base + 1;
#else
const int min_args = min_args_base;
#endif // CONFIG_VP9_HIGHBITDEPTH
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
double framerate = 30.0;
exec_name = argv[0];
// Check usage and arguments.
if (argc < min_args) {
#if CONFIG_VP9_HIGHBITDEPTH
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
#else
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
"<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
#endif // CONFIG_VP9_HIGHBITDEPTH
}
encoder = get_vpx_encoder_by_name(argv[3]);
if (!encoder)
die("Unsupported codec.");
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
width = strtol(argv[4], NULL, 0);
height = strtol(argv[5], NULL, 0);
if (width < 16 || width % 2 || height < 16 || height % 2) {
die("Invalid resolution: %d x %d", width, height);
}
layering_mode = strtol(argv[10], NULL, 0);
if (layering_mode < 0 || layering_mode > 12) {
die("Invalid layering mode (0..12) %s", argv[10]);
}
if (argc != min_args + mode_to_num_layers[layering_mode]) {
die("Invalid number of arguments");
}
#if CONFIG_VP9_HIGHBITDEPTH
switch (strtol(argv[argc-1], NULL, 0)) {
case 8:
bit_depth = VPX_BITS_8;
input_bit_depth = 8;
break;
case 10:
bit_depth = VPX_BITS_10;
input_bit_depth = 10;
break;
case 12:
bit_depth = VPX_BITS_12;
input_bit_depth = 12;
break;
default:
die("Invalid bit depth (8, 10, 12) %s", argv[argc-1]);
}
if (!vpx_img_alloc(&raw,
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 :
VPX_IMG_FMT_I42016,
width, height, 32)) {
die("Failed to allocate image", width, height);
}
#else
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
die("Failed to allocate image", width, height);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
// Populate encoder configuration.
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) {
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
return EXIT_FAILURE;
}
// Update the default configuration with our settings.
cfg.g_w = width;
cfg.g_h = height;
#if CONFIG_VP9_HIGHBITDEPTH
if (bit_depth != VPX_BITS_8) {
cfg.g_bit_depth = bit_depth;
cfg.g_input_bit_depth = input_bit_depth;
cfg.g_profile = 2;
}
#endif // CONFIG_VP9_HIGHBITDEPTH
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
cfg.g_timebase.num = strtol(argv[6], NULL, 0);
cfg.g_timebase.den = strtol(argv[7], NULL, 0);
speed = strtol(argv[8], NULL, 0);
if (speed < 0) {
die("Invalid speed setting: must be positive");
}
for (i = min_args_base;
(int)i < min_args_base + mode_to_num_layers[layering_mode];
++i) {
rc.layer_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.
cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
cfg.rc_end_usage = VPX_CBR;
cfg.rc_min_quantizer = 2;
cfg.rc_max_quantizer = 56;
if (strncmp(encoder->name, "vp9", 3) == 0)
cfg.rc_max_quantizer = 52;
cfg.rc_undershoot_pct = 50;
cfg.rc_overshoot_pct = 50;
cfg.rc_buf_initial_sz = 500;
cfg.rc_buf_optimal_sz = 600;
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.
cfg.g_error_resilient = 1;
cfg.g_lag_in_frames = 0;
cfg.kf_mode = VPX_KF_AUTO;
// Disable automatic keyframe placement.
cfg.kf_min_dist = cfg.kf_max_dist = 3000;
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
set_temporal_layer_pattern(layering_mode,
&cfg,
layer_flags,
&flag_periodicity);
set_rate_control_metrics(&rc, &cfg);
// Target bandwidth for the whole stream.
// Set to layer_target_bitrate for highest layer (total bitrate).
cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1];
// Open input file.
if (!(infile = fopen(argv[1], "rb"))) {
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.
for (i = 0; i < cfg.ts_number_layers; ++i) {
char file_name[PATH_MAX];
VpxVideoInfo info;
info.codec_fourcc = encoder->fourcc;
info.frame_width = cfg.g_w;
info.frame_height = cfg.g_h;
info.time_base.numerator = cfg.g_timebase.num;
info.time_base.denominator = cfg.g_timebase.den;
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
if (!outfile[i])
die("Failed to open %s for writing", file_name);
assert(outfile[i] != NULL);
}
// No spatial layers in this encoder.
cfg.ss_number_layers = 1;
// Initialize codec.
#if CONFIG_VP9_HIGHBITDEPTH
if (vpx_codec_enc_init(
&codec, encoder->codec_interface(), &cfg,
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
#else
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
#endif // CONFIG_VP9_HIGHBITDEPTH
die_codec(&codec, "Failed to initialize encoder");
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 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, VP9E_SET_AQ_MODE, 3);
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 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_TOKEN_PARTITIONS, 1);
// This controls the maximum target size of the key frame.
// For generating smaller key frames, use a smaller max_intra_size_pct
// value, like 100 or 200.
{
const int max_intra_size_pct = 900;
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
max_intra_size_pct);
}
frame_avail = 1;
while (frame_avail || got_data) {
struct vpx_usec_timer timer;
vpx_codec_iter_t iter = NULL;
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.
layer_id.spatial_layer_id = 0;
#endif
layer_id.temporal_layer_id =
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
if (strncmp(encoder->name, "vp9", 3) == 0) {
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];
if (layering_mode == 0)
flags = 0;
frame_avail = vpx_img_read(&raw, infile);
if (frame_avail)
++rc.layer_input_frames[layer_id.temporal_layer_id];
vpx_usec_timer_start(&timer);
if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts, 1, flags,
VPX_DL_REALTIME)) {
die_codec(&codec, "Failed to encode frame");
}
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
// Reset KF flag.
if (layering_mode != 7) {
layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;
}
got_data = 0;
while ( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
got_data = 1;
switch (pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT:
for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
i < cfg.ts_number_layers; ++i) {
vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf,
pkt->data.frame.sz, pts);
++rc.layer_tot_enc_frames[i];
rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz;
// Keep count of rate control stats per layer (for non-key frames).
if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] &&
!(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz;
rc.layer_avg_rate_mismatch[i] +=
fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) /
rc.layer_pfb[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;
default:
break;
}
}
++frame_cnt;
pts += frame_duration;
}
fclose(infile);
printout_rate_control_summary(&rc, &cfg, frame_cnt);
printf("\n");
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);
if (vpx_codec_destroy(&codec))
die_codec(&codec, "Failed to destroy codec");
// Try to rewrite the output file headers with the actual frame count.
for (i = 0; i < cfg.ts_number_layers; ++i)
vpx_video_writer_close(outfile[i]);
vpx_img_free(&raw);
return EXIT_SUCCESS;
}

View File

@@ -36,7 +36,7 @@ DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "WebM VP8 Codec SDK"
PROJECT_NAME = "WebM Codec SDK"
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

248
libs.mk
View File

@@ -17,32 +17,6 @@ else
ASM:=.asm
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
#
@@ -51,7 +25,7 @@ $$(BUILD_PFX)$(1).h: $$(SRC_PATH_BARE)/$(2)
@echo " [CREATE] $$@"
$$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \
--sym=$(1) \
--config=$$(CONFIG_DIR)$$(target)$$(if $$(FAT_ARCHS),,-$$(TOOLCHAIN)).mk \
--config=$$(CONFIG_DIR)$$(target)-$$(TOOLCHAIN).mk \
$$(RTCD_OPTIONS) $$^ > $$@
CLEAN-OBJS += $$(BUILD_PFX)$(1).h
RTCD += $$(BUILD_PFX)$(1).h
@@ -60,13 +34,6 @@ endef
CODEC_SRCS-yes += CHANGELOG
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
CODEC_SRCS-yes += $(addprefix vpx/,$(call enabled,API_SRCS))
CODEC_DOC_SRCS += $(addprefix vpx/,$(call enabled,API_DOC_SRCS))
@@ -80,6 +47,9 @@ CODEC_SRCS-yes += $(addprefix vpx_scale/,$(call enabled,SCALE_SRCS))
include $(SRC_PATH_BARE)/vpx_ports/vpx_ports.mk
CODEC_SRCS-yes += $(addprefix vpx_ports/,$(call enabled,PORTS_SRCS))
include $(SRC_PATH_BARE)/vpx_dsp/vpx_dsp.mk
CODEC_SRCS-yes += $(addprefix vpx_dsp/,$(call enabled,DSP_SRCS))
ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),)
VP8_PREFIX=vp8/
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk
@@ -115,6 +85,7 @@ ifeq ($(CONFIG_VP9_ENCODER),yes)
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS))
CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.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)/$(VP9_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
CODEC_DOC_SECTIONS += vp9 vp9_encoder
@@ -162,18 +133,18 @@ INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Release/%)
INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%)
endif
CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh
CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.pl
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/emmintrin_compat.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops_aligned.h
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_once.h
CODEC_SRCS-$(BUILD_LIBVPX) += $(BUILD_PFX)vpx_config.c
CODEC_SRCS-yes += build/make/version.sh
CODEC_SRCS-yes += build/make/rtcd.pl
CODEC_SRCS-yes += vpx_ports/emmintrin_compat.h
CODEC_SRCS-yes += vpx_ports/mem_ops.h
CODEC_SRCS-yes += vpx_ports/mem_ops_aligned.h
CODEC_SRCS-yes += vpx_ports/vpx_once.h
CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
endif
CODEC_EXPORTS-$(BUILD_LIBVPX) += vpx/exports_com
CODEC_EXPORTS-yes += vpx/exports_com
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
@@ -204,33 +175,13 @@ INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(call enabled,CODEC_EXPORTS)
# based build systems.
libvpx_srcs.txt:
@echo " [CREATE] $@"
@echo $(CODEC_SRCS) | xargs -n1 echo | sort -u > $@
@echo $(CODEC_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
CLEAN-OBJS += libvpx_srcs.txt
ifeq ($(CONFIG_EXTERNAL_BUILD),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)
@echo " [CREATE] $@"
$(qexec)$(SRC_PATH_BARE)/build/make/gen_msvs_def.sh\
@@ -245,7 +196,7 @@ ASM_INCLUDES := \
vpx_config.asm \
vpx_ports/x86_abi_support.asm \
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def obj_int_extract.$(VCPROJ_SFX)
vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
@echo " [CREATE] $@"
$(qexec)$(GEN_VCPROJ) \
$(if $(CONFIG_SHARED),--dll,--lib) \
@@ -260,7 +211,7 @@ vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def obj_int_extract.$(VCPROJ_SFX)
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
--src-path-bare="$(SRC_PATH_BARE)" \
PROJECTS-$(BUILD_LIBVPX) += vpx.$(VCPROJ_SFX)
PROJECTS-yes += vpx.$(VCPROJ_SFX)
vpx.$(VCPROJ_SFX): vpx_config.asm
vpx.$(VCPROJ_SFX): $(RTCD)
@@ -268,32 +219,42 @@ vpx.$(VCPROJ_SFX): $(RTCD)
endif
else
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
OBJS-$(BUILD_LIBVPX) += $(LIBVPX_OBJS)
LIBS-$(if $(BUILD_LIBVPX),$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
OBJS-yes += $(LIBVPX_OBJS)
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
BUILD_LIBVPX_SO := $(if $(BUILD_LIBVPX),$(CONFIG_SHARED))
SO_VERSION_MAJOR := 2
SO_VERSION_MINOR := 0
SO_VERSION_PATCH := 0
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
LIBVPX_SO := libvpx.$(VERSION_MAJOR).dylib
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
SHARED_LIB_SUF := .dylib
EXPORT_FILE := libvpx.syms
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
libvpx.dylib )
else
LIBVPX_SO := libvpx.so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
ifeq ($(filter os2%,$(TGT_OS)),$(TGT_OS))
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
SYM_LINK := libvpx.so
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
libvpx.so libvpx.so.$(VERSION_MAJOR) \
libvpx.so.$(VERSION_MAJOR).$(VERSION_MINOR))
libvpx.so libvpx.so.$(SO_VERSION_MAJOR) \
libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR))
endif
endif
LIBS-$(BUILD_LIBVPX_SO) += $(BUILD_PFX)$(LIBVPX_SO)\
$(notdir $(LIBVPX_SO_SYMLINKS))
LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\
$(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): extralibs += -lm
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(VERSION_MAJOR)
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(SO_VERSION_MAJOR)
$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE)
libvpx.ver: $(call enabled,CODEC_EXPORTS)
@@ -308,6 +269,19 @@ libvpx.syms: $(call enabled,CODEC_EXPORTS)
$(qexec)awk '{print "_"$$2}' $^ >$@
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
$(1): $(2)
@echo " [LN] $(2) $$@"
@@ -323,11 +297,12 @@ $(eval $(call libvpx_symlink_template,\
$(LIBVPX_SO)))
INSTALL-LIBS-$(BUILD_LIBVPX_SO) += $(LIBVPX_SO_SYMLINKS)
INSTALL-LIBS-$(BUILD_LIBVPX_SO) += $(LIBSUBDIR)/$(LIBVPX_SO)
INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBVPX_SO_SYMLINKS)
INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBSUBDIR)/$(LIBVPX_SO)
INSTALL-LIBS-$(CONFIG_SHARED) += $(if $(LIBVPX_SO_IMPLIB),$(LIBSUBDIR)/$(LIBVPX_SO_IMPLIB))
LIBS-$(BUILD_LIBVPX) += vpx.pc
LIBS-yes += vpx.pc
vpx.pc: config.mk libs.mk
@echo " [CREATE] $@"
$(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@
@@ -353,9 +328,6 @@ INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc
CLEAN-OBJS += vpx.pc
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
#
@@ -376,7 +348,7 @@ CLEAN-OBJS += $(BUILD_PFX)vpx_config.asm
endif
#
# Add assembler dependencies for configuration and offsets
# Add assembler dependencies for configuration.
#
$(filter %.s.o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
$(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
@@ -385,12 +357,6 @@ $(filter %$(ASM).o,$(OBJS-yes)): $(BUILD_PFX)vpx_config.asm
$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h)
CLEAN-OBJS += $(BUILD_PFX)vpx_version.h
#
# Add include path for libwebm sources.
#
ifeq ($(CONFIG_WEBM_IO),yes)
CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/libwebm
endif
##
## libvpx test directives
@@ -400,14 +366,18 @@ LIBVPX_TEST_DATA_PATH ?= .
include $(SRC_PATH_BARE)/test/test.mk
LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
LIBVPX_TEST_BINS=./test_libvpx$(EXE_SFX)
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
$(call enabled,LIBVPX_TEST_DATA))
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:
@echo " [CREATE] $@"
@echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | sort -u > $@
@echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
CLEAN-OBJS += libvpx_test_srcs.txt
$(LIBVPX_TEST_DATA): $(SRC_PATH_BARE)/test/test-data.sha1
@@ -464,12 +434,29 @@ test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
--out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
-I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
$(if $(CONFIG_WEBM_IO),-I"$(SRC_PATH_BARE)/third_party/libwebm") \
-L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^
PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX)
LIBVPX_TEST_BINS := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BINS)))
LIBVPX_TEST_BIN := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BIN)))
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
else
@@ -480,45 +467,54 @@ ifeq ($(filter win%,$(TGT_OS)),$(TGT_OS))
# Disabling pthreads globally will cause issues on darwin and possibly elsewhere
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0
endif
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS)
LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
GTEST_INCLUDES := -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 += $(GTEST_INCLUDES)
OBJS-yes += $(GTEST_OBJS)
LIBS-yes += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
$(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS)
LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS)))
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS)
BINS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_BINS)
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES)
OBJS-yes += $(LIBVPX_TEST_OBJS)
BINS-yes += $(LIBVPX_TEST_BIN)
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),.so,.a)
$(foreach bin,$(LIBVPX_TEST_BINS),\
$(if $(BUILD_LIBVPX),$(eval $(bin): \
lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a ))\
$(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\
$(LIBVPX_TEST_OBJS) \
-L. -lvpx -lgtest $(extralibs) -lm)\
)))\
$(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a)
TEST_LIBS := lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a
$(LIBVPX_TEST_BIN): $(TEST_LIBS)
$(eval $(call linkerxx_template,$(LIBVPX_TEST_BIN), \
$(LIBVPX_TEST_OBJS) \
-L. -lvpx -lgtest $(extralibs) -lm))
endif
ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),)
$(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-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\
$(shell find $(SRC_PATH_BARE)/third_party/googletest -type f))
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS)
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(TEST_INTRA_PRED_SPEED_SRCS)
define test_shard_template
test:: test_shard.$(1)
test_shard.$(1): $(LIBVPX_TEST_BINS) testdata
test-no-data-check:: test_shard_ndc.$(1)
test_shard.$(1) test_shard_ndc.$(1): $(LIBVPX_TEST_BIN)
@set -e; \
for t in $(LIBVPX_TEST_BINS); do \
export GTEST_SHARD_INDEX=$(1); \
export GTEST_TOTAL_SHARDS=$(2); \
$$$$t; \
done
export GTEST_SHARD_INDEX=$(1); \
export GTEST_TOTAL_SHARDS=$(2); \
$(LIBVPX_TEST_BIN)
test_shard.$(1): testdata
.PHONY: test_shard.$(1)
endef
@@ -541,7 +537,11 @@ libs.doxy: $(CODEC_DOC_SRCS)
@echo "ENABLED_SECTIONS += $(sort $(CODEC_DOC_SECTIONS))" >> $@
## Generate rtcd.h for all objects
ifeq ($(CONFIG_DEPENDENCY_TRACKING),yes)
$(OBJS-yes:.o=.d): $(RTCD)
else
$(OBJS-yes): $(RTCD)
endif
## Update the global src list
SRCS += $(CODEC_SRCS) $(LIBVPX_TEST_SRCS) $(GTEST_SRCS)
@@ -559,15 +559,16 @@ ifeq ($(CONFIG_MSVS),yes)
# TODO(tomfinegan): Support running the debug versions of tools?
TEST_BIN_PATH := $(addsuffix /$(TGT_OS:win64=x64)/Release, $(TEST_BIN_PATH))
endif
utiltest: testdata
utiltest utiltest-no-data-check:
$(qexec)$(SRC_PATH_BARE)/test/vpxdec.sh \
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
--bin-path $(TEST_BIN_PATH)
$(qexec)$(SRC_PATH_BARE)/test/vpxenc.sh \
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
--bin-path $(TEST_BIN_PATH)
utiltest: testdata
else
utiltest:
utiltest utiltest-no-data-check:
@echo Unit tests must be enabled to make the utiltest target.
endif
@@ -585,11 +586,12 @@ ifeq ($(CONFIG_MSVS),yes)
# TODO(tomfinegan): Support running the debug versions of tools?
EXAMPLES_BIN_PATH := $(TGT_OS:win64=x64)/Release
endif
exampletest: examples testdata
exampletest exampletest-no-data-check: examples
$(qexec)$(SRC_PATH_BARE)/test/examples.sh \
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
--bin-path $(EXAMPLES_BIN_PATH)
exampletest: testdata
else
exampletest:
exampletest exampletest-no-data-check:
@echo Unit tests must be enabled to make the exampletest target.
endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,9 +40,17 @@ include $(CLEAR_VARS)
LOCAL_ARM_MODE := arm
LOCAL_MODULE := libvpx_test
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
LOCAL_C_INCLUDES := $(BINDINGS_DIR)
FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes)))
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)

229
test/blockiness_test.cc Normal file
View File

@@ -0,0 +1,229 @@
/*
* 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 <limits.h>
#include <stdio.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 "third_party/googletest/src/include/gtest/gtest.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

189
test/byte_alignment_test.cc Normal file
View File

@@ -0,0 +1,189 @@
/*
* 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

@@ -35,6 +35,11 @@ class CodecFactory {
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
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,
unsigned long deadline,
const unsigned long init_flags,
@@ -72,6 +77,10 @@ class VP8Decoder : public Decoder {
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long 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:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP8_DECODER
@@ -104,8 +113,14 @@ class VP8CodecFactory : public 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_VP8_DECODER
return new VP8Decoder(cfg, deadline);
return new VP8Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
@@ -154,6 +169,10 @@ class VP9Decoder : public Decoder {
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long 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:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP9_DECODER
@@ -186,8 +205,14 @@ class VP9CodecFactory : public 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_VP9_DECODER
return new VP9Decoder(cfg, deadline);
return new VP9Decoder(cfg, flags, deadline);
#else
return NULL;
#endif

224
test/consistency_test.cc Normal file
View File

@@ -0,0 +1,224 @@
/*
* 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 <limits.h>
#include <stdio.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 "third_party/googletest/src/include/gtest/gtest.h"
#include "vp9/encoder/vp9_ssim.h"
#include "vpx_mem/vpx_mem.h"
extern "C"
double vp9_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
vp9_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

View File

@@ -10,12 +10,14 @@
#include <string.h>
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_filter.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
@@ -31,13 +33,16 @@ typedef void (*ConvolveFunc)(const uint8_t *src, ptrdiff_t src_stride,
int w, int h);
struct ConvolveFunctions {
ConvolveFunctions(ConvolveFunc h8, ConvolveFunc h8_avg,
ConvolveFunctions(ConvolveFunc copy, ConvolveFunc avg,
ConvolveFunc h8, ConvolveFunc h8_avg,
ConvolveFunc v8, ConvolveFunc v8_avg,
ConvolveFunc hv8, ConvolveFunc hv8_avg,
int bd)
: h8_(h8), v8_(v8), hv8_(hv8), h8_avg_(h8_avg), v8_avg_(v8_avg),
hv8_avg_(hv8_avg), use_highbd_(bd) {}
: copy_(copy), avg_(avg), h8_(h8), v8_(v8), hv8_(hv8), h8_avg_(h8_avg),
v8_avg_(v8_avg), hv8_avg_(hv8_avg), use_highbd_(bd) {}
ConvolveFunc copy_;
ConvolveFunc avg_;
ConvolveFunc h8_;
ConvolveFunc v8_;
ConvolveFunc hv8_;
@@ -298,25 +303,35 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
vpx_memalign(kDataAlignment, kInputBufferSize + 1)) + 1;
output_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kOutputBufferSize));
output_ref_ = reinterpret_cast<uint8_t*>(
vpx_memalign(kDataAlignment, kOutputBufferSize));
#if CONFIG_VP9_HIGHBITDEPTH
input16_ = reinterpret_cast<uint16_t*>(
vpx_memalign(kDataAlignment,
(kInputBufferSize + 1) * sizeof(uint16_t))) + 1;
output16_ = reinterpret_cast<uint16_t*>(
vpx_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t)));
output16_ref_ = reinterpret_cast<uint16_t*>(
vpx_memalign(kDataAlignment, (kOutputBufferSize) * sizeof(uint16_t)));
#endif
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
static void TearDownTestCase() {
vpx_free(input_ - 1);
input_ = NULL;
vpx_free(output_);
output_ = NULL;
vpx_free(output_ref_);
output_ref_ = NULL;
#if CONFIG_VP9_HIGHBITDEPTH
vpx_free(input16_ - 1);
input16_ = NULL;
vpx_free(output16_);
output16_ = NULL;
vpx_free(output16_ref_);
output16_ref_ = NULL;
#endif
}
@@ -382,6 +397,13 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
#endif
}
void CopyOutputToRef() {
memcpy(output_ref_, output_, kOutputBufferSize);
#if CONFIG_VP9_HIGHBITDEPTH
memcpy(output16_ref_, output16_, kOutputBufferSize);
#endif
}
void CheckGuardBlocks() {
for (int i = 0; i < kOutputBufferSize; ++i) {
if (IsIndexInBorder(i))
@@ -415,6 +437,19 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
#endif
}
uint8_t *output_ref() const {
#if CONFIG_VP9_HIGHBITDEPTH
if (UUT_->use_highbd_ == 0) {
return output_ref_ + BorderTop() * kOuterBlockSize + BorderLeft();
} else {
return CONVERT_TO_BYTEPTR(output16_ref_ + BorderTop() * kOuterBlockSize +
BorderLeft());
}
#else
return output_ref_ + BorderTop() * kOuterBlockSize + BorderLeft();
#endif
}
uint16_t lookup(uint8_t *list, int index) const {
#if CONFIG_VP9_HIGHBITDEPTH
if (UUT_->use_highbd_ == 0) {
@@ -493,24 +528,65 @@ class ConvolveTest : public ::testing::TestWithParam<ConvolveParam> {
const ConvolveFunctions* UUT_;
static uint8_t* input_;
static uint8_t* output_;
static uint8_t* output_ref_;
#if CONFIG_VP9_HIGHBITDEPTH
static uint16_t* input16_;
static uint16_t* output16_;
static uint16_t* output16_ref_;
int mask_;
#endif
};
uint8_t* ConvolveTest::input_ = NULL;
uint8_t* ConvolveTest::output_ = NULL;
uint8_t* ConvolveTest::output_ref_ = NULL;
#if CONFIG_VP9_HIGHBITDEPTH
uint16_t* ConvolveTest::input16_ = NULL;
uint16_t* ConvolveTest::output16_ = NULL;
uint16_t* ConvolveTest::output16_ref_ = NULL;
#endif
TEST_P(ConvolveTest, GuardBlocks) {
CheckGuardBlocks();
}
TEST_P(ConvolveTest, Copy) {
uint8_t* const in = input();
uint8_t* const out = output();
ASM_REGISTER_STATE_CHECK(
UUT_->copy_(in, kInputStride, out, kOutputStride, NULL, 0, NULL, 0,
Width(), Height()));
CheckGuardBlocks();
for (int y = 0; y < Height(); ++y)
for (int x = 0; x < Width(); ++x)
ASSERT_EQ(lookup(out, y * kOutputStride + x),
lookup(in, y * kInputStride + x))
<< "(" << x << "," << y << ")";
}
TEST_P(ConvolveTest, Avg) {
uint8_t* const in = input();
uint8_t* const out = output();
uint8_t* const out_ref = output_ref();
CopyOutputToRef();
ASM_REGISTER_STATE_CHECK(
UUT_->avg_(in, kInputStride, out, kOutputStride, NULL, 0, NULL, 0,
Width(), Height()));
CheckGuardBlocks();
for (int y = 0; y < Height(); ++y)
for (int x = 0; x < Width(); ++x)
ASSERT_EQ(lookup(out, y * kOutputStride + x),
ROUND_POWER_OF_TWO(lookup(in, y * kInputStride + x) +
lookup(out_ref, y * kOutputStride + x), 1))
<< "(" << x << "," << y << ")";
}
TEST_P(ConvolveTest, CopyHoriz) {
uint8_t* const in = input();
uint8_t* const out = output();
@@ -1188,6 +1264,30 @@ void wrap_convolve8_avg_sse2_12(const uint8_t *src, ptrdiff_t src_stride,
}
#endif // HAVE_SSE2 && ARCH_X86_64
void wrap_convolve_copy_c_8(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
int filter_x_stride,
const int16_t *filter_y,
int filter_y_stride,
int w, int h) {
vp9_highbd_convolve_copy_c(src, src_stride, dst, dst_stride,
filter_x, filter_x_stride,
filter_y, filter_y_stride, w, h, 8);
}
void wrap_convolve_avg_c_8(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
int filter_x_stride,
const int16_t *filter_y,
int filter_y_stride,
int w, int h) {
vp9_highbd_convolve_avg_c(src, src_stride, dst, dst_stride,
filter_x, filter_x_stride,
filter_y, filter_y_stride, w, h, 8);
}
void wrap_convolve8_horiz_c_8(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
@@ -1260,6 +1360,30 @@ void wrap_convolve8_avg_c_8(const uint8_t *src, ptrdiff_t src_stride,
filter_y, filter_y_stride, w, h, 8);
}
void wrap_convolve_copy_c_10(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
int filter_x_stride,
const int16_t *filter_y,
int filter_y_stride,
int w, int h) {
vp9_highbd_convolve_copy_c(src, src_stride, dst, dst_stride,
filter_x, filter_x_stride,
filter_y, filter_y_stride, w, h, 10);
}
void wrap_convolve_avg_c_10(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
int filter_x_stride,
const int16_t *filter_y,
int filter_y_stride,
int w, int h) {
vp9_highbd_convolve_avg_c(src, src_stride, dst, dst_stride,
filter_x, filter_x_stride,
filter_y, filter_y_stride, w, h, 10);
}
void wrap_convolve8_horiz_c_10(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
@@ -1332,6 +1456,30 @@ void wrap_convolve8_avg_c_10(const uint8_t *src, ptrdiff_t src_stride,
filter_y, filter_y_stride, w, h, 10);
}
void wrap_convolve_copy_c_12(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
int filter_x_stride,
const int16_t *filter_y,
int filter_y_stride,
int w, int h) {
vp9_highbd_convolve_copy_c(src, src_stride, dst, dst_stride,
filter_x, filter_x_stride,
filter_y, filter_y_stride, w, h, 12);
}
void wrap_convolve_avg_c_12(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
int filter_x_stride,
const int16_t *filter_y,
int filter_y_stride,
int w, int h) {
vp9_highbd_convolve_avg_c(src, src_stride, dst, dst_stride,
filter_x, filter_x_stride,
filter_y, filter_y_stride, w, h, 12);
}
void wrap_convolve8_horiz_c_12(const uint8_t *src, ptrdiff_t src_stride,
uint8_t *dst, ptrdiff_t dst_stride,
const int16_t *filter_x,
@@ -1405,6 +1553,7 @@ void wrap_convolve8_avg_c_12(const uint8_t *src, ptrdiff_t src_stride,
}
const ConvolveFunctions convolve8_c(
wrap_convolve_copy_c_8, wrap_convolve_avg_c_8,
wrap_convolve8_horiz_c_8, wrap_convolve8_avg_horiz_c_8,
wrap_convolve8_vert_c_8, wrap_convolve8_avg_vert_c_8,
wrap_convolve8_c_8, wrap_convolve8_avg_c_8, 8);
@@ -1423,6 +1572,7 @@ INSTANTIATE_TEST_CASE_P(C_8, ConvolveTest, ::testing::Values(
make_tuple(32, 64, &convolve8_c),
make_tuple(64, 64, &convolve8_c)));
const ConvolveFunctions convolve10_c(
wrap_convolve_copy_c_10, wrap_convolve_avg_c_10,
wrap_convolve8_horiz_c_10, wrap_convolve8_avg_horiz_c_10,
wrap_convolve8_vert_c_10, wrap_convolve8_avg_vert_c_10,
wrap_convolve8_c_10, wrap_convolve8_avg_c_10, 10);
@@ -1441,6 +1591,7 @@ INSTANTIATE_TEST_CASE_P(C_10, ConvolveTest, ::testing::Values(
make_tuple(32, 64, &convolve10_c),
make_tuple(64, 64, &convolve10_c)));
const ConvolveFunctions convolve12_c(
wrap_convolve_copy_c_12, wrap_convolve_avg_c_12,
wrap_convolve8_horiz_c_12, wrap_convolve8_avg_horiz_c_12,
wrap_convolve8_vert_c_12, wrap_convolve8_avg_vert_c_12,
wrap_convolve8_c_12, wrap_convolve8_avg_c_12, 12);
@@ -1462,6 +1613,7 @@ INSTANTIATE_TEST_CASE_P(C_12, ConvolveTest, ::testing::Values(
#else
const ConvolveFunctions convolve8_c(
vp9_convolve_copy_c, vp9_convolve_avg_c,
vp9_convolve8_horiz_c, vp9_convolve8_avg_horiz_c,
vp9_convolve8_vert_c, vp9_convolve8_avg_vert_c,
vp9_convolve8_c, vp9_convolve8_avg_c, 0);
@@ -1485,10 +1637,21 @@ INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::Values(
#if HAVE_SSE2 && ARCH_X86_64
#if CONFIG_VP9_HIGHBITDEPTH
const ConvolveFunctions convolve8_sse2(
wrap_convolve_copy_c_8, wrap_convolve_avg_c_8,
wrap_convolve8_horiz_sse2_8, wrap_convolve8_avg_horiz_sse2_8,
wrap_convolve8_vert_sse2_8, wrap_convolve8_avg_vert_sse2_8,
wrap_convolve8_sse2_8, wrap_convolve8_avg_sse2_8, 8);
INSTANTIATE_TEST_CASE_P(SSE2_8, ConvolveTest, ::testing::Values(
const ConvolveFunctions convolve10_sse2(
wrap_convolve_copy_c_10, wrap_convolve_avg_c_10,
wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, 10);
const ConvolveFunctions convolve12_sse2(
wrap_convolve_copy_c_12, wrap_convolve_avg_c_12,
wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, 12);
INSTANTIATE_TEST_CASE_P(SSE2, ConvolveTest, ::testing::Values(
make_tuple(4, 4, &convolve8_sse2),
make_tuple(8, 4, &convolve8_sse2),
make_tuple(4, 8, &convolve8_sse2),
@@ -1501,12 +1664,7 @@ INSTANTIATE_TEST_CASE_P(SSE2_8, ConvolveTest, ::testing::Values(
make_tuple(32, 32, &convolve8_sse2),
make_tuple(64, 32, &convolve8_sse2),
make_tuple(32, 64, &convolve8_sse2),
make_tuple(64, 64, &convolve8_sse2)));
const ConvolveFunctions convolve10_sse2(
wrap_convolve8_horiz_sse2_10, wrap_convolve8_avg_horiz_sse2_10,
wrap_convolve8_vert_sse2_10, wrap_convolve8_avg_vert_sse2_10,
wrap_convolve8_sse2_10, wrap_convolve8_avg_sse2_10, 10);
INSTANTIATE_TEST_CASE_P(SSE2_10, ConvolveTest, ::testing::Values(
make_tuple(64, 64, &convolve8_sse2),
make_tuple(4, 4, &convolve10_sse2),
make_tuple(8, 4, &convolve10_sse2),
make_tuple(4, 8, &convolve10_sse2),
@@ -1519,12 +1677,7 @@ INSTANTIATE_TEST_CASE_P(SSE2_10, ConvolveTest, ::testing::Values(
make_tuple(32, 32, &convolve10_sse2),
make_tuple(64, 32, &convolve10_sse2),
make_tuple(32, 64, &convolve10_sse2),
make_tuple(64, 64, &convolve10_sse2)));
const ConvolveFunctions convolve12_sse2(
wrap_convolve8_horiz_sse2_12, wrap_convolve8_avg_horiz_sse2_12,
wrap_convolve8_vert_sse2_12, wrap_convolve8_avg_vert_sse2_12,
wrap_convolve8_sse2_12, wrap_convolve8_avg_sse2_12, 12);
INSTANTIATE_TEST_CASE_P(SSE2_12, ConvolveTest, ::testing::Values(
make_tuple(64, 64, &convolve10_sse2),
make_tuple(4, 4, &convolve12_sse2),
make_tuple(8, 4, &convolve12_sse2),
make_tuple(4, 8, &convolve12_sse2),
@@ -1540,6 +1693,7 @@ INSTANTIATE_TEST_CASE_P(SSE2_12, ConvolveTest, ::testing::Values(
make_tuple(64, 64, &convolve12_sse2)));
#else
const ConvolveFunctions convolve8_sse2(
vp9_convolve_copy_sse2, vp9_convolve_avg_sse2,
vp9_convolve8_horiz_sse2, vp9_convolve8_avg_horiz_sse2,
vp9_convolve8_vert_sse2, vp9_convolve8_avg_vert_sse2,
vp9_convolve8_sse2, vp9_convolve8_avg_sse2, 0);
@@ -1563,6 +1717,7 @@ INSTANTIATE_TEST_CASE_P(SSE2, ConvolveTest, ::testing::Values(
#if HAVE_SSSE3
const ConvolveFunctions convolve8_ssse3(
vp9_convolve_copy_c, vp9_convolve_avg_c,
vp9_convolve8_horiz_ssse3, vp9_convolve8_avg_horiz_ssse3,
vp9_convolve8_vert_ssse3, vp9_convolve8_avg_vert_ssse3,
vp9_convolve8_ssse3, vp9_convolve8_avg_ssse3, 0);
@@ -1585,6 +1740,7 @@ INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest, ::testing::Values(
#if HAVE_AVX2 && HAVE_SSSE3
const ConvolveFunctions convolve8_avx2(
vp9_convolve_copy_c, vp9_convolve_avg_c,
vp9_convolve8_horiz_avx2, vp9_convolve8_avg_horiz_ssse3,
vp9_convolve8_vert_avx2, vp9_convolve8_avg_vert_ssse3,
vp9_convolve8_avx2, vp9_convolve8_avg_ssse3, 0);
@@ -1605,11 +1761,20 @@ INSTANTIATE_TEST_CASE_P(AVX2, ConvolveTest, ::testing::Values(
make_tuple(64, 64, &convolve8_avx2)));
#endif // HAVE_AVX2 && HAVE_SSSE3
#if HAVE_NEON
#if HAVE_NEON_ASM
const ConvolveFunctions convolve8_neon(
vp9_convolve_copy_neon, vp9_convolve_avg_neon,
vp9_convolve8_horiz_neon, vp9_convolve8_avg_horiz_neon,
vp9_convolve8_vert_neon, vp9_convolve8_avg_vert_neon,
vp9_convolve8_neon, vp9_convolve8_avg_neon, 0);
#else // HAVE_NEON
const ConvolveFunctions convolve8_neon(
vp9_convolve_copy_neon, vp9_convolve_avg_neon,
vp9_convolve8_horiz_neon, vp9_convolve8_avg_horiz_neon,
vp9_convolve8_vert_neon, vp9_convolve8_avg_vert_neon,
vp9_convolve8_neon, vp9_convolve8_avg_neon, 0);
#endif // HAVE_NEON_ASM
INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest, ::testing::Values(
make_tuple(4, 4, &convolve8_neon),
@@ -1625,10 +1790,11 @@ INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest, ::testing::Values(
make_tuple(64, 32, &convolve8_neon),
make_tuple(32, 64, &convolve8_neon),
make_tuple(64, 64, &convolve8_neon)));
#endif
#endif // HAVE_NEON
#if HAVE_DSPR2
const ConvolveFunctions convolve8_dspr2(
vp9_convolve_copy_dspr2, vp9_convolve_avg_dspr2,
vp9_convolve8_horiz_dspr2, vp9_convolve8_avg_horiz_dspr2,
vp9_convolve8_vert_dspr2, vp9_convolve8_avg_vert_dspr2,
vp9_convolve8_dspr2, vp9_convolve8_avg_dspr2, 0);
@@ -1648,4 +1814,27 @@ INSTANTIATE_TEST_CASE_P(DSPR2, ConvolveTest, ::testing::Values(
make_tuple(32, 64, &convolve8_dspr2),
make_tuple(64, 64, &convolve8_dspr2)));
#endif
#if HAVE_MSA
const ConvolveFunctions convolve8_msa(
vp9_convolve_copy_msa, vp9_convolve_avg_msa,
vp9_convolve8_horiz_msa, vp9_convolve8_avg_horiz_msa,
vp9_convolve8_vert_msa, vp9_convolve8_avg_vert_msa,
vp9_convolve8_msa, vp9_convolve8_avg_msa, 0);
INSTANTIATE_TEST_CASE_P(MSA, ConvolveTest, ::testing::Values(
make_tuple(4, 4, &convolve8_msa),
make_tuple(8, 4, &convolve8_msa),
make_tuple(4, 8, &convolve8_msa),
make_tuple(8, 8, &convolve8_msa),
make_tuple(16, 8, &convolve8_msa),
make_tuple(8, 16, &convolve8_msa),
make_tuple(16, 16, &convolve8_msa),
make_tuple(32, 16, &convolve8_msa),
make_tuple(16, 32, &convolve8_msa),
make_tuple(32, 32, &convolve8_msa),
make_tuple(64, 32, &convolve8_msa),
make_tuple(32, 64, &convolve8_msa),
make_tuple(64, 64, &convolve8_msa)));
#endif // HAVE_MSA
} // namespace

View File

@@ -14,6 +14,7 @@
#include "test/i420_video_source.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "vpx/vpx_codec.h"
namespace {
@@ -38,13 +39,25 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
first_drop_ = 0;
bits_total_ = 0;
duration_ = 0.0;
denoiser_offon_test_ = 0;
denoiser_offon_period_ = -1;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0)
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_);
}
const vpx_rational_t tb = video->timebase();
timebase_ = static_cast<double>(tb.num) / tb.den;
duration_ = 0;
@@ -124,6 +137,8 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
double effective_datarate_;
size_t bits_in_last_frame_;
int denoiser_on_;
int denoiser_offon_test_;
int denoiser_offon_period_;
};
#if CONFIG_TEMPORAL_DENOISING
@@ -155,6 +170,29 @@ TEST_P(DatarateTestLarge, DenoiserLevels) {
<< " 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
TEST_P(DatarateTestLarge, BasicBufferModel) {
@@ -218,5 +256,664 @@ TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
}
}
class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
public:
DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
protected:
virtual ~DatarateTestVP9Large() {}
virtual void SetUp() {
InitializeConfig();
SetMode(GET_PARAM(1));
set_cpu_used_ = 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;
tot_frame_number_ = 0;
first_drop_ = 0;
num_drops_ = 0;
// Denoiser is off by default.
denoiser_on_ = 0;
// For testing up to 3 layers.
for (int i = 0; i < 3; ++i) {
bits_total_[i] = 0;
}
denoiser_offon_test_ = 0;
denoiser_offon_period_ = -1;
}
//
// 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.
// For this 3 layer example, the 2nd enhancement layer (layer 2) does not
// update any reference frames.
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 and ARF; update L.
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
VP8_EFLAG_NO_REF_GF;
} else if ((frame_num - 2) % 4 == 0) {
// Layer 1: predict from L, G, ARF; update G.
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
} else if ((frame_num - 1) % 2 == 0) {
// Layer 2: predict from L, G, ARF; update none.
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
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 (video->frame() == 0)
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
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 (video->frame() == 0) {
encoder->Control(VP9E_SET_SVC, 1);
}
vpx_svc_layer_id_t layer_id;
layer_id.spatial_layer_id = 0;
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
layer_id.temporal_layer_id = SetLayerId(video->frame(),
cfg_.ts_number_layers);
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
}
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) {
// Time since last timestamp = duration.
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
if (duration > 1) {
// If first drop not set and we have a drop set it to this time.
if (!first_drop_)
first_drop_ = last_pts_ + 1;
// Update the number of frame drops.
num_drops_ += static_cast<int>(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);
// Add to the buffer the bits we'd expect from a constant bitrate server.
bits_in_buffer_model_ += static_cast<int64_t>(
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
// Buffer should not go negative.
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;
// 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;
++frame_number_;
++tot_frame_number_;
}
virtual void EndPassHook(void) {
for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
++layer) {
duration_ = (last_pts_ + 1) * timebase_;
if (bits_total_[layer]) {
// Effective file datarate:
effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
}
}
}
vpx_codec_pts_t last_pts_;
double timebase_;
int frame_number_; // Counter for number of non-dropped/encoded frames.
int tot_frame_number_; // Counter for total number of input frames.
int64_t bits_total_[3];
double duration_;
double effective_datarate_[3];
int set_cpu_used_;
int64_t bits_in_buffer_model_;
vpx_codec_pts_t first_drop_;
int num_drops_;
int denoiser_on_;
int denoiser_offon_test_;
int denoiser_offon_period_;
};
// Check basic rate targeting,
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
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 = 0;
cfg_.rc_max_quantizer = 63;
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, 140);
for (int i = 150; i < 800; i += 200) {
cfg_.rc_target_bitrate = i;
ResetModel();
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!";
}
}
// Check basic rate targeting,
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
cfg_.g_profile = 1;
cfg_.g_timebase = video.timebase();
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 = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
for (int i = 250; i < 900; i += 200) {
cfg_.rc_target_bitrate = i;
ResetModel();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
effective_datarate_[0] * 0.85)
<< " The datarate for the file exceeds the target by too much!";
ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
effective_datarate_[0] * 1.15)
<< " The datarate for the file missed the target!"
<< cfg_.rc_target_bitrate << " "<< effective_datarate_;
}
}
// Check that (1) the first dropped frame gets earlier and earlier
// as the drop frame threshold is increased, and (2) that the total number of
// frame drops does not decrease as we increase frame drop threshold.
// Use a lower qp-max to force some frame drops.
TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_undershoot_pct = 20;
cfg_.rc_undershoot_pct = 20;
cfg_.rc_dropframe_thresh = 10;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 50;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_target_bitrate = 200;
cfg_.g_lag_in_frames = 0;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 140);
const int kDropFrameThreshTestStep = 30;
vpx_codec_pts_t last_drop = 140;
int last_num_drops = 0;
for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
cfg_.rc_dropframe_thresh = i;
ResetModel();
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!";
ASSERT_LE(first_drop_, last_drop)
<< " The first dropped frame for drop_thresh " << i
<< " > first dropped frame for drop_thresh "
<< i - kDropFrameThreshTestStep;
ASSERT_GE(num_drops_, last_num_drops * 0.90)
<< " The number of dropped frames for drop_thresh " << i
<< " < number of dropped frames for drop_thresh "
<< i - kDropFrameThreshTestStep;
last_drop = first_drop_;
last_num_drops = num_drops_;
}
}
// Check basic rate targeting for 2 temporal layers.
TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
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 = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
// 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
cfg_.ss_number_layers = 1;
cfg_.ts_number_layers = 2;
cfg_.ts_rate_decimator[0] = 2;
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,
30, 1, 0, 200);
for (int i = 200; i <= 800; i += 200) {
cfg_.rc_target_bitrate = i;
ResetModel();
// 60-40 bitrate allocation for 2 temporal layers.
cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[1] = 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_.layer_target_bitrate[j] * 0.85)
<< " The datarate for the file is lower than target by too much, "
"for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
<< " The datarate for the file is greater than target by too much, "
"for layer: " << j;
}
}
}
// Check basic rate targeting for 3 temporal layers.
TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
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 = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
// 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
cfg_.ss_number_layers = 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_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
::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;
ResetModel();
// 40-20-40 bitrate allocation for 3 temporal layers.
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.layer_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) {
// TODO(yaowu): Work out more stable rc control strategy and
// Adjust the thresholds to be tighter than .75.
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
<< " The datarate for the file is lower than target by too much, "
"for layer: " << j;
// TODO(yaowu): Work out more stable rc control strategy and
// Adjust the thresholds to be tighter than 1.25.
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
<< " The datarate for the file is greater than target by too much, "
"for layer: " << j;
}
}
}
// Check basic rate targeting for 3 temporal layers, with frame dropping.
// Only for one (low) bitrate with lower max_quantizer, and somewhat higher
// frame drop threshold, to force frame dropping.
TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
// Set frame drop threshold and rc_max_quantizer to force some frame drops.
cfg_.rc_dropframe_thresh = 20;
cfg_.rc_max_quantizer = 45;
cfg_.rc_min_quantizer = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_lag_in_frames = 0;
// 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
cfg_.ss_number_layers = 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_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
30, 1, 0, 200);
cfg_.rc_target_bitrate = 200;
ResetModel();
// 40-20-40 bitrate allocation for 3 temporal layers.
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
cfg_.layer_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_.layer_target_bitrate[j] * 0.85)
<< " The datarate for the file is lower than target by too much, "
"for layer: " << j;
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
<< " The datarate for the file is greater than target by too much, "
"for layer: " << j;
// Expect some frame drops in this test: for this 200 frames test,
// expect at least 10% and not more than 60% drops.
ASSERT_GE(num_drops_, 20);
ASSERT_LE(num_drops_, 130);
}
}
#if CONFIG_VP9_TEMPORAL_DENOISING
// Check basic datarate targeting, for a single bitrate, when denoiser is on.
TEST_P(DatarateTestVP9Large, DenoiserLevels) {
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, 140);
// 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();
// Turn on the denoiser.
denoiser_on_ = 1;
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!";
}
// 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
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;
}
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);
}
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_;
}
}
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_;
};
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.
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_.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!";
}
}
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
::testing::Values(::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime),
::testing::Range(2, 7));
VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
::testing::Values(::libvpx_test::kRealTime),
::testing::Range(5, 8));
} // namespace

View File

@@ -20,8 +20,10 @@
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_scan.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom;
@@ -338,8 +340,8 @@ void idct16x16_10_add_10_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) {
vp9_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
}
#endif
#endif
#endif // HAVE_SSE2
#endif // CONFIG_VP9_HIGHBITDEPTH
class Trans16x16TestBase {
public:
@@ -356,13 +358,13 @@ class Trans16x16TestBase {
int64_t total_error = 0;
const int count_test_block = 10000;
for (int i = 0; i < count_test_block; ++i) {
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
#endif
// Initialize a test block with input range [-mask_, mask_].
@@ -416,9 +418,9 @@ class Trans16x16TestBase {
void RunCoeffCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_].
@@ -437,15 +439,13 @@ class Trans16x16TestBase {
void RunMemCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_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_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_].
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_;
}
if (i == 0) {
@@ -472,24 +472,19 @@ class Trans16x16TestBase {
void RunQuantCheck(int dc_thred, int ac_thred) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 100000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_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, int16_t, input_extreme_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
#endif
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_].
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_;
}
if (i == 0)
@@ -502,11 +497,11 @@ class Trans16x16TestBase {
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
// clear reconstructed pixel buffers
vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
#if CONFIG_VP9_HIGHBITDEPTH
vpx_memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
vpx_memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
#endif
// quantization with maximum allowed step sizes
@@ -539,14 +534,14 @@ class Trans16x16TestBase {
void RunInvAccuracyCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
#endif
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int i = 0; i < count_test_block; ++i) {
double out_r[kNumCoeffs];
@@ -562,7 +557,7 @@ class Trans16x16TestBase {
src16[j] = rnd.Rand16() & mask_;
dst16[j] = rnd.Rand16() & mask_;
in[j] = src16[j] - dst16[j];
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
}
}
@@ -576,7 +571,7 @@ class Trans16x16TestBase {
} else {
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
16));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
}
for (int j = 0; j < kNumCoeffs; ++j) {
@@ -585,7 +580,7 @@ class Trans16x16TestBase {
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
const uint32_t diff = dst[j] - src[j];
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
const uint32_t error = diff * diff;
EXPECT_GE(1u, error)
<< "Error: 16x16 IDCT has error " << error
@@ -593,24 +588,25 @@ class Trans16x16TestBase {
}
}
}
void CompareInvReference(IdctFunc ref_txfm, int thresh) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 10000;
const int eob = 10;
const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan;
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
#endif
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int i = 0; i < count_test_block; ++i) {
for (int j = 0; j < kNumCoeffs; ++j) {
if (j < eob) {
// 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 {
coeff[scan[j]] = 0;
}
@@ -621,7 +617,7 @@ class Trans16x16TestBase {
} else {
dst16[j] = 0;
ref16[j] = 0;
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
}
}
if (bit_depth_ == VPX_BITS_8) {
@@ -632,7 +628,7 @@ class Trans16x16TestBase {
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
pitch_));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
}
for (int j = 0; j < kNumCoeffs; ++j) {
@@ -641,7 +637,7 @@ class Trans16x16TestBase {
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
#else
const uint32_t diff = dst[j] - ref[j];
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
const uint32_t error = diff * diff;
EXPECT_EQ(0u, error)
<< "Error: 16x16 IDCT Comparison has error " << error
@@ -649,6 +645,7 @@ class Trans16x16TestBase {
}
}
}
int pitch_;
int tx_type_;
vpx_bit_depth_t bit_depth_;
@@ -796,9 +793,9 @@ class InvTrans16x16DCT
virtual void SetUp() {
ref_txfm_ = GET_PARAM(0);
inv_txfm_ = GET_PARAM(1);
thresh_ = GET_PARAM(2);
thresh_ = GET_PARAM(2);
bit_depth_ = GET_PARAM(3);
pitch_ = 16;
pitch_ = 16;
mask_ = (1 << bit_depth_) - 1;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
@@ -832,7 +829,7 @@ INSTANTIATE_TEST_CASE_P(
C, Trans16x16DCT,
::testing::Values(
make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
@@ -858,7 +855,7 @@ 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, 2, VPX_BITS_8),
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -885,7 +882,7 @@ INSTANTIATE_TEST_CASE_P(
VPX_BITS_8),
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3,
VPX_BITS_8)));
#endif
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -930,13 +927,21 @@ INSTANTIATE_TEST_CASE_P(
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
make_tuple(&idct16x16_12,
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
#endif
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSSE3, Trans16x16DCT,
MSA, Trans16x16DCT,
::testing::Values(
make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0,
make_tuple(&vp9_fdct16x16_msa,
&vp9_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)));
#endif
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

@@ -23,6 +23,7 @@
#include "vp9/common/vp9_entropy.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom;
@@ -90,7 +91,7 @@ void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
vp9_highbd_idct32x32_1024_add_c(in, out, stride, 12);
}
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
public:
@@ -119,13 +120,13 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
uint32_t max_error = 0;
int64_t total_error = 0;
const int count_test_block = 10000;
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
#endif
for (int i = 0; i < count_test_block; ++i) {
@@ -184,9 +185,9 @@ TEST_P(Trans32x32Test, CoeffCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
for (int j = 0; j < kNumCoeffs; ++j)
@@ -212,15 +213,13 @@ TEST_P(Trans32x32Test, MemCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 2000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_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_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_].
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_;
}
if (i == 0) {
@@ -257,13 +256,13 @@ TEST_P(Trans32x32Test, MemCheck) {
TEST_P(Trans32x32Test, InverseAccuracy) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
#endif
for (int i = 0; i < count_test_block; ++i) {
@@ -335,7 +334,7 @@ INSTANTIATE_TEST_CASE_P(
&vp9_idct32x32_1024_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_fdct32x32_rd_c,
&vp9_idct32x32_1024_add_c, 1, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -345,7 +344,7 @@ INSTANTIATE_TEST_CASE_P(
&vp9_idct32x32_1024_add_neon, 0, VPX_BITS_8),
make_tuple(&vp9_fdct32x32_rd_c,
&vp9_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
#endif
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -355,7 +354,7 @@ INSTANTIATE_TEST_CASE_P(
&vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
make_tuple(&vp9_fdct32x32_rd_sse2,
&vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
#endif
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -371,7 +370,7 @@ INSTANTIATE_TEST_CASE_P(
VPX_BITS_8),
make_tuple(&vp9_fdct32x32_rd_sse2, &vp9_idct32x32_1024_add_c, 1,
VPX_BITS_8)));
#endif
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -381,5 +380,15 @@ INSTANTIATE_TEST_CASE_P(
&vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
make_tuple(&vp9_fdct32x32_rd_avx2,
&vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
#endif
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, Trans32x32Test,
::testing::Values(
make_tuple(&vp9_fdct32x32_msa,
&vp9_idct32x32_1024_add_msa, 0, VPX_BITS_8),
make_tuple(&vp9_fdct32x32_rd_msa,
&vp9_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

@@ -57,6 +57,21 @@ 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
// Test VP9 codec controls after a decode error to ensure the code doesn't
// misbehave.
@@ -65,6 +80,7 @@ void TestVp9Controls(vpx_codec_ctx_t *dec) {
VP8D_GET_LAST_REF_UPDATES,
VP8D_GET_FRAME_CORRUPTED,
VP9D_GET_DISPLAY_SIZE,
VP9D_GET_FRAME_SIZE
};
int val[2];

View File

@@ -8,13 +8,17 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <string>
#include "test/codec_factory.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/md5_helper.h"
#include "test/util.h"
#include "test/webm_video_source.h"
#include "vpx_ports/vpx_timer.h"
#include "./ivfenc.h"
#include "./vpx_version.h"
using std::tr1::make_tuple;
@@ -24,7 +28,9 @@ namespace {
#define VIDEO_NAME 0
#define THREADS 1
const int kMaxPsnr = 100;
const double kUsecsInSec = 1000000.0;
const char kNewEncodeOutputFile[] = "new_encode.ivf";
/*
DecodePerfTest takes a tuple of filename + number of threads to decode with
@@ -105,4 +111,163 @@ TEST_P(DecodePerfTest, PerfTest) {
INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
::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

View File

@@ -65,7 +65,7 @@ void DecoderTest::HandlePeekResult(Decoder *const decoder,
void DecoderTest::RunLoop(CompressedVideoSource *video,
const vpx_codec_dec_cfg_t &dec_cfg) {
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, flags_, 0);
ASSERT_TRUE(decoder != NULL);
bool end_of_file = false;
@@ -110,4 +110,12 @@ void DecoderTest::RunLoop(CompressedVideoSource *video) {
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

View File

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

View File

@@ -7,6 +7,7 @@
* 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 "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "./vpx_version.h"
@@ -50,7 +51,8 @@ const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
};
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 12 };
const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8 };
const int kEncodePerfTestThreads[] = { 1, 2, 4 };
#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
@@ -63,7 +65,8 @@ class VP9EncodePerfTest
min_psnr_(kMaxPsnr),
nframes_(0),
encoding_mode_(GET_PARAM(1)),
speed_(0) {}
speed_(0),
threads_(1) {}
virtual ~VP9EncodePerfTest() {}
@@ -82,12 +85,18 @@ class VP9EncodePerfTest
cfg_.rc_buf_optimal_sz = 600;
cfg_.rc_resize_allowed = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_error_resilient = 1;
cfg_.g_threads = threads_;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
if (video->frame() == 0) {
const int log2_tile_columns = 3;
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);
}
}
@@ -113,54 +122,77 @@ class VP9EncodePerfTest
speed_ = speed;
}
void set_threads(unsigned int threads) {
threads_ = threads;
}
private:
double min_psnr_;
unsigned int nframes_;
libvpx_test::TestMode encoding_mode_;
unsigned speed_;
unsigned int threads_;
};
TEST_P(VP9EncodePerfTest, PerfTest) {
for (size_t i = 0; i < NELEMENTS(kVP9EncodePerfTestVectors); ++i) {
for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
SetUp();
for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
if (kVP9EncodePerfTestVectors[i].width < 512 &&
kEncodePerfTestThreads[k] > 1)
continue;
else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
kEncodePerfTestThreads[k] > 2)
continue;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
set_threads(kEncodePerfTestThreads[k]);
SetUp();
init_flags_ = VPX_CODEC_USE_PSNR;
const vpx_rational timebase = { 33333333, 1000000000 };
cfg_.g_timebase = timebase;
cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
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]);
init_flags_ = VPX_CODEC_USE_PSNR;
vpx_usec_timer t;
vpx_usec_timer_start(&t);
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]);
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
vpx_usec_timer t;
vpx_usec_timer_start(&t);
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();
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
printf("{\n");
printf("\t\"type\" : \"encode_perf_test\",\n");
printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
printf("\t\"videoName\" : \"%s\",\n", video_name);
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("}\n");
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();
std::string display_name(video_name);
if (kEncodePerfTestThreads[k] > 1) {
char thread_count[32];
snprintf(thread_count, sizeof(thread_count), "_t-%d",
kEncodePerfTestThreads[k]);
display_name += thread_count;
}
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,6 +8,8 @@
* 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/encode_test_driver.h"
@@ -17,6 +19,38 @@
#include "third_party/googletest/src/include/gtest/gtest.h"
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_VP8_ENCODER
ASSERT_EQ(&vpx_codec_vp8_cx_algo, CodecInterface())
<< "Unknown Codec Interface";
#endif
}
}
}
void Encoder::EncodeFrame(VideoSource *video, const unsigned long frame_flags) {
if (video->img())
EncodeFrameInternal(*video, frame_flags);
@@ -39,17 +73,6 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
vpx_codec_err_t res;
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
if (cfg_.g_w != img->d_w || cfg_.g_h != img->d_h) {
cfg_.g_w = img->d_w;
@@ -60,8 +83,7 @@ void Encoder::EncodeFrameInternal(const VideoSource &video,
// Encode the frame
API_REGISTER_STATE_CHECK(
res = vpx_codec_encode(&encoder_,
video.img(), video.pts(), video.duration(),
res = vpx_codec_encode(&encoder_, img, video.pts(), video.duration(),
frame_flags, deadline_));
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
@@ -77,6 +99,7 @@ void Encoder::Flush() {
void EncoderTest::InitializeConfig() {
const vpx_codec_err_t res = codec_->DefaultEncoderConfig(&cfg_, 0);
dec_cfg_ = vpx_codec_dec_cfg_t();
ASSERT_EQ(VPX_CODEC_OK, res);
}
@@ -142,12 +165,6 @@ void EncoderTest::MismatchHook(const vpx_image_t* /*img1*/,
void EncoderTest::RunLoop(VideoSource *video) {
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
#if CONFIG_ROW_TILE
// Decode all tiles.
dec_cfg.tile_col = -1;
dec_cfg.tile_row = -1;
#endif // CONFIG_ROW_TILE
stats_.Reset();
ASSERT_TRUE(passes_ == 1 || passes_ == 2);
@@ -165,9 +182,18 @@ void EncoderTest::RunLoop(VideoSource *video) {
Encoder* const encoder = codec_->CreateEncoder(cfg_, deadline_, init_flags_,
&stats_);
ASSERT_TRUE(encoder != NULL);
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
video->Begin();
encoder->InitEncoder(video);
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;
for (again = true, video->Begin(); again; video->Next()) {
for (again = true; again; video->Next()) {
again = (video->img() != NULL);
PreEncodeFrameHook(video);
@@ -207,6 +233,13 @@ 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) {
const vpx_image_t *img_enc = encoder->GetPreviewFrame();
DxDataIterator dec_iter = decoder->GetDxData();

View File

@@ -104,6 +104,8 @@ class Encoder {
return CxDataIterator(&encoder_);
}
void InitEncoder(VideoSource *video);
const vpx_image_t *GetPreviewFrame() {
return vpx_codec_get_preview_frame(&encoder_);
}
@@ -126,6 +128,15 @@ class Encoder {
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
}
void Control(int ctrl_id, struct vpx_svc_layer_id *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_svc_parameters *arg) {
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
void Control(int ctrl_id, vpx_active_map_t *arg) {
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
@@ -133,6 +144,12 @@ class Encoder {
}
#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) {
deadline_ = deadline;
}
@@ -170,7 +187,10 @@ class EncoderTest {
protected:
explicit EncoderTest(const CodecFactory *codec)
: 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() {}
@@ -180,6 +200,11 @@ class EncoderTest {
// Map the TestMode enum to the deadline_ and passes_ variables.
void SetMode(TestMode mode);
// Set encoder flag.
void set_init_flags(unsigned long flag) { // NOLINT(runtime/int)
init_flags_ = flag;
}
// Main loop
virtual void RunLoop(VideoSource *video);
@@ -233,6 +258,7 @@ class EncoderTest {
bool abort_;
vpx_codec_enc_cfg_t cfg_;
vpx_codec_dec_cfg_t dec_cfg_;
unsigned int passes_;
unsigned long deadline_;
TwopassStatsStore stats_;

View File

@@ -37,6 +37,7 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
void Reset() {
error_nframes_ = 0;
droppable_nframes_ = 0;
pattern_switch_ = 0;
}
virtual void SetUp() {
@@ -56,22 +57,77 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
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 |
VP8_EFLAG_NO_UPD_GF |
VP8_EFLAG_NO_UPD_ARF);
if (droppable_nframes_ > 0 &&
(cfg_.g_pass == VPX_RC_LAST_PASS || cfg_.g_pass == VPX_RC_ONE_PASS)) {
// For temporal layer case.
if (cfg_.ts_number_layers > 1) {
frame_flags_ = SetFrameFlags(video->frame(),
cfg_.ts_number_layers,
pattern_switch_);
for (unsigned int i = 0; i < droppable_nframes_; ++i) {
if (droppable_frames_[i] == video->frame()) {
std::cout << " Encoding droppable 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;
}
}
} 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;
}
}
}
}
}
@@ -133,11 +189,16 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
return mismatch_nframes_;
}
void SetPatternSwitch(int frame_switch) {
pattern_switch_ = frame_switch;
}
private:
double psnr_;
unsigned int nframes_;
unsigned int error_nframes_;
unsigned int droppable_nframes_;
unsigned int pattern_switch_;
double mismatch_psnr_;
unsigned int mismatch_nframes_;
unsigned int error_frames_[kMaxErrorFrames];
@@ -236,7 +297,290 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
#endif
}
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
// Check for successful decoding and no encoder/decoder mismatch
// if we lose (i.e., drop before decoding) the enhancement layer frames for a
// two layer temporal pattern. The base layer does not predict from the top
// layer, so successful decoding is expected.
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
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) {
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);
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
ONE_PASS_TEST_MODES);
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
} // namespace

View File

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

View File

@@ -22,6 +22,7 @@
#include "vp9/common/vp9_entropy.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom;
@@ -84,8 +85,8 @@ void idct4x4_10_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) {
vp9_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
}
#endif
#endif
#endif // HAVE_SSE2
#endif // CONFIG_VP9_HIGHBITDEPTH
class Trans4x4TestBase {
public:
@@ -102,13 +103,13 @@ class Trans4x4TestBase {
int64_t total_error = 0;
const int count_test_block = 10000;
for (int i = 0; i < count_test_block; ++i) {
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
#endif
// Initialize a test block with input range [-255, 255].
@@ -142,6 +143,7 @@ class Trans4x4TestBase {
const uint32_t diff =
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
ASSERT_EQ(VPX_BITS_8, bit_depth_);
const uint32_t diff = dst[j] - src[j];
#endif
const uint32_t error = diff * diff;
@@ -163,9 +165,9 @@ class Trans4x4TestBase {
void RunCoeffCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 5000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_].
@@ -184,15 +186,13 @@ class Trans4x4TestBase {
void RunMemCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 5000;
DECLARE_ALIGNED_ARRAY(16, int16_t, input_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_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
// Initialize a test block with input range [-mask_, mask_].
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_;
}
if (i == 0) {
@@ -219,13 +219,13 @@ class Trans4x4TestBase {
void RunInvAccuracyCheck(int limit) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
#endif
for (int i = 0; i < count_test_block; ++i) {
@@ -426,7 +426,7 @@ INSTANTIATE_TEST_CASE_P(
C, Trans4x4DCT,
::testing::Values(
make_tuple(&vp9_fdct4x4_c, &vp9_idct4x4_16_add_c, 0, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
@@ -452,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, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
@@ -466,7 +466,7 @@ INSTANTIATE_TEST_CASE_P(
C, Trans4x4WHT,
::testing::Values(
make_tuple(&vp9_fwht4x4_c, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -474,14 +474,17 @@ INSTANTIATE_TEST_CASE_P(
::testing::Values(
make_tuple(&vp9_fdct4x4_c,
&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(
DISABLED_NEON, Trans4x4HT,
NEON, Trans4x4HT,
::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, 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, 3, VPX_BITS_8)));
#endif
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
@@ -504,7 +507,7 @@ 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, 2, VPX_BITS_8),
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 3, VPX_BITS_8)));
#endif
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -532,5 +535,19 @@ INSTANTIATE_TEST_CASE_P(
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, 3, VPX_BITS_8)));
#endif
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, Trans4x4DCT,
::testing::Values(
make_tuple(&vp9_fdct4x4_msa, &vp9_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

View File

@@ -20,11 +20,32 @@
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_scan.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
#include "vpx_ports/mem.h"
using libvpx_test::ACMRandom;
namespace {
const int kNumCoeffs = 64;
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) {
const double kInvSqrt2 = 0.707106781186547524400844362104;
for (int k = 0; k < 8; k++) {
@@ -59,19 +80,6 @@ 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) {
vp9_fdct8x8_c(in, out, stride);
@@ -122,8 +130,8 @@ void idct8x8_64_add_10_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) {
vp9_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
}
#endif
#endif
#endif // HAVE_SSE2
#endif // CONFIG_VP9_HIGHBITDEPTH
class FwdTrans8x8TestBase {
public:
@@ -135,8 +143,8 @@ class FwdTrans8x8TestBase {
void RunSignBiasCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_output_block, 64);
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
DECLARE_ALIGNED(16, tran_low_t, test_output_block[64]);
int count_sign_block[64][2];
const int count_test_block = 100000;
@@ -160,7 +168,7 @@ class FwdTrans8x8TestBase {
for (int j = 0; j < 64; ++j) {
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
const int max_diff = 1125;
const int max_diff = kSignBiasMaxDiff255;
EXPECT_LT(diff, max_diff << (bit_depth_ - 8))
<< "Error: 8x8 FDCT/FHT has a sign bias > "
<< 1. * max_diff / count_test_block * 100 << "%"
@@ -173,7 +181,7 @@ class FwdTrans8x8TestBase {
memset(count_sign_block, 0, sizeof(count_sign_block));
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)
test_input_block[j] = ((rnd.Rand16() & mask_) >> 4) -
((rnd.Rand16() & mask_) >> 4);
@@ -190,9 +198,9 @@ class FwdTrans8x8TestBase {
for (int j = 0; j < 64; ++j) {
const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
const int max_diff = 10000;
const int max_diff = kSignBiasMaxDiff15;
EXPECT_LT(diff, max_diff << (bit_depth_ - 8))
<< "Error: 4x4 FDCT/FHT has a sign bias > "
<< "Error: 8x8 FDCT/FHT has a sign bias > "
<< 1. * max_diff / count_test_block * 100 << "%"
<< " for input range [-15, 15] at index " << j
<< " count0: " << count_sign_block[j][0]
@@ -206,13 +214,13 @@ class FwdTrans8x8TestBase {
int max_error = 0;
int total_error = 0;
const int count_test_block = 100000;
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
DECLARE_ALIGNED(16, uint8_t, dst[64]);
DECLARE_ALIGNED(16, uint8_t, src[64]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64);
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
DECLARE_ALIGNED(16, uint16_t, src16[64]);
#endif
for (int i = 0; i < count_test_block; ++i) {
@@ -283,14 +291,14 @@ class FwdTrans8x8TestBase {
int total_error = 0;
int total_coeff_error = 0;
const int count_test_block = 100000;
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_temp_block, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]);
DECLARE_ALIGNED(16, uint8_t, dst[64]);
DECLARE_ALIGNED(16, uint8_t, src[64]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64);
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64);
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
DECLARE_ALIGNED(16, uint16_t, src16[64]);
#endif
for (int i = 0; i < count_test_block; ++i) {
@@ -372,13 +380,13 @@ class FwdTrans8x8TestBase {
void RunInvAccuracyCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
#endif
for (int i = 0; i < count_test_block; ++i) {
@@ -430,9 +438,9 @@ class FwdTrans8x8TestBase {
void RunFwdAccuracyCheck() {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 1000;
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_r, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, coeff_r[kNumCoeffs]);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
for (int i = 0; i < count_test_block; ++i) {
double out_r[kNumCoeffs];
@@ -460,12 +468,12 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = 10000;
const int eob = 12;
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
#endif
const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan;
@@ -620,8 +628,8 @@ class InvTrans8x8DCT
virtual void SetUp() {
ref_txfm_ = GET_PARAM(0);
inv_txfm_ = GET_PARAM(1);
thresh_ = GET_PARAM(2);
pitch_ = 8;
thresh_ = GET_PARAM(2);
pitch_ = 8;
bit_depth_ = GET_PARAM(3);
mask_ = (1 << bit_depth_) - 1;
}
@@ -649,20 +657,21 @@ using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12),
make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
#else
INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8HT,
::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, 1, VPX_BITS_10),
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
@@ -671,11 +680,12 @@ INSTANTIATE_TEST_CASE_P(
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, 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, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
#else
// TODO(jingning): re-enable after this handles the expanded range [0, 65535]
// returned from Rand16().
INSTANTIATE_TEST_CASE_P(
C, FwdTrans8x8HT,
::testing::Values(
@@ -683,24 +693,31 @@ 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, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
// TODO(jingning): re-enable after this handles the expanded range [0, 65535]
// returned from Rand16().
INSTANTIATE_TEST_CASE_P(
NEON, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vp9_fdct8x8_neon, &vp9_idct8x8_64_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(
DISABLED_NEON, FwdTrans8x8HT,
NEON, FwdTrans8x8HT,
::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, 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, 3, VPX_BITS_8)));
#endif
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
// TODO(jingning): re-enable after these handle the expanded range [0, 65535]
// returned from Rand16().
INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8DCT,
::testing::Values(
@@ -713,12 +730,13 @@ 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, 2, VPX_BITS_8),
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8)));
#endif
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8),
make_tuple(&vp9_highbd_fdct8x8_c,
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
make_tuple(&vp9_highbd_fdct8x8_sse2,
@@ -726,10 +744,10 @@ INSTANTIATE_TEST_CASE_P(
make_tuple(&vp9_highbd_fdct8x8_c,
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
make_tuple(&vp9_highbd_fdct8x8_sse2,
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
// TODO(jingning): re-enable after these handle the expanded range [0, 65535]
// returned from Rand16().
INSTANTIATE_TEST_CASE_P(
SSE2, FwdTrans8x8HT,
::testing::Values(
@@ -751,15 +769,30 @@ INSTANTIATE_TEST_CASE_P(
&idct8x8_10_add_12_sse2, 6225, VPX_BITS_12),
make_tuple(&idct8x8_12,
&idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
#endif
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
!CONFIG_EMULATE_HARDWARE
// TODO(jingning): re-enable after this handles the expanded range [0, 65535]
// returned from Rand16().
INSTANTIATE_TEST_CASE_P(
SSSE3, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vp9_fdct8x8_ssse3, &vp9_idct8x8_64_add_ssse3, 0,
VPX_BITS_8)));
#endif
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
MSA, FwdTrans8x8DCT,
::testing::Values(
make_tuple(&vp9_fdct8x8_msa, &vp9_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

View File

@@ -121,6 +121,8 @@ const DecodeParam kVP9InvalidFileTests[] = {
{1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.v2.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-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,
@@ -151,6 +153,7 @@ const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
{4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
{4, "invalid-"
"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"},
{4, "invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.v2.ivf"},
};

View File

@@ -21,10 +21,9 @@
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/common/vp9_loopfilter.h"
#include "vpx/vpx_integer.h"
#define MAX_LOOP_FILTER 63
using libvpx_test::ACMRandom;
namespace {
@@ -53,7 +52,7 @@ typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
const uint8_t *thresh1);
#endif // CONFIG_VP9_HIGHBITDEPTH
typedef std::tr1::tuple<loop_op_t, loop_op_t, int> loop8_param_t;
typedef std::tr1::tuple<loop_op_t, loop_op_t, int, int> loop8_param_t;
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
#if HAVE_SSE2
@@ -108,6 +107,50 @@ void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
#endif // CONFIG_VP9_HIGHBITDEPTH
#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) {
vp9_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) {
vp9_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) {
vp9_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) {
vp9_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) {
vp9_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) {
vp9_lpf_vertical_16_c(s, p, blimit, limit, thresh);
}
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
public:
virtual ~Loop8Test6Param() {}
@@ -115,6 +158,7 @@ class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
loopfilter_op_ = GET_PARAM(0);
ref_loopfilter_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
count_ = GET_PARAM(3);
mask_ = (1 << bit_depth_) - 1;
}
@@ -122,6 +166,7 @@ class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
protected:
int bit_depth_;
int count_;
int mask_;
loop_op_t loopfilter_op_;
loop_op_t ref_loopfilter_op_;
@@ -151,29 +196,22 @@ TEST_P(Loop8Test6Param, OperationCheck) {
const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH
int32_t bd = bit_depth_;
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
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 = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -184,7 +222,6 @@ TEST_P(Loop8Test6Param, OperationCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
int32_t p = kNumCoeffs/32;
int count = 1;
uint16_t tmp_s[kNumCoeffs];
int j = 0;
@@ -216,13 +253,13 @@ TEST_P(Loop8Test6Param, OperationCheck) {
ref_s[j] = s[j];
}
#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(
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
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(
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
for (int j = 0; j < kNumCoeffs; ++j) {
@@ -244,29 +281,35 @@ TEST_P(Loop8Test6Param, ValueCheck) {
const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_;
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
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) {
int err_count = 0;
uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
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 = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t, limit[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -277,19 +320,18 @@ TEST_P(Loop8Test6Param, ValueCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
int32_t p = kNumCoeffs / 32;
int count = 1;
for (int j = 0; j < kNumCoeffs; ++j) {
s[j] = rnd.Rand16() & mask_;
ref_s[j] = s[j];
}
#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(
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
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(
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
for (int j = 0; j < kNumCoeffs; ++j) {
err_count += ref_s[j] != s[j];
@@ -310,30 +352,22 @@ TEST_P(Loop8Test9Param, OperationCheck) {
const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH
const int32_t bd = bit_depth_;
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
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 = rnd.Rand8();
// lim <= MAX_LOOP_FILTER
while (tmp > MAX_LOOP_FILTER) {
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -343,19 +377,12 @@ TEST_P(Loop8Test9Param, OperationCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
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 = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -427,29 +454,22 @@ TEST_P(Loop8Test9Param, ValueCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
const int count_test_block = number_of_iterations;
#if CONFIG_VP9_HIGHBITDEPTH
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
#else
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
#endif // CONFIG_VP9_HIGHBITDEPTH
int err_count_total = 0;
int first_failure = -1;
for (int i = 0; i < count_test_block; ++i) {
int err_count = 0;
uint8_t tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
uint8_t tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
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 = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t, limit0[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -459,19 +479,12 @@ TEST_P(Loop8Test9Param, ValueCheck) {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
};
tmp = rnd.Rand8();
// mblim <= 3 * MAX_LOOP_FILTER + 4
while (tmp > 3 * MAX_LOOP_FILTER + 4) {
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(3 * MAX_LOOP_FILTER + 4));
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 = rnd.Rand8();
while (tmp > MAX_LOOP_FILTER) { // lim <= MAX_LOOP_FILTER
tmp = rnd.Rand8();
}
tmp = static_cast<uint8_t>(rnd(MAX_LOOP_FILTER));
DECLARE_ALIGNED(16, const uint8_t, limit1[16]) = {
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp,
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
@@ -519,77 +532,81 @@ using std::tr1::make_tuple;
#if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE_SINGLE, Loop8Test6Param,
SSE2, Loop8Test6Param,
::testing::Values(
make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
&vp9_highbd_lpf_horizontal_4_c, 8),
&vp9_highbd_lpf_horizontal_4_c, 8, 1),
make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
&vp9_highbd_lpf_vertical_4_c, 8),
&vp9_highbd_lpf_vertical_4_c, 8, 1),
make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
&vp9_highbd_lpf_horizontal_8_c, 8),
&vp9_highbd_lpf_horizontal_8_c, 8, 1),
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vp9_highbd_lpf_horizontal_16_c, 8),
&vp9_highbd_lpf_horizontal_16_c, 8, 1),
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vp9_highbd_lpf_horizontal_16_c, 8, 2),
make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
&vp9_highbd_lpf_vertical_8_c, 8),
&vp9_highbd_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 8),
&wrapper_vertical_16_c, 8, 1),
make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
&vp9_highbd_lpf_horizontal_4_c, 10),
&vp9_highbd_lpf_horizontal_4_c, 10, 1),
make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
&vp9_highbd_lpf_vertical_4_c, 10),
&vp9_highbd_lpf_vertical_4_c, 10, 1),
make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
&vp9_highbd_lpf_horizontal_8_c, 10),
&vp9_highbd_lpf_horizontal_8_c, 10, 1),
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vp9_highbd_lpf_horizontal_16_c, 10),
&vp9_highbd_lpf_horizontal_16_c, 10, 1),
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vp9_highbd_lpf_horizontal_16_c, 10, 2),
make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
&vp9_highbd_lpf_vertical_8_c, 10),
&vp9_highbd_lpf_vertical_8_c, 10, 1),
make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 10),
&wrapper_vertical_16_c, 10, 1),
make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
&vp9_highbd_lpf_horizontal_4_c, 12),
&vp9_highbd_lpf_horizontal_4_c, 12, 1),
make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
&vp9_highbd_lpf_vertical_4_c, 12),
&vp9_highbd_lpf_vertical_4_c, 12, 1),
make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
&vp9_highbd_lpf_horizontal_8_c, 12),
&vp9_highbd_lpf_horizontal_8_c, 12, 1),
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vp9_highbd_lpf_horizontal_16_c, 12),
&vp9_highbd_lpf_horizontal_16_c, 12, 1),
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
&vp9_highbd_lpf_horizontal_16_c, 12, 2),
make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
&vp9_highbd_lpf_vertical_8_c, 12),
&vp9_highbd_lpf_vertical_8_c, 12, 1),
make_tuple(&wrapper_vertical_16_sse2,
&wrapper_vertical_16_c, 12)));
&wrapper_vertical_16_c, 12, 1),
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
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE_SINGLE, Loop8Test6Param,
SSE2, Loop8Test6Param,
::testing::Values(
make_tuple(&vp9_lpf_horizontal_8_sse2, &vp9_lpf_horizontal_8_c, 8),
make_tuple(&vp9_lpf_horizontal_16_sse2, &vp9_lpf_horizontal_16_c, 8),
make_tuple(&vp9_lpf_vertical_8_sse2, &vp9_lpf_vertical_8_c, 8)));
make_tuple(&vp9_lpf_horizontal_8_sse2, &vp9_lpf_horizontal_8_c, 8, 1),
make_tuple(&vp9_lpf_horizontal_16_sse2, &vp9_lpf_horizontal_16_c, 8, 1),
make_tuple(&vp9_lpf_horizontal_16_sse2, &vp9_lpf_horizontal_16_c, 8, 2),
make_tuple(&vp9_lpf_vertical_8_sse2, &vp9_lpf_vertical_8_c, 8, 1),
make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8, 1)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
INSTANTIATE_TEST_CASE_P(
AVX2, Loop8Test6Param,
::testing::Values(
make_tuple(&vp9_lpf_horizontal_16_avx2, &vp9_lpf_horizontal_16_c, 8, 1),
make_tuple(&vp9_lpf_horizontal_16_avx2, &vp9_lpf_horizontal_16_c, 8,
2)));
#endif
#if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE_DUAL, Loop8Test6Param,
::testing::Values(
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 8),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 10),
make_tuple(&wrapper_vertical_16_dual_sse2,
&wrapper_vertical_16_dual_c, 12)));
#else
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE_DUAL, Loop8Test6Param,
::testing::Values(
make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_SSE2
#if HAVE_SSE2
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSE_C_COMPARE_DUAL, Loop8Test9Param,
SSE2, Loop8Test9Param,
::testing::Values(
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
&vp9_highbd_lpf_horizontal_4_dual_c, 8),
@@ -617,7 +634,7 @@ INSTANTIATE_TEST_CASE_P(
&vp9_highbd_lpf_vertical_8_dual_c, 12)));
#else
INSTANTIATE_TEST_CASE_P(
SSE_C_COMPARE_DUAL, Loop8Test9Param,
SSE2, Loop8Test9Param,
::testing::Values(
make_tuple(&vp9_lpf_horizontal_4_dual_sse2,
&vp9_lpf_horizontal_4_dual_c, 8),
@@ -629,4 +646,71 @@ INSTANTIATE_TEST_CASE_P(
&vp9_lpf_vertical_8_dual_c, 8)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#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(&vp9_lpf_horizontal_16_neon,
&vp9_lpf_horizontal_16_c, 8, 1),
make_tuple(&vp9_lpf_horizontal_16_neon,
&vp9_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),
make_tuple(&vp9_lpf_horizontal_8_neon,
&vp9_lpf_horizontal_8_c, 8, 1),
make_tuple(&vp9_lpf_vertical_8_neon,
&vp9_lpf_vertical_8_c, 8, 1),
#endif // HAVE_NEON_ASM
make_tuple(&vp9_lpf_horizontal_4_neon,
&vp9_lpf_horizontal_4_c, 8, 1),
make_tuple(&vp9_lpf_vertical_4_neon,
&vp9_lpf_vertical_4_c, 8, 1)));
INSTANTIATE_TEST_CASE_P(
NEON, Loop8Test9Param,
::testing::Values(
#if HAVE_NEON_ASM
make_tuple(&vp9_lpf_horizontal_8_dual_neon,
&vp9_lpf_horizontal_8_dual_c, 8),
make_tuple(&vp9_lpf_vertical_8_dual_neon,
&vp9_lpf_vertical_8_dual_c, 8),
#endif // HAVE_NEON_ASM
make_tuple(&vp9_lpf_horizontal_4_dual_neon,
&vp9_lpf_horizontal_4_dual_c, 8),
make_tuple(&vp9_lpf_vertical_4_dual_neon,
&vp9_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(&vp9_lpf_horizontal_8_msa, &vp9_lpf_horizontal_8_c, 8, 1),
make_tuple(&vp9_lpf_horizontal_16_msa, &vp9_lpf_horizontal_16_c, 8, 1),
make_tuple(&vp9_lpf_horizontal_16_msa, &vp9_lpf_horizontal_16_c, 8, 2),
make_tuple(&vp9_lpf_vertical_8_msa, &vp9_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(&vp9_lpf_horizontal_4_dual_msa,
&vp9_lpf_horizontal_4_dual_c, 8),
make_tuple(&vp9_lpf_horizontal_8_dual_msa,
&vp9_lpf_horizontal_8_dual_c, 8),
make_tuple(&vp9_lpf_vertical_4_dual_msa,
&vp9_lpf_vertical_4_dual_c, 8),
make_tuple(&vp9_lpf_vertical_8_dual_msa,
&vp9_lpf_vertical_8_dual_c, 8)));
#endif // HAVE_MSA && (!CONFIG_VP9_HIGHBITDEPTH)
} // namespace

View File

@@ -1,209 +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 <string.h>
#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 {
const int number_of_iterations = 500;
typedef unsigned int (*MaskedSADFunc)(const uint8_t *a, int a_stride,
const uint8_t *b, int b_stride,
const uint8_t *m, int m_stride);
typedef std::tr1::tuple<MaskedSADFunc, MaskedSADFunc> MaskedSADParam;
class MaskedSADTest : public ::testing::TestWithParam<MaskedSADParam> {
public:
virtual ~MaskedSADTest() {}
virtual void SetUp() {
maskedSAD_op_ = GET_PARAM(0);
ref_maskedSAD_op_ = GET_PARAM(1);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
MaskedSADFunc maskedSAD_op_;
MaskedSADFunc ref_maskedSAD_op_;
};
TEST_P(MaskedSADTest, OperationCheck) {
unsigned int ref_ret, ret;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint8_t, src_ptr, 4096);
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref_ptr, 4096);
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, 4096);
int err_count = 0;
int first_failure = -1;
int src_stride = 64;
int ref_stride = 64;
int msk_stride = 64;
for (int i = 0; i < number_of_iterations; ++i) {
for (int j = 0; j < 4096; j++) {
src_ptr[j] = rnd.Rand8();
ref_ptr[j] = rnd.Rand8();
msk_ptr[j] = ((rnd.Rand8()&0x7f) > 64) ? rnd.Rand8()&0x3f : 64;
}
ref_ret = ref_maskedSAD_op_(src_ptr, src_stride, ref_ptr, ref_stride,
msk_ptr, msk_stride);
ASM_REGISTER_STATE_CHECK(ret = maskedSAD_op_(src_ptr, src_stride,
ref_ptr, ref_stride,
msk_ptr, msk_stride));
if (ret != ref_ret) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked SAD Test, C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
#if CONFIG_VP9_HIGHBITDEPTH
typedef unsigned int (*HighbdMaskedSADFunc)(const uint8_t *a, int a_stride,
const uint8_t *b, int b_stride,
const uint8_t *m, int m_stride);
typedef std::tr1::tuple<HighbdMaskedSADFunc, HighbdMaskedSADFunc>
HighbdMaskedSADParam;
class HighbdMaskedSADTest : public ::testing::
TestWithParam<HighbdMaskedSADParam> {
public:
virtual ~HighbdMaskedSADTest() {}
virtual void SetUp() {
maskedSAD_op_ = GET_PARAM(0);
ref_maskedSAD_op_ = GET_PARAM(1);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
HighbdMaskedSADFunc maskedSAD_op_;
HighbdMaskedSADFunc ref_maskedSAD_op_;
};
TEST_P(HighbdMaskedSADTest, OperationCheck) {
unsigned int ref_ret, ret;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint16_t, src_ptr, 4096);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_ptr, 4096);
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, 4096);
uint8_t* src8_ptr = CONVERT_TO_BYTEPTR(src_ptr);
uint8_t* ref8_ptr = CONVERT_TO_BYTEPTR(ref_ptr);
int err_count = 0;
int first_failure = -1;
int src_stride = 64;
int ref_stride = 64;
int msk_stride = 64;
for (int i = 0; i < number_of_iterations; ++i) {
for (int j = 0; j < 4096; j++) {
src_ptr[j] = rnd.Rand16()&0xfff;
ref_ptr[j] = rnd.Rand16()&0xfff;
msk_ptr[j] = ((rnd.Rand8()&0x7f) > 64) ? rnd.Rand8()&0x3f : 64;
}
ref_ret = ref_maskedSAD_op_(src8_ptr, src_stride, ref8_ptr, ref_stride,
msk_ptr, msk_stride);
ASM_REGISTER_STATE_CHECK(ret = maskedSAD_op_(src8_ptr, src_stride,
ref8_ptr, ref_stride,
msk_ptr, msk_stride));
if (ret != ref_ret) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
EXPECT_EQ(0, err_count)
<< "Error: High BD Masked SAD Test, C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
#endif // CONFIG_VP9_HIGHBITDEPTH
using std::tr1::make_tuple;
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(
SSSE3_C_COMPARE, MaskedSADTest,
::testing::Values(
make_tuple(&vp9_masked_sad64x64_ssse3,
&vp9_masked_sad64x64_c),
make_tuple(&vp9_masked_sad64x32_ssse3,
&vp9_masked_sad64x32_c),
make_tuple(&vp9_masked_sad32x64_ssse3,
&vp9_masked_sad32x64_c),
make_tuple(&vp9_masked_sad32x32_ssse3,
&vp9_masked_sad32x32_c),
make_tuple(&vp9_masked_sad32x16_ssse3,
&vp9_masked_sad32x16_c),
make_tuple(&vp9_masked_sad16x32_ssse3,
&vp9_masked_sad16x32_c),
make_tuple(&vp9_masked_sad16x16_ssse3,
&vp9_masked_sad16x16_c),
make_tuple(&vp9_masked_sad16x8_ssse3,
&vp9_masked_sad16x8_c),
make_tuple(&vp9_masked_sad8x16_ssse3,
&vp9_masked_sad8x16_c),
make_tuple(&vp9_masked_sad8x8_ssse3,
&vp9_masked_sad8x8_c),
make_tuple(&vp9_masked_sad8x4_ssse3,
&vp9_masked_sad8x4_c),
make_tuple(&vp9_masked_sad4x8_ssse3,
&vp9_masked_sad4x8_c),
make_tuple(&vp9_masked_sad4x4_ssse3,
&vp9_masked_sad4x4_c)));
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSSE3_C_COMPARE, HighbdMaskedSADTest,
::testing::Values(
make_tuple(&vp9_highbd_masked_sad64x64_ssse3,
&vp9_highbd_masked_sad64x64_c),
make_tuple(&vp9_highbd_masked_sad64x32_ssse3,
&vp9_highbd_masked_sad64x32_c),
make_tuple(&vp9_highbd_masked_sad32x64_ssse3,
&vp9_highbd_masked_sad32x64_c),
make_tuple(&vp9_highbd_masked_sad32x32_ssse3,
&vp9_highbd_masked_sad32x32_c),
make_tuple(&vp9_highbd_masked_sad32x16_ssse3,
&vp9_highbd_masked_sad32x16_c),
make_tuple(&vp9_highbd_masked_sad16x32_ssse3,
&vp9_highbd_masked_sad16x32_c),
make_tuple(&vp9_highbd_masked_sad16x16_ssse3,
&vp9_highbd_masked_sad16x16_c),
make_tuple(&vp9_highbd_masked_sad16x8_ssse3,
&vp9_highbd_masked_sad16x8_c),
make_tuple(&vp9_highbd_masked_sad8x16_ssse3,
&vp9_highbd_masked_sad8x16_c),
make_tuple(&vp9_highbd_masked_sad8x8_ssse3,
&vp9_highbd_masked_sad8x8_c),
make_tuple(&vp9_highbd_masked_sad8x4_ssse3,
&vp9_highbd_masked_sad8x4_c),
make_tuple(&vp9_highbd_masked_sad4x8_ssse3,
&vp9_highbd_masked_sad4x8_c),
make_tuple(&vp9_highbd_masked_sad4x4_ssse3,
&vp9_highbd_masked_sad4x4_c)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_SSSE3
} // namespace

View File

@@ -1,753 +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 <string.h>
#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"
#include "vp9/common/vp9_filter.h"
#define MAX_SIZE 64
using libvpx_test::ACMRandom;
namespace {
const int number_of_iterations = 500;
typedef unsigned int (*MaskedVarianceFunc)(const uint8_t *a, int a_stride,
const uint8_t *b, int b_stride,
const uint8_t *m, int m_stride,
unsigned int *sse);
typedef std::tr1::tuple<MaskedVarianceFunc,
MaskedVarianceFunc> MaskedVarianceParam;
class MaskedVarianceTest :
public ::testing::TestWithParam<MaskedVarianceParam> {
public:
virtual ~MaskedVarianceTest() {}
virtual void SetUp() {
opt_func_ = GET_PARAM(0);
ref_func_ = GET_PARAM(1);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
MaskedVarianceFunc opt_func_;
MaskedVarianceFunc ref_func_;
};
TEST_P(MaskedVarianceTest, OperationCheck) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint8_t, src_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, MAX_SIZE*MAX_SIZE);
int err_count = 0;
int first_failure = -1;
int src_stride = MAX_SIZE;
int ref_stride = MAX_SIZE;
int msk_stride = MAX_SIZE;
for (int i = 0; i < number_of_iterations; ++i) {
for (int j = 0; j < MAX_SIZE*MAX_SIZE; j++) {
src_ptr[j] = rnd.Rand8();
ref_ptr[j] = rnd.Rand8();
msk_ptr[j] = rnd(65);
}
ref_ret = ref_func_(src_ptr, src_stride,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src_ptr, src_stride,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Variance Test OperationCheck,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
TEST_P(MaskedVarianceTest, ExtremeValues) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint8_t, src_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, MAX_SIZE*MAX_SIZE);
int err_count = 0;
int first_failure = -1;
int src_stride = MAX_SIZE;
int ref_stride = MAX_SIZE;
int msk_stride = MAX_SIZE;
for (int i = 0; i < 8; ++i) {
memset(src_ptr, (i & 0x1) ? 255 : 0, MAX_SIZE*MAX_SIZE);
memset(ref_ptr, (i & 0x2) ? 255 : 0, MAX_SIZE*MAX_SIZE);
memset(msk_ptr, (i & 0x4) ? 64 : 0, MAX_SIZE*MAX_SIZE);
ref_ret = ref_func_(src_ptr, src_stride,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src_ptr, src_stride,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Variance Test ExtremeValues,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
typedef unsigned int (*MaskedSubPixelVarianceFunc)(
const uint8_t *a, int a_stride,
int xoffset, int yoffset,
const uint8_t *b, int b_stride,
const uint8_t *m, int m_stride,
unsigned int *sse);
typedef std::tr1::tuple<MaskedSubPixelVarianceFunc,
MaskedSubPixelVarianceFunc> MaskedSubPixelVarianceParam;
class MaskedSubPixelVarianceTest :
public ::testing::TestWithParam<MaskedSubPixelVarianceParam> {
public:
virtual ~MaskedSubPixelVarianceTest() {}
virtual void SetUp() {
opt_func_ = GET_PARAM(0);
ref_func_ = GET_PARAM(1);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
MaskedSubPixelVarianceFunc opt_func_;
MaskedSubPixelVarianceFunc ref_func_;
};
TEST_P(MaskedSubPixelVarianceTest, OperationCheck) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint8_t, src_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
int err_count = 0;
int first_failure = -1;
int src_stride = (MAX_SIZE+1);
int ref_stride = (MAX_SIZE+1);
int msk_stride = (MAX_SIZE+1);
int xoffset;
int yoffset;
for (int i = 0; i < number_of_iterations; ++i) {
int xoffsets[] = {0, 8, rnd(SUBPEL_SHIFTS)};
int yoffsets[] = {0, 8, rnd(SUBPEL_SHIFTS)};
for (int j = 0; j < (MAX_SIZE+1)*(MAX_SIZE+1); j++) {
src_ptr[j] = rnd.Rand8();
ref_ptr[j] = rnd.Rand8();
msk_ptr[j] = rnd(65);
}
for (int k = 0; k < 3; k++) {
xoffset = xoffsets[k];
for (int l = 0; l < 3; l++) {
xoffset = xoffsets[k];
yoffset = yoffsets[l];
ref_ret = ref_func_(src_ptr, src_stride,
xoffset, yoffset,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src_ptr, src_stride,
xoffset, yoffset,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Sub Pixel Variance Test OperationCheck,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
TEST_P(MaskedSubPixelVarianceTest, ExtremeValues) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint8_t, src_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
int first_failure_x = -1;
int first_failure_y = -1;
int err_count = 0;
int first_failure = -1;
int src_stride = (MAX_SIZE+1);
int ref_stride = (MAX_SIZE+1);
int msk_stride = (MAX_SIZE+1);
for (int xoffset = 0 ; xoffset < SUBPEL_SHIFTS ; xoffset++) {
for (int yoffset = 0 ; yoffset < SUBPEL_SHIFTS ; yoffset++) {
for (int i = 0; i < 8; ++i) {
memset(src_ptr, (i & 0x1) ? 255 : 0, (MAX_SIZE+1)*(MAX_SIZE+1));
memset(ref_ptr, (i & 0x2) ? 255 : 0, (MAX_SIZE+1)*(MAX_SIZE+1));
memset(msk_ptr, (i & 0x4) ? 64 : 0, (MAX_SIZE+1)*(MAX_SIZE+1));
ref_ret = ref_func_(src_ptr, src_stride,
xoffset, yoffset,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src_ptr, src_stride,
xoffset, yoffset,
ref_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1) {
first_failure = i;
first_failure_x = xoffset;
first_failure_y = yoffset;
}
}
}
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Variance Test ExtremeValues,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure
<< " x_offset = " << first_failure_x
<< " y_offset = " << first_failure_y;
}
#if CONFIG_VP9_HIGHBITDEPTH
typedef std::tr1::tuple<MaskedVarianceFunc,
MaskedVarianceFunc,
vpx_bit_depth_t> HighbdMaskedVarianceParam;
class HighbdMaskedVarianceTest :
public ::testing::TestWithParam<HighbdMaskedVarianceParam> {
public:
virtual ~HighbdMaskedVarianceTest() {}
virtual void SetUp() {
opt_func_ = GET_PARAM(0);
ref_func_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
MaskedVarianceFunc opt_func_;
MaskedVarianceFunc ref_func_;
vpx_bit_depth_t bit_depth_;
};
TEST_P(HighbdMaskedVarianceTest, OperationCheck) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint16_t, src_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, MAX_SIZE*MAX_SIZE);
uint8_t* src8_ptr = CONVERT_TO_BYTEPTR(src_ptr);
uint8_t* ref8_ptr = CONVERT_TO_BYTEPTR(ref_ptr);
int err_count = 0;
int first_failure = -1;
int src_stride = MAX_SIZE;
int ref_stride = MAX_SIZE;
int msk_stride = MAX_SIZE;
for (int i = 0; i < number_of_iterations; ++i) {
for (int j = 0; j < MAX_SIZE*MAX_SIZE; j++) {
src_ptr[j] = rnd.Rand16() & ((1 << bit_depth_) - 1);
ref_ptr[j] = rnd.Rand16() & ((1 << bit_depth_) - 1);
msk_ptr[j] = rnd(65);
}
ref_ret = ref_func_(src8_ptr, src_stride,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src8_ptr, src_stride,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Variance Test OperationCheck,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
TEST_P(HighbdMaskedVarianceTest, ExtremeValues) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint16_t, src_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_ptr, MAX_SIZE*MAX_SIZE);
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, MAX_SIZE*MAX_SIZE);
uint8_t* src8_ptr = CONVERT_TO_BYTEPTR(src_ptr);
uint8_t* ref8_ptr = CONVERT_TO_BYTEPTR(ref_ptr);
int err_count = 0;
int first_failure = -1;
int src_stride = MAX_SIZE;
int ref_stride = MAX_SIZE;
int msk_stride = MAX_SIZE;
for (int i = 0; i < 8; ++i) {
vpx_memset16(src_ptr, (i & 0x1) ? ((1 << bit_depth_) - 1) : 0,
MAX_SIZE*MAX_SIZE);
vpx_memset16(ref_ptr, (i & 0x2) ? ((1 << bit_depth_) - 1) : 0,
MAX_SIZE*MAX_SIZE);
memset(msk_ptr, (i & 0x4) ? 64 : 0, MAX_SIZE*MAX_SIZE);
ref_ret = ref_func_(src8_ptr, src_stride,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src8_ptr, src_stride,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1)
first_failure = i;
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Variance Test ExtremeValues,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure;
}
typedef std::tr1::tuple<MaskedSubPixelVarianceFunc,
MaskedSubPixelVarianceFunc,
vpx_bit_depth_t> HighbdMaskedSubPixelVarianceParam;
class HighbdMaskedSubPixelVarianceTest :
public ::testing::TestWithParam<HighbdMaskedSubPixelVarianceParam> {
public:
virtual ~HighbdMaskedSubPixelVarianceTest() {}
virtual void SetUp() {
opt_func_ = GET_PARAM(0);
ref_func_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
MaskedSubPixelVarianceFunc opt_func_;
MaskedSubPixelVarianceFunc ref_func_;
vpx_bit_depth_t bit_depth_;
};
TEST_P(HighbdMaskedSubPixelVarianceTest, OperationCheck) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint16_t, src_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
uint8_t* src8_ptr = CONVERT_TO_BYTEPTR(src_ptr);
uint8_t* ref8_ptr = CONVERT_TO_BYTEPTR(ref_ptr);
int err_count = 0;
int first_failure = -1;
int first_failure_x = -1;
int first_failure_y = -1;
int src_stride = (MAX_SIZE+1);
int ref_stride = (MAX_SIZE+1);
int msk_stride = (MAX_SIZE+1);
int xoffset, yoffset;
for (int i = 0; i < number_of_iterations; ++i) {
for (xoffset = 0; xoffset < SUBPEL_SHIFTS; xoffset++) {
for (yoffset = 0; yoffset < SUBPEL_SHIFTS; yoffset++) {
for (int j = 0; j < (MAX_SIZE+1)*(MAX_SIZE+1); j++) {
src_ptr[j] = rnd.Rand16() & ((1 << bit_depth_) - 1);
ref_ptr[j] = rnd.Rand16() & ((1 << bit_depth_) - 1);
msk_ptr[j] = rnd(65);
}
ref_ret = ref_func_(src8_ptr, src_stride,
xoffset, yoffset,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src8_ptr, src_stride,
xoffset, yoffset,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1) {
first_failure = i;
first_failure_x = xoffset;
first_failure_y = yoffset;
}
}
}
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Sub Pixel Variance Test OperationCheck,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure
<< " x_offset = " << first_failure_x
<< " y_offset = " << first_failure_y;
}
TEST_P(HighbdMaskedSubPixelVarianceTest, ExtremeValues) {
unsigned int ref_ret, opt_ret;
unsigned int ref_sse, opt_sse;
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED_ARRAY(16, uint16_t, src_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
DECLARE_ALIGNED_ARRAY(16, uint8_t, msk_ptr, (MAX_SIZE+1)*(MAX_SIZE+1));
uint8_t* src8_ptr = CONVERT_TO_BYTEPTR(src_ptr);
uint8_t* ref8_ptr = CONVERT_TO_BYTEPTR(ref_ptr);
int first_failure_x = -1;
int first_failure_y = -1;
int err_count = 0;
int first_failure = -1;
int src_stride = (MAX_SIZE+1);
int ref_stride = (MAX_SIZE+1);
int msk_stride = (MAX_SIZE+1);
for (int xoffset = 0 ; xoffset < SUBPEL_SHIFTS ; xoffset++) {
for (int yoffset = 0 ; yoffset < SUBPEL_SHIFTS ; yoffset++) {
for (int i = 0; i < 8; ++i) {
vpx_memset16(src_ptr, (i & 0x1) ? ((1 << bit_depth_) - 1) : 0,
(MAX_SIZE+1)*(MAX_SIZE+1));
vpx_memset16(ref_ptr, (i & 0x2) ? ((1 << bit_depth_) - 1) : 0,
(MAX_SIZE+1)*(MAX_SIZE+1));
memset(msk_ptr, (i & 0x4) ? 64 : 0, (MAX_SIZE+1)*(MAX_SIZE+1));
ref_ret = ref_func_(src8_ptr, src_stride,
xoffset, yoffset,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&ref_sse);
ASM_REGISTER_STATE_CHECK(opt_ret = opt_func_(src8_ptr, src_stride,
xoffset, yoffset,
ref8_ptr, ref_stride,
msk_ptr, msk_stride,
&opt_sse));
if (opt_ret != ref_ret || opt_sse != ref_sse) {
err_count++;
if (first_failure == -1) {
first_failure = i;
first_failure_x = xoffset;
first_failure_y = yoffset;
}
}
}
}
}
EXPECT_EQ(0, err_count)
<< "Error: Masked Variance Test ExtremeValues,"
<< "C output doesn't match SSSE3 output. "
<< "First failed at test case " << first_failure
<< " x_offset = " << first_failure_x
<< " y_offset = " << first_failure_y;
}
#endif // CONFIG_VP9_HIGHBITDEPTH
using std::tr1::make_tuple;
#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(
SSSE3_C_COMPARE, MaskedVarianceTest,
::testing::Values(
make_tuple(&vp9_masked_variance64x64_ssse3,
&vp9_masked_variance64x64_c),
make_tuple(&vp9_masked_variance64x32_ssse3,
&vp9_masked_variance64x32_c),
make_tuple(&vp9_masked_variance32x64_ssse3,
&vp9_masked_variance32x64_c),
make_tuple(&vp9_masked_variance32x32_ssse3,
&vp9_masked_variance32x32_c),
make_tuple(&vp9_masked_variance32x16_ssse3,
&vp9_masked_variance32x16_c),
make_tuple(&vp9_masked_variance16x32_ssse3,
&vp9_masked_variance16x32_c),
make_tuple(&vp9_masked_variance16x16_ssse3,
&vp9_masked_variance16x16_c),
make_tuple(&vp9_masked_variance16x8_ssse3,
&vp9_masked_variance16x8_c),
make_tuple(&vp9_masked_variance8x16_ssse3,
&vp9_masked_variance8x16_c),
make_tuple(&vp9_masked_variance8x8_ssse3,
&vp9_masked_variance8x8_c),
make_tuple(&vp9_masked_variance8x4_ssse3,
&vp9_masked_variance8x4_c),
make_tuple(&vp9_masked_variance4x8_ssse3,
&vp9_masked_variance4x8_c),
make_tuple(&vp9_masked_variance4x4_ssse3,
&vp9_masked_variance4x4_c)));
INSTANTIATE_TEST_CASE_P(
SSSE3_C_COMPARE, MaskedSubPixelVarianceTest,
::testing::Values(
make_tuple(&vp9_masked_sub_pixel_variance64x64_ssse3,
&vp9_masked_sub_pixel_variance64x64_c),
make_tuple(&vp9_masked_sub_pixel_variance64x32_ssse3,
&vp9_masked_sub_pixel_variance64x32_c),
make_tuple(&vp9_masked_sub_pixel_variance32x64_ssse3,
&vp9_masked_sub_pixel_variance32x64_c),
make_tuple(&vp9_masked_sub_pixel_variance32x32_ssse3,
&vp9_masked_sub_pixel_variance32x32_c),
make_tuple(&vp9_masked_sub_pixel_variance32x16_ssse3,
&vp9_masked_sub_pixel_variance32x16_c),
make_tuple(&vp9_masked_sub_pixel_variance16x32_ssse3,
&vp9_masked_sub_pixel_variance16x32_c),
make_tuple(&vp9_masked_sub_pixel_variance16x16_ssse3,
&vp9_masked_sub_pixel_variance16x16_c),
make_tuple(&vp9_masked_sub_pixel_variance16x8_ssse3,
&vp9_masked_sub_pixel_variance16x8_c),
make_tuple(&vp9_masked_sub_pixel_variance8x16_ssse3,
&vp9_masked_sub_pixel_variance8x16_c),
make_tuple(&vp9_masked_sub_pixel_variance8x8_ssse3,
&vp9_masked_sub_pixel_variance8x8_c),
make_tuple(&vp9_masked_sub_pixel_variance8x4_ssse3,
&vp9_masked_sub_pixel_variance8x4_c),
make_tuple(&vp9_masked_sub_pixel_variance4x8_ssse3,
&vp9_masked_sub_pixel_variance4x8_c),
make_tuple(&vp9_masked_sub_pixel_variance4x4_ssse3,
&vp9_masked_sub_pixel_variance4x4_c)));
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
SSSE3_C_COMPARE, HighbdMaskedVarianceTest,
::testing::Values(
make_tuple(&vp9_highbd_masked_variance64x64_ssse3,
&vp9_highbd_masked_variance64x64_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance64x32_ssse3,
&vp9_highbd_masked_variance64x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance32x64_ssse3,
&vp9_highbd_masked_variance32x64_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance32x32_ssse3,
&vp9_highbd_masked_variance32x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance32x16_ssse3,
&vp9_highbd_masked_variance32x16_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance16x32_ssse3,
&vp9_highbd_masked_variance16x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance16x16_ssse3,
&vp9_highbd_masked_variance16x16_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance16x8_ssse3,
&vp9_highbd_masked_variance16x8_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance8x16_ssse3,
&vp9_highbd_masked_variance8x16_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance8x8_ssse3,
&vp9_highbd_masked_variance8x8_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance8x4_ssse3,
&vp9_highbd_masked_variance8x4_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance4x8_ssse3,
&vp9_highbd_masked_variance4x8_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_variance4x4_ssse3,
&vp9_highbd_masked_variance4x4_c, VPX_BITS_8),
make_tuple(&vp9_highbd_10_masked_variance64x64_ssse3,
&vp9_highbd_10_masked_variance64x64_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance64x32_ssse3,
&vp9_highbd_10_masked_variance64x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance32x64_ssse3,
&vp9_highbd_10_masked_variance32x64_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance32x32_ssse3,
&vp9_highbd_10_masked_variance32x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance32x16_ssse3,
&vp9_highbd_10_masked_variance32x16_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance16x32_ssse3,
&vp9_highbd_10_masked_variance16x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance16x16_ssse3,
&vp9_highbd_10_masked_variance16x16_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance16x8_ssse3,
&vp9_highbd_10_masked_variance16x8_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance8x16_ssse3,
&vp9_highbd_10_masked_variance8x16_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance8x8_ssse3,
&vp9_highbd_10_masked_variance8x8_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance8x4_ssse3,
&vp9_highbd_10_masked_variance8x4_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance4x8_ssse3,
&vp9_highbd_10_masked_variance4x8_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_variance4x4_ssse3,
&vp9_highbd_10_masked_variance4x4_c, VPX_BITS_10),
make_tuple(&vp9_highbd_12_masked_variance64x64_ssse3,
&vp9_highbd_12_masked_variance64x64_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance64x32_ssse3,
&vp9_highbd_12_masked_variance64x32_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance32x64_ssse3,
&vp9_highbd_12_masked_variance32x64_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance32x32_ssse3,
&vp9_highbd_12_masked_variance32x32_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance32x16_ssse3,
&vp9_highbd_12_masked_variance32x16_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance16x32_ssse3,
&vp9_highbd_12_masked_variance16x32_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance16x16_ssse3,
&vp9_highbd_12_masked_variance16x16_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance16x8_ssse3,
&vp9_highbd_12_masked_variance16x8_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance8x16_ssse3,
&vp9_highbd_12_masked_variance8x16_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance8x8_ssse3,
&vp9_highbd_12_masked_variance8x8_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance8x4_ssse3,
&vp9_highbd_12_masked_variance8x4_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance4x8_ssse3,
&vp9_highbd_12_masked_variance4x8_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_variance4x4_ssse3,
&vp9_highbd_12_masked_variance4x4_c, VPX_BITS_12)));
INSTANTIATE_TEST_CASE_P(
SSSE3_C_COMPARE, HighbdMaskedSubPixelVarianceTest,
::testing::Values(
make_tuple(&vp9_highbd_masked_sub_pixel_variance64x64_ssse3,
&vp9_highbd_masked_sub_pixel_variance64x64_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance64x32_ssse3,
&vp9_highbd_masked_sub_pixel_variance64x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance32x64_ssse3,
&vp9_highbd_masked_sub_pixel_variance32x64_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance32x32_ssse3,
&vp9_highbd_masked_sub_pixel_variance32x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance32x16_ssse3,
&vp9_highbd_masked_sub_pixel_variance32x16_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance16x32_ssse3,
&vp9_highbd_masked_sub_pixel_variance16x32_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance16x16_ssse3,
&vp9_highbd_masked_sub_pixel_variance16x16_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance16x8_ssse3,
&vp9_highbd_masked_sub_pixel_variance16x8_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance8x16_ssse3,
&vp9_highbd_masked_sub_pixel_variance8x16_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance8x8_ssse3,
&vp9_highbd_masked_sub_pixel_variance8x8_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance8x4_ssse3,
&vp9_highbd_masked_sub_pixel_variance8x4_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance4x8_ssse3,
&vp9_highbd_masked_sub_pixel_variance4x8_c, VPX_BITS_8),
make_tuple(&vp9_highbd_masked_sub_pixel_variance4x4_ssse3,
&vp9_highbd_masked_sub_pixel_variance4x4_c, VPX_BITS_8),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance64x64_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance64x64_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance64x32_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance64x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance32x64_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance32x64_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance32x32_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance32x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance32x16_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance32x16_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance16x32_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance16x32_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance16x16_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance16x16_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance16x8_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance16x8_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance8x16_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance8x16_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance8x8_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance8x8_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance8x4_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance8x4_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance4x8_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance4x8_c, VPX_BITS_10),
make_tuple(&vp9_highbd_10_masked_sub_pixel_variance4x4_ssse3,
&vp9_highbd_10_masked_sub_pixel_variance4x4_c, VPX_BITS_10),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance64x64_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance64x64_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance64x32_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance64x32_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance32x64_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance32x64_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance32x32_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance32x32_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance32x16_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance32x16_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance16x32_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance16x32_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance16x16_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance16x16_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance16x8_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance16x8_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance8x16_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance8x16_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance8x8_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance8x8_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance8x4_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance8x4_c, VPX_BITS_12) ,
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance4x8_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance4x8_c, VPX_BITS_12),
make_tuple(&vp9_highbd_12_masked_sub_pixel_variance4x4_ssse3,
&vp9_highbd_12_masked_sub_pixel_variance4x4_c, VPX_BITS_12)));
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // HAVE_SSSE3
} // namespace

View File

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

View File

@@ -74,16 +74,16 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block1, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block2, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
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_ARRAY(16, int16_t, input_extreme_block, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kMaxNumCoeffs);
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) {
@@ -153,10 +153,10 @@ TEST_P(PartialIDctTest, ResultsMatch) {
FAIL() << "Wrong Size!";
break;
}
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block1, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block2, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
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;
@@ -230,7 +230,7 @@ INSTANTIATE_TEST_CASE_P(
&vp9_idct4x4_1_add_c,
TX_4X4, 1)));
#if HAVE_NEON_ASM
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
NEON, PartialIDctTest,
::testing::Values(
@@ -258,7 +258,7 @@ INSTANTIATE_TEST_CASE_P(
&vp9_idct4x4_16_add_c,
&vp9_idct4x4_1_add_neon,
TX_4X4, 1)));
#endif
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
@@ -305,13 +305,38 @@ INSTANTIATE_TEST_CASE_P(
TX_8X8, 12)));
#endif
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
SSSE3, PartialIDctTest,
MSA, PartialIDctTest,
::testing::Values(
make_tuple(&vp9_fdct32x32_c,
&vp9_idct32x32_1024_add_c,
&vp9_idct32x32_34_add_msa,
TX_32X32, 34),
make_tuple(&vp9_fdct32x32_c,
&vp9_idct32x32_1024_add_c,
&vp9_idct32x32_1_add_msa,
TX_32X32, 1),
make_tuple(&vp9_fdct16x16_c,
&vp9_idct16x16_256_add_c,
&vp9_idct16x16_10_add_ssse3,
TX_16X16, 10)));
#endif
&vp9_idct16x16_10_add_msa,
TX_16X16, 10),
make_tuple(&vp9_fdct16x16_c,
&vp9_idct16x16_256_add_c,
&vp9_idct16x16_1_add_msa,
TX_16X16, 1),
make_tuple(&vp9_fdct8x8_c,
&vp9_idct8x8_64_add_c,
&vp9_idct8x8_12_add_msa,
TX_8X8, 10),
make_tuple(&vp9_fdct8x8_c,
&vp9_idct8x8_64_add_c,
&vp9_idct8x8_1_add_msa,
TX_8X8, 1),
make_tuple(&vp9_fdct4x4_c,
&vp9_idct4x4_16_add_c,
&vp9_idct4x4_1_add_msa,
TX_4X4, 1)));
#endif // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
} // namespace

View File

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

View File

@@ -8,8 +8,6 @@
* 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"
@@ -19,326 +17,179 @@
#include "test/util.h"
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_entropy.h"
#include "./vp8_rtcd.h"
#include "vp8/common/blockd.h"
#include "vp8/common/onyx.h"
#include "vp8/encoder/block.h"
#include "vp8/encoder/onyx_int.h"
#include "vp8/encoder/quantize.h"
#include "vpx/vpx_integer.h"
using libvpx_test::ACMRandom;
#include "vpx_mem/vpx_mem.h"
namespace {
#if CONFIG_VP9_HIGHBITDEPTH
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, uint16_t *eob,
const int16_t *scan, const int16_t *iscan);
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, int>
QuantizeParam;
class QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
public:
virtual ~QuantizeTest() {}
virtual void SetUp() {
quantize_op_ = GET_PARAM(0);
ref_quantize_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
mask_ = (1 << bit_depth_) - 1;
}
const int kNumBlocks = 25;
const int kNumBlockEntries = 16;
virtual void TearDown() { libvpx_test::ClearSystemState(); }
typedef void (*VP8Quantize)(BLOCK *b, BLOCKD *d);
protected:
int 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;
}
typedef std::tr1::tuple<VP8Quantize, VP8Quantize> VP8QuantizeParam;
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
int bit_depth_;
int mask_;
QuantizeFunc quantize_op_;
QuantizeFunc ref_quantize_op_;
};
TEST_P(QuantizeTest, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
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_intra_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;
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,
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, 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());
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_intra_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,
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, 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());
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_intra_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,
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, 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());
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_intra_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,
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, 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 libvpx_test::ACMRandom;
using std::tr1::make_tuple;
// Create and populate a VP8_COMP instance which has a complete set of
// quantization inputs as well as a second MACROBLOCKD for output.
class QuantizeTestBase {
public:
virtual ~QuantizeTestBase() {
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() {
SetupCompressor();
asm_quant_ = GET_PARAM(0);
c_quant_ = GET_PARAM(1);
}
void RunComparison() {
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();
}
private:
VP8Quantize asm_quant_;
VP8Quantize c_quant_;
};
TEST_P(QuantizeTest, TestZeroInput) {
FillCoeffConstant(0);
RunComparison();
}
TEST_P(QuantizeTest, TestLargeNegativeInput) {
FillCoeffConstant(0);
// Generate a qcoeff which contains 512/-512 (0x0100/0xFE00) to catch issues
// like BUG=883 where the constant being compared was incorrectly initialized.
vp8_comp_->mb.coeff[0] = -8191;
RunComparison();
}
TEST_P(QuantizeTest, TestRandomInput) {
FillCoeffRandom();
RunComparison();
}
TEST_P(QuantizeTest, TestMultipleQ) {
for (int q = 0; q < QINDEX_RANGE; ++q) {
UpdateQuantizer(q);
FillCoeffRandom();
RunComparison();
}
}
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2_C_COMPARE, QuantizeTest,
::testing::Values(
make_tuple(&vp9_highbd_quantize_b_sse2,
&vp9_highbd_quantize_b_c, 8),
make_tuple(&vp9_highbd_quantize_b_sse2,
&vp9_highbd_quantize_b_c, 10),
make_tuple(&vp9_highbd_quantize_b_sse2,
&vp9_highbd_quantize_b_c, 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, 8),
make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
&vp9_highbd_quantize_b_32x32_c, 10),
make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
&vp9_highbd_quantize_b_32x32_c, 12)));
SSE2, QuantizeTest,
::testing::Values(
make_tuple(&vp8_fast_quantize_b_sse2, &vp8_fast_quantize_b_c),
make_tuple(&vp8_regular_quantize_b_sse2, &vp8_regular_quantize_b_c)));
#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
} // namespace

View File

@@ -144,6 +144,7 @@ class ResizeTest : public ::libvpx_test::EncoderTest,
TEST_P(ResizeTest, TestExternalResizeWorks) {
ResizingVideoSource video;
cfg_.g_lag_in_frames = 0;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
@@ -153,9 +154,9 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight);
EXPECT_EQ(expected_w, info->w)
<< "Frame " << frame << "had unexpected width";
<< "Frame " << frame << " had unexpected width";
EXPECT_EQ(expected_h, info->h)
<< "Frame " << frame << "had unexpected height";
<< "Frame " << frame << " had unexpected height";
}
}
@@ -260,7 +261,116 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
}
}
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);
VP9_INSTANTIATE_TEST_CASE(ResizeTest,
::testing::Values(::libvpx_test::kRealTime));
VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest,
::testing::Values(::libvpx_test::kOnePassBest));
VP9_INSTANTIATE_TEST_CASE(ResizeCspTest,
::testing::Values(::libvpx_test::kRealTime));
} // 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_cols = 320 >> 4;
const int mbs = (cpi.common.mb_rows * cpi.common.mb_cols);
vpx_memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));
memset(cpi.segment_feature_data, 0, sizeof(cpi.segment_feature_data));
// Segment map
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.
unsigned char *roi_map =
reinterpret_cast<unsigned char *>(vpx_calloc(mbs, 1));
vpx_memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
vpx_memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
vpx_memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2));
memset(&roi_map[mbs >> 2], 1, (mbs >> 2));
memset(&roi_map[mbs >> 1], 2, (mbs >> 2));
memset(&roi_map[mbs -(mbs >> 2)], 3, (mbs >> 2));
// Do a test call with valid parameters.
int roi_retval = vp8_set_roimap(&cpi, roi_map, cpi.common.mb_rows,

797
test/svc_test.cc Normal file
View File

@@ -0,0 +1,797 @@
/*
* 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 <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/i420_video_source.h"
#include "vp9/decoder/vp9_decoder.h"
#include "vpx/svc_context.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
namespace {
using libvpx_test::CodecFactory;
using libvpx_test::Decoder;
using libvpx_test::DxDataIterator;
using libvpx_test::VP9CodecFactory;
class SvcTest : public ::testing::Test {
protected:
static const uint32_t kWidth = 352;
static const uint32_t kHeight = 288;
SvcTest()
: codec_iface_(0),
test_file_name_("hantro_collage_w352h288.yuv"),
codec_initialized_(false),
decoder_(0) {
memset(&svc_, 0, sizeof(svc_));
memset(&codec_, 0, sizeof(codec_));
memset(&codec_enc_, 0, sizeof(codec_enc_));
}
virtual ~SvcTest() {}
virtual void SetUp() {
svc_.log_level = SVC_LOG_DEBUG;
svc_.log_print = 0;
codec_iface_ = vpx_codec_vp9_cx();
const vpx_codec_err_t res =
vpx_codec_enc_config_default(codec_iface_, &codec_enc_, 0);
EXPECT_EQ(VPX_CODEC_OK, res);
codec_enc_.g_w = kWidth;
codec_enc_.g_h = kHeight;
codec_enc_.g_timebase.num = 1;
codec_enc_.g_timebase.den = 60;
codec_enc_.kf_min_dist = 100;
codec_enc_.kf_max_dist = 100;
vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
VP9CodecFactory codec_factory;
decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
tile_columns_ = 0;
tile_rows_ = 0;
}
virtual void TearDown() {
ReleaseEncoder();
delete(decoder_);
}
void InitializeEncoder() {
const vpx_codec_err_t res =
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_OK, res);
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;
}
void ReleaseEncoder() {
vpx_svc_release(&svc_);
if (codec_initialized_) vpx_codec_destroy(&codec_);
codec_initialized_ = false;
}
void GetStatsData(std::string *const stats_buf) {
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *cx_pkt;
while ((cx_pkt = vpx_codec_get_cx_data(&codec_, &iter)) != NULL) {
if (cx_pkt->kind == VPX_CODEC_STATS_PKT) {
EXPECT_GT(cx_pkt->data.twopass_stats.sz, 0U);
ASSERT_TRUE(cx_pkt->data.twopass_stats.buf != NULL);
stats_buf->append(static_cast<char*>(cx_pkt->data.twopass_stats.buf),
cx_pkt->data.twopass_stats.sz);
}
}
}
void Pass1EncodeNFrames(const int n, const int layers,
std::string *const stats_buf) {
vpx_codec_err_t res;
ASSERT_GT(n, 0);
ASSERT_GT(layers, 0);
svc_.spatial_layers = layers;
codec_enc_.g_pass = VPX_RC_FIRST_PASS;
InitializeEncoder();
libvpx_test::I420VideoSource video(test_file_name_,
codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den,
codec_enc_.g_timebase.num, 0, 30);
video.Begin();
for (int i = 0; i < n; ++i) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
GetStatsData(stats_buf);
video.Next();
}
// Flush encoder and test EOS packet.
res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
GetStatsData(stats_buf);
ReleaseEncoder();
}
void StoreFrames(const size_t max_frame_received,
struct vpx_fixed_buf *const outputs,
size_t *const frame_received) {
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *cx_pkt;
while ((cx_pkt = vpx_codec_get_cx_data(&codec_, &iter)) != NULL) {
if (cx_pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
const size_t frame_size = cx_pkt->data.frame.sz;
EXPECT_GT(frame_size, 0U);
ASSERT_TRUE(cx_pkt->data.frame.buf != NULL);
ASSERT_LT(*frame_received, max_frame_received);
if (*frame_received == 0)
EXPECT_EQ(1, !!(cx_pkt->data.frame.flags & VPX_FRAME_IS_KEY));
outputs[*frame_received].buf = malloc(frame_size + 16);
ASSERT_TRUE(outputs[*frame_received].buf != NULL);
memcpy(outputs[*frame_received].buf, cx_pkt->data.frame.buf,
frame_size);
outputs[*frame_received].sz = frame_size;
++(*frame_received);
}
}
}
void Pass2EncodeNFrames(std::string *const stats_buf,
const int n, const int layers,
struct vpx_fixed_buf *const outputs) {
vpx_codec_err_t res;
size_t frame_received = 0;
ASSERT_TRUE(outputs != NULL);
ASSERT_GT(n, 0);
ASSERT_GT(layers, 0);
svc_.spatial_layers = layers;
codec_enc_.rc_target_bitrate = 500;
if (codec_enc_.g_pass == VPX_RC_LAST_PASS) {
ASSERT_TRUE(stats_buf != NULL);
ASSERT_GT(stats_buf->size(), 0U);
codec_enc_.rc_twopass_stats_in.buf = &(*stats_buf)[0];
codec_enc_.rc_twopass_stats_in.sz = stats_buf->size();
}
InitializeEncoder();
libvpx_test::I420VideoSource video(test_file_name_,
codec_enc_.g_w, codec_enc_.g_h,
codec_enc_.g_timebase.den,
codec_enc_.g_timebase.num, 0, 30);
video.Begin();
for (int i = 0; i < n; ++i) {
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
video.duration(), VPX_DL_GOOD_QUALITY);
ASSERT_EQ(VPX_CODEC_OK, res);
StoreFrames(n, outputs, &frame_received);
video.Next();
}
// Flush encoder.
res = vpx_svc_encode(&svc_, &codec_, NULL, 0,
video.duration(), VPX_DL_GOOD_QUALITY);
EXPECT_EQ(VPX_CODEC_OK, res);
StoreFrames(n, outputs, &frame_received);
EXPECT_EQ(frame_received, static_cast<size_t>(n));
ReleaseEncoder();
}
void DecodeNFrames(const struct vpx_fixed_buf *const inputs, const int n) {
int decoded_frames = 0;
int received_frames = 0;
ASSERT_TRUE(inputs != NULL);
ASSERT_GT(n, 0);
for (int i = 0; i < n; ++i) {
ASSERT_TRUE(inputs[i].buf != NULL);
ASSERT_GT(inputs[i].sz, 0U);
const vpx_codec_err_t res_dec =
decoder_->DecodeFrame(static_cast<const uint8_t *>(inputs[i].buf),
inputs[i].sz);
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
++decoded_frames;
DxDataIterator dec_iter = decoder_->GetDxData();
while (dec_iter.Next() != NULL) {
++received_frames;
}
}
EXPECT_EQ(decoded_frames, n);
EXPECT_EQ(received_frames, n);
}
void DropEnhancementLayers(struct vpx_fixed_buf *const inputs,
const int num_super_frames,
const int remained_spatial_layers) {
ASSERT_TRUE(inputs != NULL);
ASSERT_GT(num_super_frames, 0);
ASSERT_GT(remained_spatial_layers, 0);
for (int i = 0; i < num_super_frames; ++i) {
uint32_t frame_sizes[8] = {0};
int frame_count = 0;
int frames_found = 0;
int frame;
ASSERT_TRUE(inputs[i].buf != NULL);
ASSERT_GT(inputs[i].sz, 0U);
vpx_codec_err_t res =
vp9_parse_superframe_index(static_cast<const uint8_t*>(inputs[i].buf),
inputs[i].sz, frame_sizes, &frame_count,
NULL, NULL);
ASSERT_EQ(VPX_CODEC_OK, res);
if (frame_count == 0) {
// There's no super frame but only a single frame.
ASSERT_EQ(1, remained_spatial_layers);
} else {
// Found a super frame.
uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf);
uint8_t *frame_start = frame_data;
for (frame = 0; frame < frame_count; ++frame) {
// Looking for a visible frame.
if (frame_data[0] & 0x02) {
++frames_found;
if (frames_found == remained_spatial_layers)
break;
}
frame_data += frame_sizes[frame];
}
ASSERT_LT(frame, frame_count) << "Couldn't find a visible frame. "
<< "remained_spatial_layers: " << remained_spatial_layers
<< " super_frame: " << i;
if (frame == frame_count - 1)
continue;
frame_data += frame_sizes[frame];
// We need to add one more frame for multiple frame contexts.
uint8_t marker =
static_cast<const uint8_t*>(inputs[i].buf)[inputs[i].sz - 1];
const uint32_t mag = ((marker >> 3) & 0x3) + 1;
const size_t index_sz = 2 + mag * frame_count;
const size_t new_index_sz = 2 + mag * (frame + 1);
marker &= 0x0f8;
marker |= frame;
// Copy existing frame sizes.
memmove(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1,
new_index_sz - 2);
// New marker.
frame_data[0] = marker;
frame_data += (mag * (frame + 1) + 1);
*frame_data++ = marker;
inputs[i].sz = frame_data - frame_start;
}
}
}
void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) {
ASSERT_TRUE(inputs != NULL);
ASSERT_GT(n, 0);
for (int i = 0; i < n; ++i) {
free(inputs[i].buf);
inputs[i].buf = NULL;
inputs[i].sz = 0;
}
}
SvcContext svc_;
vpx_codec_ctx_t codec_;
struct vpx_codec_enc_cfg codec_enc_;
vpx_codec_iface_t *codec_iface_;
std::string test_file_name_;
bool codec_initialized_;
Decoder *decoder_;
int tile_columns_;
int tile_rows_;
};
TEST_F(SvcTest, SvcInit) {
// test missing parameters
vpx_codec_err_t res = vpx_svc_init(NULL, &codec_, codec_iface_, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_init(&svc_, NULL, codec_iface_, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_init(&svc_, &codec_, NULL, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
svc_.spatial_layers = 6; // too many layers
res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
svc_.spatial_layers = 0; // use default layers
InitializeEncoder();
EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers);
}
TEST_F(SvcTest, InitTwoLayers) {
svc_.spatial_layers = 2;
InitializeEncoder();
}
TEST_F(SvcTest, InvalidOptions) {
vpx_codec_err_t res = vpx_svc_set_options(&svc_, NULL);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "not-an-option=1");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
}
TEST_F(SvcTest, SetLayersOption) {
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "spatial-layers=3");
EXPECT_EQ(VPX_CODEC_OK, res);
InitializeEncoder();
EXPECT_EQ(3, svc_.spatial_layers);
}
TEST_F(SvcTest, SetMultipleOptions) {
vpx_codec_err_t res =
vpx_svc_set_options(&svc_, "spatial-layers=2 scale-factors=1/3,2/3");
EXPECT_EQ(VPX_CODEC_OK, res);
InitializeEncoder();
EXPECT_EQ(2, svc_.spatial_layers);
}
TEST_F(SvcTest, SetScaleFactorsOption) {
svc_.spatial_layers = 2;
vpx_codec_err_t res =
vpx_svc_set_options(&svc_, "scale-factors=not-scale-factors");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "scale-factors=1/3, 3*3");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "scale-factors=1/3");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3");
EXPECT_EQ(VPX_CODEC_OK, res);
InitializeEncoder();
}
TEST_F(SvcTest, SetQuantizersOption) {
svc_.spatial_layers = 2;
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "max-quantizers=nothing");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "min-quantizers=nothing");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "max-quantizers=40");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "min-quantizers=40");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "max-quantizers=30,30 min-quantizers=40,40");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "max-quantizers=40,40 min-quantizers=30,30");
InitializeEncoder();
}
TEST_F(SvcTest, SetAutoAltRefOption) {
svc_.spatial_layers = 5;
vpx_codec_err_t res = vpx_svc_set_options(&svc_, "auto-alt-refs=none");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
res = vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1,1,0");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
InitializeEncoder();
}
// Test that decoder can handle an SVC frame as the first frame in a sequence.
TEST_F(SvcTest, OnePassEncodeOneFrame) {
codec_enc_.g_pass = VPX_RC_ONE_PASS;
vpx_fixed_buf output = {0};
Pass2EncodeNFrames(NULL, 1, 2, &output);
DecodeNFrames(&output, 1);
FreeBitstreamBuffers(&output, 1);
}
TEST_F(SvcTest, OnePassEncodeThreeFrames) {
codec_enc_.g_pass = VPX_RC_ONE_PASS;
codec_enc_.g_lag_in_frames = 0;
vpx_fixed_buf outputs[3];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 3);
FreeBitstreamBuffers(&outputs[0], 3);
}
TEST_F(SvcTest, TwoPassEncode10Frames) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(20, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20);
}
TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 5, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 4);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 3);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 2);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
Pass1EncodeNFrames(20, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1 scale-factors=1/1,1/1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20);
}
TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
Pass1EncodeNFrames(20, 3, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
vpx_svc_set_options(&svc_,
"auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
vpx_fixed_buf outputs[20];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
DecodeNFrames(&outputs[0], 20);
DropEnhancementLayers(&outputs[0], 20, 2);
DecodeNFrames(&outputs[0], 20);
DropEnhancementLayers(&outputs[0], 20, 1);
DecodeNFrames(&outputs[0], 20);
FreeBitstreamBuffers(&outputs[0], 20);
}
TEST_F(SvcTest, SetMultipleFrameContextsOption) {
svc_.spatial_layers = 5;
vpx_codec_err_t res =
vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
EXPECT_EQ(VPX_CODEC_OK, res);
res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
svc_.spatial_layers = 2;
res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
InitializeEncoder();
}
TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode2SpatialLayersWithMultipleFrameContextsDecodeBaselayer) {
// First pass encode
std::string stats_buf;
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
Pass1EncodeNFrames(10, 2, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode3SNRLayersWithMultipleFrameContextsDecode321Layer) {
// First pass encode
std::string stats_buf;
vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
Pass1EncodeNFrames(10, 3, &stats_buf);
// Second pass encode
codec_enc_.g_pass = VPX_RC_LAST_PASS;
codec_enc_.g_error_resilient = 0;
vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 "
"multi-frame-contexts=1");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 2);
DecodeNFrames(&outputs[0], 10);
DropEnhancementLayers(&outputs[0], 10, 1);
DecodeNFrames(&outputs[0], 10);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayers) {
// 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");
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, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
// 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;
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);
}
TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) {
// 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");
vpx_fixed_buf outputs[10];
memset(&outputs[0], 0, sizeof(outputs));
Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i)
base_layer[i] = outputs[i * 2];
DecodeNFrames(&base_layer[0], 5);
FreeBitstreamBuffers(&outputs[0], 10);
}
TEST_F(SvcTest,
TwoPassEncode2TemporalLayersWithMultipleFrameContextsDecodeBaseLayer) {
// 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;
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]);
vpx_fixed_buf base_layer[5];
for (int i = 0; i < 5; ++i)
base_layer[i] = outputs[i * 2];
DecodeNFrames(&base_layer[0], 5);
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

View File

@@ -12,11 +12,13 @@ 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_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_422.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) += niklas_1280_720_30.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
@@ -553,6 +555,8 @@ 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-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-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.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-08-tile-4x4.webm
@@ -659,6 +663,10 @@ 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.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
@@ -691,10 +699,16 @@ 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-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-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.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.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.res
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.v2.ivf
@@ -709,8 +723,13 @@ 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-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-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)
# Encode / Decode test
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_1280_720_30.yuv
# 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_640x360_tile_1x2_337kbps.webm
@@ -746,3 +765,6 @@ 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) += thaloundeskmtg_640_480_30.yuv
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,6 +22,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += aq_segment_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += datarate_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) += resize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += yuv_video_source.h
@@ -30,36 +31,42 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += config_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += cq_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) += invalid_file_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_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) += 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_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.h
LIBVPX_TEST_SRCS-yes += encode_test_driver.cc
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += encode_test_driver.cc
LIBVPX_TEST_SRCS-yes += encode_test_driver.h
## IVF writing.
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../ivfenc.c ../ivfenc.h
## Y4m parsing.
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += y4m_test.cc ../y4menc.c ../y4menc.h
## WebM Parsing
ifeq ($(CONFIG_WEBM_IO), yes)
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.cc
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.cc
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvparser.h
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser/mkvreader.h
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser.cpp
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvreader.cpp
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvparser.hpp
LIBWEBM_PARSER_SRCS += ../third_party/libwebm/mkvreader.hpp
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += $(LIBWEBM_PARSER_SRCS)
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../tools_common.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.cc
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h
LIBVPX_TEST_SRCS-$(CONFIG_VP9_DECODER) += vp9_skip_loopfilter_test.cc
endif
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += decode_api_test.cc
@@ -86,11 +93,12 @@ endif
ifeq ($(CONFIG_SHARED),)
## VP8
ifeq ($(CONFIG_VP8),yes)
ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),)
# These tests require both the encoder and decoder to be built.
ifeq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),yesyes)
LIBVPX_TEST_SRCS-yes += vp8_boolcoder_test.cc
LIBVPX_TEST_SRCS-yes += vp8_fragments_test.cc
endif
LIBVPX_TEST_SRCS-$(CONFIG_POSTPROC) += pp_filter_test.cc
@@ -99,6 +107,7 @@ 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) += vp8_fdct4x4_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP8_ENCODER) += quantize_test.cc
LIBVPX_TEST_SRCS-yes += idct_test.cc
LIBVPX_TEST_SRCS-yes += intrapred_test.cc
@@ -112,7 +121,7 @@ endif
endif # VP8
## VP9
ifeq ($(CONFIG_VP9),yes)
ifneq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_DECODER),)
# These tests require both the encoder and decoder to be built.
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_DECODER),yesyes)
@@ -122,7 +131,7 @@ LIBVPX_TEST_SRCS-yes += partial_idct_test.cc
LIBVPX_TEST_SRCS-yes += superframe_test.cc
LIBVPX_TEST_SRCS-yes += tile_independence_test.cc
LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc
LIBVPX_TEST_SRCS-yes += vp9_encoder_parms_get_to_decoder.cc
endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9) += convolve_test.cc
@@ -136,26 +145,29 @@ 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) += lpf_8_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_avg_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += quantize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += error_block_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_error_block_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_quantize_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9) += vp9_intrapred_test.cc
ifeq ($(CONFIG_VP9_ENCODER),yes)
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
ifeq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_TEMPORAL_DENOISING),yesyes)
LIBVPX_TEST_SRCS-$(HAVE_SSE2) += vp9_denoiser_sse2_test.cc
endif
ifeq ($(CONFIG_VP9)$(CONFIG_WEDGE_PARTITION),yesyes)
LIBVPX_TEST_SRCS-$(HAVE_SSSE3) += masked_variance_test.cc
endif
ifeq ($(CONFIG_VP9)$(CONFIG_WEDGE_PARTITION),yesyes)
LIBVPX_TEST_SRCS-$(HAVE_SSSE3) += masked_sad_test.cc
endif
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += vp9_arf_freq_test.cc
endif # VP9
LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += sad_test.cc
TEST_INTRA_PRED_SPEED_SRCS-$(CONFIG_VP9_DECODER) := test_intra_pred_speed.cc
TEST_INTRA_PRED_SPEED_SRCS-$(CONFIG_VP9_DECODER) += ../md5_utils.h ../md5_utils.c
endif # CONFIG_SHARED
include $(SRC_PATH_BARE)/test/test-data.mk

View File

@@ -0,0 +1,384 @@
/*
* 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 VP9 intra-predictor functions
#include <stdio.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vp9_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 vp9_intra_pred[] = { \
dc, dc_left, dc_top, dc_128, v, h, d45, \
d135, d117, d153, d207, d63, tm}; \
test_func(vp9_intra_pred); \
}
// -----------------------------------------------------------------------------
// 4x4
INTRA_PRED_TEST(C, TestIntraPred4, vp9_dc_predictor_4x4_c,
vp9_dc_left_predictor_4x4_c, vp9_dc_top_predictor_4x4_c,
vp9_dc_128_predictor_4x4_c, vp9_v_predictor_4x4_c,
vp9_h_predictor_4x4_c, vp9_d45_predictor_4x4_c,
vp9_d135_predictor_4x4_c, vp9_d117_predictor_4x4_c,
vp9_d153_predictor_4x4_c, vp9_d207_predictor_4x4_c,
vp9_d63_predictor_4x4_c, vp9_tm_predictor_4x4_c)
#if HAVE_SSE
INTRA_PRED_TEST(SSE, TestIntraPred4, vp9_dc_predictor_4x4_sse,
vp9_dc_left_predictor_4x4_sse, vp9_dc_top_predictor_4x4_sse,
vp9_dc_128_predictor_4x4_sse, vp9_v_predictor_4x4_sse, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, vp9_tm_predictor_4x4_sse)
#endif // HAVE_SSE
#if HAVE_SSSE3
INTRA_PRED_TEST(SSSE3, TestIntraPred4, NULL, NULL, NULL, NULL, NULL,
vp9_h_predictor_4x4_ssse3, vp9_d45_predictor_4x4_ssse3, NULL,
NULL, vp9_d153_predictor_4x4_ssse3,
vp9_d207_predictor_4x4_ssse3, vp9_d63_predictor_4x4_ssse3, NULL)
#endif // HAVE_SSSE3
#if HAVE_DSPR2
INTRA_PRED_TEST(DSPR2, TestIntraPred4, vp9_dc_predictor_4x4_dspr2, NULL, NULL,
NULL, NULL, vp9_h_predictor_4x4_dspr2, NULL, NULL, NULL, NULL,
NULL, NULL, vp9_tm_predictor_4x4_dspr2)
#endif // HAVE_DSPR2
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred4, vp9_dc_predictor_4x4_neon,
vp9_dc_left_predictor_4x4_neon, vp9_dc_top_predictor_4x4_neon,
vp9_dc_128_predictor_4x4_neon, vp9_v_predictor_4x4_neon,
vp9_h_predictor_4x4_neon, vp9_d45_predictor_4x4_neon,
vp9_d135_predictor_4x4_neon, NULL, NULL, NULL, NULL,
vp9_tm_predictor_4x4_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred4, vp9_dc_predictor_4x4_msa,
vp9_dc_left_predictor_4x4_msa, vp9_dc_top_predictor_4x4_msa,
vp9_dc_128_predictor_4x4_msa, vp9_v_predictor_4x4_msa,
vp9_h_predictor_4x4_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vp9_tm_predictor_4x4_msa)
#endif // HAVE_MSA
// -----------------------------------------------------------------------------
// 8x8
INTRA_PRED_TEST(C, TestIntraPred8, vp9_dc_predictor_8x8_c,
vp9_dc_left_predictor_8x8_c, vp9_dc_top_predictor_8x8_c,
vp9_dc_128_predictor_8x8_c, vp9_v_predictor_8x8_c,
vp9_h_predictor_8x8_c, vp9_d45_predictor_8x8_c,
vp9_d135_predictor_8x8_c, vp9_d117_predictor_8x8_c,
vp9_d153_predictor_8x8_c, vp9_d207_predictor_8x8_c,
vp9_d63_predictor_8x8_c, vp9_tm_predictor_8x8_c)
#if HAVE_SSE
INTRA_PRED_TEST(SSE, TestIntraPred8, vp9_dc_predictor_8x8_sse,
vp9_dc_left_predictor_8x8_sse, vp9_dc_top_predictor_8x8_sse,
vp9_dc_128_predictor_8x8_sse, vp9_v_predictor_8x8_sse, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL)
#endif // HAVE_SSE
#if HAVE_SSE2
INTRA_PRED_TEST(SSE2, TestIntraPred8, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, vp9_tm_predictor_8x8_sse2)
#endif // HAVE_SSE2
#if HAVE_SSSE3
INTRA_PRED_TEST(SSSE3, TestIntraPred8, NULL, NULL, NULL, NULL, NULL,
vp9_h_predictor_8x8_ssse3, vp9_d45_predictor_8x8_ssse3, NULL,
NULL, vp9_d153_predictor_8x8_ssse3,
vp9_d207_predictor_8x8_ssse3, vp9_d63_predictor_8x8_ssse3, NULL)
#endif // HAVE_SSSE3
#if HAVE_DSPR2
INTRA_PRED_TEST(DSPR2, TestIntraPred8, vp9_dc_predictor_8x8_dspr2, NULL, NULL,
NULL, NULL, vp9_h_predictor_8x8_dspr2, NULL, NULL, NULL, NULL,
NULL, NULL, vp9_tm_predictor_8x8_c)
#endif // HAVE_DSPR2
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred8, vp9_dc_predictor_8x8_neon,
vp9_dc_left_predictor_8x8_neon, vp9_dc_top_predictor_8x8_neon,
vp9_dc_128_predictor_8x8_neon, vp9_v_predictor_8x8_neon,
vp9_h_predictor_8x8_neon, vp9_d45_predictor_8x8_neon, NULL,
NULL, NULL, NULL, NULL, vp9_tm_predictor_8x8_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred8, vp9_dc_predictor_8x8_msa,
vp9_dc_left_predictor_8x8_msa, vp9_dc_top_predictor_8x8_msa,
vp9_dc_128_predictor_8x8_msa, vp9_v_predictor_8x8_msa,
vp9_h_predictor_8x8_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vp9_tm_predictor_8x8_msa)
#endif // HAVE_MSA
// -----------------------------------------------------------------------------
// 16x16
INTRA_PRED_TEST(C, TestIntraPred16, vp9_dc_predictor_16x16_c,
vp9_dc_left_predictor_16x16_c, vp9_dc_top_predictor_16x16_c,
vp9_dc_128_predictor_16x16_c, vp9_v_predictor_16x16_c,
vp9_h_predictor_16x16_c, vp9_d45_predictor_16x16_c,
vp9_d135_predictor_16x16_c, vp9_d117_predictor_16x16_c,
vp9_d153_predictor_16x16_c, vp9_d207_predictor_16x16_c,
vp9_d63_predictor_16x16_c, vp9_tm_predictor_16x16_c)
#if HAVE_SSE2
INTRA_PRED_TEST(SSE2, TestIntraPred16, vp9_dc_predictor_16x16_sse2,
vp9_dc_left_predictor_16x16_sse2,
vp9_dc_top_predictor_16x16_sse2,
vp9_dc_128_predictor_16x16_sse2, vp9_v_predictor_16x16_sse2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
vp9_tm_predictor_16x16_sse2)
#endif // HAVE_SSE2
#if HAVE_SSSE3
INTRA_PRED_TEST(SSSE3, TestIntraPred16, NULL, NULL, NULL, NULL, NULL,
vp9_h_predictor_16x16_ssse3, vp9_d45_predictor_16x16_ssse3,
NULL, NULL, vp9_d153_predictor_16x16_ssse3,
vp9_d207_predictor_16x16_ssse3, vp9_d63_predictor_16x16_ssse3,
NULL)
#endif // HAVE_SSSE3
#if HAVE_DSPR2
INTRA_PRED_TEST(DSPR2, TestIntraPred16, vp9_dc_predictor_16x16_dspr2, NULL,
NULL, NULL, NULL, vp9_h_predictor_16x16_dspr2, NULL, NULL, NULL,
NULL, NULL, NULL, NULL)
#endif // HAVE_DSPR2
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred16, vp9_dc_predictor_16x16_neon,
vp9_dc_left_predictor_16x16_neon,
vp9_dc_top_predictor_16x16_neon,
vp9_dc_128_predictor_16x16_neon, vp9_v_predictor_16x16_neon,
vp9_h_predictor_16x16_neon, vp9_d45_predictor_16x16_neon, NULL,
NULL, NULL, NULL, NULL, vp9_tm_predictor_16x16_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred16, vp9_dc_predictor_16x16_msa,
vp9_dc_left_predictor_16x16_msa, vp9_dc_top_predictor_16x16_msa,
vp9_dc_128_predictor_16x16_msa, vp9_v_predictor_16x16_msa,
vp9_h_predictor_16x16_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vp9_tm_predictor_16x16_msa)
#endif // HAVE_MSA
// -----------------------------------------------------------------------------
// 32x32
INTRA_PRED_TEST(C, TestIntraPred32, vp9_dc_predictor_32x32_c,
vp9_dc_left_predictor_32x32_c, vp9_dc_top_predictor_32x32_c,
vp9_dc_128_predictor_32x32_c, vp9_v_predictor_32x32_c,
vp9_h_predictor_32x32_c, vp9_d45_predictor_32x32_c,
vp9_d135_predictor_32x32_c, vp9_d117_predictor_32x32_c,
vp9_d153_predictor_32x32_c, vp9_d207_predictor_32x32_c,
vp9_d63_predictor_32x32_c, vp9_tm_predictor_32x32_c)
#if HAVE_SSE2
#if ARCH_X86_64
INTRA_PRED_TEST(SSE2, TestIntraPred32, vp9_dc_predictor_32x32_sse2,
vp9_dc_left_predictor_32x32_sse2,
vp9_dc_top_predictor_32x32_sse2,
vp9_dc_128_predictor_32x32_sse2, vp9_v_predictor_32x32_sse2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
vp9_tm_predictor_32x32_sse2)
#else
INTRA_PRED_TEST(SSE2, TestIntraPred32, vp9_dc_predictor_32x32_sse2,
vp9_dc_left_predictor_32x32_sse2,
vp9_dc_top_predictor_32x32_sse2,
vp9_dc_128_predictor_32x32_sse2, vp9_v_predictor_32x32_sse2,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
#endif // ARCH_X86_64
#endif // HAVE_SSE2
#if HAVE_SSSE3
INTRA_PRED_TEST(SSSE3, TestIntraPred32, NULL, NULL, NULL, NULL, NULL,
vp9_h_predictor_32x32_ssse3, vp9_d45_predictor_32x32_ssse3,
NULL, NULL, vp9_d153_predictor_32x32_ssse3,
vp9_d207_predictor_32x32_ssse3, vp9_d63_predictor_32x32_ssse3,
NULL)
#endif // HAVE_SSSE3
#if HAVE_NEON
INTRA_PRED_TEST(NEON, TestIntraPred32, vp9_dc_predictor_32x32_neon,
vp9_dc_left_predictor_32x32_neon,
vp9_dc_top_predictor_32x32_neon,
vp9_dc_128_predictor_32x32_neon, vp9_v_predictor_32x32_neon,
vp9_h_predictor_32x32_neon, NULL, NULL, NULL, NULL, NULL, NULL,
vp9_tm_predictor_32x32_neon)
#endif // HAVE_NEON
#if HAVE_MSA
INTRA_PRED_TEST(MSA, TestIntraPred32, vp9_dc_predictor_32x32_msa,
vp9_dc_left_predictor_32x32_msa, vp9_dc_top_predictor_32x32_msa,
vp9_dc_128_predictor_32x32_msa, vp9_v_predictor_32x32_msa,
vp9_h_predictor_32x32_msa, NULL, NULL, NULL, NULL, NULL,
NULL, vp9_tm_predictor_32x32_msa)
#endif // HAVE_MSA
#include "test/test_libvpx.cc"

View File

@@ -15,10 +15,12 @@
extern "C" {
#if CONFIG_VP8
extern void vp8_rtcd();
#endif
#endif // CONFIG_VP8
#if CONFIG_VP9
extern void vp9_rtcd();
#endif
#endif // CONFIG_VP9
extern void vpx_dsp_rtcd();
extern void vpx_scale_rtcd();
}
#include "third_party/googletest/src/include/gtest/gtest.h"
@@ -36,21 +38,21 @@ int main(int argc, char **argv) {
#if ARCH_X86 || ARCH_X86_64
const int simd_caps = x86_simd_caps();
if (!(simd_caps & HAS_MMX))
append_negative_gtest_filter(":MMX/*");
append_negative_gtest_filter(":MMX.*:MMX/*");
if (!(simd_caps & HAS_SSE))
append_negative_gtest_filter(":SSE/*");
append_negative_gtest_filter(":SSE.*:SSE/*");
if (!(simd_caps & HAS_SSE2))
append_negative_gtest_filter(":SSE2/*");
append_negative_gtest_filter(":SSE2.*:SSE2/*");
if (!(simd_caps & HAS_SSE3))
append_negative_gtest_filter(":SSE3/*");
append_negative_gtest_filter(":SSE3.*:SSE3/*");
if (!(simd_caps & HAS_SSSE3))
append_negative_gtest_filter(":SSSE3/*");
append_negative_gtest_filter(":SSSE3.*:SSSE3/*");
if (!(simd_caps & HAS_SSE4_1))
append_negative_gtest_filter(":SSE4_1/*");
append_negative_gtest_filter(":SSE4_1.*:SSE4_1/*");
if (!(simd_caps & HAS_AVX))
append_negative_gtest_filter(":AVX/*");
append_negative_gtest_filter(":AVX.*:AVX/*");
if (!(simd_caps & HAS_AVX2))
append_negative_gtest_filter(":AVX2/*");
append_negative_gtest_filter(":AVX2.*:AVX2/*");
#endif
#if !CONFIG_SHARED
@@ -59,11 +61,13 @@ int main(int argc, char **argv) {
#if CONFIG_VP8
vp8_rtcd();
#endif
#endif // CONFIG_VP8
#if CONFIG_VP9
vp9_rtcd();
#endif
#endif
#endif // CONFIG_VP9
vpx_dsp_rtcd();
vpx_scale_rtcd();
#endif // !CONFIG_SHARED
return RUN_ALL_TESTS();
}

View File

@@ -12,6 +12,7 @@
#include <cstdlib>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "../tools_common.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
@@ -26,10 +27,24 @@
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,
public ::libvpx_test::CodecTestWithParam<const char*> {
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
protected:
TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(NULL) {}
TestVectorTest()
: DecoderTest(GET_PARAM(0)),
md5_file_(NULL) {
}
virtual ~TestVectorTest() {
if (md5_file_)
@@ -71,8 +86,25 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
// checksums match the correct md5 data, then the test is passed. Otherwise,
// the test failed.
TEST_P(TestVectorTest, MD5Match) {
const std::string filename = GET_PARAM(1);
const DecodeParam input = 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;
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.
if (filename.substr(filename.length() - 3, 3) == "ivf") {
@@ -92,23 +124,50 @@ TEST_P(TestVectorTest, MD5Match) {
const std::string md5_filename = filename + ".md5";
OpenMD5File(md5_filename);
// Set decode config and flags.
set_cfg(cfg);
set_flags(flags);
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
delete video;
}
// Test VP8 decode in serial mode with single thread.
// NOTE: VP8 only support serial mode.
#if CONFIG_VP8_DECODER
VP8_INSTANTIATE_TEST_CASE(TestVectorTest,
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
libvpx_test::kVP8TestVectors +
libvpx_test::kNumVP8TestVectors));
#endif // CONFIG_VP8_DECODER
VP8_INSTANTIATE_TEST_CASE(
TestVectorTest,
::testing::Combine(
::testing::Values(0), // Serial Mode.
::testing::Values(1), // Single thread.
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
libvpx_test::kVP8TestVectors +
libvpx_test::kNumVP8TestVectors)));
#endif
// Test VP9 decode in serial mode with single thread.
#if CONFIG_VP9_DECODER
VP9_INSTANTIATE_TEST_CASE(TestVectorTest,
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
libvpx_test::kVP9TestVectors +
libvpx_test::kNumVP9TestVectors));
#endif // 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

View File

@@ -165,7 +165,10 @@ const char *const kVP9TestVectors[] = {
"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-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",
#endif
"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.webm", "vp90-2-14-resize-fp-tiles-1-4.webm",
@@ -191,6 +194,7 @@ const char *const kVP9TestVectors[] = {
"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);
#endif // CONFIG_VP9_DECODER

View File

@@ -106,22 +106,24 @@ check_git_hashes() {
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
# LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that
# the variables are set and that they all evaluate to directory paths.
verify_vpx_test_environment() {
if [ ! -d "${LIBVPX_BIN_PATH}" ]; then
echo "The LIBVPX_BIN_PATH environment variable must be set."
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
test_env_var_dir "LIBVPX_BIN_PATH" \
&& test_env_var_dir "LIBVPX_CONFIG_PATH" \
&& test_env_var_dir "LIBVPX_TEST_DATA_PATH"
}
# Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which
@@ -261,6 +263,9 @@ run_tests() {
return
fi
# Don't bother with the environment tests if everything else was disabled.
[ -z "${tests_to_filter}" ] && return
# Combine environment and actual tests.
local tests_to_run="${env_tests} ${tests_to_filter}"
@@ -378,8 +383,7 @@ else
VPX_TEST_TEMP_ROOT=/tmp
fi
VPX_TEST_RAND=$(awk 'BEGIN { srand(); printf "%d\n",(rand() * 32768)}')
VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_${VPX_TEST_RAND}"
VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_$$"
if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \
[ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then
@@ -397,11 +401,16 @@ 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_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_WIDTH=352
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.
trap cleanup EXIT
@@ -417,13 +426,13 @@ vlog "$(basename "${0%.*}") test configuration:
VPX_TEST_LIST_TESTS=${VPX_TEST_LIST_TESTS}
VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}
VPX_TEST_PREFIX=${VPX_TEST_PREFIX}
VPX_TEST_RAND=${VPX_TEST_RAND}
VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS}
VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT}
VPX_TEST_TEMP_ROOT=${VPX_TEST_TEMP_ROOT}
VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT}
YUV_RAW_INPUT=${YUV_RAW_INPUT}
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.

File diff suppressed because it is too large Load Diff

View File

@@ -134,8 +134,13 @@ class VideoSource {
class DummyVideoSource : public VideoSource {
public:
DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
SetSize(80, 64);
DummyVideoSource()
: img_(NULL),
limit_(100),
width_(80),
height_(64),
format_(VPX_IMG_FMT_I420) {
ReallocImage();
}
virtual ~DummyVideoSource() { vpx_img_free(img_); }
@@ -174,23 +179,35 @@ class DummyVideoSource : public VideoSource {
void SetSize(unsigned int width, unsigned int 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;
height_ = height;
ReallocImage();
}
}
void SetImageFormat(vpx_img_fmt_t format) {
if (format_ != format) {
format_ = format;
ReallocImage();
}
}
protected:
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_;
size_t raw_sz_;
unsigned int limit_;
unsigned int frame_;
unsigned int width_;
unsigned int height_;
vpx_img_fmt_t format_;
};

View File

@@ -52,13 +52,13 @@ TEST_P(VP8DenoiserTest, BitexactCheck) {
// mc_avg_block is the denoised reference block,
// avg_block_c is the denoised result from C code,
// avg_block_sse2 is the denoised result from SSE2 code.
DECLARE_ALIGNED_ARRAY(16, uint8_t, sig_block_c, kNumPixels);
DECLARE_ALIGNED(16, uint8_t, sig_block_c[kNumPixels]);
// Since in VP8 denoiser, the source signal will be changed,
// we need another copy of the source signal as the input of sse2 code.
DECLARE_ALIGNED_ARRAY(16, uint8_t, sig_block_sse2, kNumPixels);
DECLARE_ALIGNED_ARRAY(16, uint8_t, mc_avg_block, kNumPixels);
DECLARE_ALIGNED_ARRAY(16, uint8_t, avg_block_c, kNumPixels);
DECLARE_ALIGNED_ARRAY(16, uint8_t, avg_block_sse2, kNumPixels);
DECLARE_ALIGNED(16, uint8_t, sig_block_sse2[kNumPixels]);
DECLARE_ALIGNED(16, uint8_t, mc_avg_block[kNumPixels]);
DECLARE_ALIGNED(16, uint8_t, avg_block_c[kNumPixels]);
DECLARE_ALIGNED(16, uint8_t, avg_block_sse2[kNumPixels]);
for (int i = 0; i < count_test_block; ++i) {
// Generate random motion magnitude, 20% of which exceed the threshold.

View File

@@ -0,0 +1,37 @@
/*
* 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 "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/video_source.h"
namespace {
class VP8FramgmentsTest
: public ::libvpx_test::EncoderTest,
public ::testing::Test {
protected:
VP8FramgmentsTest() : EncoderTest(&::libvpx_test::kVP8) {}
virtual ~VP8FramgmentsTest() {}
virtual void SetUp() {
const unsigned long init_flags = // NOLINT(runtime/int)
VPX_CODEC_USE_OUTPUT_PARTITION;
InitializeConfig();
SetMode(::libvpx_test::kRealTime);
set_init_flags(init_flags);
}
};
TEST_F(VP8FramgmentsTest, TestFragmentsEncodeDecode) {
::libvpx_test::RandomVideoSource video;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
}
} // namespace

View File

@@ -8,27 +8,30 @@
## in the file PATENTS. All contributing project authors may
## be found in the AUTHORS file in the root of the source tree.
##
## This file tests the libvpx cx_set_ref example. To add new tests to this
## This file tests the libvpx vp8cx_set_ref example. To add new tests to this
## file, do the following:
## 1. Write a shell function (this is your test).
## 2. Add the function to cx_set_ref_tests (on a new line).
## 2. Add the function to vp8cx_set_ref_tests (on a new line).
##
. $(dirname $0)/tools_common.sh
# Environment check: $YUV_RAW_INPUT is required.
cx_set_ref_verify_environment() {
vp8cx_set_ref_verify_environment() {
if [ ! -e "${YUV_RAW_INPUT}" ]; then
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
return 1
fi
}
# Runs cx_set_ref and updates the reference frame before encoding frame 90.
# $1 is the codec name.
# Runs vp8cx_set_ref and updates the reference frame before encoding frame 90.
# $1 is the codec name, which vp8cx_set_ref does not support at present: It's
# currently used only to name the output file.
# TODO(tomfinegan): Pass the codec param once the example is updated to support
# VP9.
vpx_set_ref() {
local encoder="${LIBVPX_BIN_PATH}/vp8cx_set_ref${VPX_TEST_EXE_SUFFIX}"
local codec="$1"
local encoder="${LIBVPX_BIN_PATH}/${codec}cx_set_ref${VPX_TEST_EXE_SUFFIX}"
local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf"
local output_file="${VPX_TEST_OUTPUT_DIR}/vp8cx_set_ref_${codec}.ivf"
local ref_frame_num=90
if [ ! -x "${encoder}" ]; then
@@ -43,18 +46,12 @@ vpx_set_ref() {
[ -e "${output_file}" ] || return 1
}
cx_set_ref_vp8() {
vp8cx_set_ref_vp8() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_set_ref vp8 || return 1
fi
}
cx_set_ref_vp9() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_set_ref vp9 || return 1
fi
}
vp8cx_set_ref_tests="vp8cx_set_ref_vp8"
cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9"
run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}"
run_tests vp8cx_set_ref_verify_environment "${vp8cx_set_ref_tests}"

230
test/vp9_arf_freq_test.cc Normal file
View File

@@ -0,0 +1,230 @@
/*
* 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 "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/y4m_video_source.h"
#include "test/yuv_video_source.h"
#include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "vp9/encoder/vp9_ratectrl.h"
namespace {
const unsigned int kFrames = 100;
const int kBitrate = 500;
#define ARF_NOT_SEEN 1000001
#define ARF_SEEN_ONCE 1000000
typedef struct {
const char *filename;
unsigned int width;
unsigned int height;
unsigned int framerate_num;
unsigned int framerate_den;
unsigned int input_bit_depth;
vpx_img_fmt fmt;
vpx_bit_depth_t bit_depth;
unsigned int profile;
} TestVideoParam;
typedef struct {
libvpx_test::TestMode mode;
int cpu_used;
} TestEncodeParam;
const TestVideoParam kTestVectors[] = {
// artificially increase framerate to trigger default check
{"hantro_collage_w352h288.yuv", 352, 288, 5000, 1,
8, VPX_IMG_FMT_I420, VPX_BITS_8, 0},
{"hantro_collage_w352h288.yuv", 352, 288, 30, 1,
8, VPX_IMG_FMT_I420, VPX_BITS_8, 0},
{"rush_hour_444.y4m", 352, 288, 30, 1,
8, VPX_IMG_FMT_I444, VPX_BITS_8, 1},
#if CONFIG_VP9_HIGHBITDEPTH
// Add list of profile 2/3 test videos here ...
#endif // CONFIG_VP9_HIGHBITDEPTH
};
const TestEncodeParam kEncodeVectors[] = {
{::libvpx_test::kOnePassGood, 2},
{::libvpx_test::kOnePassGood, 5},
{::libvpx_test::kTwoPassGood, 1},
{::libvpx_test::kTwoPassGood, 2},
{::libvpx_test::kTwoPassGood, 5},
{::libvpx_test::kRealTime, 5},
};
const int kMinArfVectors[] = {
// NOTE: 0 refers to the default built-in logic in:
// vp9_rc_get_default_min_gf_interval(...)
0, 4, 8, 12, 15
};
int is_extension_y4m(const char *filename) {
const char *dot = strrchr(filename, '.');
if (!dot || dot == filename)
return 0;
else
return !strcmp(dot, ".y4m");
}
class ArfFreqTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith3Params<TestVideoParam, \
TestEncodeParam, int> {
protected:
ArfFreqTest()
: EncoderTest(GET_PARAM(0)),
test_video_param_(GET_PARAM(1)),
test_encode_param_(GET_PARAM(2)),
min_arf_requested_(GET_PARAM(3)) {
}
virtual ~ArfFreqTest() {}
virtual void SetUp() {
InitializeConfig();
SetMode(test_encode_param_.mode);
if (test_encode_param_.mode != ::libvpx_test::kRealTime) {
cfg_.g_lag_in_frames = 25;
cfg_.rc_end_usage = VPX_VBR;
} else {
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
}
dec_cfg_.threads = 4;
}
virtual void BeginPassHook(unsigned int) {
min_arf_ = ARF_NOT_SEEN;
run_of_visible_frames_ = 0;
}
int GetNumFramesInPkt(const vpx_codec_cx_pkt_t *pkt) {
const uint8_t *buffer = reinterpret_cast<uint8_t*>(pkt->data.frame.buf);
const uint8_t marker = buffer[pkt->data.frame.sz - 1];
const int mag = ((marker >> 3) & 3) + 1;
int frames = (marker & 0x7) + 1;
const unsigned int index_sz = 2 + mag * frames;
// Check for superframe or not.
// Assume superframe has only one visible frame, the rest being
// invisible. If superframe index is not found, then there is only
// one frame.
if (!((marker & 0xe0) == 0xc0 &&
pkt->data.frame.sz >= index_sz &&
buffer[pkt->data.frame.sz - index_sz] == marker)) {
frames = 1;
}
return frames;
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
return;
const int frames = GetNumFramesInPkt(pkt);
if (frames == 1) {
run_of_visible_frames_++;
} else if (frames == 2) {
if (min_arf_ == ARF_NOT_SEEN) {
min_arf_ = ARF_SEEN_ONCE;
} else if (min_arf_ == ARF_SEEN_ONCE ||
run_of_visible_frames_ < min_arf_) {
min_arf_ = run_of_visible_frames_;
}
run_of_visible_frames_ = 1;
} else {
min_arf_ = 0;
run_of_visible_frames_ = 1;
}
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 0) {
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(VP9E_SET_TILE_COLUMNS, 4);
encoder->Control(VP8E_SET_CPUUSED, test_encode_param_.cpu_used);
encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_arf_requested_);
if (test_encode_param_.mode != ::libvpx_test::kRealTime) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
}
}
}
int GetMinArfDistance() const {
return min_arf_;
}
int GetMinArfDistanceRequested() const {
if (min_arf_requested_)
return min_arf_requested_;
else
return vp9_rc_get_default_min_gf_interval(
test_video_param_.width, test_video_param_.height,
(double)test_video_param_.framerate_num /
test_video_param_.framerate_den);
}
TestVideoParam test_video_param_;
TestEncodeParam test_encode_param_;
private:
int min_arf_requested_;
int min_arf_;
int run_of_visible_frames_;
};
TEST_P(ArfFreqTest, MinArfFreqTest) {
cfg_.rc_target_bitrate = kBitrate;
cfg_.g_error_resilient = 0;
cfg_.g_profile = test_video_param_.profile;
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
cfg_.g_bit_depth = test_video_param_.bit_depth;
init_flags_ = VPX_CODEC_USE_PSNR;
if (cfg_.g_bit_depth > 8)
init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
libvpx_test::VideoSource *video;
if (is_extension_y4m(test_video_param_.filename)) {
video = new libvpx_test::Y4mVideoSource(test_video_param_.filename,
0, kFrames);
} else {
video = new libvpx_test::YUVVideoSource(test_video_param_.filename,
test_video_param_.fmt,
test_video_param_.width,
test_video_param_.height,
test_video_param_.framerate_num,
test_video_param_.framerate_den,
0, kFrames);
}
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
const int min_arf_dist = GetMinArfDistance();
const int min_arf_dist_requested = GetMinArfDistanceRequested();
if (min_arf_dist != ARF_NOT_SEEN && min_arf_dist != ARF_SEEN_ONCE) {
EXPECT_GE(min_arf_dist, min_arf_dist_requested);
}
delete(video);
}
VP9_INSTANTIATE_TEST_CASE(
ArfFreqTest,
::testing::ValuesIn(kTestVectors),
::testing::ValuesIn(kEncodeVectors),
::testing::ValuesIn(kMinArfVectors));
} // namespace

View File

@@ -57,7 +57,7 @@ class AverageTestBase : public ::testing::Test {
}
// Sum Pixels
unsigned int ReferenceAverage(const uint8_t* source, int pitch ) {
unsigned int ReferenceAverage8x8(const uint8_t* source, int pitch ) {
unsigned int average = 0;
for (int h = 0; h < 8; ++h)
for (int w = 0; w < 8; ++w)
@@ -65,6 +65,14 @@ class AverageTestBase : public ::testing::Test {
return ((average + 32) >> 6);
}
unsigned int ReferenceAverage4x4(const uint8_t* source, int pitch ) {
unsigned int average = 0;
for (int h = 0; h < 4; ++h)
for (int w = 0; w < 4; ++w)
average += source[h * source_stride_ + w];
return ((average + 8) >> 4);
}
void FillConstant(uint8_t fill_constant) {
for (int i = 0; i < width_ * height_; ++i) {
source_data_[i] = fill_constant;
@@ -85,7 +93,7 @@ class AverageTestBase : public ::testing::Test {
};
typedef unsigned int (*AverageFunction)(const uint8_t* s, int pitch);
typedef std::tr1::tuple<int, int, int, AverageFunction> AvgFunc;
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
class AverageTest
: public AverageTestBase,
@@ -95,18 +103,97 @@ class AverageTest
protected:
void CheckAverages() {
unsigned int expected = ReferenceAverage(source_data_+ GET_PARAM(2),
source_stride_);
unsigned int expected = 0;
if (GET_PARAM(3) == 8) {
expected = ReferenceAverage8x8(source_data_+ GET_PARAM(2),
source_stride_);
} else if (GET_PARAM(3) == 4) {
expected = ReferenceAverage4x4(source_data_+ GET_PARAM(2),
source_stride_);
}
ASM_REGISTER_STATE_CHECK(GET_PARAM(3)(source_data_+ GET_PARAM(2),
ASM_REGISTER_STATE_CHECK(GET_PARAM(4)(source_data_+ GET_PARAM(2),
source_stride_));
unsigned int actual = GET_PARAM(3)(source_data_+ GET_PARAM(2),
unsigned int actual = GET_PARAM(4)(source_data_+ GET_PARAM(2),
source_stride_);
EXPECT_EQ(expected, actual);
}
};
typedef void (*IntProRowFunc)(int16_t hbuf[16], uint8_t const *ref,
const int ref_stride, const int height);
typedef std::tr1::tuple<int, IntProRowFunc, IntProRowFunc> IntProRowParam;
class IntProRowTest
: public AverageTestBase,
public ::testing::WithParamInterface<IntProRowParam> {
public:
IntProRowTest()
: AverageTestBase(16, GET_PARAM(0)),
hbuf_asm_(NULL),
hbuf_c_(NULL) {
asm_func_ = GET_PARAM(1);
c_func_ = GET_PARAM(2);
}
protected:
virtual void SetUp() {
hbuf_asm_ = reinterpret_cast<int16_t*>(
vpx_memalign(kDataAlignment, sizeof(*hbuf_asm_) * 16));
hbuf_c_ = reinterpret_cast<int16_t*>(
vpx_memalign(kDataAlignment, sizeof(*hbuf_c_) * 16));
}
virtual void TearDown() {
vpx_free(hbuf_c_);
hbuf_c_ = NULL;
vpx_free(hbuf_asm_);
hbuf_asm_ = NULL;
}
void RunComparison() {
ASM_REGISTER_STATE_CHECK(c_func_(hbuf_c_, source_data_, 0, height_));
ASM_REGISTER_STATE_CHECK(asm_func_(hbuf_asm_, source_data_, 0, height_));
EXPECT_EQ(0, memcmp(hbuf_c_, hbuf_asm_, sizeof(*hbuf_c_) * 16))
<< "Output mismatch";
}
private:
IntProRowFunc asm_func_;
IntProRowFunc c_func_;
int16_t *hbuf_asm_;
int16_t *hbuf_c_;
};
typedef int16_t (*IntProColFunc)(uint8_t const *ref, const int width);
typedef std::tr1::tuple<int, IntProColFunc, IntProColFunc> IntProColParam;
class IntProColTest
: public AverageTestBase,
public ::testing::WithParamInterface<IntProColParam> {
public:
IntProColTest() : AverageTestBase(GET_PARAM(0), 1), sum_asm_(0), sum_c_(0) {
asm_func_ = GET_PARAM(1);
c_func_ = GET_PARAM(2);
}
protected:
void RunComparison() {
ASM_REGISTER_STATE_CHECK(sum_c_ = c_func_(source_data_, width_));
ASM_REGISTER_STATE_CHECK(sum_asm_ = asm_func_(source_data_, width_));
EXPECT_EQ(sum_c_, sum_asm_) << "Output mismatch";
}
private:
IntProColFunc asm_func_;
IntProColFunc c_func_;
int16_t sum_asm_;
int16_t sum_c_;
};
uint8_t* AverageTestBase::source_data_ = NULL;
@@ -129,22 +216,88 @@ TEST_P(AverageTest, Random) {
}
}
TEST_P(IntProRowTest, MinValue) {
FillConstant(0);
RunComparison();
}
TEST_P(IntProRowTest, MaxValue) {
FillConstant(255);
RunComparison();
}
TEST_P(IntProRowTest, Random) {
FillRandom();
RunComparison();
}
TEST_P(IntProColTest, MinValue) {
FillConstant(0);
RunComparison();
}
TEST_P(IntProColTest, MaxValue) {
FillConstant(255);
RunComparison();
}
TEST_P(IntProColTest, Random) {
FillRandom();
RunComparison();
}
using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, AverageTest,
::testing::Values(
make_tuple(16, 16, 1, &vp9_avg_8x8_c)));
make_tuple(16, 16, 1, 8, &vp9_avg_8x8_c),
make_tuple(16, 16, 1, 4, &vp9_avg_4x4_c)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, AverageTest,
::testing::Values(
make_tuple(16, 16, 0, &vp9_avg_8x8_sse2),
make_tuple(16, 16, 5, &vp9_avg_8x8_sse2),
make_tuple(32, 32, 15, &vp9_avg_8x8_sse2)));
make_tuple(16, 16, 0, 8, &vp9_avg_8x8_sse2),
make_tuple(16, 16, 5, 8, &vp9_avg_8x8_sse2),
make_tuple(32, 32, 15, 8, &vp9_avg_8x8_sse2),
make_tuple(16, 16, 0, 4, &vp9_avg_4x4_sse2),
make_tuple(16, 16, 5, 4, &vp9_avg_4x4_sse2),
make_tuple(32, 32, 15, 4, &vp9_avg_4x4_sse2)));
INSTANTIATE_TEST_CASE_P(
SSE2, IntProRowTest, ::testing::Values(
make_tuple(16, &vp9_int_pro_row_sse2, &vp9_int_pro_row_c),
make_tuple(32, &vp9_int_pro_row_sse2, &vp9_int_pro_row_c),
make_tuple(64, &vp9_int_pro_row_sse2, &vp9_int_pro_row_c)));
INSTANTIATE_TEST_CASE_P(
SSE2, IntProColTest, ::testing::Values(
make_tuple(16, &vp9_int_pro_col_sse2, &vp9_int_pro_col_c),
make_tuple(32, &vp9_int_pro_col_sse2, &vp9_int_pro_col_c),
make_tuple(64, &vp9_int_pro_col_sse2, &vp9_int_pro_col_c)));
#endif
#if HAVE_NEON
INSTANTIATE_TEST_CASE_P(
NEON, AverageTest,
::testing::Values(
make_tuple(16, 16, 0, 8, &vp9_avg_8x8_neon),
make_tuple(16, 16, 5, 8, &vp9_avg_8x8_neon),
make_tuple(32, 32, 15, 8, &vp9_avg_8x8_neon)));
#endif
#if HAVE_MSA
INSTANTIATE_TEST_CASE_P(
MSA, AverageTest,
::testing::Values(
make_tuple(16, 16, 0, 8, &vp9_avg_8x8_msa),
make_tuple(16, 16, 5, 8, &vp9_avg_8x8_msa),
make_tuple(32, 32, 15, 8, &vp9_avg_8x8_msa),
make_tuple(16, 16, 0, 4, &vp9_avg_4x4_msa),
make_tuple(16, 16, 5, 4, &vp9_avg_4x4_msa),
make_tuple(32, 32, 15, 4, &vp9_avg_4x4_msa)));
#endif
} // namespace

View File

@@ -52,10 +52,10 @@ TEST_P(VP9DenoiserTest, BitexactCheck) {
// mc_avg_block is the denoised reference block,
// avg_block_c is the denoised result from C code,
// avg_block_sse2 is the denoised result from SSE2 code.
DECLARE_ALIGNED_ARRAY(16, uint8_t, sig_block, kNumPixels);
DECLARE_ALIGNED_ARRAY(16, uint8_t, mc_avg_block, kNumPixels);
DECLARE_ALIGNED_ARRAY(16, uint8_t, avg_block_c, kNumPixels);
DECLARE_ALIGNED_ARRAY(16, uint8_t, avg_block_sse2, kNumPixels);
DECLARE_ALIGNED(16, uint8_t, sig_block[kNumPixels]);
DECLARE_ALIGNED(16, uint8_t, mc_avg_block[kNumPixels]);
DECLARE_ALIGNED(16, uint8_t, avg_block_c[kNumPixels]);
DECLARE_ALIGNED(16, uint8_t, avg_block_sse2[kNumPixels]);
for (int i = 0; i < count_test_block; ++i) {
// Generate random motion magnitude, 20% of which exceed the threshold.

View File

@@ -0,0 +1,193 @@
/*
* 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 "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/y4m_video_source.h"
#include "test/yuv_video_source.h"
#include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "vp9/decoder/vp9_decoder.h"
typedef vpx_codec_stream_info_t vp9_stream_info_t;
struct vpx_codec_alg_priv {
vpx_codec_priv_t base;
vpx_codec_dec_cfg_t cfg;
vp9_stream_info_t si;
struct VP9Decoder *pbi;
int postproc_cfg_set;
vp8_postproc_cfg_t postproc_cfg;
vpx_decrypt_cb decrypt_cb;
void *decrypt_state;
vpx_image_t img;
int img_avail;
int flushed;
int invert_tile_order;
int frame_parallel_decode;
// External frame buffer info to save for VP9 common.
void *ext_priv; // Private data associated with the external frame buffers.
vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb;
vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
};
static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) {
return (vpx_codec_alg_priv_t *)ctx->priv;
}
namespace {
const unsigned int kFramerate = 50;
const int kCpuUsed = 2;
struct EncodePerfTestVideo {
const char *name;
uint32_t width;
uint32_t height;
uint32_t bitrate;
int frames;
};
const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
{"niklas_1280_720_30.y4m", 1280, 720, 600, 10},
};
struct EncodeParameters {
int32_t tile_rows;
int32_t tile_cols;
int32_t lossless;
int32_t error_resilient;
int32_t frame_parallel;
vpx_color_space_t cs;
// TODO(JBB): quantizers / bitrate
};
const EncodeParameters kVP9EncodeParameterSet[] = {
{0, 0, 0, 1, 0, VPX_CS_BT_601},
{0, 0, 0, 0, 0, VPX_CS_BT_709},
{0, 0, 1, 0, 0, VPX_CS_BT_2020},
{0, 2, 0, 0, 1, VPX_CS_UNKNOWN},
// TODO(JBB): Test profiles (requires more work).
};
int is_extension_y4m(const char *filename) {
const char *dot = strrchr(filename, '.');
if (!dot || dot == filename)
return 0;
else
return !strcmp(dot, ".y4m");
}
class Vp9EncoderParmsGetToDecoder
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<EncodeParameters, \
EncodePerfTestVideo> {
protected:
Vp9EncoderParmsGetToDecoder()
: EncoderTest(GET_PARAM(0)),
encode_parms(GET_PARAM(1)) {
}
virtual ~Vp9EncoderParmsGetToDecoder() {}
virtual void SetUp() {
InitializeConfig();
SetMode(::libvpx_test::kTwoPassGood);
cfg_.g_lag_in_frames = 25;
cfg_.g_error_resilient = encode_parms.error_resilient;
dec_cfg_.threads = 4;
test_video_ = GET_PARAM(2);
cfg_.rc_target_bitrate = test_video_.bitrate;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP9E_SET_COLOR_SPACE, encode_parms.cs);
encoder->Control(VP9E_SET_LOSSLESS, encode_parms.lossless);
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
encode_parms.frame_parallel);
encoder->Control(VP9E_SET_TILE_ROWS, encode_parms.tile_rows);
encoder->Control(VP9E_SET_TILE_COLUMNS, encode_parms.tile_cols);
encoder->Control(VP8E_SET_CPUUSED, kCpuUsed);
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
}
}
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
const libvpx_test::VideoSource& video,
libvpx_test::Decoder *decoder) {
vpx_codec_ctx_t* vp9_decoder = decoder->GetDecoder();
vpx_codec_alg_priv_t* priv =
(vpx_codec_alg_priv_t*) get_alg_priv(vp9_decoder);
VP9Decoder* pbi = priv->pbi;
VP9_COMMON* common = &pbi->common;
if (encode_parms.lossless) {
EXPECT_EQ(common->base_qindex, 0);
EXPECT_EQ(common->y_dc_delta_q, 0);
EXPECT_EQ(common->uv_dc_delta_q, 0);
EXPECT_EQ(common->uv_ac_delta_q, 0);
EXPECT_EQ(common->tx_mode, ONLY_4X4);
}
EXPECT_EQ(common->error_resilient_mode, encode_parms.error_resilient);
if (encode_parms.error_resilient) {
EXPECT_EQ(common->frame_parallel_decoding_mode, 1);
EXPECT_EQ(common->use_prev_frame_mvs, 0);
} else {
EXPECT_EQ(common->frame_parallel_decoding_mode,
encode_parms.frame_parallel);
}
EXPECT_EQ(common->color_space, encode_parms.cs);
EXPECT_EQ(common->log2_tile_cols, encode_parms.tile_cols);
EXPECT_EQ(common->log2_tile_rows, encode_parms.tile_rows);
EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
return VPX_CODEC_OK == res_dec;
}
EncodePerfTestVideo test_video_;
private:
EncodeParameters encode_parms;
};
// TODO(hkuang): This test conflicts with frame parallel decode. So disable it
// for now until fix.
TEST_P(Vp9EncoderParmsGetToDecoder, DISABLED_BitstreamParms) {
init_flags_ = VPX_CODEC_USE_PSNR;
libvpx_test::VideoSource *video;
if (is_extension_y4m(test_video_.name)) {
video = new libvpx_test::Y4mVideoSource(test_video_.name,
0, test_video_.frames);
} else {
video = new libvpx_test::YUVVideoSource(test_video_.name,
VPX_IMG_FMT_I420,
test_video_.width,
test_video_.height,
kFramerate, 1, 0,
test_video_.frames);
}
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
delete(video);
}
VP9_INSTANTIATE_TEST_CASE(
Vp9EncoderParmsGetToDecoder,
::testing::ValuesIn(kVP9EncodeParameterSet),
::testing::ValuesIn(kVP9EncodePerfTestVectors));
} // namespace

View File

@@ -22,8 +22,17 @@ const unsigned int kHeight = 90;
const unsigned int kFramerate = 50;
const unsigned int kFrames = 10;
const int kBitrate = 500;
const int kCpuUsed = 0;
const double psnr_threshold = 35.0;
// List of psnr thresholds for speed settings 0-7 and 5 encoding modes
const double kPsnrThreshold[][5] = {
{ 36.0, 37.0, 37.0, 37.0, 37.0 },
{ 35.0, 36.0, 36.0, 36.0, 36.0 },
{ 34.0, 35.0, 35.0, 35.0, 35.0 },
{ 33.0, 34.0, 34.0, 34.0, 34.0 },
{ 32.0, 33.0, 33.0, 33.0, 33.0 },
{ 31.0, 32.0, 32.0, 32.0, 32.0 },
{ 30.0, 31.0, 31.0, 31.0, 31.0 },
{ 29.0, 30.0, 30.0, 30.0, 30.0 },
};
typedef struct {
const char *filename;
@@ -33,7 +42,7 @@ typedef struct {
unsigned int profile;
} TestVideoParam;
const TestVideoParam TestVectors[] = {
const TestVideoParam kTestVectors[] = {
{"park_joy_90p_8_420.y4m", 8, VPX_IMG_FMT_I420, VPX_BITS_8, 0},
{"park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, VPX_BITS_8, 1},
{"park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1},
@@ -50,6 +59,16 @@ const TestVideoParam TestVectors[] = {
#endif // CONFIG_VP9_HIGHBITDEPTH
};
// Encoding modes tested
const libvpx_test::TestMode kEncodingModeVectors[] = {
::libvpx_test::kTwoPassGood,
::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime,
};
// Speed settings tested
const int kCpuUsedVectors[] = {1, 2, 3, 5, 6};
int is_extension_y4m(const char *filename) {
const char *dot = strrchr(filename, '.');
if (!dot || dot == filename)
@@ -60,11 +79,13 @@ int is_extension_y4m(const char *filename) {
class EndToEndTestLarge
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, \
TestVideoParam> {
public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, \
TestVideoParam, int> {
protected:
EndToEndTestLarge()
: EncoderTest(GET_PARAM(0)),
test_video_param_(GET_PARAM(2)),
cpu_used_(GET_PARAM(3)),
psnr_(0.0),
nframes_(0),
encoding_mode_(GET_PARAM(1)) {
@@ -81,8 +102,11 @@ class EndToEndTestLarge
} else {
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.rc_buf_sz = 1000;
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 600;
}
test_video_param_ = GET_PARAM(2);
dec_cfg_.threads = 4;
}
virtual void BeginPassHook(unsigned int) {
@@ -98,7 +122,9 @@ class EndToEndTestLarge
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP8E_SET_CPUUSED, kCpuUsed);
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
encoder->Control(VP9E_SET_TILE_COLUMNS, 4);
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
@@ -114,7 +140,12 @@ class EndToEndTestLarge
return 0.0;
}
double GetPsnrThreshold() {
return kPsnrThreshold[cpu_used_][encoding_mode_];
}
TestVideoParam test_video_param_;
int cpu_used_;
private:
double psnr_;
@@ -129,6 +160,8 @@ TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) {
cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
cfg_.g_bit_depth = test_video_param_.bit_depth;
init_flags_ = VPX_CODEC_USE_PSNR;
if (cfg_.g_bit_depth > 8)
init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
libvpx_test::VideoSource *video;
if (is_extension_y4m(test_video_param_.filename)) {
@@ -143,13 +176,14 @@ TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) {
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
const double psnr = GetAveragePsnr();
EXPECT_GT(psnr, psnr_threshold);
EXPECT_GT(psnr, GetPsnrThreshold());
delete(video);
}
VP9_INSTANTIATE_TEST_CASE(
EndToEndTestLarge,
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
::testing::ValuesIn(TestVectors));
::testing::ValuesIn(kEncodingModeVectors),
::testing::ValuesIn(kTestVectors),
::testing::ValuesIn(kCpuUsedVectors));
} // namespace

View File

@@ -13,27 +13,31 @@
#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_codec.h"
#include "vpx/vpx_integer.h"
using libvpx_test::ACMRandom;
namespace {
#if CONFIG_VP9_HIGHBITDEPTH
const int number_of_iterations = 1000;
const int kNumIterations = 1000;
typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
const tran_low_t *dqcoeff, intptr_t block_size,
int64_t *ssz, int bps);
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:
@@ -54,8 +58,8 @@ class ErrorBlockTest
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);
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
int err_count_total = 0;
int first_failure = -1;
intptr_t block_size;
@@ -63,12 +67,12 @@ TEST_P(ErrorBlockTest, OperationCheck) {
int64_t ret;
int64_t ref_ssz;
int64_t ref_ret;
for (int i = 0; i < number_of_iterations; ++i) {
for (int i = 0; i < kNumIterations; ++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);
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_);
@@ -81,14 +85,14 @@ TEST_P(ErrorBlockTest, OperationCheck) {
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;
<< "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);
DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
int err_count_total = 0;
int first_failure = -1;
intptr_t block_size;
@@ -96,8 +100,8 @@ TEST_P(ErrorBlockTest, ExtremeValues) {
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 max_val = ((1 << 20) - 1);
for (int i = 0; i < kNumIterations; ++i) {
int err_count = 0;
int k = (i / 9) % 5;
@@ -126,21 +130,22 @@ TEST_P(ErrorBlockTest, ExtremeValues) {
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;
<< "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)));
SSE2, 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

137
test/vp9_ethread_test.cc Normal file
View File

@@ -0,0 +1,137 @@
/*
* 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 <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/md5_helper.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
namespace {
class VP9EncoderThreadTest
: public ::libvpx_test::EncoderTest,
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
protected:
VP9EncoderThreadTest()
: EncoderTest(GET_PARAM(0)),
encoder_initialized_(false),
tiles_(2),
encoding_mode_(GET_PARAM(1)),
set_cpu_used_(GET_PARAM(2)) {
init_flags_ = VPX_CODEC_USE_PSNR;
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
cfg.w = 1280;
cfg.h = 720;
decoder_ = codec_->CreateDecoder(cfg, 0);
md5_.clear();
}
virtual ~VP9EncoderThreadTest() {
delete decoder_;
}
virtual void SetUp() {
InitializeConfig();
SetMode(encoding_mode_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
cfg_.g_lag_in_frames = 3;
cfg_.rc_end_usage = VPX_VBR;
cfg_.rc_2pass_vbr_minsection_pct = 5;
cfg_.rc_2pass_vbr_minsection_pct = 2000;
} else {
cfg_.g_lag_in_frames = 0;
cfg_.rc_end_usage = VPX_CBR;
cfg_.g_error_resilient = 1;
}
cfg_.rc_max_quantizer = 56;
cfg_.rc_min_quantizer = 0;
}
virtual void BeginPassHook(unsigned int /*pass*/) {
encoder_initialized_ = false;
}
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (!encoder_initialized_) {
// Encode 4 column tiles.
encoder->Control(VP9E_SET_TILE_COLUMNS, tiles_);
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
if (encoding_mode_ != ::libvpx_test::kRealTime) {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
encoder->Control(VP8E_SET_ARNR_STRENGTH, 5);
encoder->Control(VP8E_SET_ARNR_TYPE, 3);
} else {
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
encoder->Control(VP9E_SET_AQ_MODE, 3);
}
encoder_initialized_ = true;
}
}
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
const vpx_codec_err_t res = decoder_->DecodeFrame(
reinterpret_cast<uint8_t*>(pkt->data.frame.buf), pkt->data.frame.sz);
if (res != VPX_CODEC_OK) {
abort_ = true;
ASSERT_EQ(VPX_CODEC_OK, res);
}
const vpx_image_t *img = decoder_->GetDxData().Next();
if (img) {
::libvpx_test::MD5 md5_res;
md5_res.Add(img);
md5_.push_back(md5_res.Get());
}
}
bool encoder_initialized_;
int tiles_;
::libvpx_test::TestMode encoding_mode_;
int set_cpu_used_;
::libvpx_test::Decoder *decoder_;
std::vector<std::string> md5_;
};
TEST_P(VP9EncoderThreadTest, EncoderResultTest) {
std::vector<std::string> single_thr_md5, multi_thr_md5;
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 20);
cfg_.rc_target_bitrate = 1000;
// Encode using single thread.
cfg_.g_threads = 1;
init_flags_ = VPX_CODEC_USE_PSNR;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
single_thr_md5 = md5_;
md5_.clear();
// Encode using multiple threads.
cfg_.g_threads = 4;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
multi_thr_md5 = md5_;
md5_.clear();
// Compare to check if two vectors are equal.
ASSERT_EQ(single_thr_md5, multi_thr_md5);
}
VP9_INSTANTIATE_TEST_CASE(
VP9EncoderThreadTest,
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
::libvpx_test::kRealTime),
::testing::Range(1, 9));
} // namespace

View File

@@ -0,0 +1,220 @@
/*
* 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 <cstdio>
#include <cstdlib>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/ivf_video_source.h"
#include "test/md5_helper.h"
#include "test/util.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
#include "vpx_mem/vpx_mem.h"
namespace {
using std::string;
#if CONFIG_WEBM_IO
struct PauseFileList {
const char *name;
// md5 sum for decoded frames which does not include skipped frames.
const char *expected_md5;
const int pause_frame_num;
};
// Decodes |filename| with |num_threads|. Pause at the specified frame_num,
// seek to next key frame and then continue decoding until the end. Return
// the md5 of the decoded frames which does not include skipped frames.
string DecodeFileWithPause(const string &filename, int num_threads,
int pause_num) {
libvpx_test::WebMVideoSource video(filename);
video.Init();
int in_frames = 0;
int out_frames = 0;
vpx_codec_dec_cfg_t cfg = {0};
cfg.threads = num_threads;
vpx_codec_flags_t flags = 0;
flags |= VPX_CODEC_USE_FRAME_THREADING;
libvpx_test::VP9Decoder decoder(cfg, flags, 0);
libvpx_test::MD5 md5;
video.Begin();
do {
++in_frames;
const vpx_codec_err_t res =
decoder.DecodeFrame(video.cxdata(), video.frame_size());
if (res != VPX_CODEC_OK) {
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
break;
}
// Pause at specified frame number.
if (in_frames == pause_num) {
// Flush the decoder and then seek to next key frame.
decoder.DecodeFrame(NULL, 0);
video.SeekToNextKeyFrame();
} else {
video.Next();
}
// Flush the decoder at the end of the video.
if (!video.cxdata())
decoder.DecodeFrame(NULL, 0);
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
const vpx_image_t *img;
// Get decompressed data
while ((img = dec_iter.Next())) {
++out_frames;
md5.Add(img);
}
} while (video.cxdata() != NULL);
EXPECT_EQ(in_frames, out_frames) <<
"Input frame count does not match output frame count";
return string(md5.Get());
}
void DecodeFilesWithPause(const PauseFileList files[]) {
for (const PauseFileList *iter = files; iter->name != NULL; ++iter) {
SCOPED_TRACE(iter->name);
for (int t = 2; t <= 8; ++t) {
EXPECT_EQ(iter->expected_md5,
DecodeFileWithPause(iter->name, t, iter->pause_frame_num))
<< "threads = " << t;
}
}
}
TEST(VP9MultiThreadedFrameParallel, PauseSeekResume) {
// vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
// one key frame for every ten frames.
static const PauseFileList files[] = {
{ "vp90-2-07-frame_parallel-1.webm",
"6ea7c3875d67252e7caf2bc6e75b36b1", 6 },
{ "vp90-2-07-frame_parallel-1.webm",
"4bb634160c7356a8d7d4299b6dc83a45", 12 },
{ "vp90-2-07-frame_parallel-1.webm",
"89772591e6ef461f9fa754f916c78ed8", 26 },
{ NULL, NULL, 0 },
};
DecodeFilesWithPause(files);
}
struct FileList {
const char *name;
// md5 sum for decoded frames which does not include corrupted frames.
const char *expected_md5;
// Expected number of decoded frames which does not include corrupted frames.
const int expected_frame_count;
};
// Decodes |filename| with |num_threads|. Return the md5 of the decoded
// frames which does not include corrupted frames.
string DecodeFile(const string &filename, int num_threads,
int expected_frame_count) {
libvpx_test::WebMVideoSource video(filename);
video.Init();
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
cfg.threads = num_threads;
const vpx_codec_flags_t flags = VPX_CODEC_USE_FRAME_THREADING;
libvpx_test::VP9Decoder decoder(cfg, flags, 0);
libvpx_test::MD5 md5;
video.Begin();
int out_frames = 0;
do {
const vpx_codec_err_t res =
decoder.DecodeFrame(video.cxdata(), video.frame_size());
// TODO(hkuang): frame parallel mode should return an error on corruption.
if (res != VPX_CODEC_OK) {
EXPECT_EQ(VPX_CODEC_OK, res) << decoder.DecodeError();
break;
}
video.Next();
// Flush the decoder at the end of the video.
if (!video.cxdata())
decoder.DecodeFrame(NULL, 0);
libvpx_test::DxDataIterator dec_iter = decoder.GetDxData();
const vpx_image_t *img;
// Get decompressed data
while ((img = dec_iter.Next())) {
++out_frames;
md5.Add(img);
}
} while (video.cxdata() != NULL);
EXPECT_EQ(expected_frame_count, out_frames) <<
"Input frame count does not match expected output frame count";
return string(md5.Get());
}
void DecodeFiles(const FileList files[]) {
for (const FileList *iter = files; iter->name != NULL; ++iter) {
SCOPED_TRACE(iter->name);
for (int t = 2; t <= 8; ++t) {
EXPECT_EQ(iter->expected_md5,
DecodeFile(iter->name, t, iter->expected_frame_count))
<< "threads = " << t;
}
}
}
TEST(VP9MultiThreadedFrameParallel, InvalidFileTest) {
static const FileList files[] = {
// invalid-vp90-2-07-frame_parallel-1.webm is a 40 frame video file with
// one key frame for every ten frames. The 11th frame has corrupted data.
{ "invalid-vp90-2-07-frame_parallel-1.webm",
"0549d0f45f60deaef8eb708e6c0eb6cb", 30 },
// invalid-vp90-2-07-frame_parallel-2.webm is a 40 frame video file with
// one key frame for every ten frames. The 1st and 31st frames have
// corrupted data.
{ "invalid-vp90-2-07-frame_parallel-2.webm",
"6a1f3cf6f9e7a364212fadb9580d525e", 20 },
// invalid-vp90-2-07-frame_parallel-3.webm is a 40 frame video file with
// one key frame for every ten frames. The 5th and 13th frames have
// corrupted data.
{ "invalid-vp90-2-07-frame_parallel-3.webm",
"8256544308de926b0681e04685b98677", 27 },
{ NULL, NULL, 0 },
};
DecodeFiles(files);
}
TEST(VP9MultiThreadedFrameParallel, ValidFileTest) {
static const FileList files[] = {
#if CONFIG_VP9_HIGHBITDEPTH
{ "vp92-2-20-10bit-yuv420.webm",
"a16b99df180c584e8db2ffeda987d293", 10 },
#endif
{ NULL, NULL, 0 },
};
DecodeFiles(files);
}
#endif // CONFIG_WEBM_IO
} // namespace

View File

@@ -120,10 +120,10 @@ class VP9IntraPredTest
TEST_P(VP9IntraPredTest, IntraPredTests) {
// max block size is 32
DECLARE_ALIGNED_ARRAY(16, uint16_t, left_col, 2*32);
DECLARE_ALIGNED_ARRAY(16, uint16_t, above_data, 2*32+32);
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst, 3 * 32 * 32);
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_dst, 3 * 32 * 32);
DECLARE_ALIGNED(16, uint16_t, left_col[2*32]);
DECLARE_ALIGNED(16, uint16_t, above_data[2*32+32]);
DECLARE_ALIGNED(16, uint16_t, dst[3 * 32 * 32]);
DECLARE_ALIGNED(16, uint16_t, ref_dst[3 * 32 * 32]);
RunTest(left_col, above_data, dst, ref_dst);
}

351
test/vp9_quantize_test.cc Normal file
View File

@@ -0,0 +1,351 @@
/*
* 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 <math.h>
#include <stdlib.h>
#include <string.h>
#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 "vp9/common/vp9_scan.h"
#include "vpx/vpx_codec.h"
#include "vpx/vpx_integer.h"
using libvpx_test::ACMRandom;
namespace {
#if CONFIG_VP9_HIGHBITDEPTH
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,
uint16_t *eob, const int16_t *scan,
const int16_t *iscan);
typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
QuantizeParam;
class VP9QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
public:
virtual ~VP9QuantizeTest() {}
virtual void SetUp() {
quantize_op_ = GET_PARAM(0);
ref_quantize_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
mask_ = (1 << bit_depth_) - 1;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
vpx_bit_depth_t bit_depth_;
int mask_;
QuantizeFunc quantize_op_;
QuantizeFunc ref_quantize_op_;
};
class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
public:
virtual ~VP9Quantize32Test() {}
virtual void SetUp() {
quantize_op_ = GET_PARAM(0);
ref_quantize_op_ = GET_PARAM(1);
bit_depth_ = GET_PARAM(2);
mask_ = (1 << bit_depth_) - 1;
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
vpx_bit_depth_t bit_depth_;
int mask_;
QuantizeFunc quantize_op_;
QuantizeFunc ref_quantize_op_;
};
TEST_P(VP9QuantizeTest, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
DECLARE_ALIGNED(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) {
const int skip_block = i == 0;
const TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
const TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
const 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,
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, 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(VP9Quantize32Test, OperationCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
DECLARE_ALIGNED(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) {
const int skip_block = i == 0;
const TX_SIZE sz = TX_32X32;
const TX_TYPE tx_type = (TX_TYPE)(i % 4);
const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
const 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,
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, 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(VP9QuantizeTest, EOBCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
DECLARE_ALIGNED(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,
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, 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(VP9Quantize32Test, EOBCheck) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
DECLARE_ALIGNED(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,
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, 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
INSTANTIATE_TEST_CASE_P(
SSE2, VP9QuantizeTest,
::testing::Values(
make_tuple(&vp9_highbd_quantize_b_sse2,
&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, VP9Quantize32Test,
::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 // CONFIG_VP9_HIGHBITDEPTH
} // namespace

View File

@@ -0,0 +1,180 @@
/*
* 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 <string>
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/md5_helper.h"
#include "test/util.h"
#include "test/webm_video_source.h"
namespace {
const char kVp9TestFile[] = "vp90-2-08-tile_1x8_frame_parallel.webm";
const char kVp9Md5File[] = "vp90-2-08-tile_1x8_frame_parallel.webm.md5";
// Class for testing shutting off the loop filter.
class SkipLoopFilterTest {
public:
SkipLoopFilterTest()
: video_(NULL),
decoder_(NULL),
md5_file_(NULL) {}
~SkipLoopFilterTest() {
if (md5_file_ != NULL)
fclose(md5_file_);
delete decoder_;
delete video_;
}
// If |threads| > 0 then set the decoder with that number of threads.
void Init(int num_threads) {
expected_md5_[0] = '\0';
junk_[0] = '\0';
video_ = new libvpx_test::WebMVideoSource(kVp9TestFile);
ASSERT_TRUE(video_ != NULL);
video_->Init();
video_->Begin();
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
if (num_threads > 0)
cfg.threads = num_threads;
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
ASSERT_TRUE(decoder_ != NULL);
OpenMd5File(kVp9Md5File);
}
// Set the VP9 skipLoopFilter control value.
void SetSkipLoopFilter(int value, vpx_codec_err_t expected_value) {
decoder_->Control(VP9_SET_SKIP_LOOP_FILTER, value, expected_value);
}
vpx_codec_err_t DecodeOneFrame() {
const vpx_codec_err_t res =
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
if (res == VPX_CODEC_OK) {
ReadMd5();
video_->Next();
}
return res;
}
vpx_codec_err_t DecodeRemainingFrames() {
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;
ReadMd5();
}
return VPX_CODEC_OK;
}
// Checks if MD5 matches or doesn't.
void CheckMd5(bool matches) {
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
const vpx_image_t *img = dec_iter.Next();
CheckMd5Vpx(*img, matches);
}
private:
// 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;
}
// Reads the next line of the MD5 file.
void ReadMd5() {
ASSERT_TRUE(md5_file_ != NULL);
const int res = fscanf(md5_file_, "%s %s", expected_md5_, junk_);
ASSERT_NE(EOF, res) << "Read md5 data failed";
expected_md5_[32] = '\0';
}
// Checks if the last read MD5 matches |img| or doesn't.
void CheckMd5Vpx(const vpx_image_t &img, bool matches) {
::libvpx_test::MD5 md5_res;
md5_res.Add(&img);
const char *const actual_md5 = md5_res.Get();
// Check MD5.
if (matches)
ASSERT_STREQ(expected_md5_, actual_md5) << "MD5 checksums don't match";
else
ASSERT_STRNE(expected_md5_, actual_md5) << "MD5 checksums match";
}
libvpx_test::WebMVideoSource *video_;
libvpx_test::VP9Decoder *decoder_;
FILE *md5_file_;
char expected_md5_[33];
char junk_[128];
};
TEST(SkipLoopFilterTest, ShutOffLoopFilter) {
const int non_zero_value = 1;
const int num_threads = 0;
SkipLoopFilterTest skip_loop_filter;
skip_loop_filter.Init(num_threads);
skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames());
skip_loop_filter.CheckMd5(false);
}
TEST(SkipLoopFilterTest, ShutOffLoopFilterSingleThread) {
const int non_zero_value = 1;
const int num_threads = 1;
SkipLoopFilterTest skip_loop_filter;
skip_loop_filter.Init(num_threads);
skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames());
skip_loop_filter.CheckMd5(false);
}
TEST(SkipLoopFilterTest, ShutOffLoopFilter8Threads) {
const int non_zero_value = 1;
const int num_threads = 8;
SkipLoopFilterTest skip_loop_filter;
skip_loop_filter.Init(num_threads);
skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames());
skip_loop_filter.CheckMd5(false);
}
TEST(SkipLoopFilterTest, WithLoopFilter) {
const int non_zero_value = 1;
const int num_threads = 0;
SkipLoopFilterTest skip_loop_filter;
skip_loop_filter.Init(num_threads);
skip_loop_filter.SetSkipLoopFilter(non_zero_value, VPX_CODEC_OK);
skip_loop_filter.SetSkipLoopFilter(0, VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames());
skip_loop_filter.CheckMd5(true);
}
TEST(SkipLoopFilterTest, ToggleLoopFilter) {
const int num_threads = 0;
SkipLoopFilterTest skip_loop_filter;
skip_loop_filter.Init(num_threads);
for (int i = 0; i < 10; ++i) {
skip_loop_filter.SetSkipLoopFilter(i % 2, VPX_CODEC_OK);
ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeOneFrame());
}
ASSERT_EQ(VPX_CODEC_OK, skip_loop_filter.DecodeRemainingFrames());
skip_loop_filter.CheckMd5(false);
}
} // namespace

72
test/vp9_spatial_svc_encoder.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/sh
##
## 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.
##
## This file tests the libvpx vp9_spatial_svc_encoder example. To add new
## tests to to this file, do the following:
## 1. Write a shell function (this is your test).
## 2. Add the function to vp9_spatial_svc_tests (on a new line).
##
. $(dirname $0)/tools_common.sh
# Environment check: $YUV_RAW_INPUT is required.
vp9_spatial_svc_encoder_verify_environment() {
if [ ! -e "${YUV_RAW_INPUT}" ]; then
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
return 1
fi
}
# Runs vp9_spatial_svc_encoder. $1 is the test name.
vp9_spatial_svc_encoder() {
local readonly \
encoder="${LIBVPX_BIN_PATH}/vp9_spatial_svc_encoder${VPX_TEST_EXE_SUFFIX}"
local readonly test_name="$1"
local readonly \
output_file="${VPX_TEST_OUTPUT_DIR}/vp9_ssvc_encoder${test_name}.ivf"
local readonly frames_to_encode=10
local readonly max_kf=9999
shift
if [ ! -x "${encoder}" ]; then
elog "${encoder} does not exist or is not executable."
return 1
fi
eval "${VPX_TEST_PREFIX}" "${encoder}" -w "${YUV_RAW_INPUT_WIDTH}" \
-h "${YUV_RAW_INPUT_HEIGHT}" -k "${max_kf}" -f "${frames_to_encode}" \
"$@" "${YUV_RAW_INPUT}" "${output_file}" ${devnull}
[ -e "${output_file}" ] || return 1
}
# Each test is run with layer count 1-$vp9_ssvc_test_layers.
vp9_ssvc_test_layers=5
vp9_spatial_svc() {
if [ "$(vp9_encode_available)" = "yes" ]; then
local readonly test_name="vp9_spatial_svc"
for layers in $(seq 1 ${vp9_ssvc_test_layers}); do
vp9_spatial_svc_encoder "${test_name}" -l ${layers}
done
fi
}
readonly vp9_spatial_svc_tests="DISABLED_vp9_spatial_svc_mode_i
DISABLED_vp9_spatial_svc_mode_altip
DISABLED_vp9_spatial_svc_mode_ip
DISABLED_vp9_spatial_svc_mode_gf
vp9_spatial_svc"
if [ "$(vpx_config_option_enabled CONFIG_SPATIAL_SVC)" = "yes" ]; then
run_tests \
vp9_spatial_svc_encoder_verify_environment \
"${vp9_spatial_svc_tests}"
fi

View File

@@ -207,7 +207,7 @@ int Reset(VP9Worker *const /*worker*/) { return 1; }
int Sync(VP9Worker *const worker) { return !worker->had_error; }
void Execute(VP9Worker *const worker) {
worker->had_error |= worker->hook(worker->data1, worker->data2);
worker->had_error |= !worker->hook(worker->data1, worker->data2);
}
void Launch(VP9Worker *const worker) { Execute(worker); }

View File

@@ -33,10 +33,10 @@ class VpxScaleBase {
void ResetImage(int width, int height) {
width_ = width;
height_ = height;
vpx_memset(&img_, 0, sizeof(img_));
memset(&img_, 0, sizeof(img_));
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&img_, width_, height_,
VP8BORDERINPIXELS));
vpx_memset(img_.buffer_alloc, kBufFiller, img_.frame_size);
memset(img_.buffer_alloc, kBufFiller, img_.frame_size);
FillPlane(img_.y_buffer, img_.y_crop_width, img_.y_crop_height,
img_.y_stride);
FillPlane(img_.u_buffer, img_.uv_crop_width, img_.uv_crop_height,
@@ -44,15 +44,15 @@ class VpxScaleBase {
FillPlane(img_.v_buffer, img_.uv_crop_width, img_.uv_crop_height,
img_.uv_stride);
vpx_memset(&ref_img_, 0, sizeof(ref_img_));
memset(&ref_img_, 0, sizeof(ref_img_));
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&ref_img_, width_, height_,
VP8BORDERINPIXELS));
vpx_memset(ref_img_.buffer_alloc, kBufFiller, ref_img_.frame_size);
memset(ref_img_.buffer_alloc, kBufFiller, ref_img_.frame_size);
vpx_memset(&cpy_img_, 0, sizeof(cpy_img_));
memset(&cpy_img_, 0, sizeof(cpy_img_));
ASSERT_EQ(0, vp8_yv12_alloc_frame_buffer(&cpy_img_, width_, height_,
VP8BORDERINPIXELS));
vpx_memset(cpy_img_.buffer_alloc, kBufFiller, cpy_img_.frame_size);
memset(cpy_img_.buffer_alloc, kBufFiller, cpy_img_.frame_size);
ReferenceCopyFrame();
}
@@ -87,8 +87,8 @@ class VpxScaleBase {
// Fill the border pixels from the nearest image pixel.
for (int y = 0; y < crop_height; ++y) {
vpx_memset(left, left[padding], padding);
vpx_memset(right, right[-1], right_extend);
memset(left, left[padding], padding);
memset(right, right[-1], right_extend);
left += stride;
right += stride;
}
@@ -101,13 +101,13 @@ class VpxScaleBase {
// The first row was already extended to the left and right. Copy it up.
for (int y = 0; y < padding; ++y) {
vpx_memcpy(top, left, extend_width);
memcpy(top, left, extend_width);
top += stride;
}
uint8_t *bottom = left + (crop_height * stride);
for (int y = 0; y < bottom_extend; ++y) {
vpx_memcpy(bottom, left + (crop_height - 1) * stride, extend_width);
memcpy(bottom, left + (crop_height - 1) * stride, extend_width);
bottom += stride;
}
}

290
test/vpx_temporal_svc_encoder.sh Executable file
View File

@@ -0,0 +1,290 @@
#!/bin/sh
##
## 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.
##
## This file tests the libvpx vpx_temporal_svc_encoder example. To add new
## tests to this file, do the following:
## 1. Write a shell function (this is your test).
## 2. Add the function to vpx_tsvc_encoder_tests (on a new line).
##
. $(dirname $0)/tools_common.sh
# Environment check: $YUV_RAW_INPUT is required.
vpx_tsvc_encoder_verify_environment() {
if [ ! -e "${YUV_RAW_INPUT}" ]; then
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
return 1
fi
if [ "$(vpx_config_option_enabled CONFIG_TEMPORAL_DENOISING)" != "yes" ]; then
elog "Warning: Temporal denoising is disabled! Spatial denoising will be " \
"used instead, which is probably not what you want for this test."
fi
}
# Runs vpx_temporal_svc_encoder using the codec specified by $1 and output file
# name by $2. Additional positional parameters are passed directly to
# vpx_temporal_svc_encoder.
vpx_tsvc_encoder() {
local encoder="${LIBVPX_BIN_PATH}/vpx_temporal_svc_encoder"
encoder="${encoder}${VPX_TEST_EXE_SUFFIX}"
local codec="$1"
local output_file_base="$2"
local output_file="${VPX_TEST_OUTPUT_DIR}/${output_file_base}"
local timebase_num="1"
local timebase_den="1000"
local speed="6"
local frame_drop_thresh="30"
shift 2
if [ ! -x "${encoder}" ]; then
elog "${encoder} does not exist or is not executable."
return 1
fi
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT}" "${output_file}" \
"${codec}" "${YUV_RAW_INPUT_WIDTH}" "${YUV_RAW_INPUT_HEIGHT}" \
"${timebase_num}" "${timebase_den}" "${speed}" "${frame_drop_thresh}" \
"$@" \
${devnull}
}
# Confirms that all expected output files exist given the output file name
# passed to vpx_temporal_svc_encoder.
# The file name passed to vpx_temporal_svc_encoder is joined with the stream
# number and the extension .ivf to produce per stream output files. Here $1 is
# file name, and $2 is expected number of files.
files_exist() {
local file_name="${VPX_TEST_OUTPUT_DIR}/$1"
local num_files="$(($2 - 1))"
for stream_num in $(seq 0 ${num_files}); do
[ -e "${file_name}_${stream_num}.ivf" ] || return 1
done
}
# Run vpx_temporal_svc_encoder in all supported modes for vp8 and vp9.
vpx_tsvc_encoder_vp8_mode_0() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 0 200 || return 1
# Mode 0 produces 1 stream
files_exist "${FUNCNAME}" 1 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_1() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 1 200 400 || return 1
# Mode 1 produces 2 streams
files_exist "${FUNCNAME}" 2 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_2() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 2 200 400 || return 1
# Mode 2 produces 2 streams
files_exist "${FUNCNAME}" 2 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_3() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 3 200 400 600 || return 1
# Mode 3 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_4() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 4 200 400 600 || return 1
# Mode 4 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_5() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 5 200 400 600 || return 1
# Mode 5 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_6() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 6 200 400 600 || return 1
# Mode 6 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_7() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 7 200 400 600 800 1000 || return 1
# Mode 7 produces 5 streams
files_exist "${FUNCNAME}" 5 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_8() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 8 200 400 || return 1
# Mode 8 produces 2 streams
files_exist "${FUNCNAME}" 2 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_9() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 9 200 400 600 || return 1
# Mode 9 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_10() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 10 200 400 600 || return 1
# Mode 10 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp8_mode_11() {
if [ "$(vp8_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp8 "${FUNCNAME}" 11 200 400 600 || return 1
# Mode 11 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_0() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 0 200 || return 1
# Mode 0 produces 1 stream
files_exist "${FUNCNAME}" 1 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_1() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 1 200 400 || return 1
# Mode 1 produces 2 streams
files_exist "${FUNCNAME}" 2 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_2() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 2 200 400 || return 1
# Mode 2 produces 2 streams
files_exist "${FUNCNAME}" 2 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_3() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 3 200 400 600 || return 1
# Mode 3 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_4() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 4 200 400 600 || return 1
# Mode 4 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_5() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 5 200 400 600 || return 1
# Mode 5 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_6() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 6 200 400 600 || return 1
# Mode 6 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_7() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 7 200 400 600 800 1000 || return 1
# Mode 7 produces 5 streams
files_exist "${FUNCNAME}" 5 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_8() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 8 200 400 || return 1
# Mode 8 produces 2 streams
files_exist "${FUNCNAME}" 2 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_9() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 9 200 400 600 || return 1
# Mode 9 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_10() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 10 200 400 600 || return 1
# Mode 10 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_vp9_mode_11() {
if [ "$(vp9_encode_available)" = "yes" ]; then
vpx_tsvc_encoder vp9 "${FUNCNAME}" 11 200 400 600 || return 1
# Mode 11 produces 3 streams
files_exist "${FUNCNAME}" 3 || return 1
fi
}
vpx_tsvc_encoder_tests="vpx_tsvc_encoder_vp8_mode_0
vpx_tsvc_encoder_vp8_mode_1
vpx_tsvc_encoder_vp8_mode_2
vpx_tsvc_encoder_vp8_mode_3
vpx_tsvc_encoder_vp8_mode_4
vpx_tsvc_encoder_vp8_mode_5
vpx_tsvc_encoder_vp8_mode_6
vpx_tsvc_encoder_vp8_mode_7
vpx_tsvc_encoder_vp8_mode_8
vpx_tsvc_encoder_vp8_mode_9
vpx_tsvc_encoder_vp8_mode_10
vpx_tsvc_encoder_vp8_mode_11
vpx_tsvc_encoder_vp9_mode_0
vpx_tsvc_encoder_vp9_mode_1
vpx_tsvc_encoder_vp9_mode_2
vpx_tsvc_encoder_vp9_mode_3
vpx_tsvc_encoder_vp9_mode_4
vpx_tsvc_encoder_vp9_mode_5
vpx_tsvc_encoder_vp9_mode_6
vpx_tsvc_encoder_vp9_mode_7
vpx_tsvc_encoder_vp9_mode_8
vpx_tsvc_encoder_vp9_mode_9
vpx_tsvc_encoder_vp9_mode_10
vpx_tsvc_encoder_vp9_mode_11"
run_tests vpx_tsvc_encoder_verify_environment "${vpx_tsvc_encoder_tests}"

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