Compare commits
1 Commits
sandbox/ya
...
sandbox/Ji
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3a6af5feb |
@@ -1,68 +0,0 @@
|
|||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
# BasedOnStyle: Google
|
|
||||||
# Generated with clang-format 3.7.1
|
|
||||||
AccessModifierOffset: -1
|
|
||||||
AlignAfterOpenBracket: true
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignEscapedNewlinesLeft: true
|
|
||||||
AlignOperands: true
|
|
||||||
AlignTrailingComments: true
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
|
||||||
AllowShortBlocksOnASingleLine: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: true
|
|
||||||
AllowShortFunctionsOnASingleLine: All
|
|
||||||
AllowShortIfStatementsOnASingleLine: true
|
|
||||||
AllowShortLoopsOnASingleLine: true
|
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
|
||||||
AlwaysBreakTemplateDeclarations: true
|
|
||||||
BinPackArguments: true
|
|
||||||
BinPackParameters: true
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
ColumnLimit: 80
|
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|
||||||
ConstructorInitializerIndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: false
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
DisableFormat: false
|
|
||||||
ExperimentalAutoDetectBinPacking: false
|
|
||||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentWidth: 2
|
|
||||||
IndentWrappedFunctionNames: false
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
|
||||||
MacroBlockBegin: ''
|
|
||||||
MacroBlockEnd: ''
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: None
|
|
||||||
ObjCBlockIndentWidth: 2
|
|
||||||
ObjCSpaceAfterProperty: false
|
|
||||||
ObjCSpaceBeforeProtocolList: false
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 1
|
|
||||||
PenaltyBreakComment: 300
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyExcessCharacter: 1000000
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 200
|
|
||||||
PointerAlignment: Right
|
|
||||||
SpaceAfterCStyleCast: false
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 2
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
Standard: Auto
|
|
||||||
TabWidth: 8
|
|
||||||
UseTab: Never
|
|
||||||
...
|
|
||||||
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -30,17 +30,14 @@
|
|||||||
/examples/decode_with_partial_drops
|
/examples/decode_with_partial_drops
|
||||||
/examples/example_xma
|
/examples/example_xma
|
||||||
/examples/postproc
|
/examples/postproc
|
||||||
/examples/resize_util
|
|
||||||
/examples/set_maps
|
/examples/set_maps
|
||||||
/examples/simple_decoder
|
/examples/simple_decoder
|
||||||
/examples/simple_encoder
|
/examples/simple_encoder
|
||||||
/examples/twopass_encoder
|
/examples/twopass_encoder
|
||||||
/examples/vp8_multi_resolution_encoder
|
/examples/vp8_multi_resolution_encoder
|
||||||
/examples/vp8cx_set_ref
|
/examples/vp8cx_set_ref
|
||||||
/examples/vp9_lossless_encoder
|
|
||||||
/examples/vp9_spatial_scalable_encoder
|
/examples/vp9_spatial_scalable_encoder
|
||||||
/examples/vpx_temporal_scalable_patterns
|
/examples/vpx_temporal_scalable_patterns
|
||||||
/examples/vpx_temporal_svc_encoder
|
|
||||||
/ivfdec
|
/ivfdec
|
||||||
/ivfdec.dox
|
/ivfdec.dox
|
||||||
/ivfenc
|
/ivfenc
|
||||||
@@ -48,14 +45,12 @@
|
|||||||
/libvpx.so*
|
/libvpx.so*
|
||||||
/libvpx.ver
|
/libvpx.ver
|
||||||
/samples.dox
|
/samples.dox
|
||||||
/test_intra_pred_speed
|
|
||||||
/test_libvpx
|
/test_libvpx
|
||||||
/vp8_api1_migration.dox
|
/vp8_api1_migration.dox
|
||||||
/vp[89x]_rtcd.h
|
/vp[89x]_rtcd.h
|
||||||
/vpx.pc
|
/vpx.pc
|
||||||
/vpx_config.c
|
/vpx_config.c
|
||||||
/vpx_config.h
|
/vpx_config.h
|
||||||
/vpx_dsp_rtcd.h
|
|
||||||
/vpx_scale_rtcd.h
|
/vpx_scale_rtcd.h
|
||||||
/vpx_version.h
|
/vpx_version.h
|
||||||
/vpxdec
|
/vpxdec
|
||||||
|
|||||||
26
.mailmap
26
.mailmap
@@ -1,32 +1,18 @@
|
|||||||
Adrian Grange <agrange@google.com>
|
Adrian Grange <agrange@google.com>
|
||||||
Aℓex Converse <aconverse@google.com>
|
|
||||||
Aℓex Converse <aconverse@google.com> <alex.converse@gmail.com>
|
|
||||||
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
Alexis Ballier <aballier@gentoo.org> <alexis.ballier@gmail.com>
|
||||||
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
|
||||||
Deb Mukherjee <debargha@google.com>
|
|
||||||
Erik Niemeyer <erik.a.niemeyer@intel.com> <erik.a.niemeyer@gmail.com>
|
|
||||||
Guillaume Martres <gmartres@google.com> <smarter3@gmail.com>
|
|
||||||
Hangyu Kuang <hkuang@google.com>
|
Hangyu Kuang <hkuang@google.com>
|
||||||
Hui Su <huisu@google.com>
|
|
||||||
Jacky Chen <jackychen@google.com>
|
|
||||||
Jim Bankoski <jimbankoski@google.com>
|
Jim Bankoski <jimbankoski@google.com>
|
||||||
|
John Koleszar <jkoleszar@google.com>
|
||||||
Johann Koenig <johannkoenig@google.com>
|
Johann Koenig <johannkoenig@google.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
|
Johann Koenig <johannkoenig@google.com> <johann.koenig@duck.com>
|
||||||
Johann Koenig <johannkoenig@google.com> <johann.koenig@gmail.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>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
Paul Wilkins <paulwilkins@google.com>
|
|
||||||
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
|
||||||
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
|
||||||
Ronald S. Bultje <rsbultje@gmail.com> <rbultje@google.com>
|
|
||||||
Sami Pietilä <samipietila@google.com>
|
Sami Pietilä <samipietila@google.com>
|
||||||
Tamar Levy <tamar.levy@intel.com>
|
|
||||||
Tamar Levy <tamar.levy@intel.com> <levytamar82@gmail.com>
|
|
||||||
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
Tero Rintaluoma <teror@google.com> <tero.rintaluoma@on2.com>
|
||||||
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
|
Timothy B. Terriberry <tterribe@xiph.org> Tim Terriberry <tterriberry@mozilla.com>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
Tom Finegan <tomfinegan@google.com> <tomfinegan@chromium.org>
|
Ralph Giles <giles@xiph.org> <giles@entropywave.com>
|
||||||
|
Ralph Giles <giles@xiph.org> <giles@mozilla.com>
|
||||||
|
Alpha Lam <hclam@google.com> <hclam@chromium.org>
|
||||||
|
Deb Mukherjee <debargha@google.com>
|
||||||
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
Yaowu Xu <yaowu@google.com> <yaowu@xuyaowu.com>
|
||||||
|
|||||||
40
AUTHORS
40
AUTHORS
@@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
Aaron Watry <awatry@gmail.com>
|
Aaron Watry <awatry@gmail.com>
|
||||||
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
|
||||||
Adam Xu <adam@xuyaowu.com>
|
|
||||||
Adrian Grange <agrange@google.com>
|
Adrian Grange <agrange@google.com>
|
||||||
Aℓex Converse <aconverse@google.com>
|
|
||||||
Ahmad Sharif <asharif@google.com>
|
Ahmad Sharif <asharif@google.com>
|
||||||
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
Alexander Voronov <avoronov@graphics.cs.msu.ru>
|
||||||
|
Alex Converse <alex.converse@gmail.com>
|
||||||
Alexis Ballier <aballier@gentoo.org>
|
Alexis Ballier <aballier@gentoo.org>
|
||||||
Alok Ahuja <waveletcoeff@gmail.com>
|
Alok Ahuja <waveletcoeff@gmail.com>
|
||||||
Alpha Lam <hclam@google.com>
|
Alpha Lam <hclam@google.com>
|
||||||
@@ -15,65 +14,44 @@ A.Mahfoodh <ab.mahfoodh@gmail.com>
|
|||||||
Ami Fischman <fischman@chromium.org>
|
Ami Fischman <fischman@chromium.org>
|
||||||
Andoni Morales Alastruey <ylatuya@gmail.com>
|
Andoni Morales Alastruey <ylatuya@gmail.com>
|
||||||
Andres Mejia <mcitadel@gmail.com>
|
Andres Mejia <mcitadel@gmail.com>
|
||||||
Andrew Russell <anrussell@google.com>
|
|
||||||
Angie Chiang <angiebird@google.com>
|
|
||||||
Aron Rosenberg <arosenberg@logitech.com>
|
Aron Rosenberg <arosenberg@logitech.com>
|
||||||
Attila Nagy <attilanagy@google.com>
|
Attila Nagy <attilanagy@google.com>
|
||||||
Brion Vibber <bvibber@wikimedia.org>
|
|
||||||
changjun.yang <changjun.yang@intel.com>
|
changjun.yang <changjun.yang@intel.com>
|
||||||
Charles 'Buck' Krasic <ckrasic@google.com>
|
|
||||||
chm <chm@rock-chips.com>
|
chm <chm@rock-chips.com>
|
||||||
Christian Duvivier <cduvivier@google.com>
|
Christian Duvivier <cduvivier@google.com>
|
||||||
Daniel Kang <ddkang@google.com>
|
Daniel Kang <ddkang@google.com>
|
||||||
Deb Mukherjee <debargha@google.com>
|
Deb Mukherjee <debargha@google.com>
|
||||||
Dim Temp <dimtemp0@gmail.com>
|
|
||||||
Dmitry Kovalev <dkovalev@google.com>
|
Dmitry Kovalev <dkovalev@google.com>
|
||||||
Dragan Mrdjan <dmrdjan@mips.com>
|
Dragan Mrdjan <dmrdjan@mips.com>
|
||||||
Ed Baker <edward.baker@intel.com>
|
Erik Niemeyer <erik.a.niemeyer@gmail.com>
|
||||||
Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
|
||||||
Erik Niemeyer <erik.a.niemeyer@intel.com>
|
|
||||||
Fabio Pedretti <fabio.ped@libero.it>
|
Fabio Pedretti <fabio.ped@libero.it>
|
||||||
Frank Galligan <fgalligan@google.com>
|
Frank Galligan <fgalligan@google.com>
|
||||||
Fredrik Söderquist <fs@opera.com>
|
Fredrik Söderquist <fs@opera.com>
|
||||||
Fritz Koenig <frkoenig@google.com>
|
Fritz Koenig <frkoenig@google.com>
|
||||||
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
Gaute Strokkenes <gaute.strokkenes@broadcom.com>
|
||||||
Geza Lore <gezalore@gmail.com>
|
|
||||||
Ghislain MARY <ghislainmary2@gmail.com>
|
|
||||||
Giuseppe Scrivano <gscrivano@gnu.org>
|
Giuseppe Scrivano <gscrivano@gnu.org>
|
||||||
Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
|
|
||||||
Guillaume Martres <gmartres@google.com>
|
Guillaume Martres <gmartres@google.com>
|
||||||
Guillermo Ballester Valor <gbvalor@gmail.com>
|
Guillermo Ballester Valor <gbvalor@gmail.com>
|
||||||
Hangyu Kuang <hkuang@google.com>
|
Hangyu Kuang <hkuang@google.com>
|
||||||
Hanno Böck <hanno@hboeck.de>
|
|
||||||
Henrik Lundin <hlundin@google.com>
|
Henrik Lundin <hlundin@google.com>
|
||||||
Hui Su <huisu@google.com>
|
Hui Su <huisu@google.com>
|
||||||
Ivan Maltz <ivanmaltz@google.com>
|
Ivan Maltz <ivanmaltz@google.com>
|
||||||
Jacek Caban <cjacek@gmail.com>
|
|
||||||
Jacky Chen <jackychen@google.com>
|
|
||||||
James Berry <jamesberry@google.com>
|
James Berry <jamesberry@google.com>
|
||||||
James Yu <james.yu@linaro.org>
|
|
||||||
James Zern <jzern@google.com>
|
James Zern <jzern@google.com>
|
||||||
Jan Gerber <j@mailb.org>
|
|
||||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
Janne Salonen <jsalonen@google.com>
|
Janne Salonen <jsalonen@google.com>
|
||||||
Jeff Faust <jfaust@google.com>
|
Jeff Faust <jfaust@google.com>
|
||||||
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||||
Jeff Petkau <jpet@chromium.org>
|
Jeff Petkau <jpet@chromium.org>
|
||||||
Jia Jia <jia.jia@linaro.org>
|
|
||||||
Jim Bankoski <jimbankoski@google.com>
|
Jim Bankoski <jimbankoski@google.com>
|
||||||
Jingning Han <jingning@google.com>
|
Jingning Han <jingning@google.com>
|
||||||
Joey Parrish <joeyparrish@google.com>
|
|
||||||
Johann Koenig <johannkoenig@google.com>
|
Johann Koenig <johannkoenig@google.com>
|
||||||
John Koleszar <jkoleszar@google.com>
|
John Koleszar <jkoleszar@google.com>
|
||||||
Johnny Klonaris <google@jawknee.com>
|
|
||||||
John Stark <jhnstrk@gmail.com>
|
|
||||||
Joshua Bleecher Snyder <josh@treelinelabs.com>
|
Joshua Bleecher Snyder <josh@treelinelabs.com>
|
||||||
Joshua Litt <joshualitt@google.com>
|
Joshua Litt <joshualitt@google.com>
|
||||||
Julia Robson <juliamrobson@gmail.com>
|
|
||||||
Justin Clift <justin@salasaga.org>
|
Justin Clift <justin@salasaga.org>
|
||||||
Justin Lebar <justin.lebar@gmail.com>
|
Justin Lebar <justin.lebar@gmail.com>
|
||||||
KO Myung-Hun <komh@chollian.net>
|
KO Myung-Hun <komh@chollian.net>
|
||||||
Lawrence Velázquez <larryv@macports.org>
|
|
||||||
Lou Quillio <louquillio@google.com>
|
Lou Quillio <louquillio@google.com>
|
||||||
Luca Barbato <lu_zero@gentoo.org>
|
Luca Barbato <lu_zero@gentoo.org>
|
||||||
Makoto Kato <makoto.kt@gmail.com>
|
Makoto Kato <makoto.kt@gmail.com>
|
||||||
@@ -87,48 +65,36 @@ Michael Kohler <michaelkohler@live.com>
|
|||||||
Mike Frysinger <vapier@chromium.org>
|
Mike Frysinger <vapier@chromium.org>
|
||||||
Mike Hommey <mhommey@mozilla.com>
|
Mike Hommey <mhommey@mozilla.com>
|
||||||
Mikhal Shemer <mikhal@google.com>
|
Mikhal Shemer <mikhal@google.com>
|
||||||
Minghai Shang <minghai@google.com>
|
|
||||||
Morton Jonuschat <yabawock@gmail.com>
|
Morton Jonuschat <yabawock@gmail.com>
|
||||||
Nico Weber <thakis@chromium.org>
|
|
||||||
Parag Salasakar <img.mips1@gmail.com>
|
Parag Salasakar <img.mips1@gmail.com>
|
||||||
Pascal Massimino <pascal.massimino@gmail.com>
|
Pascal Massimino <pascal.massimino@gmail.com>
|
||||||
Patrik Westin <patrik.westin@gmail.com>
|
Patrik Westin <patrik.westin@gmail.com>
|
||||||
Paul Wilkins <paulwilkins@google.com>
|
Paul Wilkins <paulwilkins@google.com>
|
||||||
Pavol Rusnak <stick@gk2.sk>
|
Pavol Rusnak <stick@gk2.sk>
|
||||||
Paweł Hajdan <phajdan@google.com>
|
Paweł Hajdan <phajdan@google.com>
|
||||||
Pengchong Jin <pengchong@google.com>
|
|
||||||
Peter de Rivaz <peter.derivaz@gmail.com>
|
|
||||||
Philip Jägenstedt <philipj@opera.com>
|
Philip Jägenstedt <philipj@opera.com>
|
||||||
Priit Laes <plaes@plaes.org>
|
Priit Laes <plaes@plaes.org>
|
||||||
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
|
||||||
Rafaël Carré <funman@videolan.org>
|
Rafaël Carré <funman@videolan.org>
|
||||||
Ralph Giles <giles@xiph.org>
|
Ralph Giles <giles@xiph.org>
|
||||||
Rob Bradford <rob@linux.intel.com>
|
Rob Bradford <rob@linux.intel.com>
|
||||||
Ronald S. Bultje <rsbultje@gmail.com>
|
Ronald S. Bultje <rbultje@google.com>
|
||||||
Rui Ueyama <ruiu@google.com>
|
|
||||||
Sami Pietilä <samipietila@google.com>
|
Sami Pietilä <samipietila@google.com>
|
||||||
Scott Graham <scottmg@chromium.org>
|
Scott Graham <scottmg@chromium.org>
|
||||||
Scott LaVarnway <slavarnway@google.com>
|
Scott LaVarnway <slavarnway@google.com>
|
||||||
Sean McGovern <gseanmcg@gmail.com>
|
|
||||||
Sergey Ulanov <sergeyu@chromium.org>
|
|
||||||
Shimon Doodkin <helpmepro1@gmail.com>
|
Shimon Doodkin <helpmepro1@gmail.com>
|
||||||
Shunyao Li <shunyaoli@google.com>
|
|
||||||
Stefan Holmer <holmer@google.com>
|
Stefan Holmer <holmer@google.com>
|
||||||
Suman Sunkara <sunkaras@google.com>
|
Suman Sunkara <sunkaras@google.com>
|
||||||
Taekhyun Kim <takim@nvidia.com>
|
Taekhyun Kim <takim@nvidia.com>
|
||||||
Takanori MATSUURA <t.matsuu@gmail.com>
|
Takanori MATSUURA <t.matsuu@gmail.com>
|
||||||
Tamar Levy <tamar.levy@intel.com>
|
Tamar Levy <tamar.levy@intel.com>
|
||||||
Tao Bai <michaelbai@chromium.org>
|
|
||||||
Tero Rintaluoma <teror@google.com>
|
Tero Rintaluoma <teror@google.com>
|
||||||
Thijs Vermeir <thijsvermeir@gmail.com>
|
Thijs Vermeir <thijsvermeir@gmail.com>
|
||||||
Tim Kopp <tkopp@google.com>
|
|
||||||
Timothy B. Terriberry <tterribe@xiph.org>
|
Timothy B. Terriberry <tterribe@xiph.org>
|
||||||
Tom Finegan <tomfinegan@google.com>
|
Tom Finegan <tomfinegan@google.com>
|
||||||
Vignesh Venkatasubramanian <vigneshv@google.com>
|
Vignesh Venkatasubramanian <vigneshv@google.com>
|
||||||
Yaowu Xu <yaowu@google.com>
|
Yaowu Xu <yaowu@google.com>
|
||||||
Yongzhe Wang <yongzhe@google.com>
|
|
||||||
Yunqing Wang <yunqingwang@google.com>
|
Yunqing Wang <yunqingwang@google.com>
|
||||||
Zoe Liu <zoeliu@google.com>
|
|
||||||
Google Inc.
|
Google Inc.
|
||||||
The Mozilla Foundation
|
The Mozilla Foundation
|
||||||
The Xiph.Org Foundation
|
The Xiph.Org Foundation
|
||||||
|
|||||||
44
CHANGELOG
44
CHANGELOG
@@ -1,47 +1,3 @@
|
|||||||
Next Release
|
|
||||||
- Incompatible changes:
|
|
||||||
The VP9 encoder's default keyframe interval changed to 128 from 9999.
|
|
||||||
|
|
||||||
2015-11-09 v1.5.0 "Javan Whistling Duck"
|
|
||||||
This release improves upon the VP9 encoder and speeds up the encoding and
|
|
||||||
decoding processes.
|
|
||||||
|
|
||||||
- Upgrading:
|
|
||||||
This release is ABI incompatible with 1.4.0. It drops deprecated VP8
|
|
||||||
controls and adds a variety of VP9 controls for testing.
|
|
||||||
|
|
||||||
The vpxenc utility now prefers VP9 by default.
|
|
||||||
|
|
||||||
- Enhancements:
|
|
||||||
Faster VP9 encoding and decoding
|
|
||||||
Smaller library size by combining functions used by VP8 and VP9
|
|
||||||
|
|
||||||
- Bug Fixes:
|
|
||||||
A variety of fuzzing issues
|
|
||||||
|
|
||||||
2015-04-03 v1.4.0 "Indian Runner Duck"
|
|
||||||
This release includes significant improvements to the VP9 codec.
|
|
||||||
|
|
||||||
- Upgrading:
|
|
||||||
This release is ABI incompatible with 1.3.0. It drops the compatibility
|
|
||||||
layer, requiring VPX_IMG_FMT_* instead of IMG_FMT_*, and adds several codec
|
|
||||||
controls for VP9.
|
|
||||||
|
|
||||||
- Enhancements:
|
|
||||||
Faster VP9 encoding and decoding
|
|
||||||
Multithreaded VP9 decoding (tile and frame-based)
|
|
||||||
Multithreaded VP9 encoding - on by default
|
|
||||||
YUV 4:2:2 and 4:4:4 support in VP9
|
|
||||||
10 and 12bit support in VP9
|
|
||||||
64bit ARM support by replacing ARM assembly with intrinsics
|
|
||||||
|
|
||||||
- Bug Fixes:
|
|
||||||
Fixes a VP9 bitstream issue in Profile 1. This only affected non-YUV 4:2:0
|
|
||||||
files.
|
|
||||||
|
|
||||||
- Known Issues:
|
|
||||||
Frame Parallel decoding fails for segmented and non-420 files.
|
|
||||||
|
|
||||||
2013-11-15 v1.3.0 "Forest"
|
2013-11-15 v1.3.0 "Forest"
|
||||||
This release introduces the VP9 codec in a backward-compatible way.
|
This release introduces the VP9 codec in a backward-compatible way.
|
||||||
All existing users of VP8 can continue to use the library without
|
All existing users of VP8 can continue to use the library without
|
||||||
|
|||||||
2
PATENTS
2
PATENTS
@@ -17,7 +17,7 @@ or agree to the institution of patent litigation or any other patent
|
|||||||
enforcement activity against any entity (including a cross-claim or
|
enforcement activity against any entity (including a cross-claim or
|
||||||
counterclaim in a lawsuit) alleging that any of these implementations of WebM
|
counterclaim in a lawsuit) alleging that any of these implementations of WebM
|
||||||
or any code incorporated within any of these implementations of WebM
|
or any code incorporated within any of these implementations of WebM
|
||||||
constitute direct or contributory patent infringement, or inducement of
|
constitutes direct or contributory patent infringement, or inducement of
|
||||||
patent infringement, then any patent rights granted to you under this License
|
patent infringement, then any patent rights granted to you under this License
|
||||||
for these implementations of WebM shall terminate as of the date such
|
for these implementations of WebM shall terminate as of the date such
|
||||||
litigation is filed.
|
litigation is filed.
|
||||||
|
|||||||
26
README
26
README
@@ -1,4 +1,4 @@
|
|||||||
README - 23 March 2015
|
README - 30 May 2014
|
||||||
|
|
||||||
Welcome to the WebM VP8/VP9 Codec SDK!
|
Welcome to the WebM VP8/VP9 Codec SDK!
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
--help output of the configure script. As of this writing, the list of
|
--help output of the configure script. As of this writing, the list of
|
||||||
available targets is:
|
available targets is:
|
||||||
|
|
||||||
|
armv6-darwin-gcc
|
||||||
armv6-linux-rvct
|
armv6-linux-rvct
|
||||||
armv6-linux-gcc
|
armv6-linux-gcc
|
||||||
armv6-none-rvct
|
armv6-none-rvct
|
||||||
@@ -58,10 +59,15 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
armv7-none-rvct
|
armv7-none-rvct
|
||||||
armv7-win32-vs11
|
armv7-win32-vs11
|
||||||
armv7-win32-vs12
|
armv7-win32-vs12
|
||||||
armv7-win32-vs14
|
|
||||||
armv7s-darwin-gcc
|
armv7s-darwin-gcc
|
||||||
mips32-linux-gcc
|
mips32-linux-gcc
|
||||||
mips64-linux-gcc
|
mips64-linux-gcc
|
||||||
|
ppc32-darwin8-gcc
|
||||||
|
ppc32-darwin9-gcc
|
||||||
|
ppc32-linux-gcc
|
||||||
|
ppc64-darwin8-gcc
|
||||||
|
ppc64-darwin9-gcc
|
||||||
|
ppc64-linux-gcc
|
||||||
sparc-solaris-gcc
|
sparc-solaris-gcc
|
||||||
x86-android-gcc
|
x86-android-gcc
|
||||||
x86-darwin8-gcc
|
x86-darwin8-gcc
|
||||||
@@ -72,33 +78,39 @@ COMPILING THE APPLICATIONS/LIBRARIES:
|
|||||||
x86-darwin11-gcc
|
x86-darwin11-gcc
|
||||||
x86-darwin12-gcc
|
x86-darwin12-gcc
|
||||||
x86-darwin13-gcc
|
x86-darwin13-gcc
|
||||||
x86-darwin14-gcc
|
|
||||||
x86-iphonesimulator-gcc
|
x86-iphonesimulator-gcc
|
||||||
x86-linux-gcc
|
x86-linux-gcc
|
||||||
x86-linux-icc
|
x86-linux-icc
|
||||||
x86-os2-gcc
|
x86-os2-gcc
|
||||||
x86-solaris-gcc
|
x86-solaris-gcc
|
||||||
x86-win32-gcc
|
x86-win32-gcc
|
||||||
|
x86-win32-vs7
|
||||||
|
x86-win32-vs8
|
||||||
|
x86-win32-vs9
|
||||||
x86-win32-vs10
|
x86-win32-vs10
|
||||||
x86-win32-vs11
|
x86-win32-vs11
|
||||||
x86-win32-vs12
|
x86-win32-vs12
|
||||||
x86-win32-vs14
|
|
||||||
x86_64-android-gcc
|
|
||||||
x86_64-darwin9-gcc
|
x86_64-darwin9-gcc
|
||||||
x86_64-darwin10-gcc
|
x86_64-darwin10-gcc
|
||||||
x86_64-darwin11-gcc
|
x86_64-darwin11-gcc
|
||||||
x86_64-darwin12-gcc
|
x86_64-darwin12-gcc
|
||||||
x86_64-darwin13-gcc
|
x86_64-darwin13-gcc
|
||||||
x86_64-darwin14-gcc
|
|
||||||
x86_64-iphonesimulator-gcc
|
x86_64-iphonesimulator-gcc
|
||||||
x86_64-linux-gcc
|
x86_64-linux-gcc
|
||||||
x86_64-linux-icc
|
x86_64-linux-icc
|
||||||
x86_64-solaris-gcc
|
x86_64-solaris-gcc
|
||||||
x86_64-win64-gcc
|
x86_64-win64-gcc
|
||||||
|
x86_64-win64-vs8
|
||||||
|
x86_64-win64-vs9
|
||||||
x86_64-win64-vs10
|
x86_64-win64-vs10
|
||||||
x86_64-win64-vs11
|
x86_64-win64-vs11
|
||||||
x86_64-win64-vs12
|
x86_64-win64-vs12
|
||||||
x86_64-win64-vs14
|
universal-darwin8-gcc
|
||||||
|
universal-darwin9-gcc
|
||||||
|
universal-darwin10-gcc
|
||||||
|
universal-darwin11-gcc
|
||||||
|
universal-darwin12-gcc
|
||||||
|
universal-darwin13-gcc
|
||||||
generic-gnu
|
generic-gnu
|
||||||
|
|
||||||
The generic-gnu target, in conjunction with the CROSS environment variable,
|
The generic-gnu target, in conjunction with the CROSS environment variable,
|
||||||
|
|||||||
4
args.c
4
args.c
@@ -14,7 +14,9 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "args.h"
|
#include "args.h"
|
||||||
|
|
||||||
#include "vpx_ports/msvc.h"
|
#ifdef _MSC_VER
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__
|
#if defined(__GNUC__) && __GNUC__
|
||||||
extern void die(const char *fmt, ...) __attribute__((noreturn));
|
extern void die(const char *fmt, ...) __attribute__((noreturn));
|
||||||
|
|||||||
@@ -67,8 +67,6 @@ else ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
|||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
else ifeq ($(TARGET_ARCH_ABI),x86)
|
else ifeq ($(TARGET_ARCH_ABI),x86)
|
||||||
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
include $(CONFIG_DIR)libs-x86-android-gcc.mk
|
||||||
else ifeq ($(TARGET_ARCH_ABI),x86_64)
|
|
||||||
include $(CONFIG_DIR)libs-x86_64-android-gcc.mk
|
|
||||||
else ifeq ($(TARGET_ARCH_ABI),mips)
|
else ifeq ($(TARGET_ARCH_ABI),mips)
|
||||||
include $(CONFIG_DIR)libs-mips-android-gcc.mk
|
include $(CONFIG_DIR)libs-mips-android-gcc.mk
|
||||||
else
|
else
|
||||||
@@ -160,26 +158,24 @@ LOCAL_CFLAGS += \
|
|||||||
|
|
||||||
LOCAL_MODULE := libvpx
|
LOCAL_MODULE := libvpx
|
||||||
|
|
||||||
|
LOCAL_LDLIBS := -llog
|
||||||
|
|
||||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||||
LOCAL_STATIC_LIBRARIES := cpufeatures
|
LOCAL_STATIC_LIBRARIES := cpufeatures
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Add a dependency to force generation of the RTCD files.
|
# Add a dependency to force generation of the RTCD files.
|
||||||
define rtcd_dep_template
|
ifeq ($(CONFIG_VP8), yes)
|
||||||
rtcd_dep_template_SRCS := $(addprefix $(LOCAL_PATH)/, $(LOCAL_SRC_FILES))
|
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp8_rtcd.h
|
||||||
rtcd_dep_template_SRCS := $$(rtcd_dep_template_SRCS:.neon=)
|
|
||||||
ifeq ($(CONFIG_VP10), yes)
|
|
||||||
$$(rtcd_dep_template_SRCS): vp10_rtcd.h
|
|
||||||
endif
|
endif
|
||||||
$$(rtcd_dep_template_SRCS): vpx_scale_rtcd.h
|
ifeq ($(CONFIG_VP9), yes)
|
||||||
$$(rtcd_dep_template_SRCS): vpx_dsp_rtcd.h
|
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vp9_rtcd.h
|
||||||
|
|
||||||
ifneq ($(findstring $(TARGET_ARCH_ABI),x86 x86_64),)
|
|
||||||
$$(rtcd_dep_template_SRCS): vpx_config.asm
|
|
||||||
endif
|
endif
|
||||||
endef
|
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_scale_rtcd.h
|
||||||
|
|
||||||
$(eval $(call rtcd_dep_template))
|
ifeq ($(TARGET_ARCH_ABI),x86)
|
||||||
|
$(foreach file, $(LOCAL_SRC_FILES), $(LOCAL_PATH)/$(file)): vpx_config.asm
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@@ -188,11 +184,7 @@ clean:
|
|||||||
@$(RM) -r $(ASM_CNV_PATH)
|
@$(RM) -r $(ASM_CNV_PATH)
|
||||||
@$(RM) $(CLEAN-OBJS)
|
@$(RM) $(CLEAN-OBJS)
|
||||||
|
|
||||||
ifeq ($(ENABLE_SHARED),1)
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
else
|
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
ifeq ($(CONFIG_RUNTIME_CPU_DETECT),yes)
|
||||||
$(call import-module,cpufeatures)
|
$(call import-module,cpufeatures)
|
||||||
|
|||||||
@@ -22,11 +22,9 @@ clean:: .DEFAULT
|
|||||||
exampletest: .DEFAULT
|
exampletest: .DEFAULT
|
||||||
install:: .DEFAULT
|
install:: .DEFAULT
|
||||||
test:: .DEFAULT
|
test:: .DEFAULT
|
||||||
test-no-data-check:: .DEFAULT
|
|
||||||
testdata:: .DEFAULT
|
testdata:: .DEFAULT
|
||||||
utiltest: .DEFAULT
|
utiltest: .DEFAULT
|
||||||
exampletest-no-data-check utiltest-no-data-check: .DEFAULT
|
|
||||||
test_%: .DEFAULT ;
|
|
||||||
|
|
||||||
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
|
# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
|
||||||
# installed on cygwin, so we need to autodetect here.
|
# installed on cygwin, so we need to autodetect here.
|
||||||
@@ -58,10 +56,13 @@ dist:
|
|||||||
fi
|
fi
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Since we invoke make recursively for multiple targets we need to include the
|
|
||||||
# .mk file for the correct target, but only when $(target) is non-empty.
|
|
||||||
ifneq ($(target),)
|
ifneq ($(target),)
|
||||||
include $(target)-$(TOOLCHAIN).mk
|
# Normally, we want to build the filename from the target and the toolchain.
|
||||||
|
# This disambiguates from the $(target).mk file that exists in the source tree.
|
||||||
|
# However, the toolchain is part of the target in universal builds, so we
|
||||||
|
# don't want to include TOOLCHAIN in that case. FAT_ARCHS is used to test
|
||||||
|
# if we're in the universal case.
|
||||||
|
include $(target)$(if $(FAT_ARCHS),,-$(TOOLCHAIN)).mk
|
||||||
endif
|
endif
|
||||||
BUILD_ROOT?=.
|
BUILD_ROOT?=.
|
||||||
VPATH=$(SRC_PATH_BARE)
|
VPATH=$(SRC_PATH_BARE)
|
||||||
@@ -115,29 +116,28 @@ test::
|
|||||||
testdata::
|
testdata::
|
||||||
.PHONY: utiltest
|
.PHONY: utiltest
|
||||||
utiltest:
|
utiltest:
|
||||||
.PHONY: test-no-data-check exampletest-no-data-check utiltest-no-data-check
|
|
||||||
test-no-data-check::
|
|
||||||
exampletest-no-data-check utiltest-no-data-check:
|
|
||||||
|
|
||||||
# Force to realign stack always on OS/2
|
# Add compiler flags for intrinsic files
|
||||||
ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
ifeq ($(TOOLCHAIN), x86-os2-gcc)
|
||||||
CFLAGS += -mstackrealign
|
STACKREALIGN=-mstackrealign
|
||||||
|
else
|
||||||
|
STACKREALIGN=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
|
||||||
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
|
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2
|
$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3
|
$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3
|
$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3
|
$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3
|
$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1
|
$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1
|
$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
|
$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
|
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
|
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2 $(STACKREALIGN)
|
||||||
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
|
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2 $(STACKREALIGN)
|
||||||
|
|
||||||
$(BUILD_PFX)%.c.d: %.c
|
$(BUILD_PFX)%.c.d: %.c
|
||||||
$(if $(quiet),@echo " [DEP] $@")
|
$(if $(quiet),@echo " [DEP] $@")
|
||||||
@@ -283,7 +283,7 @@ define archive_template
|
|||||||
# for creating them.
|
# for creating them.
|
||||||
$(1):
|
$(1):
|
||||||
$(if $(quiet),@echo " [AR] $$@")
|
$(if $(quiet),@echo " [AR] $$@")
|
||||||
$(qexec)$$(AR) $$(ARFLAGS) $$@ $$^
|
$(qexec)$$(AR) $$(ARFLAGS) $$@ $$?
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define so_template
|
define so_template
|
||||||
@@ -313,15 +313,18 @@ $(1):
|
|||||||
$$(filter %.o,$$^) $$(extralibs)
|
$$(filter %.o,$$^) $$(extralibs)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define dll_template
|
|
||||||
# Not using a pattern rule here because we don't want to generate empty
|
|
||||||
# archives when they are listed as a dependency in files not responsible
|
define lipo_lib_template
|
||||||
# for creating them.
|
$(1): $(addsuffix /$(1),$(FAT_ARCHS))
|
||||||
$(1):
|
$(if $(quiet),@echo " [LIPO] $$@")
|
||||||
$(if $(quiet),@echo " [LD] $$@")
|
$(qexec)libtool -static -o $$@ $$?
|
||||||
$(qexec)$$(LD) -Zdll $$(LDFLAGS) \
|
endef
|
||||||
-o $$@ \
|
|
||||||
$$(filter %.o,$$^) $$(extralibs) $$(EXPORTS_FILE)
|
define lipo_bin_template
|
||||||
|
$(1): $(addsuffix /$(1),$(FAT_ARCHS))
|
||||||
|
$(if $(quiet),@echo " [LIPO] $$@")
|
||||||
|
$(qexec)lipo -output $$@ -create $$?
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
@@ -380,9 +383,8 @@ LIBS=$(call enabled,LIBS)
|
|||||||
.libs: $(LIBS)
|
.libs: $(LIBS)
|
||||||
@touch $@
|
@touch $@
|
||||||
$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib))))
|
$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib))))
|
||||||
$(foreach lib,$(filter %so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR).$(SO_VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib))))
|
$(foreach lib,$(filter %so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib))))
|
||||||
$(foreach lib,$(filter %$(SO_VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib))))
|
$(foreach lib,$(filter %$(VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib))))
|
||||||
$(foreach lib,$(filter %$(SO_VERSION_MAJOR).dll,$(LIBS)),$(eval $(call dll_template,$(lib))))
|
|
||||||
|
|
||||||
INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS)
|
INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS)
|
||||||
ifeq ($(MAKECMDGOALS),dist)
|
ifeq ($(MAKECMDGOALS),dist)
|
||||||
@@ -418,6 +420,7 @@ ifneq ($(call enabled,DIST-SRCS),)
|
|||||||
DIST-SRCS-yes += build/make/gen_asm_deps.sh
|
DIST-SRCS-yes += build/make/gen_asm_deps.sh
|
||||||
DIST-SRCS-yes += build/make/Makefile
|
DIST-SRCS-yes += build/make/Makefile
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_def.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_def.sh
|
||||||
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_proj.sh
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_sln.sh
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/gen_msvs_vcxproj.sh
|
||||||
DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh
|
DIST-SRCS-$(CONFIG_MSVS) += build/make/msvs_common.sh
|
||||||
@@ -448,5 +451,3 @@ all: $(BUILD_TARGETS)
|
|||||||
install:: $(INSTALL_TARGETS)
|
install:: $(INSTALL_TARGETS)
|
||||||
dist: $(INSTALL_TARGETS)
|
dist: $(INSTALL_TARGETS)
|
||||||
test::
|
test::
|
||||||
|
|
||||||
.SUFFIXES: # Delete default suffix rules
|
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ Build options:
|
|||||||
--target=TARGET target platform tuple [generic-gnu]
|
--target=TARGET target platform tuple [generic-gnu]
|
||||||
--cpu=CPU optimize for a specific cpu rather than a family
|
--cpu=CPU optimize for a specific cpu rather than a family
|
||||||
--extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]
|
--extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]
|
||||||
--extra-cxxflags=ECXXFLAGS add ECXXFLAGS to CXXFLAGS [$CXXFLAGS]
|
|
||||||
${toggle_extra_warnings} emit harmless warnings (always non-fatal)
|
${toggle_extra_warnings} emit harmless warnings (always non-fatal)
|
||||||
${toggle_werror} treat warnings as errors, if possible
|
${toggle_werror} treat warnings as errors, if possible
|
||||||
(not available with all compilers)
|
(not available with all compilers)
|
||||||
@@ -185,7 +184,6 @@ add_extralibs() {
|
|||||||
#
|
#
|
||||||
# Boolean Manipulation Functions
|
# Boolean Manipulation Functions
|
||||||
#
|
#
|
||||||
|
|
||||||
enable_feature(){
|
enable_feature(){
|
||||||
set_all yes $*
|
set_all yes $*
|
||||||
}
|
}
|
||||||
@@ -202,24 +200,6 @@ disabled(){
|
|||||||
eval test "x\$$1" = "xno"
|
eval test "x\$$1" = "xno"
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_codec(){
|
|
||||||
enabled "${1}" || echo " enabling ${1}"
|
|
||||||
enable_feature "${1}"
|
|
||||||
|
|
||||||
is_in "${1}" vp8 vp9 vp10 && enable_feature "${1}_encoder" "${1}_decoder"
|
|
||||||
}
|
|
||||||
|
|
||||||
disable_codec(){
|
|
||||||
disabled "${1}" || echo " disabling ${1}"
|
|
||||||
disable_feature "${1}"
|
|
||||||
|
|
||||||
is_in "${1}" vp8 vp9 vp10 && disable_feature "${1}_encoder" "${1}_decoder"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Iterates through positional parameters, checks to confirm the parameter has
|
|
||||||
# not been explicitly (force) disabled, and enables the setting controlled by
|
|
||||||
# the parameter when the setting is not disabled.
|
|
||||||
# Note: Does NOT alter RTCD generation options ($RTCD_OPTIONS).
|
|
||||||
soft_enable() {
|
soft_enable() {
|
||||||
for var in $*; do
|
for var in $*; do
|
||||||
if ! disabled $var; then
|
if ! disabled $var; then
|
||||||
@@ -229,10 +209,6 @@ soft_enable() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Iterates through positional parameters, checks to confirm the parameter has
|
|
||||||
# not been explicitly (force) enabled, and disables the setting controlled by
|
|
||||||
# the parameter when the setting is not enabled.
|
|
||||||
# Note: Does NOT alter RTCD generation options ($RTCD_OPTIONS).
|
|
||||||
soft_disable() {
|
soft_disable() {
|
||||||
for var in $*; do
|
for var in $*; do
|
||||||
if ! enabled $var; then
|
if ! enabled $var; then
|
||||||
@@ -361,10 +337,6 @@ check_add_cflags() {
|
|||||||
check_cflags "$@" && add_cflags_only "$@"
|
check_cflags "$@" && add_cflags_only "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
check_add_cxxflags() {
|
|
||||||
check_cxxflags "$@" && add_cxxflags_only "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
check_add_asflags() {
|
check_add_asflags() {
|
||||||
log add_asflags "$@"
|
log add_asflags "$@"
|
||||||
add_asflags "$@"
|
add_asflags "$@"
|
||||||
@@ -418,7 +390,7 @@ write_common_config_banner() {
|
|||||||
write_common_config_targets() {
|
write_common_config_targets() {
|
||||||
for t in ${all_targets}; do
|
for t in ${all_targets}; do
|
||||||
if enabled ${t}; then
|
if enabled ${t}; then
|
||||||
if enabled child; then
|
if enabled universal || enabled child; then
|
||||||
fwrite config.mk "ALL_TARGETS += ${t}-${toolchain}"
|
fwrite config.mk "ALL_TARGETS += ${t}-${toolchain}"
|
||||||
else
|
else
|
||||||
fwrite config.mk "ALL_TARGETS += ${t}"
|
fwrite config.mk "ALL_TARGETS += ${t}"
|
||||||
@@ -456,7 +428,7 @@ NM=${NM}
|
|||||||
|
|
||||||
CFLAGS = ${CFLAGS}
|
CFLAGS = ${CFLAGS}
|
||||||
CXXFLAGS = ${CXXFLAGS}
|
CXXFLAGS = ${CXXFLAGS}
|
||||||
ARFLAGS = -crs\$(if \$(quiet),,v)
|
ARFLAGS = -rus\$(if \$(quiet),c,v)
|
||||||
LDFLAGS = ${LDFLAGS}
|
LDFLAGS = ${LDFLAGS}
|
||||||
ASFLAGS = ${ASFLAGS}
|
ASFLAGS = ${ASFLAGS}
|
||||||
extralibs = ${extralibs}
|
extralibs = ${extralibs}
|
||||||
@@ -531,25 +503,24 @@ process_common_cmdline() {
|
|||||||
--extra-cflags=*)
|
--extra-cflags=*)
|
||||||
extra_cflags="${optval}"
|
extra_cflags="${optval}"
|
||||||
;;
|
;;
|
||||||
--extra-cxxflags=*)
|
|
||||||
extra_cxxflags="${optval}"
|
|
||||||
;;
|
|
||||||
--enable-?*|--disable-?*)
|
--enable-?*|--disable-?*)
|
||||||
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
||||||
if is_in ${option} ${ARCH_EXT_LIST}; then
|
if echo "${ARCH_EXT_LIST}" | grep "^ *$option\$" >/dev/null; then
|
||||||
[ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${option} "
|
[ $action = "disable" ] && RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${option} "
|
||||||
elif [ $action = "disable" ] && ! disabled $option ; then
|
elif [ $action = "disable" ] && ! disabled $option ; then
|
||||||
is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt
|
echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
|
||||||
|
die_unknown $opt
|
||||||
log_echo " disabling $option"
|
log_echo " disabling $option"
|
||||||
elif [ $action = "enable" ] && ! enabled $option ; then
|
elif [ $action = "enable" ] && ! enabled $option ; then
|
||||||
is_in ${option} ${CMDLINE_SELECT} || die_unknown $opt
|
echo "${CMDLINE_SELECT}" | grep "^ *$option\$" >/dev/null ||
|
||||||
|
die_unknown $opt
|
||||||
log_echo " enabling $option"
|
log_echo " enabling $option"
|
||||||
fi
|
fi
|
||||||
${action}_feature $option
|
${action}_feature $option
|
||||||
;;
|
;;
|
||||||
--require-?*)
|
--require-?*)
|
||||||
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
||||||
if is_in ${option} ${ARCH_EXT_LIST}; then
|
if echo "${ARCH_EXT_LIST}" none | grep "^ *$option\$" >/dev/null; then
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
|
RTCD_OPTIONS="${RTCD_OPTIONS}${opt} "
|
||||||
else
|
else
|
||||||
die_unknown $opt
|
die_unknown $opt
|
||||||
@@ -646,44 +617,16 @@ show_darwin_sdk_path() {
|
|||||||
xcodebuild -sdk $1 -version Path 2>/dev/null
|
xcodebuild -sdk $1 -version Path 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Print the major version number of the Darwin SDK specified by $1.
|
|
||||||
show_darwin_sdk_major_version() {
|
|
||||||
xcrun --sdk $1 --show-sdk-version 2>/dev/null | cut -d. -f1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print the Xcode version.
|
|
||||||
show_xcode_version() {
|
|
||||||
xcodebuild -version | head -n1 | cut -d' ' -f2
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fails when Xcode version is less than 6.3.
|
|
||||||
check_xcode_minimum_version() {
|
|
||||||
xcode_major=$(show_xcode_version | cut -f1 -d.)
|
|
||||||
xcode_minor=$(show_xcode_version | cut -f2 -d.)
|
|
||||||
xcode_min_major=6
|
|
||||||
xcode_min_minor=3
|
|
||||||
if [ ${xcode_major} -lt ${xcode_min_major} ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if [ ${xcode_major} -eq ${xcode_min_major} ] \
|
|
||||||
&& [ ${xcode_minor} -lt ${xcode_min_minor} ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
process_common_toolchain() {
|
process_common_toolchain() {
|
||||||
if [ -z "$toolchain" ]; then
|
if [ -z "$toolchain" ]; then
|
||||||
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
gcctarget="${CHOST:-$(gcc -dumpmachine 2> /dev/null)}"
|
||||||
|
|
||||||
# detect tgt_isa
|
# detect tgt_isa
|
||||||
case "$gcctarget" in
|
case "$gcctarget" in
|
||||||
aarch64*)
|
|
||||||
tgt_isa=arm64
|
|
||||||
;;
|
|
||||||
armv6*)
|
armv6*)
|
||||||
tgt_isa=armv6
|
tgt_isa=armv6
|
||||||
;;
|
;;
|
||||||
armv7*-hardfloat* | armv7*-gnueabihf | arm-*-gnueabihf)
|
armv7*-hardfloat*)
|
||||||
tgt_isa=armv7
|
tgt_isa=armv7
|
||||||
float_abi=hard
|
float_abi=hard
|
||||||
;;
|
;;
|
||||||
@@ -697,6 +640,12 @@ process_common_toolchain() {
|
|||||||
*i[3456]86*)
|
*i[3456]86*)
|
||||||
tgt_isa=x86
|
tgt_isa=x86
|
||||||
;;
|
;;
|
||||||
|
*powerpc64*)
|
||||||
|
tgt_isa=ppc64
|
||||||
|
;;
|
||||||
|
*powerpc*)
|
||||||
|
tgt_isa=ppc32
|
||||||
|
;;
|
||||||
*sparc*)
|
*sparc*)
|
||||||
tgt_isa=sparc
|
tgt_isa=sparc
|
||||||
;;
|
;;
|
||||||
@@ -704,6 +653,14 @@ process_common_toolchain() {
|
|||||||
|
|
||||||
# detect tgt_os
|
# detect tgt_os
|
||||||
case "$gcctarget" in
|
case "$gcctarget" in
|
||||||
|
*darwin8*)
|
||||||
|
tgt_isa=universal
|
||||||
|
tgt_os=darwin8
|
||||||
|
;;
|
||||||
|
*darwin9*)
|
||||||
|
tgt_isa=universal
|
||||||
|
tgt_os=darwin9
|
||||||
|
;;
|
||||||
*darwin10*)
|
*darwin10*)
|
||||||
tgt_isa=x86_64
|
tgt_isa=x86_64
|
||||||
tgt_os=darwin10
|
tgt_os=darwin10
|
||||||
@@ -724,10 +681,6 @@ process_common_toolchain() {
|
|||||||
tgt_isa=x86_64
|
tgt_isa=x86_64
|
||||||
tgt_os=darwin14
|
tgt_os=darwin14
|
||||||
;;
|
;;
|
||||||
*darwin15*)
|
|
||||||
tgt_isa=x86_64
|
|
||||||
tgt_os=darwin15
|
|
||||||
;;
|
|
||||||
x86_64*mingw32*)
|
x86_64*mingw32*)
|
||||||
tgt_os=win64
|
tgt_os=win64
|
||||||
;;
|
;;
|
||||||
@@ -784,27 +737,12 @@ process_common_toolchain() {
|
|||||||
enabled shared && soft_enable pic
|
enabled shared && soft_enable pic
|
||||||
|
|
||||||
# Minimum iOS version for all target platforms (darwin and iphonesimulator).
|
# Minimum iOS version for all target platforms (darwin and iphonesimulator).
|
||||||
# Shared library framework builds are only possible on iOS 8 and later.
|
|
||||||
if enabled shared; then
|
|
||||||
IOS_VERSION_OPTIONS="--enable-shared"
|
|
||||||
IOS_VERSION_MIN="8.0"
|
|
||||||
else
|
|
||||||
IOS_VERSION_OPTIONS=""
|
|
||||||
IOS_VERSION_MIN="6.0"
|
IOS_VERSION_MIN="6.0"
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle darwin variants. Newer SDKs allow targeting older
|
# Handle darwin variants. Newer SDKs allow targeting older
|
||||||
# platforms, so use the newest one available.
|
# platforms, so use the newest one available.
|
||||||
case ${toolchain} in
|
case ${toolchain} in
|
||||||
arm*-darwin*)
|
*-darwin*)
|
||||||
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
|
||||||
iphoneos_sdk_dir="$(show_darwin_sdk_path iphoneos)"
|
|
||||||
if [ -d "${iphoneos_sdk_dir}" ]; then
|
|
||||||
add_cflags "-isysroot ${iphoneos_sdk_dir}"
|
|
||||||
add_ldflags "-isysroot ${iphoneos_sdk_dir}"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
x86*-darwin*)
|
|
||||||
osx_sdk_dir="$(show_darwin_sdk_path macosx)"
|
osx_sdk_dir="$(show_darwin_sdk_path macosx)"
|
||||||
if [ -d "${osx_sdk_dir}" ]; then
|
if [ -d "${osx_sdk_dir}" ]; then
|
||||||
add_cflags "-isysroot ${osx_sdk_dir}"
|
add_cflags "-isysroot ${osx_sdk_dir}"
|
||||||
@@ -842,10 +780,6 @@ process_common_toolchain() {
|
|||||||
add_cflags "-mmacosx-version-min=10.10"
|
add_cflags "-mmacosx-version-min=10.10"
|
||||||
add_ldflags "-mmacosx-version-min=10.10"
|
add_ldflags "-mmacosx-version-min=10.10"
|
||||||
;;
|
;;
|
||||||
*-darwin15-*)
|
|
||||||
add_cflags "-mmacosx-version-min=10.11"
|
|
||||||
add_ldflags "-mmacosx-version-min=10.11"
|
|
||||||
;;
|
|
||||||
*-iphonesimulator-*)
|
*-iphonesimulator-*)
|
||||||
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
add_cflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||||
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
add_ldflags "-miphoneos-version-min=${IOS_VERSION_MIN}"
|
||||||
@@ -861,6 +795,7 @@ process_common_toolchain() {
|
|||||||
case ${toolchain} in
|
case ${toolchain} in
|
||||||
sparc-solaris-*)
|
sparc-solaris-*)
|
||||||
add_extralibs -lposix4
|
add_extralibs -lposix4
|
||||||
|
disable_feature fast_unaligned
|
||||||
;;
|
;;
|
||||||
*-solaris-*)
|
*-solaris-*)
|
||||||
add_extralibs -lposix4
|
add_extralibs -lposix4
|
||||||
@@ -883,36 +818,12 @@ process_common_toolchain() {
|
|||||||
if disabled neon && enabled neon_asm; then
|
if disabled neon && enabled neon_asm; then
|
||||||
die "Disabling neon while keeping neon-asm is not supported"
|
die "Disabling neon while keeping neon-asm is not supported"
|
||||||
fi
|
fi
|
||||||
case ${toolchain} in
|
|
||||||
# Apple iOS SDKs no longer support armv6 as of the version 9
|
|
||||||
# release (coincides with release of Xcode 7). Only enable media
|
|
||||||
# when using earlier SDK releases.
|
|
||||||
*-darwin*)
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphoneos)" -lt 9 ]; then
|
|
||||||
soft_enable media
|
soft_enable media
|
||||||
else
|
soft_enable fast_unaligned
|
||||||
soft_disable media
|
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-media "
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
soft_enable media
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
armv6)
|
armv6)
|
||||||
case ${toolchain} in
|
|
||||||
*-darwin*)
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphoneos)" -lt 9 ]; then
|
|
||||||
soft_enable media
|
soft_enable media
|
||||||
else
|
soft_enable fast_unaligned
|
||||||
die "Your iOS SDK does not support armv6."
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
soft_enable media
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -920,6 +831,7 @@ process_common_toolchain() {
|
|||||||
|
|
||||||
case ${tgt_cc} in
|
case ${tgt_cc} in
|
||||||
gcc)
|
gcc)
|
||||||
|
CROSS=${CROSS:-arm-none-linux-gnueabi-}
|
||||||
link_with_cc=gcc
|
link_with_cc=gcc
|
||||||
setup_gnu_toolchain
|
setup_gnu_toolchain
|
||||||
arch_int=${tgt_isa##armv}
|
arch_int=${tgt_isa##armv}
|
||||||
@@ -941,9 +853,6 @@ EOF
|
|||||||
check_add_cflags -mfpu=neon #-ftree-vectorize
|
check_add_cflags -mfpu=neon #-ftree-vectorize
|
||||||
check_add_asflags -mfpu=neon
|
check_add_asflags -mfpu=neon
|
||||||
fi
|
fi
|
||||||
elif [ ${tgt_isa} = "arm64" ] || [ ${tgt_isa} = "armv8" ]; then
|
|
||||||
check_add_cflags -march=armv8-a
|
|
||||||
check_add_asflags -march=armv8-a
|
|
||||||
else
|
else
|
||||||
check_add_cflags -march=${tgt_isa}
|
check_add_cflags -march=${tgt_isa}
|
||||||
check_add_asflags -march=${tgt_isa}
|
check_add_asflags -march=${tgt_isa}
|
||||||
@@ -1011,10 +920,6 @@ EOF
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
android*)
|
android*)
|
||||||
if [ -z "${sdk_path}" ]; then
|
|
||||||
die "Must specify --sdk-path for Android builds."
|
|
||||||
fi
|
|
||||||
|
|
||||||
SDK_PATH=${sdk_path}
|
SDK_PATH=${sdk_path}
|
||||||
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
COMPILER_LOCATION=`find "${SDK_PATH}" \
|
||||||
-name "arm-linux-androideabi-gcc*" -print -quit`
|
-name "arm-linux-androideabi-gcc*" -print -quit`
|
||||||
@@ -1036,10 +941,8 @@ EOF
|
|||||||
awk '{ print $1 }' | tail -1`
|
awk '{ print $1 }' | tail -1`
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -d "${alt_libc}" ]; then
|
|
||||||
add_cflags "--sysroot=${alt_libc}"
|
add_cflags "--sysroot=${alt_libc}"
|
||||||
add_ldflags "--sysroot=${alt_libc}"
|
add_ldflags "--sysroot=${alt_libc}"
|
||||||
fi
|
|
||||||
|
|
||||||
# linker flag that routes around a CPU bug in some
|
# linker flag that routes around a CPU bug in some
|
||||||
# Cortex-A8 implementations (NDK Dev Guide)
|
# Cortex-A8 implementations (NDK Dev Guide)
|
||||||
@@ -1065,7 +968,18 @@ EOF
|
|||||||
NM="$(${XCRUN_FIND} nm)"
|
NM="$(${XCRUN_FIND} nm)"
|
||||||
RANLIB="$(${XCRUN_FIND} ranlib)"
|
RANLIB="$(${XCRUN_FIND} ranlib)"
|
||||||
AS_SFX=.s
|
AS_SFX=.s
|
||||||
|
|
||||||
|
# Special handling of ld for armv6 because libclang_rt.ios.a does
|
||||||
|
# not contain armv6 support in Apple's clang package:
|
||||||
|
# Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn).
|
||||||
|
# TODO(tomfinegan): Remove this. Our minimum iOS version (6.0)
|
||||||
|
# renders support for armv6 unnecessary because the 3GS and up
|
||||||
|
# support neon.
|
||||||
|
if [ "${tgt_isa}" = "armv6" ]; then
|
||||||
|
LD="$(${XCRUN_FIND} ld)"
|
||||||
|
else
|
||||||
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
LD="${CXX:-$(${XCRUN_FIND} ld)}"
|
||||||
|
fi
|
||||||
|
|
||||||
# ASFLAGS is written here instead of using check_add_asflags
|
# ASFLAGS is written here instead of using check_add_asflags
|
||||||
# because we need to overwrite all of ASFLAGS and purge the
|
# because we need to overwrite all of ASFLAGS and purge the
|
||||||
@@ -1091,26 +1005,7 @@ EOF
|
|||||||
[ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
|
[ -d "${try_dir}" ] && add_ldflags -L"${try_dir}"
|
||||||
done
|
done
|
||||||
|
|
||||||
case ${tgt_isa} in
|
|
||||||
armv7|armv7s|armv8|arm64)
|
|
||||||
if enabled neon && ! check_xcode_minimum_version; then
|
|
||||||
soft_disable neon
|
|
||||||
log_echo " neon disabled: upgrade Xcode (need v6.3+)."
|
|
||||||
if enabled neon_asm; then
|
|
||||||
soft_disable neon_asm
|
|
||||||
log_echo " neon_asm disabled: upgrade Xcode (need v6.3+)."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl"
|
asm_conversion_cmd="${source_path}/build/make/ads2gas_apple.pl"
|
||||||
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphoneos)" -gt 8 ]; then
|
|
||||||
check_add_cflags -fembed-bitcode
|
|
||||||
check_add_asflags -fembed-bitcode
|
|
||||||
check_add_ldflags -fembed-bitcode
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
linux*)
|
linux*)
|
||||||
@@ -1118,7 +1013,7 @@ EOF
|
|||||||
if enabled rvct; then
|
if enabled rvct; then
|
||||||
# Check if we have CodeSourcery GCC in PATH. Needed for
|
# Check if we have CodeSourcery GCC in PATH. Needed for
|
||||||
# libraries
|
# libraries
|
||||||
which arm-none-linux-gnueabi-gcc 2>&- || \
|
hash arm-none-linux-gnueabi-gcc 2>&- || \
|
||||||
die "Couldn't find CodeSourcery GCC from PATH"
|
die "Couldn't find CodeSourcery GCC from PATH"
|
||||||
|
|
||||||
# Use armcc as a linker to enable translation of
|
# Use armcc as a linker to enable translation of
|
||||||
@@ -1144,32 +1039,30 @@ EOF
|
|||||||
tune_cflags="-mtune="
|
tune_cflags="-mtune="
|
||||||
if enabled dspr2; then
|
if enabled dspr2; then
|
||||||
check_add_cflags -mips32r2 -mdspr2
|
check_add_cflags -mips32r2 -mdspr2
|
||||||
fi
|
disable_feature fast_unaligned
|
||||||
|
|
||||||
if enabled runtime_cpu_detect; then
|
|
||||||
disable_feature runtime_cpu_detect
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${tune_cpu}" ]; then
|
if [ -n "${tune_cpu}" ]; then
|
||||||
case ${tune_cpu} in
|
case ${tune_cpu} in
|
||||||
p5600)
|
p5600)
|
||||||
check_add_cflags -mips32r5 -mload-store-pairs
|
add_cflags -mips32r5 -funroll-loops -mload-store-pairs
|
||||||
check_add_cflags -msched-weight -mhard-float -mfp64
|
add_cflags -msched-weight -mhard-float
|
||||||
check_add_asflags -mips32r5 -mhard-float -mfp64
|
add_asflags -mips32r5 -mhard-float
|
||||||
check_add_ldflags -mfp64
|
|
||||||
;;
|
;;
|
||||||
i6400|p6600)
|
i6400)
|
||||||
check_add_cflags -mips64r6 -mabi=64 -msched-weight
|
add_cflags -mips64r6 -mabi=64 -funroll-loops -mload-store-pairs
|
||||||
check_add_cflags -mload-store-pairs -mhard-float -mfp64
|
add_cflags -msched-weight -mhard-float
|
||||||
check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64
|
add_asflags -mips64r6 -mabi=64 -mhard-float
|
||||||
check_add_ldflags -mips64r6 -mabi=64 -mfp64
|
add_ldflags -mips64r6 -mabi=64
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if enabled msa; then
|
if enabled msa; then
|
||||||
add_cflags -mmsa
|
add_cflags -mmsa -mfp64 -flax-vector-conversions
|
||||||
add_asflags -mmsa
|
add_asflags -mmsa -mfp64 -flax-vector-conversions
|
||||||
add_ldflags -mmsa
|
add_ldflags -mmsa -mfp64 -flax-vector-conversions
|
||||||
|
|
||||||
|
disable_feature fast_unaligned
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1177,6 +1070,29 @@ EOF
|
|||||||
check_add_asflags -march=${tgt_isa}
|
check_add_asflags -march=${tgt_isa}
|
||||||
check_add_asflags -KPIC
|
check_add_asflags -KPIC
|
||||||
;;
|
;;
|
||||||
|
ppc*)
|
||||||
|
enable_feature ppc
|
||||||
|
bits=${tgt_isa##ppc}
|
||||||
|
link_with_cc=gcc
|
||||||
|
setup_gnu_toolchain
|
||||||
|
add_asflags -force_cpusubtype_ALL -I"\$(dir \$<)darwin"
|
||||||
|
soft_enable altivec
|
||||||
|
enabled altivec && add_cflags -maltivec
|
||||||
|
|
||||||
|
case "$tgt_os" in
|
||||||
|
linux*)
|
||||||
|
add_asflags -maltivec -mregnames -I"\$(dir \$<)linux"
|
||||||
|
;;
|
||||||
|
darwin*)
|
||||||
|
darwin_arch="-arch ppc"
|
||||||
|
enabled ppc64 && darwin_arch="${darwin_arch}64"
|
||||||
|
add_cflags ${darwin_arch} -m${bits} -fasm-blocks
|
||||||
|
add_asflags ${darwin_arch} -force_cpusubtype_ALL -I"\$(dir \$<)darwin"
|
||||||
|
add_ldflags ${darwin_arch} -m${bits}
|
||||||
|
enabled altivec && add_cflags -faltivec
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
x86*)
|
x86*)
|
||||||
case ${tgt_os} in
|
case ${tgt_os} in
|
||||||
win*)
|
win*)
|
||||||
@@ -1186,12 +1102,10 @@ EOF
|
|||||||
CC=${CC:-${CROSS}gcc}
|
CC=${CC:-${CROSS}gcc}
|
||||||
CXX=${CXX:-${CROSS}g++}
|
CXX=${CXX:-${CROSS}g++}
|
||||||
LD=${LD:-${CROSS}gcc}
|
LD=${LD:-${CROSS}gcc}
|
||||||
CROSS=${CROSS-g}
|
CROSS=${CROSS:-g}
|
||||||
;;
|
;;
|
||||||
os2)
|
os2)
|
||||||
disable_feature pic
|
|
||||||
AS=${AS:-nasm}
|
AS=${AS:-nasm}
|
||||||
add_ldflags -Zhigh-mem
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -1239,12 +1153,6 @@ EOF
|
|||||||
soft_disable avx2
|
soft_disable avx2
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
case $vc_version in
|
|
||||||
7|8|9)
|
|
||||||
echo "${tgt_cc} omits stdint.h, disabling webm-io..."
|
|
||||||
soft_disable webm_io
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -1265,24 +1173,15 @@ EOF
|
|||||||
soft_enable runtime_cpu_detect
|
soft_enable runtime_cpu_detect
|
||||||
# We can't use 'check_cflags' until the compiler is configured and CC is
|
# We can't use 'check_cflags' until the compiler is configured and CC is
|
||||||
# populated.
|
# populated.
|
||||||
for ext in ${ARCH_EXT_LIST_X86}; do
|
check_gcc_machine_option mmx
|
||||||
# disable higher order extensions to simplify asm dependencies
|
check_gcc_machine_option sse
|
||||||
if [ "$disable_exts" = "yes" ]; then
|
check_gcc_machine_option sse2
|
||||||
if ! disabled $ext; then
|
check_gcc_machine_option sse3
|
||||||
RTCD_OPTIONS="${RTCD_OPTIONS}--disable-${ext} "
|
check_gcc_machine_option ssse3
|
||||||
disable_feature $ext
|
check_gcc_machine_option sse4 sse4_1
|
||||||
fi
|
check_gcc_machine_option avx
|
||||||
elif disabled $ext; then
|
check_gcc_machine_option avx2
|
||||||
disable_exts="yes"
|
|
||||||
else
|
|
||||||
# use the shortened version for the flag: sse4_1 -> sse4
|
|
||||||
check_gcc_machine_option ${ext%_*} $ext
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if enabled external_build; then
|
|
||||||
log_echo " skipping assembler detection"
|
|
||||||
else
|
|
||||||
case "${AS}" in
|
case "${AS}" in
|
||||||
auto|"")
|
auto|"")
|
||||||
which nasm >/dev/null 2>&1 && AS=nasm
|
which nasm >/dev/null 2>&1 && AS=nasm
|
||||||
@@ -1296,12 +1195,10 @@ EOF
|
|||||||
&& AS=""
|
&& AS=""
|
||||||
fi
|
fi
|
||||||
[ "${AS}" = auto ] || [ -z "${AS}" ] \
|
[ "${AS}" = auto ] || [ -z "${AS}" ] \
|
||||||
&& die "Neither yasm nor nasm have been found." \
|
&& die "Neither yasm nor nasm have been found"
|
||||||
"See the prerequisites section in the README for more info."
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
log_echo " using $AS"
|
log_echo " using $AS"
|
||||||
fi
|
|
||||||
[ "${AS##*/}" = nasm ] && add_asflags -Ox
|
[ "${AS##*/}" = nasm ] && add_asflags -Ox
|
||||||
AS_SFX=.asm
|
AS_SFX=.asm
|
||||||
case ${tgt_os} in
|
case ${tgt_os} in
|
||||||
@@ -1337,13 +1234,6 @@ EOF
|
|||||||
enabled x86 && sim_arch="-arch i386" || sim_arch="-arch x86_64"
|
enabled x86 && sim_arch="-arch i386" || sim_arch="-arch x86_64"
|
||||||
add_cflags ${sim_arch}
|
add_cflags ${sim_arch}
|
||||||
add_ldflags ${sim_arch}
|
add_ldflags ${sim_arch}
|
||||||
|
|
||||||
if [ "$(show_darwin_sdk_major_version iphonesimulator)" -gt 8 ]; then
|
|
||||||
# yasm v1.3.0 doesn't know what -fembed-bitcode means, so turning it
|
|
||||||
# on is pointless (unless building a C-only lib). Warn the user, but
|
|
||||||
# do nothing here.
|
|
||||||
log "Warning: Bitcode embed disabled for simulator targets."
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
os2)
|
os2)
|
||||||
add_asflags -f aout
|
add_asflags -f aout
|
||||||
@@ -1355,7 +1245,7 @@ EOF
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
*-gcc|generic-gnu)
|
universal*|*-gcc|generic-gnu)
|
||||||
link_with_cc=gcc
|
link_with_cc=gcc
|
||||||
enable_feature gcc
|
enable_feature gcc
|
||||||
setup_gnu_toolchain
|
setup_gnu_toolchain
|
||||||
@@ -1396,6 +1286,10 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${tgt_isa}" = "x86_64" ] || [ "${tgt_isa}" = "x86" ]; then
|
||||||
|
soft_enable use_x86inc
|
||||||
|
fi
|
||||||
|
|
||||||
# Position Independent Code (PIC) support, for building relocatable
|
# Position Independent Code (PIC) support, for building relocatable
|
||||||
# shared objects
|
# shared objects
|
||||||
enabled gcc && enabled pic && check_add_cflags -fPIC
|
enabled gcc && enabled pic && check_add_cflags -fPIC
|
||||||
@@ -1435,15 +1329,11 @@ EOF
|
|||||||
# only for MIPS platforms
|
# only for MIPS platforms
|
||||||
case ${toolchain} in
|
case ${toolchain} in
|
||||||
mips*)
|
mips*)
|
||||||
if enabled big_endian; then
|
|
||||||
if enabled dspr2; then
|
if enabled dspr2; then
|
||||||
|
if enabled big_endian; then
|
||||||
echo "dspr2 optimizations are available only for little endian platforms"
|
echo "dspr2 optimizations are available only for little endian platforms"
|
||||||
disable_feature dspr2
|
disable_feature dspr2
|
||||||
fi
|
fi
|
||||||
if enabled msa; then
|
|
||||||
echo "msa optimizations are available only for little endian platforms"
|
|
||||||
disable_feature msa
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -1453,6 +1343,12 @@ EOF
|
|||||||
add_cflags -D_LARGEFILE_SOURCE
|
add_cflags -D_LARGEFILE_SOURCE
|
||||||
add_cflags -D_FILE_OFFSET_BITS=64
|
add_cflags -D_FILE_OFFSET_BITS=64
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# append any user defined extra cflags
|
||||||
|
if [ -n "${extra_cflags}" ] ; then
|
||||||
|
check_add_cflags ${extra_cflags} || \
|
||||||
|
die "Requested extra CFLAGS '${extra_cflags}' not supported by compiler"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
process_toolchain() {
|
process_toolchain() {
|
||||||
|
|||||||
486
build/make/gen_msvs_proj.sh
Executable file
486
build/make/gen_msvs_proj.sh
Executable file
@@ -0,0 +1,486 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
##
|
||||||
|
## 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.
|
||||||
|
##
|
||||||
|
|
||||||
|
self=$0
|
||||||
|
self_basename=${self##*/}
|
||||||
|
self_dirname=$(dirname "$0")
|
||||||
|
|
||||||
|
. "$self_dirname/msvs_common.sh"|| exit 127
|
||||||
|
|
||||||
|
show_help() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: ${self_basename} --name=projname [options] file1 [file2 ...]
|
||||||
|
|
||||||
|
This script generates a Visual Studio project file from a list of source
|
||||||
|
code files.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help Print this message
|
||||||
|
--exe Generate a project for building an Application
|
||||||
|
--lib Generate a project for creating a static library
|
||||||
|
--dll Generate a project for creating a dll
|
||||||
|
--static-crt Use the static C runtime (/MT)
|
||||||
|
--target=isa-os-cc Target specifier (required)
|
||||||
|
--out=filename Write output to a file [stdout]
|
||||||
|
--name=project_name Name of the project (required)
|
||||||
|
--proj-guid=GUID GUID to use for the project
|
||||||
|
--module-def=filename File containing export definitions (for DLLs)
|
||||||
|
--ver=version Version (7,8,9) of visual studio to generate for
|
||||||
|
--src-path-bare=dir Path to root of source tree
|
||||||
|
-Ipath/to/include Additional include directories
|
||||||
|
-DFLAG[=value] Preprocessor macros to define
|
||||||
|
-Lpath/to/lib Additional library search paths
|
||||||
|
-llibname Library to link against
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_filter() {
|
||||||
|
local var=$1
|
||||||
|
local name=$2
|
||||||
|
local pats=$3
|
||||||
|
local file_list_sz
|
||||||
|
local i
|
||||||
|
local f
|
||||||
|
local saveIFS="$IFS"
|
||||||
|
local pack
|
||||||
|
echo "generating filter '$name' from ${#file_list[@]} files" >&2
|
||||||
|
IFS=*
|
||||||
|
|
||||||
|
open_tag Filter \
|
||||||
|
Name=$name \
|
||||||
|
Filter=$pats \
|
||||||
|
UniqueIdentifier=`generate_uuid` \
|
||||||
|
|
||||||
|
file_list_sz=${#file_list[@]}
|
||||||
|
for i in ${!file_list[@]}; do
|
||||||
|
f=${file_list[i]}
|
||||||
|
for pat in ${pats//;/$IFS}; do
|
||||||
|
if [ "${f##*.}" == "$pat" ]; then
|
||||||
|
unset file_list[i]
|
||||||
|
|
||||||
|
objf=$(echo ${f%.*}.obj \
|
||||||
|
| sed -e "s,$src_path_bare,," \
|
||||||
|
-e 's/^[\./]\+//g' -e 's,[:/ ],_,g')
|
||||||
|
open_tag File RelativePath="$f"
|
||||||
|
|
||||||
|
if [ "$pat" == "asm" ] && $asm_use_custom_step; then
|
||||||
|
for plat in "${platforms[@]}"; do
|
||||||
|
for cfg in Debug Release; do
|
||||||
|
open_tag FileConfiguration \
|
||||||
|
Name="${cfg}|${plat}" \
|
||||||
|
|
||||||
|
tag Tool \
|
||||||
|
Name="VCCustomBuildTool" \
|
||||||
|
Description="Assembling \$(InputFileName)" \
|
||||||
|
CommandLine="$(eval echo \$asm_${cfg}_cmdline) -o \$(IntDir)\\$objf" \
|
||||||
|
Outputs="\$(IntDir)\\$objf" \
|
||||||
|
|
||||||
|
close_tag FileConfiguration
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [ "$pat" == "c" ] || \
|
||||||
|
[ "$pat" == "cc" ] || [ "$pat" == "cpp" ]; then
|
||||||
|
for plat in "${platforms[@]}"; do
|
||||||
|
for cfg in Debug Release; do
|
||||||
|
open_tag FileConfiguration \
|
||||||
|
Name="${cfg}|${plat}" \
|
||||||
|
|
||||||
|
tag Tool \
|
||||||
|
Name="VCCLCompilerTool" \
|
||||||
|
ObjectFile="\$(IntDir)\\$objf" \
|
||||||
|
|
||||||
|
close_tag FileConfiguration
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
close_tag File
|
||||||
|
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
close_tag Filter
|
||||||
|
IFS="$saveIFS"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Process command line
|
||||||
|
unset target
|
||||||
|
for opt in "$@"; do
|
||||||
|
optval="${opt#*=}"
|
||||||
|
case "$opt" in
|
||||||
|
--help|-h) show_help
|
||||||
|
;;
|
||||||
|
--target=*) target="${optval}"
|
||||||
|
;;
|
||||||
|
--out=*) outfile="$optval"
|
||||||
|
;;
|
||||||
|
--name=*) name="${optval}"
|
||||||
|
;;
|
||||||
|
--proj-guid=*) guid="${optval}"
|
||||||
|
;;
|
||||||
|
--module-def=*) link_opts="${link_opts} ModuleDefinitionFile=${optval}"
|
||||||
|
;;
|
||||||
|
--exe) proj_kind="exe"
|
||||||
|
;;
|
||||||
|
--dll) proj_kind="dll"
|
||||||
|
;;
|
||||||
|
--lib) proj_kind="lib"
|
||||||
|
;;
|
||||||
|
--src-path-bare=*)
|
||||||
|
src_path_bare=$(fix_path "$optval")
|
||||||
|
src_path_bare=${src_path_bare%/}
|
||||||
|
;;
|
||||||
|
--static-crt) use_static_runtime=true
|
||||||
|
;;
|
||||||
|
--ver=*)
|
||||||
|
vs_ver="$optval"
|
||||||
|
case "$optval" in
|
||||||
|
[789])
|
||||||
|
;;
|
||||||
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
-I*)
|
||||||
|
opt=${opt##-I}
|
||||||
|
opt=$(fix_path "$opt")
|
||||||
|
opt="${opt%/}"
|
||||||
|
incs="${incs}${incs:+;}"${opt}""
|
||||||
|
yasmincs="${yasmincs} -I"${opt}""
|
||||||
|
;;
|
||||||
|
-D*) defines="${defines}${defines:+;}${opt##-D}"
|
||||||
|
;;
|
||||||
|
-L*) # fudge . to $(OutDir)
|
||||||
|
if [ "${opt##-L}" == "." ]; then
|
||||||
|
libdirs="${libdirs}${libdirs:+;}"\$(OutDir)""
|
||||||
|
else
|
||||||
|
# Also try directories for this platform/configuration
|
||||||
|
opt=${opt##-L}
|
||||||
|
opt=$(fix_path "$opt")
|
||||||
|
libdirs="${libdirs}${libdirs:+;}"${opt}""
|
||||||
|
libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)/\$(ConfigurationName)""
|
||||||
|
libdirs="${libdirs}${libdirs:+;}"${opt}/\$(PlatformName)""
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-l*) libs="${libs}${libs:+ }${opt##-l}.lib"
|
||||||
|
;;
|
||||||
|
-*) die_unknown $opt
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# The paths in file_list are fixed outside of the loop.
|
||||||
|
file_list[${#file_list[@]}]="$opt"
|
||||||
|
case "$opt" in
|
||||||
|
*.asm) uses_asm=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Make one call to fix_path for file_list to improve performance.
|
||||||
|
fix_file_list
|
||||||
|
|
||||||
|
outfile=${outfile:-/dev/stdout}
|
||||||
|
guid=${guid:-`generate_uuid`}
|
||||||
|
asm_use_custom_step=false
|
||||||
|
uses_asm=${uses_asm:-false}
|
||||||
|
case "${vs_ver:-8}" in
|
||||||
|
7) vs_ver_id="7.10"
|
||||||
|
asm_use_custom_step=$uses_asm
|
||||||
|
warn_64bit='Detect64BitPortabilityProblems=true'
|
||||||
|
;;
|
||||||
|
8) vs_ver_id="8.00"
|
||||||
|
asm_use_custom_step=$uses_asm
|
||||||
|
warn_64bit='Detect64BitPortabilityProblems=true'
|
||||||
|
;;
|
||||||
|
9) vs_ver_id="9.00"
|
||||||
|
asm_use_custom_step=$uses_asm
|
||||||
|
warn_64bit='Detect64BitPortabilityProblems=false'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -n "$name" ] || die "Project name (--name) must be specified!"
|
||||||
|
[ -n "$target" ] || die "Target (--target) must be specified!"
|
||||||
|
|
||||||
|
if ${use_static_runtime:-false}; then
|
||||||
|
release_runtime=0
|
||||||
|
debug_runtime=1
|
||||||
|
lib_sfx=mt
|
||||||
|
else
|
||||||
|
release_runtime=2
|
||||||
|
debug_runtime=3
|
||||||
|
lib_sfx=md
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Calculate debug lib names: If a lib ends in ${lib_sfx}.lib, then rename
|
||||||
|
# it to ${lib_sfx}d.lib. This precludes linking to release libs from a
|
||||||
|
# debug exe, so this may need to be refactored later.
|
||||||
|
for lib in ${libs}; do
|
||||||
|
if [ "$lib" != "${lib%${lib_sfx}.lib}" ]; then
|
||||||
|
lib=${lib%.lib}d.lib
|
||||||
|
fi
|
||||||
|
debug_libs="${debug_libs}${debug_libs:+ }${lib}"
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# List Keyword for this target
|
||||||
|
case "$target" in
|
||||||
|
x86*) keyword="ManagedCProj"
|
||||||
|
;;
|
||||||
|
*) die "Unsupported target $target!"
|
||||||
|
esac
|
||||||
|
|
||||||
|
# List of all platforms supported for this target
|
||||||
|
case "$target" in
|
||||||
|
x86_64*)
|
||||||
|
platforms[0]="x64"
|
||||||
|
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win64 ${yasmincs} "\$(InputPath)""
|
||||||
|
asm_Release_cmdline="yasm -Xvc -f win64 ${yasmincs} "\$(InputPath)""
|
||||||
|
;;
|
||||||
|
x86*)
|
||||||
|
platforms[0]="Win32"
|
||||||
|
asm_Debug_cmdline="yasm -Xvc -g cv8 -f win32 ${yasmincs} "\$(InputPath)""
|
||||||
|
asm_Release_cmdline="yasm -Xvc -f win32 ${yasmincs} "\$(InputPath)""
|
||||||
|
;;
|
||||||
|
*) die "Unsupported target $target!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
generate_vcproj() {
|
||||||
|
case "$proj_kind" in
|
||||||
|
exe) vs_ConfigurationType=1
|
||||||
|
;;
|
||||||
|
dll) vs_ConfigurationType=2
|
||||||
|
;;
|
||||||
|
*) vs_ConfigurationType=4
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
|
||||||
|
open_tag VisualStudioProject \
|
||||||
|
ProjectType="Visual C++" \
|
||||||
|
Version="${vs_ver_id}" \
|
||||||
|
Name="${name}" \
|
||||||
|
ProjectGUID="{${guid}}" \
|
||||||
|
RootNamespace="${name}" \
|
||||||
|
Keyword="${keyword}" \
|
||||||
|
|
||||||
|
open_tag Platforms
|
||||||
|
for plat in "${platforms[@]}"; do
|
||||||
|
tag Platform Name="$plat"
|
||||||
|
done
|
||||||
|
close_tag Platforms
|
||||||
|
|
||||||
|
open_tag Configurations
|
||||||
|
for plat in "${platforms[@]}"; do
|
||||||
|
plat_no_ws=`echo $plat | sed 's/[^A-Za-z0-9_]/_/g'`
|
||||||
|
open_tag Configuration \
|
||||||
|
Name="Debug|$plat" \
|
||||||
|
OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
|
||||||
|
IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
|
||||||
|
ConfigurationType="$vs_ConfigurationType" \
|
||||||
|
CharacterSet="1" \
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
x86*)
|
||||||
|
case "$name" in
|
||||||
|
vpx)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCCLCompilerTool" \
|
||||||
|
Optimization="0" \
|
||||||
|
AdditionalIncludeDirectories="$incs" \
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
||||||
|
RuntimeLibrary="$debug_runtime" \
|
||||||
|
UsePrecompiledHeader="0" \
|
||||||
|
WarningLevel="3" \
|
||||||
|
DebugInformationFormat="2" \
|
||||||
|
$warn_64bit \
|
||||||
|
|
||||||
|
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCCLCompilerTool" \
|
||||||
|
Optimization="0" \
|
||||||
|
AdditionalIncludeDirectories="$incs" \
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
||||||
|
RuntimeLibrary="$debug_runtime" \
|
||||||
|
UsePrecompiledHeader="0" \
|
||||||
|
WarningLevel="3" \
|
||||||
|
DebugInformationFormat="2" \
|
||||||
|
$warn_64bit \
|
||||||
|
|
||||||
|
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs" Debug="true"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$proj_kind" in
|
||||||
|
exe)
|
||||||
|
case "$target" in
|
||||||
|
x86*)
|
||||||
|
case "$name" in
|
||||||
|
*)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCLinkerTool" \
|
||||||
|
AdditionalDependencies="$debug_libs \$(NoInherit)" \
|
||||||
|
AdditionalLibraryDirectories="$libdirs" \
|
||||||
|
GenerateDebugInformation="true" \
|
||||||
|
ProgramDatabaseFile="\$(OutDir)/${name}.pdb" \
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
lib)
|
||||||
|
case "$target" in
|
||||||
|
x86*)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCLibrarianTool" \
|
||||||
|
OutputFile="\$(OutDir)/${name}${lib_sfx}d.lib" \
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
dll)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCLinkerTool" \
|
||||||
|
AdditionalDependencies="\$(NoInherit)" \
|
||||||
|
LinkIncremental="2" \
|
||||||
|
GenerateDebugInformation="true" \
|
||||||
|
AssemblyDebug="1" \
|
||||||
|
TargetMachine="1" \
|
||||||
|
$link_opts \
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
close_tag Configuration
|
||||||
|
|
||||||
|
open_tag Configuration \
|
||||||
|
Name="Release|$plat" \
|
||||||
|
OutputDirectory="\$(SolutionDir)$plat_no_ws/\$(ConfigurationName)" \
|
||||||
|
IntermediateDirectory="$plat_no_ws/\$(ConfigurationName)/${name}" \
|
||||||
|
ConfigurationType="$vs_ConfigurationType" \
|
||||||
|
CharacterSet="1" \
|
||||||
|
WholeProgramOptimization="0" \
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
x86*)
|
||||||
|
case "$name" in
|
||||||
|
vpx)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCCLCompilerTool" \
|
||||||
|
Optimization="2" \
|
||||||
|
FavorSizeorSpeed="1" \
|
||||||
|
AdditionalIncludeDirectories="$incs" \
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
||||||
|
RuntimeLibrary="$release_runtime" \
|
||||||
|
UsePrecompiledHeader="0" \
|
||||||
|
WarningLevel="3" \
|
||||||
|
DebugInformationFormat="0" \
|
||||||
|
$warn_64bit \
|
||||||
|
|
||||||
|
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCCLCompilerTool" \
|
||||||
|
AdditionalIncludeDirectories="$incs" \
|
||||||
|
Optimization="2" \
|
||||||
|
FavorSizeorSpeed="1" \
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;$defines" \
|
||||||
|
RuntimeLibrary="$release_runtime" \
|
||||||
|
UsePrecompiledHeader="0" \
|
||||||
|
WarningLevel="3" \
|
||||||
|
DebugInformationFormat="0" \
|
||||||
|
$warn_64bit \
|
||||||
|
|
||||||
|
$uses_asm && tag Tool Name="YASM" IncludePaths="$incs"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$proj_kind" in
|
||||||
|
exe)
|
||||||
|
case "$target" in
|
||||||
|
x86*)
|
||||||
|
case "$name" in
|
||||||
|
*)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCLinkerTool" \
|
||||||
|
AdditionalDependencies="$libs \$(NoInherit)" \
|
||||||
|
AdditionalLibraryDirectories="$libdirs" \
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
lib)
|
||||||
|
case "$target" in
|
||||||
|
x86*)
|
||||||
|
tag Tool \
|
||||||
|
Name="VCLibrarianTool" \
|
||||||
|
OutputFile="\$(OutDir)/${name}${lib_sfx}.lib" \
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
dll) # note differences to debug version: LinkIncremental, AssemblyDebug
|
||||||
|
tag Tool \
|
||||||
|
Name="VCLinkerTool" \
|
||||||
|
AdditionalDependencies="\$(NoInherit)" \
|
||||||
|
LinkIncremental="1" \
|
||||||
|
GenerateDebugInformation="true" \
|
||||||
|
TargetMachine="1" \
|
||||||
|
$link_opts \
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
close_tag Configuration
|
||||||
|
done
|
||||||
|
close_tag Configurations
|
||||||
|
|
||||||
|
open_tag Files
|
||||||
|
generate_filter srcs "Source Files" "c;cc;cpp;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
generate_filter hdrs "Header Files" "h;hm;inl;inc;xsd"
|
||||||
|
generate_filter resrcs "Resource Files" "rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
generate_filter resrcs "Build Files" "mk"
|
||||||
|
close_tag Files
|
||||||
|
|
||||||
|
tag Globals
|
||||||
|
close_tag VisualStudioProject
|
||||||
|
|
||||||
|
# This must be done from within the {} subshell
|
||||||
|
echo "Ignored files list (${#file_list[@]} items) is:" >&2
|
||||||
|
for f in "${file_list[@]}"; do
|
||||||
|
echo " $f" >&2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_vcproj |
|
||||||
|
sed -e '/"/s;\([^ "]\)/;\1\\;g' > ${outfile}
|
||||||
|
|
||||||
|
exit
|
||||||
|
<!--
|
||||||
|
TODO: Add any files not captured by filters.
|
||||||
|
<File
|
||||||
|
RelativePath=".\ReadMe.txt"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
-->
|
||||||
@@ -19,13 +19,13 @@ show_help() {
|
|||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: ${self_basename} [options] file1 [file2 ...]
|
Usage: ${self_basename} [options] file1 [file2 ...]
|
||||||
|
|
||||||
This script generates a Visual Studio solution file from a list of project
|
This script generates a Visual Studio 2005 solution file from a list of project
|
||||||
files.
|
files.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--help Print this message
|
--help Print this message
|
||||||
--out=outfile Redirect output to a file
|
--out=outfile Redirect output to a file
|
||||||
--ver=version Version (7,8,9,10,11,12,14) of visual studio to generate for
|
--ver=version Version (7,8,9,10,11) of visual studio to generate for
|
||||||
--target=isa-os-cc Target specifier
|
--target=isa-os-cc Target specifier
|
||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
@@ -55,11 +55,16 @@ indent_pop() {
|
|||||||
|
|
||||||
parse_project() {
|
parse_project() {
|
||||||
local file=$1
|
local file=$1
|
||||||
|
if [ "$sfx" = "vcproj" ]; then
|
||||||
|
local name=`grep Name "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
|
||||||
|
local guid=`grep ProjectGUID "$file" | awk 'BEGIN {FS="\""}{if (NR==1) print $2}'`
|
||||||
|
else
|
||||||
local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
local name=`grep RootNamespace "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
||||||
local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
local guid=`grep ProjectGuid "$file" | sed 's,.*<.*>\(.*\)</.*>.*,\1,'`
|
||||||
|
fi
|
||||||
|
|
||||||
# save the project GUID to a varaible, normalizing to the basename of the
|
# save the project GUID to a varaible, normalizing to the basename of the
|
||||||
# vcxproj file without the extension
|
# vcproj file without the extension
|
||||||
local var
|
local var
|
||||||
var=${file##*/}
|
var=${file##*/}
|
||||||
var=${var%%.${sfx}}
|
var=${var%%.${sfx}}
|
||||||
@@ -67,8 +72,13 @@ parse_project() {
|
|||||||
eval "${var}_name=$name"
|
eval "${var}_name=$name"
|
||||||
eval "${var}_guid=$guid"
|
eval "${var}_guid=$guid"
|
||||||
|
|
||||||
|
if [ "$sfx" = "vcproj" ]; then
|
||||||
|
cur_config_list=`grep -A1 '<Configuration' $file |
|
||||||
|
grep Name | cut -d\" -f2`
|
||||||
|
else
|
||||||
cur_config_list=`grep -B1 'Label="Configuration"' $file |
|
cur_config_list=`grep -B1 'Label="Configuration"' $file |
|
||||||
grep Condition | cut -d\' -f4`
|
grep Condition | cut -d\' -f4`
|
||||||
|
fi
|
||||||
new_config_list=$(for i in $config_list $cur_config_list; do
|
new_config_list=$(for i in $config_list $cur_config_list; do
|
||||||
echo $i
|
echo $i
|
||||||
done | sort | uniq)
|
done | sort | uniq)
|
||||||
@@ -93,6 +103,25 @@ process_project() {
|
|||||||
eval "${var}_guid=$guid"
|
eval "${var}_guid=$guid"
|
||||||
|
|
||||||
echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
|
echo "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"$name\", \"$file\", \"$guid\""
|
||||||
|
indent_push
|
||||||
|
|
||||||
|
eval "local deps=\"\${${var}_deps}\""
|
||||||
|
if [ -n "$deps" ] && [ "$sfx" = "vcproj" ]; then
|
||||||
|
echo "${indent}ProjectSection(ProjectDependencies) = postProject"
|
||||||
|
indent_push
|
||||||
|
|
||||||
|
for dep in $deps; do
|
||||||
|
eval "local dep_guid=\${${dep}_guid}"
|
||||||
|
[ -z "${dep_guid}" ] && die "Unknown GUID for $dep (dependency of $var)"
|
||||||
|
echo "${indent}$dep_guid = $dep_guid"
|
||||||
|
done
|
||||||
|
|
||||||
|
indent_pop
|
||||||
|
echo "${indent}EndProjectSection"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
indent_pop
|
||||||
echo "EndProject"
|
echo "EndProject"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +191,11 @@ process_makefile() {
|
|||||||
IFS=$'\r'$'\n'
|
IFS=$'\r'$'\n'
|
||||||
local TAB=$'\t'
|
local TAB=$'\t'
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
ifeq (\$(CONFIG_VS_VERSION),7)
|
||||||
|
MSBUILD_TOOL := devenv.com
|
||||||
|
else
|
||||||
MSBUILD_TOOL := msbuild.exe
|
MSBUILD_TOOL := msbuild.exe
|
||||||
|
endif
|
||||||
found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes)
|
found_devenv := \$(shell which \$(MSBUILD_TOOL) >/dev/null 2>&1 && echo yes)
|
||||||
.nodevenv.once:
|
.nodevenv.once:
|
||||||
${TAB}@echo " * \$(MSBUILD_TOOL) not found in path."
|
${TAB}@echo " * \$(MSBUILD_TOOL) not found in path."
|
||||||
@@ -171,7 +204,7 @@ ${TAB}@echo " * You will have to build all configurations manually using the"
|
|||||||
${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically,"
|
${TAB}@echo " * Visual Studio IDE. To allow make to build them automatically,"
|
||||||
${TAB}@echo " * add the Common7/IDE directory of your Visual Studio"
|
${TAB}@echo " * add the Common7/IDE directory of your Visual Studio"
|
||||||
${TAB}@echo " * installation to your path, eg:"
|
${TAB}@echo " * installation to your path, eg:"
|
||||||
${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE"
|
${TAB}@echo " * C:\Program Files\Microsoft Visual Studio 8\Common7\IDE"
|
||||||
${TAB}@echo " * "
|
${TAB}@echo " * "
|
||||||
${TAB}@touch \$@
|
${TAB}@touch \$@
|
||||||
CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once)
|
CLEAN-OBJS += \$(if \$(found_devenv),,.nodevenv.once)
|
||||||
@@ -188,9 +221,16 @@ clean::
|
|||||||
${TAB}rm -rf "$platform"/"$config"
|
${TAB}rm -rf "$platform"/"$config"
|
||||||
.PHONY: $nows_sln_config
|
.PHONY: $nows_sln_config
|
||||||
ifneq (\$(found_devenv),)
|
ifneq (\$(found_devenv),)
|
||||||
|
ifeq (\$(CONFIG_VS_VERSION),7)
|
||||||
|
$nows_sln_config: $outfile
|
||||||
|
${TAB}\$(MSBUILD_TOOL) $outfile -build "$config"
|
||||||
|
|
||||||
|
else
|
||||||
$nows_sln_config: $outfile
|
$nows_sln_config: $outfile
|
||||||
${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\
|
${TAB}\$(MSBUILD_TOOL) $outfile -m -t:Build \\
|
||||||
${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform"
|
${TAB}${TAB}-p:Configuration="$config" -p:Platform="$platform"
|
||||||
|
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
$nows_sln_config: $outfile .nodevenv.once
|
$nows_sln_config: $outfile .nodevenv.once
|
||||||
${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)."
|
${TAB}@echo " * Skipping build of $sln_config (\$(MSBUILD_TOOL) not in path)."
|
||||||
@@ -215,12 +255,23 @@ for opt in "$@"; do
|
|||||||
;;
|
;;
|
||||||
--ver=*) vs_ver="$optval"
|
--ver=*) vs_ver="$optval"
|
||||||
case $optval in
|
case $optval in
|
||||||
10|11|12|14)
|
[789]|10|11|12)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
--ver=*) vs_ver="$optval"
|
||||||
|
case $optval in
|
||||||
|
7) sln_vers="8.00"
|
||||||
|
sln_vers_str="Visual Studio .NET 2003"
|
||||||
|
;;
|
||||||
|
[89])
|
||||||
|
;;
|
||||||
|
*) die "Unrecognized Visual Studio Version '$optval' in $opt"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
--target=*) target="${optval}"
|
--target=*) target="${optval}"
|
||||||
;;
|
;;
|
||||||
-*) die_unknown $opt
|
-*) die_unknown $opt
|
||||||
@@ -230,7 +281,16 @@ for opt in "$@"; do
|
|||||||
done
|
done
|
||||||
outfile=${outfile:-/dev/stdout}
|
outfile=${outfile:-/dev/stdout}
|
||||||
mkoutfile=${mkoutfile:-/dev/stdout}
|
mkoutfile=${mkoutfile:-/dev/stdout}
|
||||||
case "${vs_ver:-10}" in
|
case "${vs_ver:-8}" in
|
||||||
|
7) sln_vers="8.00"
|
||||||
|
sln_vers_str="Visual Studio .NET 2003"
|
||||||
|
;;
|
||||||
|
8) sln_vers="9.00"
|
||||||
|
sln_vers_str="Visual Studio 2005"
|
||||||
|
;;
|
||||||
|
9) sln_vers="10.00"
|
||||||
|
sln_vers_str="Visual Studio 2008"
|
||||||
|
;;
|
||||||
10) sln_vers="11.00"
|
10) sln_vers="11.00"
|
||||||
sln_vers_str="Visual Studio 2010"
|
sln_vers_str="Visual Studio 2010"
|
||||||
;;
|
;;
|
||||||
@@ -240,11 +300,15 @@ case "${vs_ver:-10}" in
|
|||||||
12) sln_vers="12.00"
|
12) sln_vers="12.00"
|
||||||
sln_vers_str="Visual Studio 2013"
|
sln_vers_str="Visual Studio 2013"
|
||||||
;;
|
;;
|
||||||
14) sln_vers="14.00"
|
esac
|
||||||
sln_vers_str="Visual Studio 2015"
|
case "${vs_ver:-8}" in
|
||||||
|
[789])
|
||||||
|
sfx=vcproj
|
||||||
|
;;
|
||||||
|
10|11|12)
|
||||||
|
sfx=vcxproj
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
sfx=vcxproj
|
|
||||||
|
|
||||||
for f in "${file_list[@]}"; do
|
for f in "${file_list[@]}"; do
|
||||||
parse_project $f
|
parse_project $f
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Options:
|
|||||||
--name=project_name Name of the project (required)
|
--name=project_name Name of the project (required)
|
||||||
--proj-guid=GUID GUID to use for the project
|
--proj-guid=GUID GUID to use for the project
|
||||||
--module-def=filename File containing export definitions (for DLLs)
|
--module-def=filename File containing export definitions (for DLLs)
|
||||||
--ver=version Version (10,11,12,14) of visual studio to generate for
|
--ver=version Version (10,11,12) of visual studio to generate for
|
||||||
--src-path-bare=dir Path to root of source tree
|
--src-path-bare=dir Path to root of source tree
|
||||||
-Ipath/to/include Additional include directories
|
-Ipath/to/include Additional include directories
|
||||||
-DFLAG[=value] Preprocessor macros to define
|
-DFLAG[=value] Preprocessor macros to define
|
||||||
@@ -168,7 +168,7 @@ for opt in "$@"; do
|
|||||||
--ver=*)
|
--ver=*)
|
||||||
vs_ver="$optval"
|
vs_ver="$optval"
|
||||||
case "$optval" in
|
case "$optval" in
|
||||||
10|11|12|14)
|
10|11|12)
|
||||||
;;
|
;;
|
||||||
*) die Unrecognized Visual Studio Version in $opt
|
*) die Unrecognized Visual Studio Version in $opt
|
||||||
;;
|
;;
|
||||||
@@ -211,14 +211,14 @@ for opt in "$@"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Make one call to fix_path for file_list to improve performance.
|
# Make one call to fix_path for file_list to improve performance.
|
||||||
fix_file_list file_list
|
fix_file_list
|
||||||
|
|
||||||
outfile=${outfile:-/dev/stdout}
|
outfile=${outfile:-/dev/stdout}
|
||||||
guid=${guid:-`generate_uuid`}
|
guid=${guid:-`generate_uuid`}
|
||||||
asm_use_custom_step=false
|
asm_use_custom_step=false
|
||||||
uses_asm=${uses_asm:-false}
|
uses_asm=${uses_asm:-false}
|
||||||
case "${vs_ver:-11}" in
|
case "${vs_ver:-11}" in
|
||||||
10|11|12|14)
|
10|11|12)
|
||||||
asm_use_custom_step=$uses_asm
|
asm_use_custom_step=$uses_asm
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -263,8 +263,8 @@ case "$target" in
|
|||||||
;;
|
;;
|
||||||
arm*)
|
arm*)
|
||||||
platforms[0]="ARM"
|
platforms[0]="ARM"
|
||||||
asm_Debug_cmdline="armasm -nologo -oldit "%(FullPath)""
|
asm_Debug_cmdline="armasm -nologo "%(FullPath)""
|
||||||
asm_Release_cmdline="armasm -nologo -oldit "%(FullPath)""
|
asm_Release_cmdline="armasm -nologo "%(FullPath)""
|
||||||
;;
|
;;
|
||||||
*) die "Unsupported target $target!"
|
*) die "Unsupported target $target!"
|
||||||
;;
|
;;
|
||||||
@@ -344,9 +344,6 @@ generate_vcxproj() {
|
|||||||
# has to enable AppContainerApplication as well.
|
# has to enable AppContainerApplication as well.
|
||||||
tag_content PlatformToolset v120
|
tag_content PlatformToolset v120
|
||||||
fi
|
fi
|
||||||
if [ "$vs_ver" = "14" ]; then
|
|
||||||
tag_content PlatformToolset v140
|
|
||||||
fi
|
|
||||||
tag_content CharacterSet Unicode
|
tag_content CharacterSet Unicode
|
||||||
if [ "$config" = "Release" ]; then
|
if [ "$config" = "Release" ]; then
|
||||||
tag_content WholeProgramOptimization true
|
tag_content WholeProgramOptimization true
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
|
||||||
<string>en</string>
|
|
||||||
<key>CFBundleExecutable</key>
|
|
||||||
<string>VPX</string>
|
|
||||||
<key>CFBundleIdentifier</key>
|
|
||||||
<string>org.webmproject.VPX</string>
|
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
|
||||||
<string>6.0</string>
|
|
||||||
<key>CFBundleName</key>
|
|
||||||
<string>VPX</string>
|
|
||||||
<key>CFBundlePackageType</key>
|
|
||||||
<string>FMWK</string>
|
|
||||||
<key>CFBundleShortVersionString</key>
|
|
||||||
<string>${VERSION}</string>
|
|
||||||
<key>CFBundleSignature</key>
|
|
||||||
<string>????</string>
|
|
||||||
<key>CFBundleSupportedPlatforms</key>
|
|
||||||
<array>
|
|
||||||
<string>iPhoneOS</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>${VERSION}</string>
|
|
||||||
<key>MinimumOSVersion</key>
|
|
||||||
<string>${IOS_VERSION_MIN}</string>
|
|
||||||
<key>UIDeviceFamily</key>
|
|
||||||
<array>
|
|
||||||
<integer>1</integer>
|
|
||||||
<integer>2</integer>
|
|
||||||
</array>
|
|
||||||
<key>VPXFullVersion</key>
|
|
||||||
<string>${FULLVERSION}</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -24,44 +24,32 @@ CONFIGURE_ARGS="--disable-docs
|
|||||||
--disable-unit-tests"
|
--disable-unit-tests"
|
||||||
DIST_DIR="_dist"
|
DIST_DIR="_dist"
|
||||||
FRAMEWORK_DIR="VPX.framework"
|
FRAMEWORK_DIR="VPX.framework"
|
||||||
FRAMEWORK_LIB="VPX.framework/VPX"
|
|
||||||
HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx"
|
HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx"
|
||||||
|
MAKE_JOBS=1
|
||||||
SCRIPT_DIR=$(dirname "$0")
|
SCRIPT_DIR=$(dirname "$0")
|
||||||
LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd)
|
LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd)
|
||||||
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
|
||||||
ORIG_PWD="$(pwd)"
|
ORIG_PWD="$(pwd)"
|
||||||
ARM_TARGETS="arm64-darwin-gcc
|
TARGETS="arm64-darwin-gcc
|
||||||
armv7-darwin-gcc
|
armv7-darwin-gcc
|
||||||
armv7s-darwin-gcc"
|
armv7s-darwin-gcc
|
||||||
SIM_TARGETS="x86-iphonesimulator-gcc
|
x86-iphonesimulator-gcc
|
||||||
x86_64-iphonesimulator-gcc"
|
x86_64-iphonesimulator-gcc"
|
||||||
OSX_TARGETS="x86-darwin15-gcc
|
|
||||||
x86_64-darwin15-gcc"
|
|
||||||
TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
|
|
||||||
|
|
||||||
# Configures for the target specified by $1, and invokes make with the dist
|
# Configures for the target specified by $1, and invokes make with the dist
|
||||||
# target using $DIST_DIR as the distribution output directory.
|
# target using $DIST_DIR as the distribution output directory.
|
||||||
build_target() {
|
build_target() {
|
||||||
local target="$1"
|
local target="$1"
|
||||||
local old_pwd="$(pwd)"
|
local old_pwd="$(pwd)"
|
||||||
local target_specific_flags=""
|
|
||||||
|
|
||||||
vlog "***Building target: ${target}***"
|
vlog "***Building target: ${target}***"
|
||||||
|
|
||||||
case "${target}" in
|
|
||||||
x86-*)
|
|
||||||
target_specific_flags="--enable-pic"
|
|
||||||
vlog "Enabled PIC for ${target}"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
mkdir "${target}"
|
mkdir "${target}"
|
||||||
cd "${target}"
|
cd "${target}"
|
||||||
eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
|
eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
|
||||||
${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${target_specific_flags} \
|
${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${devnull}
|
||||||
${devnull}
|
|
||||||
export DIST_DIR
|
export DIST_DIR
|
||||||
eval make dist ${devnull}
|
eval make -j ${MAKE_JOBS} dist ${devnull}
|
||||||
cd "${old_pwd}"
|
cd "${old_pwd}"
|
||||||
|
|
||||||
vlog "***Done building target: ${target}***"
|
vlog "***Done building target: ${target}***"
|
||||||
@@ -138,44 +126,6 @@ create_vpx_framework_config_shim() {
|
|||||||
printf "#endif // ${include_guard}" >> "${config_file}"
|
printf "#endif // ${include_guard}" >> "${config_file}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Verifies that $FRAMEWORK_LIB fat library contains requested builds.
|
|
||||||
verify_framework_targets() {
|
|
||||||
local requested_cpus=""
|
|
||||||
local cpu=""
|
|
||||||
|
|
||||||
# Extract CPU from full target name.
|
|
||||||
for target; do
|
|
||||||
cpu="${target%%-*}"
|
|
||||||
if [ "${cpu}" = "x86" ]; then
|
|
||||||
# lipo -info outputs i386 for libvpx x86 targets.
|
|
||||||
cpu="i386"
|
|
||||||
fi
|
|
||||||
requested_cpus="${requested_cpus}${cpu} "
|
|
||||||
done
|
|
||||||
|
|
||||||
# Get target CPUs present in framework library.
|
|
||||||
local targets_built=$(${LIPO} -info ${FRAMEWORK_LIB})
|
|
||||||
|
|
||||||
# $LIPO -info outputs a string like the following:
|
|
||||||
# Architectures in the fat file: $FRAMEWORK_LIB <architectures>
|
|
||||||
# Capture only the architecture strings.
|
|
||||||
targets_built=${targets_built##*: }
|
|
||||||
|
|
||||||
# Sort CPU strings to make the next step a simple string compare.
|
|
||||||
local actual=$(echo ${targets_built} | tr " " "\n" | sort | tr "\n" " ")
|
|
||||||
local requested=$(echo ${requested_cpus} | tr " " "\n" | sort | tr "\n" " ")
|
|
||||||
|
|
||||||
vlog "Requested ${FRAMEWORK_LIB} CPUs: ${requested}"
|
|
||||||
vlog "Actual ${FRAMEWORK_LIB} CPUs: ${actual}"
|
|
||||||
|
|
||||||
if [ "${requested}" != "${actual}" ]; then
|
|
||||||
elog "Actual ${FRAMEWORK_LIB} targets do not match requested target list."
|
|
||||||
elog " Requested target CPUs: ${requested}"
|
|
||||||
elog " Actual target CPUs: ${actual}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Configures and builds each target specified by $1, and then builds
|
# Configures and builds each target specified by $1, and then builds
|
||||||
# VPX.framework.
|
# VPX.framework.
|
||||||
build_framework() {
|
build_framework() {
|
||||||
@@ -196,12 +146,7 @@ build_framework() {
|
|||||||
for target in ${targets}; do
|
for target in ${targets}; do
|
||||||
build_target "${target}"
|
build_target "${target}"
|
||||||
target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
|
target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
|
||||||
if [ "${ENABLE_SHARED}" = "yes" ]; then
|
lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.a"
|
||||||
local suffix="dylib"
|
|
||||||
else
|
|
||||||
local suffix="a"
|
|
||||||
fi
|
|
||||||
lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.${suffix}"
|
|
||||||
done
|
done
|
||||||
|
|
||||||
cd "${ORIG_PWD}"
|
cd "${ORIG_PWD}"
|
||||||
@@ -220,25 +165,13 @@ build_framework() {
|
|||||||
# Copy in vpx_version.h.
|
# Copy in vpx_version.h.
|
||||||
cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
|
cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
|
||||||
|
|
||||||
if [ "${ENABLE_SHARED}" = "yes" ]; then
|
vlog "Created fat library ${FRAMEWORK_DIR}/VPX containing:"
|
||||||
# Adjust the dylib's name so dynamic linking in apps works as expected.
|
|
||||||
install_name_tool -id '@rpath/VPX.framework/VPX' ${FRAMEWORK_DIR}/VPX
|
|
||||||
|
|
||||||
# Copy in Info.plist.
|
|
||||||
cat "${SCRIPT_DIR}/ios-Info.plist" \
|
|
||||||
| sed "s/\${FULLVERSION}/${FULLVERSION}/g" \
|
|
||||||
| sed "s/\${VERSION}/${VERSION}/g" \
|
|
||||||
| sed "s/\${IOS_VERSION_MIN}/${IOS_VERSION_MIN}/g" \
|
|
||||||
> "${FRAMEWORK_DIR}/Info.plist"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Confirm VPX.framework/VPX contains the targets requested.
|
|
||||||
verify_framework_targets ${targets}
|
|
||||||
|
|
||||||
vlog "Created fat library ${FRAMEWORK_LIB} containing:"
|
|
||||||
for lib in ${lib_list}; do
|
for lib in ${lib_list}; do
|
||||||
vlog " $(echo ${lib} | awk -F / '{print $2, $NF}')"
|
vlog " $(echo ${lib} | awk -F / '{print $2, $NF}')"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# TODO(tomfinegan): Verify that expected targets are included within
|
||||||
|
# VPX.framework/VPX via lipo -info.
|
||||||
}
|
}
|
||||||
|
|
||||||
# Trap function. Cleans up the subtree used to build all targets contained in
|
# Trap function. Cleans up the subtree used to build all targets contained in
|
||||||
@@ -256,30 +189,16 @@ cleanup() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
print_list() {
|
|
||||||
local indent="$1"
|
|
||||||
shift
|
|
||||||
local list="$@"
|
|
||||||
for entry in ${list}; do
|
|
||||||
echo "${indent}${entry}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
iosbuild_usage() {
|
iosbuild_usage() {
|
||||||
cat << EOF
|
cat << EOF
|
||||||
Usage: ${0##*/} [arguments]
|
Usage: ${0##*/} [arguments]
|
||||||
--help: Display this message and exit.
|
--help: Display this message and exit.
|
||||||
--enable-shared: Build a dynamic framework for use on iOS 8 or later.
|
|
||||||
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
--extra-configure-args <args>: Extra args to pass when configuring libvpx.
|
||||||
--macosx: Uses darwin15 targets instead of iphonesimulator targets for x86
|
--jobs: Number of make jobs.
|
||||||
and x86_64. Allows linking to framework when builds target MacOSX
|
|
||||||
instead of iOS.
|
|
||||||
--preserve-build-output: Do not delete the build directory.
|
--preserve-build-output: Do not delete the build directory.
|
||||||
--show-build-output: Show output from each library build.
|
--show-build-output: Show output from each library build.
|
||||||
--targets <targets>: Override default target list. Defaults:
|
--targets <targets>: Override default target list. Defaults:
|
||||||
$(print_list " " ${TARGETS})
|
${TARGETS}
|
||||||
--test-link: Confirms all targets can be linked. Functionally identical to
|
|
||||||
passing --enable-examples via --extra-configure-args.
|
|
||||||
--verbose: Output information about the environment and each stage of the
|
--verbose: Output information about the environment and each stage of the
|
||||||
build.
|
build.
|
||||||
EOF
|
EOF
|
||||||
@@ -308,8 +227,9 @@ while [ -n "$1" ]; do
|
|||||||
iosbuild_usage
|
iosbuild_usage
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
--enable-shared)
|
--jobs)
|
||||||
ENABLE_SHARED=yes
|
MAKE_JOBS="$2"
|
||||||
|
shift
|
||||||
;;
|
;;
|
||||||
--preserve-build-output)
|
--preserve-build-output)
|
||||||
PRESERVE_BUILD_OUTPUT=yes
|
PRESERVE_BUILD_OUTPUT=yes
|
||||||
@@ -317,16 +237,10 @@ while [ -n "$1" ]; do
|
|||||||
--show-build-output)
|
--show-build-output)
|
||||||
devnull=
|
devnull=
|
||||||
;;
|
;;
|
||||||
--test-link)
|
|
||||||
EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --enable-examples"
|
|
||||||
;;
|
|
||||||
--targets)
|
--targets)
|
||||||
TARGETS="$2"
|
TARGETS="$2"
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--macosx)
|
|
||||||
TARGETS="${ARM_TARGETS} ${OSX_TARGETS}"
|
|
||||||
;;
|
|
||||||
--verbose)
|
--verbose)
|
||||||
VERBOSE=yes
|
VERBOSE=yes
|
||||||
;;
|
;;
|
||||||
@@ -338,21 +252,6 @@ while [ -n "$1" ]; do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "${ENABLE_SHARED}" = "yes" ]; then
|
|
||||||
CONFIGURE_ARGS="--enable-shared ${CONFIGURE_ARGS}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
FULLVERSION=$("${SCRIPT_DIR}"/version.sh --bare "${LIBVPX_SOURCE_DIR}")
|
|
||||||
VERSION=$(echo "${FULLVERSION}" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')
|
|
||||||
|
|
||||||
if [ "$ENABLE_SHARED" = "yes" ]; then
|
|
||||||
IOS_VERSION_OPTIONS="--enable-shared"
|
|
||||||
IOS_VERSION_MIN="8.0"
|
|
||||||
else
|
|
||||||
IOS_VERSION_OPTIONS=""
|
|
||||||
IOS_VERSION_MIN="6.0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${VERBOSE}" = "yes" ]; then
|
if [ "${VERBOSE}" = "yes" ]; then
|
||||||
cat << EOF
|
cat << EOF
|
||||||
BUILD_ROOT=${BUILD_ROOT}
|
BUILD_ROOT=${BUILD_ROOT}
|
||||||
@@ -360,24 +259,16 @@ cat << EOF
|
|||||||
CONFIGURE_ARGS=${CONFIGURE_ARGS}
|
CONFIGURE_ARGS=${CONFIGURE_ARGS}
|
||||||
EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
|
EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
|
||||||
FRAMEWORK_DIR=${FRAMEWORK_DIR}
|
FRAMEWORK_DIR=${FRAMEWORK_DIR}
|
||||||
FRAMEWORK_LIB=${FRAMEWORK_LIB}
|
|
||||||
HEADER_DIR=${HEADER_DIR}
|
HEADER_DIR=${HEADER_DIR}
|
||||||
|
MAKE_JOBS=${MAKE_JOBS}
|
||||||
|
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
|
||||||
LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR}
|
LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR}
|
||||||
LIPO=${LIPO}
|
LIPO=${LIPO}
|
||||||
MAKEFLAGS=${MAKEFLAGS}
|
|
||||||
ORIG_PWD=${ORIG_PWD}
|
ORIG_PWD=${ORIG_PWD}
|
||||||
PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
|
TARGETS="${TARGETS}"
|
||||||
TARGETS="$(print_list "" ${TARGETS})"
|
|
||||||
ENABLE_SHARED=${ENABLE_SHARED}
|
|
||||||
OSX_TARGETS="${OSX_TARGETS}"
|
|
||||||
SIM_TARGETS="${SIM_TARGETS}"
|
|
||||||
SCRIPT_DIR="${SCRIPT_DIR}"
|
|
||||||
FULLVERSION="${FULLVERSION}"
|
|
||||||
VERSION="${VERSION}"
|
|
||||||
IOS_VERSION_MIN="${IOS_VERSION_MIN}"
|
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
build_framework "${TARGETS}"
|
build_framework "${TARGETS}"
|
||||||
echo "Successfully built '${FRAMEWORK_DIR}' for:"
|
echo "Successfully built '${FRAMEWORK_DIR}' for:"
|
||||||
print_list "" ${TARGETS}
|
echo " ${TARGETS}"
|
||||||
|
|||||||
@@ -39,12 +39,11 @@ fix_path() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Corrects the paths in file_list in one pass for efficiency.
|
# Corrects the paths in file_list in one pass for efficiency.
|
||||||
# $1 is the name of the array to be modified.
|
|
||||||
fix_file_list() {
|
fix_file_list() {
|
||||||
declare -n array_ref=$1
|
# TODO(jzern): this could be more generic and take the array as a param.
|
||||||
files=$(fix_path "${array_ref[@]}")
|
files=$(fix_path "${file_list[@]}")
|
||||||
local IFS=$'\n'
|
local IFS=$'\n'
|
||||||
array_ref=($files)
|
file_list=($files)
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_uuid() {
|
generate_uuid() {
|
||||||
|
|||||||
@@ -319,8 +319,14 @@ EOF
|
|||||||
|
|
||||||
print <<EOF;
|
print <<EOF;
|
||||||
#if HAVE_DSPR2
|
#if HAVE_DSPR2
|
||||||
void vpx_dsputil_static_init();
|
#if CONFIG_VP8
|
||||||
vpx_dsputil_static_init();
|
void dsputil_static_init();
|
||||||
|
dsputil_static_init();
|
||||||
|
#endif
|
||||||
|
#if CONFIG_VP9
|
||||||
|
void vp9_dsputil_static_init();
|
||||||
|
vp9_dsputil_static_init();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,9 +24,8 @@ out_file=${2}
|
|||||||
id=${3:-VERSION_STRING}
|
id=${3:-VERSION_STRING}
|
||||||
|
|
||||||
git_version_id=""
|
git_version_id=""
|
||||||
if [ -e "${source_path}/.git" ]; then
|
if [ -d "${source_path}/.git" ]; then
|
||||||
# Source Path is a git working copy. Check for local modifications.
|
# Source Path is a git working copy. Check for local modifications.
|
||||||
# Note that git submodules may have a file as .git, not a directory.
|
|
||||||
export GIT_DIR="${source_path}/.git"
|
export GIT_DIR="${source_path}/.git"
|
||||||
git_version_id=`git describe --match=v[0-9]* 2>/dev/null`
|
git_version_id=`git describe --match=v[0-9]* 2>/dev/null`
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
# This file is used by gcl to get repository specific information.
|
|
||||||
GERRIT_HOST: chromium-review.googlesource.com
|
|
||||||
GERRIT_PORT: 29418
|
|
||||||
CODE_REVIEW_SERVER: chromium-review.googlesource.com
|
|
||||||
239
configure
vendored
239
configure
vendored
@@ -31,15 +31,16 @@ Advanced options:
|
|||||||
--size-limit=WxH max size to allow in the decoder
|
--size-limit=WxH max size to allow in the decoder
|
||||||
--as={yasm|nasm|auto} use specified assembler [auto, yasm preferred]
|
--as={yasm|nasm|auto} use specified assembler [auto, yasm preferred]
|
||||||
--sdk-path=PATH path to root of sdk (android builds only)
|
--sdk-path=PATH path to root of sdk (android builds only)
|
||||||
|
${toggle_fast_unaligned} don't use unaligned accesses, even when
|
||||||
|
supported by hardware [auto]
|
||||||
${toggle_codec_srcs} in/exclude codec library source code
|
${toggle_codec_srcs} in/exclude codec library source code
|
||||||
${toggle_debug_libs} in/exclude debug version of libraries
|
${toggle_debug_libs} in/exclude debug version of libraries
|
||||||
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
|
${toggle_static_msvcrt} use static MSVCRT (VS builds only)
|
||||||
${toggle_vpx_highbitdepth} use VPX high bit depth (10/12) profiles
|
${toggle_vp9_highbitdepth} use VP9 high bit depth (10/12) profiles
|
||||||
${toggle_better_hw_compatibility}
|
${toggle_vp8} VP8 codec support
|
||||||
enable encoder to produce streams with better
|
${toggle_vp9} VP9 codec support
|
||||||
hardware decoder compatibility
|
|
||||||
${toggle_vp10} VP10 codec support
|
|
||||||
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
${toggle_internal_stats} output of encoder internal stats for debug, if supported (encoders)
|
||||||
|
${toggle_mem_tracker} track memory usage
|
||||||
${toggle_postproc} postprocessing
|
${toggle_postproc} postprocessing
|
||||||
${toggle_vp9_postproc} vp9 specific postprocessing
|
${toggle_vp9_postproc} vp9 specific postprocessing
|
||||||
${toggle_multithread} multithreaded encoding and decoding
|
${toggle_multithread} multithreaded encoding and decoding
|
||||||
@@ -96,11 +97,11 @@ EOF
|
|||||||
|
|
||||||
# all_platforms is a list of all supported target platforms. Maintain
|
# all_platforms is a list of all supported target platforms. Maintain
|
||||||
# alphabetically by architecture, generic-gnu last.
|
# alphabetically by architecture, generic-gnu last.
|
||||||
all_platforms="${all_platforms} arm64-darwin-gcc"
|
all_platforms="${all_platforms} armv6-darwin-gcc"
|
||||||
all_platforms="${all_platforms} arm64-linux-gcc"
|
|
||||||
all_platforms="${all_platforms} armv6-linux-rvct"
|
all_platforms="${all_platforms} armv6-linux-rvct"
|
||||||
all_platforms="${all_platforms} armv6-linux-gcc"
|
all_platforms="${all_platforms} armv6-linux-gcc"
|
||||||
all_platforms="${all_platforms} armv6-none-rvct"
|
all_platforms="${all_platforms} armv6-none-rvct"
|
||||||
|
all_platforms="${all_platforms} arm64-darwin-gcc"
|
||||||
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8
|
||||||
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8
|
||||||
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8
|
||||||
@@ -108,11 +109,15 @@ all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8
|
|||||||
all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
|
all_platforms="${all_platforms} armv7-none-rvct" #neon Cortex-A8
|
||||||
all_platforms="${all_platforms} armv7-win32-vs11"
|
all_platforms="${all_platforms} armv7-win32-vs11"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs12"
|
all_platforms="${all_platforms} armv7-win32-vs12"
|
||||||
all_platforms="${all_platforms} armv7-win32-vs14"
|
|
||||||
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
all_platforms="${all_platforms} armv7s-darwin-gcc"
|
||||||
all_platforms="${all_platforms} armv8-linux-gcc"
|
|
||||||
all_platforms="${all_platforms} mips32-linux-gcc"
|
all_platforms="${all_platforms} mips32-linux-gcc"
|
||||||
all_platforms="${all_platforms} mips64-linux-gcc"
|
all_platforms="${all_platforms} mips64-linux-gcc"
|
||||||
|
all_platforms="${all_platforms} ppc32-darwin8-gcc"
|
||||||
|
all_platforms="${all_platforms} ppc32-darwin9-gcc"
|
||||||
|
all_platforms="${all_platforms} ppc32-linux-gcc"
|
||||||
|
all_platforms="${all_platforms} ppc64-darwin8-gcc"
|
||||||
|
all_platforms="${all_platforms} ppc64-darwin9-gcc"
|
||||||
|
all_platforms="${all_platforms} ppc64-linux-gcc"
|
||||||
all_platforms="${all_platforms} sparc-solaris-gcc"
|
all_platforms="${all_platforms} sparc-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86-android-gcc"
|
all_platforms="${all_platforms} x86-android-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin8-gcc"
|
all_platforms="${all_platforms} x86-darwin8-gcc"
|
||||||
@@ -124,34 +129,41 @@ all_platforms="${all_platforms} x86-darwin11-gcc"
|
|||||||
all_platforms="${all_platforms} x86-darwin12-gcc"
|
all_platforms="${all_platforms} x86-darwin12-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin13-gcc"
|
all_platforms="${all_platforms} x86-darwin13-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin14-gcc"
|
all_platforms="${all_platforms} x86-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} x86-darwin15-gcc"
|
|
||||||
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
all_platforms="${all_platforms} x86-iphonesimulator-gcc"
|
||||||
all_platforms="${all_platforms} x86-linux-gcc"
|
all_platforms="${all_platforms} x86-linux-gcc"
|
||||||
all_platforms="${all_platforms} x86-linux-icc"
|
all_platforms="${all_platforms} x86-linux-icc"
|
||||||
all_platforms="${all_platforms} x86-os2-gcc"
|
all_platforms="${all_platforms} x86-os2-gcc"
|
||||||
all_platforms="${all_platforms} x86-solaris-gcc"
|
all_platforms="${all_platforms} x86-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86-win32-gcc"
|
all_platforms="${all_platforms} x86-win32-gcc"
|
||||||
|
all_platforms="${all_platforms} x86-win32-vs7"
|
||||||
|
all_platforms="${all_platforms} x86-win32-vs8"
|
||||||
|
all_platforms="${all_platforms} x86-win32-vs9"
|
||||||
all_platforms="${all_platforms} x86-win32-vs10"
|
all_platforms="${all_platforms} x86-win32-vs10"
|
||||||
all_platforms="${all_platforms} x86-win32-vs11"
|
all_platforms="${all_platforms} x86-win32-vs11"
|
||||||
all_platforms="${all_platforms} x86-win32-vs12"
|
all_platforms="${all_platforms} x86-win32-vs12"
|
||||||
all_platforms="${all_platforms} x86-win32-vs14"
|
|
||||||
all_platforms="${all_platforms} x86_64-android-gcc"
|
|
||||||
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
all_platforms="${all_platforms} x86_64-darwin9-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
all_platforms="${all_platforms} x86_64-darwin10-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin11-gcc"
|
all_platforms="${all_platforms} x86_64-darwin11-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin12-gcc"
|
all_platforms="${all_platforms} x86_64-darwin12-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
all_platforms="${all_platforms} x86_64-darwin13-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
all_platforms="${all_platforms} x86_64-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-darwin15-gcc"
|
|
||||||
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
all_platforms="${all_platforms} x86_64-iphonesimulator-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-linux-gcc"
|
all_platforms="${all_platforms} x86_64-linux-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-linux-icc"
|
all_platforms="${all_platforms} x86_64-linux-icc"
|
||||||
all_platforms="${all_platforms} x86_64-solaris-gcc"
|
all_platforms="${all_platforms} x86_64-solaris-gcc"
|
||||||
all_platforms="${all_platforms} x86_64-win64-gcc"
|
all_platforms="${all_platforms} x86_64-win64-gcc"
|
||||||
|
all_platforms="${all_platforms} x86_64-win64-vs8"
|
||||||
|
all_platforms="${all_platforms} x86_64-win64-vs9"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs10"
|
all_platforms="${all_platforms} x86_64-win64-vs10"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs11"
|
all_platforms="${all_platforms} x86_64-win64-vs11"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs12"
|
all_platforms="${all_platforms} x86_64-win64-vs12"
|
||||||
all_platforms="${all_platforms} x86_64-win64-vs14"
|
all_platforms="${all_platforms} universal-darwin8-gcc"
|
||||||
|
all_platforms="${all_platforms} universal-darwin9-gcc"
|
||||||
|
all_platforms="${all_platforms} universal-darwin10-gcc"
|
||||||
|
all_platforms="${all_platforms} universal-darwin11-gcc"
|
||||||
|
all_platforms="${all_platforms} universal-darwin12-gcc"
|
||||||
|
all_platforms="${all_platforms} universal-darwin13-gcc"
|
||||||
|
all_platforms="${all_platforms} universal-darwin14-gcc"
|
||||||
all_platforms="${all_platforms} generic-gnu"
|
all_platforms="${all_platforms} generic-gnu"
|
||||||
|
|
||||||
# all_targets is a list of all targets that can be configured
|
# all_targets is a list of all targets that can be configured
|
||||||
@@ -188,9 +200,6 @@ if [ ${doxy_major:-0} -ge 1 ]; then
|
|||||||
[ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable_feature doxygen
|
[ $doxy_minor -eq 5 ] && [ $doxy_patch -ge 3 ] && enable_feature doxygen
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# disable codecs when their source directory does not exist
|
|
||||||
[ -d "${source_path}/vp10" ] || disable_codec vp10
|
|
||||||
|
|
||||||
# install everything except the sources, by default. sources will have
|
# install everything except the sources, by default. sources will have
|
||||||
# to be enabled when doing dist builds, since that's no longer a common
|
# to be enabled when doing dist builds, since that's no longer a common
|
||||||
# case.
|
# case.
|
||||||
@@ -201,34 +210,45 @@ enable_feature install_libs
|
|||||||
enable_feature static
|
enable_feature static
|
||||||
enable_feature optimizations
|
enable_feature optimizations
|
||||||
enable_feature dependency_tracking
|
enable_feature dependency_tracking
|
||||||
|
enable_feature fast_unaligned #allow unaligned accesses, if supported by hw
|
||||||
enable_feature spatial_resampling
|
enable_feature spatial_resampling
|
||||||
enable_feature multithread
|
enable_feature multithread
|
||||||
enable_feature os_support
|
enable_feature os_support
|
||||||
enable_feature temporal_denoising
|
enable_feature temporal_denoising
|
||||||
|
|
||||||
CODECS="
|
[ -d "${source_path}/../include" ] && enable_feature alt_tree_layout
|
||||||
vp10_encoder
|
for d in vp8 vp9; do
|
||||||
vp10_decoder
|
[ -d "${source_path}/${d}" ] && disable_feature alt_tree_layout;
|
||||||
"
|
done
|
||||||
CODEC_FAMILIES="
|
|
||||||
vp10
|
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)"
|
||||||
|
|
||||||
ARCH_LIST="
|
ARCH_LIST="
|
||||||
arm
|
arm
|
||||||
mips
|
mips
|
||||||
x86
|
x86
|
||||||
x86_64
|
x86_64
|
||||||
"
|
ppc32
|
||||||
ARCH_EXT_LIST_X86="
|
ppc64
|
||||||
mmx
|
|
||||||
sse
|
|
||||||
sse2
|
|
||||||
sse3
|
|
||||||
ssse3
|
|
||||||
sse4_1
|
|
||||||
avx
|
|
||||||
avx2
|
|
||||||
"
|
"
|
||||||
ARCH_EXT_LIST="
|
ARCH_EXT_LIST="
|
||||||
edsp
|
edsp
|
||||||
@@ -241,39 +261,30 @@ ARCH_EXT_LIST="
|
|||||||
msa
|
msa
|
||||||
mips64
|
mips64
|
||||||
|
|
||||||
${ARCH_EXT_LIST_X86}
|
mmx
|
||||||
|
sse
|
||||||
|
sse2
|
||||||
|
sse3
|
||||||
|
ssse3
|
||||||
|
sse4_1
|
||||||
|
avx
|
||||||
|
avx2
|
||||||
|
|
||||||
|
altivec
|
||||||
"
|
"
|
||||||
HAVE_LIST="
|
HAVE_LIST="
|
||||||
${ARCH_EXT_LIST}
|
${ARCH_EXT_LIST}
|
||||||
vpx_ports
|
vpx_ports
|
||||||
|
stdint_h
|
||||||
|
alt_tree_layout
|
||||||
pthread_h
|
pthread_h
|
||||||
|
sys_mman_h
|
||||||
unistd_h
|
unistd_h
|
||||||
"
|
"
|
||||||
EXPERIMENT_LIST="
|
EXPERIMENT_LIST="
|
||||||
spatial_svc
|
spatial_svc
|
||||||
fp_mb_stats
|
fp_mb_stats
|
||||||
emulate_hardware
|
emulate_hardware
|
||||||
var_tx
|
|
||||||
rect_tx
|
|
||||||
ref_mv
|
|
||||||
dual_filter
|
|
||||||
ext_tx
|
|
||||||
ext_intra
|
|
||||||
ext_inter
|
|
||||||
ext_interp
|
|
||||||
ext_refs
|
|
||||||
global_motion
|
|
||||||
new_quant
|
|
||||||
supertx
|
|
||||||
ans
|
|
||||||
loop_restoration
|
|
||||||
ext_partition
|
|
||||||
ext_partition_types
|
|
||||||
ext_tile
|
|
||||||
obmc
|
|
||||||
warped_motion
|
|
||||||
entropy
|
|
||||||
bidir_pred
|
|
||||||
"
|
"
|
||||||
CONFIG_LIST="
|
CONFIG_LIST="
|
||||||
dependency_tracking
|
dependency_tracking
|
||||||
@@ -282,6 +293,7 @@ CONFIG_LIST="
|
|||||||
install_bins
|
install_bins
|
||||||
install_libs
|
install_libs
|
||||||
install_srcs
|
install_srcs
|
||||||
|
use_x86inc
|
||||||
debug
|
debug
|
||||||
gprof
|
gprof
|
||||||
gcov
|
gcov
|
||||||
@@ -293,6 +305,10 @@ CONFIG_LIST="
|
|||||||
|
|
||||||
codec_srcs
|
codec_srcs
|
||||||
debug_libs
|
debug_libs
|
||||||
|
fast_unaligned
|
||||||
|
mem_manager
|
||||||
|
mem_tracker
|
||||||
|
mem_checks
|
||||||
|
|
||||||
dequant_tokens
|
dequant_tokens
|
||||||
dc_recon
|
dc_recon
|
||||||
@@ -324,8 +340,7 @@ CONFIG_LIST="
|
|||||||
temporal_denoising
|
temporal_denoising
|
||||||
vp9_temporal_denoising
|
vp9_temporal_denoising
|
||||||
coefficient_range_checking
|
coefficient_range_checking
|
||||||
vpx_highbitdepth
|
vp9_highbitdepth
|
||||||
better_hw_compatibility
|
|
||||||
experimental
|
experimental
|
||||||
size_limit
|
size_limit
|
||||||
${EXPERIMENT_LIST}
|
${EXPERIMENT_LIST}
|
||||||
@@ -343,6 +358,7 @@ CMDLINE_SELECT="
|
|||||||
gprof
|
gprof
|
||||||
gcov
|
gcov
|
||||||
pic
|
pic
|
||||||
|
use_x86inc
|
||||||
optimizations
|
optimizations
|
||||||
ccache
|
ccache
|
||||||
runtime_cpu_detect
|
runtime_cpu_detect
|
||||||
@@ -354,6 +370,7 @@ CMDLINE_SELECT="
|
|||||||
libc
|
libc
|
||||||
as
|
as
|
||||||
size_limit
|
size_limit
|
||||||
|
fast_unaligned
|
||||||
codec_srcs
|
codec_srcs
|
||||||
debug_libs
|
debug_libs
|
||||||
|
|
||||||
@@ -366,6 +383,7 @@ CMDLINE_SELECT="
|
|||||||
${CODECS}
|
${CODECS}
|
||||||
${CODEC_FAMILIES}
|
${CODEC_FAMILIES}
|
||||||
static_msvcrt
|
static_msvcrt
|
||||||
|
mem_tracker
|
||||||
spatial_resampling
|
spatial_resampling
|
||||||
realtime_only
|
realtime_only
|
||||||
onthefly_bitpacking
|
onthefly_bitpacking
|
||||||
@@ -383,8 +401,7 @@ CMDLINE_SELECT="
|
|||||||
temporal_denoising
|
temporal_denoising
|
||||||
vp9_temporal_denoising
|
vp9_temporal_denoising
|
||||||
coefficient_range_checking
|
coefficient_range_checking
|
||||||
better_hw_compatibility
|
vp9_highbitdepth
|
||||||
vpx_highbitdepth
|
|
||||||
experimental
|
experimental
|
||||||
"
|
"
|
||||||
|
|
||||||
@@ -392,19 +409,15 @@ process_cmdline() {
|
|||||||
for opt do
|
for opt do
|
||||||
optval="${opt#*=}"
|
optval="${opt#*=}"
|
||||||
case "$opt" in
|
case "$opt" in
|
||||||
--disable-codecs)
|
--disable-codecs) for c in ${CODECS}; do disable_feature $c; done ;;
|
||||||
for c in ${CODEC_FAMILIES}; do disable_codec $c; done
|
|
||||||
;;
|
|
||||||
--enable-?*|--disable-?*)
|
--enable-?*|--disable-?*)
|
||||||
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
|
||||||
if is_in ${option} ${EXPERIMENT_LIST}; then
|
if echo "${EXPERIMENT_LIST}" | grep "^ *$option\$" >/dev/null; then
|
||||||
if enabled experimental; then
|
if enabled experimental; then
|
||||||
${action}_feature $option
|
${action}_feature $option
|
||||||
else
|
else
|
||||||
log_echo "Ignoring $opt -- not in experimental mode."
|
log_echo "Ignoring $opt -- not in experimental mode."
|
||||||
fi
|
fi
|
||||||
elif is_in ${option} "${CODECS} ${CODEC_FAMILIES}"; then
|
|
||||||
${action}_codec ${option}
|
|
||||||
else
|
else
|
||||||
process_common_cmdline $opt
|
process_common_cmdline $opt
|
||||||
fi
|
fi
|
||||||
@@ -418,6 +431,14 @@ process_cmdline() {
|
|||||||
post_process_cmdline() {
|
post_process_cmdline() {
|
||||||
c=""
|
c=""
|
||||||
|
|
||||||
|
# If the codec family is disabled, disable all components of that family.
|
||||||
|
# If the codec family is enabled, enable all components of that family.
|
||||||
|
log_echo "Configuring selected codecs"
|
||||||
|
for c in ${CODECS}; do
|
||||||
|
disabled ${c%%_*} && disable_feature ${c}
|
||||||
|
enabled ${c%%_*} && enable_feature ${c}
|
||||||
|
done
|
||||||
|
|
||||||
# Enable all detected codecs, if they haven't been disabled
|
# Enable all detected codecs, if they haven't been disabled
|
||||||
for c in ${CODECS}; do soft_enable $c; done
|
for c in ${CODECS}; do soft_enable $c; done
|
||||||
|
|
||||||
@@ -435,8 +456,22 @@ post_process_cmdline() {
|
|||||||
|
|
||||||
process_targets() {
|
process_targets() {
|
||||||
enabled child || write_common_config_banner
|
enabled child || write_common_config_banner
|
||||||
write_common_target_config_h ${BUILD_PFX}vpx_config.h
|
enabled universal || write_common_target_config_h ${BUILD_PFX}vpx_config.h
|
||||||
|
|
||||||
|
# For fat binaries, call configure recursively to configure for each
|
||||||
|
# binary architecture to be included.
|
||||||
|
if enabled universal; then
|
||||||
|
# Call configure (ourselves) for each subarchitecture
|
||||||
|
for arch in $fat_bin_archs; do
|
||||||
|
BUILD_PFX=${arch}/ toolchain=${arch} $self --child $cmdline_args || exit $?
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The write_common_config (config.mk) logic is deferred until after the
|
||||||
|
# recursive calls to configure complete, because we want our universal
|
||||||
|
# targets to be executed last.
|
||||||
write_common_config_targets
|
write_common_config_targets
|
||||||
|
enabled universal && echo "FAT_ARCHS=${fat_bin_archs}" >> config.mk
|
||||||
|
|
||||||
# Calculate the default distribution name, based on the enabled features
|
# Calculate the default distribution name, based on the enabled features
|
||||||
cf=""
|
cf=""
|
||||||
@@ -512,18 +547,13 @@ process_detect() {
|
|||||||
# Can only build shared libs on a subset of platforms. Doing this check
|
# Can only build shared libs on a subset of platforms. Doing this check
|
||||||
# here rather than at option parse time because the target auto-detect
|
# here rather than at option parse time because the target auto-detect
|
||||||
# magic happens after the command line has been parsed.
|
# magic happens after the command line has been parsed.
|
||||||
case "${tgt_os}" in
|
if ! enabled linux; then
|
||||||
linux|os2|darwin*|iphonesimulator*)
|
|
||||||
# Supported platforms
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if enabled gnu; then
|
if enabled gnu; then
|
||||||
echo "--enable-shared is only supported on ELF; assuming this is OK"
|
echo "--enable-shared is only supported on ELF; assuming this is OK"
|
||||||
else
|
else
|
||||||
die "--enable-shared only supported on ELF, OS/2, and Darwin for now"
|
die "--enable-shared only supported on ELF for now"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
if [ -z "$CC" ] || enabled external_build; then
|
if [ -z "$CC" ] || enabled external_build; then
|
||||||
echo "Bypassing toolchain for environment detection."
|
echo "Bypassing toolchain for environment detection."
|
||||||
@@ -550,12 +580,16 @@ process_detect() {
|
|||||||
# Specialize windows and POSIX environments.
|
# Specialize windows and POSIX environments.
|
||||||
case $toolchain in
|
case $toolchain in
|
||||||
*-win*-*)
|
*-win*-*)
|
||||||
# Don't check for any headers in Windows builds.
|
case $header-$toolchain in
|
||||||
false
|
stdint*-gcc) true;;
|
||||||
|
*) false;;
|
||||||
|
esac && enable_feature $var
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
case $header in
|
case $header in
|
||||||
|
stdint.h) true;;
|
||||||
pthread.h) true;;
|
pthread.h) true;;
|
||||||
|
sys/mman.h) true;;
|
||||||
unistd.h) true;;
|
unistd.h) true;;
|
||||||
*) false;;
|
*) false;;
|
||||||
esac && enable_feature $var
|
esac && enable_feature $var
|
||||||
@@ -571,7 +605,9 @@ process_detect() {
|
|||||||
int main(void) {return 0;}
|
int main(void) {return 0;}
|
||||||
EOF
|
EOF
|
||||||
# check system headers
|
# check system headers
|
||||||
|
check_header stdint.h
|
||||||
check_header pthread.h
|
check_header pthread.h
|
||||||
|
check_header sys/mman.h
|
||||||
check_header unistd.h # for sysconf(3) and friends.
|
check_header unistd.h # for sysconf(3) and friends.
|
||||||
|
|
||||||
check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports
|
check_header vpx/vpx_integer.h -I${source_path} && enable_feature vpx_ports
|
||||||
@@ -580,6 +616,30 @@ EOF
|
|||||||
process_toolchain() {
|
process_toolchain() {
|
||||||
process_common_toolchain
|
process_common_toolchain
|
||||||
|
|
||||||
|
# Handle universal binaries for this architecture
|
||||||
|
case $toolchain in
|
||||||
|
universal-darwin*)
|
||||||
|
darwin_ver=${tgt_os##darwin}
|
||||||
|
|
||||||
|
# Snow Leopard (10.6/darwin10) dropped support for PPC
|
||||||
|
# Include PPC support for all prior versions
|
||||||
|
if [ $darwin_ver -lt 10 ]; then
|
||||||
|
fat_bin_archs="$fat_bin_archs ppc32-${tgt_os}-gcc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tiger (10.4/darwin8) brought support for x86
|
||||||
|
if [ $darwin_ver -ge 8 ]; then
|
||||||
|
fat_bin_archs="$fat_bin_archs x86-${tgt_os}-${tgt_cc}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Leopard (10.5/darwin9) brought 64 bit support
|
||||||
|
if [ $darwin_ver -ge 9 ]; then
|
||||||
|
fat_bin_archs="$fat_bin_archs x86_64-${tgt_os}-${tgt_cc}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
# Enable some useful compiler flags
|
# Enable some useful compiler flags
|
||||||
if enabled gcc; then
|
if enabled gcc; then
|
||||||
enabled werror && check_add_cflags -Werror
|
enabled werror && check_add_cflags -Werror
|
||||||
@@ -602,11 +662,7 @@ process_toolchain() {
|
|||||||
;;
|
;;
|
||||||
*) check_add_cflags -Wunused-but-set-variable ;;
|
*) check_add_cflags -Wunused-but-set-variable ;;
|
||||||
esac
|
esac
|
||||||
if enabled mips || [ -z "${INLINE}" ]; then
|
|
||||||
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
enabled extra_warnings || check_add_cflags -Wno-unused-function
|
||||||
else
|
|
||||||
check_add_cflags -Wunused-function
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if enabled icc; then
|
if enabled icc; then
|
||||||
@@ -654,16 +710,24 @@ process_toolchain() {
|
|||||||
vs*) enable_feature msvs
|
vs*) enable_feature msvs
|
||||||
enable_feature solution
|
enable_feature solution
|
||||||
vs_version=${tgt_cc##vs}
|
vs_version=${tgt_cc##vs}
|
||||||
|
case $vs_version in
|
||||||
|
[789])
|
||||||
|
VCPROJ_SFX=vcproj
|
||||||
|
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_proj.sh
|
||||||
|
;;
|
||||||
|
10|11|12)
|
||||||
VCPROJ_SFX=vcxproj
|
VCPROJ_SFX=vcxproj
|
||||||
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
gen_vcproj_cmd=${source_path}/build/make/gen_msvs_vcxproj.sh
|
||||||
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
enabled werror && gen_vcproj_cmd="${gen_vcproj_cmd} --enable-werror"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
all_targets="${all_targets} solution"
|
all_targets="${all_targets} solution"
|
||||||
INLINE="__forceinline"
|
INLINE="__forceinline"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Other toolchain specific defaults
|
# Other toolchain specific defaults
|
||||||
case $toolchain in x86*) soft_enable postproc;; esac
|
case $toolchain in x86*|ppc*|universal*) soft_enable postproc;; esac
|
||||||
|
|
||||||
if enabled postproc_visualizer; then
|
if enabled postproc_visualizer; then
|
||||||
enabled postproc || die "postproc_visualizer requires postproc to be enabled"
|
enabled postproc || die "postproc_visualizer requires postproc to be enabled"
|
||||||
@@ -717,16 +781,6 @@ EOF
|
|||||||
esac
|
esac
|
||||||
# libwebm needs to be linked with C++ standard library
|
# libwebm needs to be linked with C++ standard library
|
||||||
enabled webm_io && LD=${CXX}
|
enabled webm_io && LD=${CXX}
|
||||||
|
|
||||||
# append any user defined extra cflags
|
|
||||||
if [ -n "${extra_cflags}" ] ; then
|
|
||||||
check_add_cflags ${extra_cflags} || \
|
|
||||||
die "Requested extra CFLAGS '${extra_cflags}' not supported by compiler"
|
|
||||||
fi
|
|
||||||
if [ -n "${extra_cxxflags}" ]; then
|
|
||||||
check_add_cxxflags ${extra_cxxflags} || \
|
|
||||||
die "Requested extra CXXFLAGS '${extra_cxxflags}' not supported by compiler"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -737,7 +791,6 @@ CONFIGURE_ARGS="$@"
|
|||||||
process "$@"
|
process "$@"
|
||||||
print_webm_license ${BUILD_PFX}vpx_config.c "/*" " */"
|
print_webm_license ${BUILD_PFX}vpx_config.c "/*" " */"
|
||||||
cat <<EOF >> ${BUILD_PFX}vpx_config.c
|
cat <<EOF >> ${BUILD_PFX}vpx_config.c
|
||||||
#include "vpx/vpx_codec.h"
|
|
||||||
static const char* const cfg = "$CONFIGURE_ARGS";
|
static const char* const cfg = "$CONFIGURE_ARGS";
|
||||||
const char *vpx_codec_build_config(void) {return cfg;}
|
const char *vpx_codec_build_config(void) {return cfg;}
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
165
examples.mk
165
examples.mk
@@ -22,44 +22,33 @@ LIBYUV_SRCS += third_party/libyuv/include/libyuv/basic_types.h \
|
|||||||
third_party/libyuv/source/planar_functions.cc \
|
third_party/libyuv/source/planar_functions.cc \
|
||||||
third_party/libyuv/source/row_any.cc \
|
third_party/libyuv/source/row_any.cc \
|
||||||
third_party/libyuv/source/row_common.cc \
|
third_party/libyuv/source/row_common.cc \
|
||||||
third_party/libyuv/source/row_gcc.cc \
|
|
||||||
third_party/libyuv/source/row_mips.cc \
|
third_party/libyuv/source/row_mips.cc \
|
||||||
third_party/libyuv/source/row_neon.cc \
|
third_party/libyuv/source/row_neon.cc \
|
||||||
third_party/libyuv/source/row_neon64.cc \
|
third_party/libyuv/source/row_neon64.cc \
|
||||||
|
third_party/libyuv/source/row_posix.cc \
|
||||||
third_party/libyuv/source/row_win.cc \
|
third_party/libyuv/source/row_win.cc \
|
||||||
third_party/libyuv/source/scale.cc \
|
third_party/libyuv/source/scale.cc \
|
||||||
third_party/libyuv/source/scale_any.cc \
|
|
||||||
third_party/libyuv/source/scale_common.cc \
|
third_party/libyuv/source/scale_common.cc \
|
||||||
third_party/libyuv/source/scale_gcc.cc \
|
|
||||||
third_party/libyuv/source/scale_mips.cc \
|
third_party/libyuv/source/scale_mips.cc \
|
||||||
third_party/libyuv/source/scale_neon.cc \
|
third_party/libyuv/source/scale_neon.cc \
|
||||||
third_party/libyuv/source/scale_neon64.cc \
|
third_party/libyuv/source/scale_neon64.cc \
|
||||||
|
third_party/libyuv/source/scale_posix.cc \
|
||||||
third_party/libyuv/source/scale_win.cc \
|
third_party/libyuv/source/scale_win.cc \
|
||||||
|
|
||||||
LIBWEBM_COMMON_SRCS += third_party/libwebm/common/hdr_util.cc \
|
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer.cpp \
|
||||||
third_party/libwebm/common/hdr_util.h \
|
third_party/libwebm/mkvmuxerutil.cpp \
|
||||||
third_party/libwebm/common/webmids.h
|
third_party/libwebm/mkvwriter.cpp \
|
||||||
|
third_party/libwebm/mkvmuxer.hpp \
|
||||||
LIBWEBM_MUXER_SRCS += third_party/libwebm/mkvmuxer/mkvmuxer.cc \
|
third_party/libwebm/mkvmuxertypes.hpp \
|
||||||
third_party/libwebm/mkvmuxer/mkvmuxerutil.cc \
|
third_party/libwebm/mkvmuxerutil.hpp \
|
||||||
third_party/libwebm/mkvmuxer/mkvwriter.cc \
|
third_party/libwebm/mkvparser.hpp \
|
||||||
third_party/libwebm/mkvmuxer/mkvmuxer.h \
|
third_party/libwebm/mkvwriter.hpp \
|
||||||
third_party/libwebm/mkvmuxer/mkvmuxertypes.h \
|
third_party/libwebm/webmids.hpp
|
||||||
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
|
|
||||||
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
|
# List of examples to build. UTILS are tools meant for distribution
|
||||||
# while EXAMPLES demonstrate specific portions of the API.
|
# while EXAMPLES demonstrate specific portions of the API.
|
||||||
@@ -67,7 +56,6 @@ UTILS-$(CONFIG_DECODERS) += vpxdec.c
|
|||||||
vpxdec.SRCS += md5_utils.c md5_utils.h
|
vpxdec.SRCS += md5_utils.c md5_utils.h
|
||||||
vpxdec.SRCS += vpx_ports/mem_ops.h
|
vpxdec.SRCS += vpx_ports/mem_ops.h
|
||||||
vpxdec.SRCS += vpx_ports/mem_ops_aligned.h
|
vpxdec.SRCS += vpx_ports/mem_ops_aligned.h
|
||||||
vpxdec.SRCS += vpx_ports/msvc.h
|
|
||||||
vpxdec.SRCS += vpx_ports/vpx_timer.h
|
vpxdec.SRCS += vpx_ports/vpx_timer.h
|
||||||
vpxdec.SRCS += vpx/vpx_integer.h
|
vpxdec.SRCS += vpx/vpx_integer.h
|
||||||
vpxdec.SRCS += args.c args.h
|
vpxdec.SRCS += args.c args.h
|
||||||
@@ -78,8 +66,6 @@ ifeq ($(CONFIG_LIBYUV),yes)
|
|||||||
vpxdec.SRCS += $(LIBYUV_SRCS)
|
vpxdec.SRCS += $(LIBYUV_SRCS)
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_WEBM_IO),yes)
|
ifeq ($(CONFIG_WEBM_IO),yes)
|
||||||
vpxdec.SRCS += $(LIBWEBM_COMMON_SRCS)
|
|
||||||
vpxdec.SRCS += $(LIBWEBM_MUXER_SRCS)
|
|
||||||
vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS)
|
vpxdec.SRCS += $(LIBWEBM_PARSER_SRCS)
|
||||||
vpxdec.SRCS += webmdec.cc webmdec.h
|
vpxdec.SRCS += webmdec.cc webmdec.h
|
||||||
endif
|
endif
|
||||||
@@ -94,27 +80,38 @@ vpxenc.SRCS += tools_common.c tools_common.h
|
|||||||
vpxenc.SRCS += warnings.c warnings.h
|
vpxenc.SRCS += warnings.c warnings.h
|
||||||
vpxenc.SRCS += vpx_ports/mem_ops.h
|
vpxenc.SRCS += vpx_ports/mem_ops.h
|
||||||
vpxenc.SRCS += vpx_ports/mem_ops_aligned.h
|
vpxenc.SRCS += vpx_ports/mem_ops_aligned.h
|
||||||
vpxenc.SRCS += vpx_ports/msvc.h
|
|
||||||
vpxenc.SRCS += vpx_ports/vpx_timer.h
|
vpxenc.SRCS += vpx_ports/vpx_timer.h
|
||||||
vpxenc.SRCS += vpxstats.c vpxstats.h
|
vpxenc.SRCS += vpxstats.c vpxstats.h
|
||||||
ifeq ($(CONFIG_LIBYUV),yes)
|
ifeq ($(CONFIG_LIBYUV),yes)
|
||||||
vpxenc.SRCS += $(LIBYUV_SRCS)
|
vpxenc.SRCS += $(LIBYUV_SRCS)
|
||||||
endif
|
endif
|
||||||
ifeq ($(CONFIG_WEBM_IO),yes)
|
ifeq ($(CONFIG_WEBM_IO),yes)
|
||||||
vpxenc.SRCS += $(LIBWEBM_COMMON_SRCS)
|
|
||||||
vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS)
|
vpxenc.SRCS += $(LIBWEBM_MUXER_SRCS)
|
||||||
vpxenc.SRCS += $(LIBWEBM_PARSER_SRCS)
|
|
||||||
vpxenc.SRCS += webmenc.cc webmenc.h
|
vpxenc.SRCS += webmenc.cc webmenc.h
|
||||||
endif
|
endif
|
||||||
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
|
vpxenc.GUID = 548DEC74-7A15-4B2B-AFC3-AA102E7C25C1
|
||||||
vpxenc.DESCRIPTION = Full featured encoder
|
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 += 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
|
EXAMPLES-$(CONFIG_ENCODERS) += vpx_temporal_svc_encoder.c
|
||||||
vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
vpx_temporal_svc_encoder.SRCS += ivfenc.c ivfenc.h
|
||||||
vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h
|
vpx_temporal_svc_encoder.SRCS += tools_common.c tools_common.h
|
||||||
vpx_temporal_svc_encoder.SRCS += video_common.h
|
vpx_temporal_svc_encoder.SRCS += video_common.h
|
||||||
vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c
|
vpx_temporal_svc_encoder.SRCS += video_writer.h video_writer.c
|
||||||
vpx_temporal_svc_encoder.SRCS += vpx_ports/msvc.h
|
|
||||||
vpx_temporal_svc_encoder.GUID = B18C08F2-A439-4502-A78E-849BE3D60947
|
vpx_temporal_svc_encoder.GUID = B18C08F2-A439-4502-A78E-849BE3D60947
|
||||||
vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder
|
vpx_temporal_svc_encoder.DESCRIPTION = Temporal SVC Encoder
|
||||||
EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
|
EXAMPLES-$(CONFIG_DECODERS) += simple_decoder.c
|
||||||
@@ -125,8 +122,16 @@ simple_decoder.SRCS += video_common.h
|
|||||||
simple_decoder.SRCS += video_reader.h video_reader.c
|
simple_decoder.SRCS += video_reader.h video_reader.c
|
||||||
simple_decoder.SRCS += vpx_ports/mem_ops.h
|
simple_decoder.SRCS += vpx_ports/mem_ops.h
|
||||||
simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h
|
simple_decoder.SRCS += vpx_ports/mem_ops_aligned.h
|
||||||
simple_decoder.SRCS += vpx_ports/msvc.h
|
|
||||||
simple_decoder.DESCRIPTION = Simplified decoder loop
|
simple_decoder.DESCRIPTION = Simplified decoder loop
|
||||||
|
EXAMPLES-$(CONFIG_DECODERS) += postproc.c
|
||||||
|
postproc.SRCS += ivfdec.h ivfdec.c
|
||||||
|
postproc.SRCS += tools_common.h tools_common.c
|
||||||
|
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.GUID = 65E33355-F35E-4088-884D-3FD4905881D7
|
||||||
|
postproc.DESCRIPTION = Decoder postprocessor control
|
||||||
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
|
EXAMPLES-$(CONFIG_DECODERS) += decode_to_md5.c
|
||||||
decode_to_md5.SRCS += md5_utils.h md5_utils.c
|
decode_to_md5.SRCS += md5_utils.h md5_utils.c
|
||||||
decode_to_md5.SRCS += ivfdec.h ivfdec.c
|
decode_to_md5.SRCS += ivfdec.h ivfdec.c
|
||||||
@@ -135,7 +140,6 @@ decode_to_md5.SRCS += video_common.h
|
|||||||
decode_to_md5.SRCS += video_reader.h video_reader.c
|
decode_to_md5.SRCS += video_reader.h video_reader.c
|
||||||
decode_to_md5.SRCS += vpx_ports/mem_ops.h
|
decode_to_md5.SRCS += vpx_ports/mem_ops.h
|
||||||
decode_to_md5.SRCS += vpx_ports/mem_ops_aligned.h
|
decode_to_md5.SRCS += vpx_ports/mem_ops_aligned.h
|
||||||
decode_to_md5.SRCS += vpx_ports/msvc.h
|
|
||||||
decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42
|
decode_to_md5.GUID = 59120B9B-2735-4BFE-B022-146CA340FE42
|
||||||
decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum
|
decode_to_md5.DESCRIPTION = Frame by frame MD5 checksum
|
||||||
EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
|
EXAMPLES-$(CONFIG_ENCODERS) += simple_encoder.c
|
||||||
@@ -143,23 +147,20 @@ simple_encoder.SRCS += ivfenc.h ivfenc.c
|
|||||||
simple_encoder.SRCS += tools_common.h tools_common.c
|
simple_encoder.SRCS += tools_common.h tools_common.c
|
||||||
simple_encoder.SRCS += video_common.h
|
simple_encoder.SRCS += video_common.h
|
||||||
simple_encoder.SRCS += video_writer.h video_writer.c
|
simple_encoder.SRCS += video_writer.h video_writer.c
|
||||||
simple_encoder.SRCS += vpx_ports/msvc.h
|
|
||||||
simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
|
simple_encoder.GUID = 4607D299-8A71-4D2C-9B1D-071899B6FBFD
|
||||||
simple_encoder.DESCRIPTION = Simplified encoder loop
|
simple_encoder.DESCRIPTION = Simplified encoder loop
|
||||||
EXAMPLES-$(CONFIG_VP10_ENCODER) += lossless_encoder.c
|
EXAMPLES-$(CONFIG_VP9_ENCODER) += vp9_lossless_encoder.c
|
||||||
lossless_encoder.SRCS += ivfenc.h ivfenc.c
|
vp9_lossless_encoder.SRCS += ivfenc.h ivfenc.c
|
||||||
lossless_encoder.SRCS += tools_common.h tools_common.c
|
vp9_lossless_encoder.SRCS += tools_common.h tools_common.c
|
||||||
lossless_encoder.SRCS += video_common.h
|
vp9_lossless_encoder.SRCS += video_common.h
|
||||||
lossless_encoder.SRCS += video_writer.h video_writer.c
|
vp9_lossless_encoder.SRCS += video_writer.h video_writer.c
|
||||||
lossless_encoder.SRCS += vpx_ports/msvc.h
|
vp9_lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
|
||||||
lossless_encoder.GUID = B63C7C88-5348-46DC-A5A6-CC151EF93366
|
vp9_lossless_encoder.DESCRIPTION = Simplified lossless VP9 encoder
|
||||||
lossless_encoder.DESCRIPTION = Simplified lossless encoder
|
|
||||||
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
|
EXAMPLES-$(CONFIG_ENCODERS) += twopass_encoder.c
|
||||||
twopass_encoder.SRCS += ivfenc.h ivfenc.c
|
twopass_encoder.SRCS += ivfenc.h ivfenc.c
|
||||||
twopass_encoder.SRCS += tools_common.h tools_common.c
|
twopass_encoder.SRCS += tools_common.h tools_common.c
|
||||||
twopass_encoder.SRCS += video_common.h
|
twopass_encoder.SRCS += video_common.h
|
||||||
twopass_encoder.SRCS += video_writer.h video_writer.c
|
twopass_encoder.SRCS += video_writer.h video_writer.c
|
||||||
twopass_encoder.SRCS += vpx_ports/msvc.h
|
|
||||||
twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8
|
twopass_encoder.GUID = 73494FA6-4AF9-4763-8FBB-265C92402FD8
|
||||||
twopass_encoder.DESCRIPTION = Two-pass encoder loop
|
twopass_encoder.DESCRIPTION = Two-pass encoder loop
|
||||||
EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c
|
EXAMPLES-$(CONFIG_DECODERS) += decode_with_drops.c
|
||||||
@@ -169,7 +170,6 @@ decode_with_drops.SRCS += video_common.h
|
|||||||
decode_with_drops.SRCS += video_reader.h video_reader.c
|
decode_with_drops.SRCS += video_reader.h video_reader.c
|
||||||
decode_with_drops.SRCS += vpx_ports/mem_ops.h
|
decode_with_drops.SRCS += vpx_ports/mem_ops.h
|
||||||
decode_with_drops.SRCS += vpx_ports/mem_ops_aligned.h
|
decode_with_drops.SRCS += vpx_ports/mem_ops_aligned.h
|
||||||
decode_with_drops.SRCS += vpx_ports/msvc.h
|
|
||||||
decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
|
decode_with_drops.GUID = CE5C53C4-8DDA-438A-86ED-0DDD3CDB8D26
|
||||||
decode_with_drops.DESCRIPTION = Drops frames while decoding
|
decode_with_drops.DESCRIPTION = Drops frames while decoding
|
||||||
EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c
|
EXAMPLES-$(CONFIG_ENCODERS) += set_maps.c
|
||||||
@@ -177,33 +177,40 @@ set_maps.SRCS += ivfenc.h ivfenc.c
|
|||||||
set_maps.SRCS += tools_common.h tools_common.c
|
set_maps.SRCS += tools_common.h tools_common.c
|
||||||
set_maps.SRCS += video_common.h
|
set_maps.SRCS += video_common.h
|
||||||
set_maps.SRCS += video_writer.h video_writer.c
|
set_maps.SRCS += video_writer.h video_writer.c
|
||||||
set_maps.SRCS += vpx_ports/msvc.h
|
|
||||||
set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
|
set_maps.GUID = ECB2D24D-98B8-4015-A465-A4AF3DCC145F
|
||||||
set_maps.DESCRIPTION = Set active and ROI maps
|
set_maps.DESCRIPTION = Set active and ROI maps
|
||||||
|
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8cx_set_ref.c
|
||||||
|
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.GUID = C5E31F7F-96F6-48BD-BD3E-10EBF6E8057A
|
||||||
|
vp8cx_set_ref.DESCRIPTION = VP8 set encoder reference frame
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP10_ENCODER), yes)
|
ifeq ($(CONFIG_MULTI_RES_ENCODING),yes)
|
||||||
ifeq ($(CONFIG_DECODERS),yes)
|
ifeq ($(CONFIG_LIBYUV),yes)
|
||||||
EXAMPLES-yes += vpxcx_set_ref.c
|
EXAMPLES-$(CONFIG_VP8_ENCODER) += vp8_multi_resolution_encoder.c
|
||||||
vpxcx_set_ref.SRCS += ivfenc.h ivfenc.c
|
vp8_multi_resolution_encoder.SRCS += ivfenc.h ivfenc.c
|
||||||
vpxcx_set_ref.SRCS += tools_common.h tools_common.c
|
vp8_multi_resolution_encoder.SRCS += tools_common.h tools_common.c
|
||||||
vpxcx_set_ref.SRCS += video_common.h
|
vp8_multi_resolution_encoder.SRCS += video_writer.h video_writer.c
|
||||||
vpxcx_set_ref.SRCS += video_writer.h video_writer.c
|
vp8_multi_resolution_encoder.SRCS += $(LIBYUV_SRCS)
|
||||||
vpxcx_set_ref.GUID = 65D7F14A-2EE6-4293-B958-AB5107A03B55
|
vp8_multi_resolution_encoder.GUID = 04f8738e-63c8-423b-90fa-7c2703a374de
|
||||||
vpxcx_set_ref.DESCRIPTION = VP10 set encoder reference frame
|
vp8_multi_resolution_encoder.DESCRIPTION = VP8 Multiple-resolution Encoding
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
# Handle extra library flags depending on codec configuration
|
# Handle extra library flags depending on codec configuration
|
||||||
|
|
||||||
# We should not link to math library (libm) on RVCT
|
# We should not link to math library (libm) on RVCT
|
||||||
# when building for bare-metal targets
|
# when building for bare-metal targets
|
||||||
ifeq ($(CONFIG_OS_SUPPORT), yes)
|
ifeq ($(CONFIG_OS_SUPPORT), yes)
|
||||||
CODEC_EXTRA_LIBS-$(CONFIG_VP10) += m
|
CODEC_EXTRA_LIBS-$(CONFIG_VP8) += m
|
||||||
|
CODEC_EXTRA_LIBS-$(CONFIG_VP9) += m
|
||||||
else
|
else
|
||||||
ifeq ($(CONFIG_GCC), yes)
|
ifeq ($(CONFIG_GCC), yes)
|
||||||
CODEC_EXTRA_LIBS-$(CONFIG_VP10) += m
|
CODEC_EXTRA_LIBS-$(CONFIG_VP8) += m
|
||||||
|
CODEC_EXTRA_LIBS-$(CONFIG_VP9) += m
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
#
|
#
|
||||||
@@ -220,8 +227,10 @@ ifeq ($(HAVE_ALT_TREE_LAYOUT),yes)
|
|||||||
INC_PATH-yes := $(SRC_PATH_BARE)/../include
|
INC_PATH-yes := $(SRC_PATH_BARE)/../include
|
||||||
else
|
else
|
||||||
LIB_PATH-yes += $(if $(BUILD_PFX),$(BUILD_PFX),.)
|
LIB_PATH-yes += $(if $(BUILD_PFX),$(BUILD_PFX),.)
|
||||||
INC_PATH-$(CONFIG_VP10_DECODER) += $(SRC_PATH_BARE)/vp10
|
INC_PATH-$(CONFIG_VP8_DECODER) += $(SRC_PATH_BARE)/vp8
|
||||||
INC_PATH-$(CONFIG_VP10_ENCODER) += $(SRC_PATH_BARE)/vp10
|
INC_PATH-$(CONFIG_VP8_ENCODER) += $(SRC_PATH_BARE)/vp8
|
||||||
|
INC_PATH-$(CONFIG_VP9_DECODER) += $(SRC_PATH_BARE)/vp9
|
||||||
|
INC_PATH-$(CONFIG_VP9_ENCODER) += $(SRC_PATH_BARE)/vp9
|
||||||
endif
|
endif
|
||||||
INC_PATH-$(CONFIG_LIBYUV) += $(SRC_PATH_BARE)/third_party/libyuv/include
|
INC_PATH-$(CONFIG_LIBYUV) += $(SRC_PATH_BARE)/third_party/libyuv/include
|
||||||
LIB_PATH := $(call enabled,LIB_PATH)
|
LIB_PATH := $(call enabled,LIB_PATH)
|
||||||
@@ -245,6 +254,14 @@ CODEC_EXTRA_LIBS=$(sort $(call enabled,CODEC_EXTRA_LIBS))
|
|||||||
$(foreach ex,$(ALL_EXAMPLES),$(eval $(notdir $(ex:.c=)).SRCS += $(ex) examples.mk))
|
$(foreach ex,$(ALL_EXAMPLES),$(eval $(notdir $(ex:.c=)).SRCS += $(ex) examples.mk))
|
||||||
|
|
||||||
|
|
||||||
|
# If this is a universal (fat) binary, then all the subarchitectures have
|
||||||
|
# already been built and our job is to stitch them together. The
|
||||||
|
# BUILD_OBJS variable indicates whether we should be building
|
||||||
|
# (compiling, linking) the library. The LIPO_OBJS variable indicates
|
||||||
|
# that we're stitching.
|
||||||
|
$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_OBJS,BUILD_OBJS):=yes)
|
||||||
|
|
||||||
|
|
||||||
# Create build/install dependencies for all examples. The common case
|
# Create build/install dependencies for all examples. The common case
|
||||||
# is handled here. The MSVS case is handled below.
|
# is handled here. The MSVS case is handled below.
|
||||||
NOT_MSVS = $(if $(CONFIG_MSVS),,yes)
|
NOT_MSVS = $(if $(CONFIG_MSVS),,yes)
|
||||||
@@ -252,28 +269,24 @@ DIST-BINS-$(NOT_MSVS) += $(addprefix bin/,$(ALL_EXAMPLES:.c=$(EXE_SFX)))
|
|||||||
INSTALL-BINS-$(NOT_MSVS) += $(addprefix bin/,$(UTILS:.c=$(EXE_SFX)))
|
INSTALL-BINS-$(NOT_MSVS) += $(addprefix bin/,$(UTILS:.c=$(EXE_SFX)))
|
||||||
DIST-SRCS-yes += $(ALL_SRCS)
|
DIST-SRCS-yes += $(ALL_SRCS)
|
||||||
INSTALL-SRCS-yes += $(UTIL_SRCS)
|
INSTALL-SRCS-yes += $(UTIL_SRCS)
|
||||||
OBJS-$(NOT_MSVS) += $(call objs,$(ALL_SRCS))
|
OBJS-$(NOT_MSVS) += $(if $(BUILD_OBJS),$(call objs,$(ALL_SRCS)))
|
||||||
BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=$(EXE_SFX)))
|
BINS-$(NOT_MSVS) += $(addprefix $(BUILD_PFX),$(ALL_EXAMPLES:.c=$(EXE_SFX)))
|
||||||
|
|
||||||
|
|
||||||
# Instantiate linker template for all examples.
|
# Instantiate linker template for all examples.
|
||||||
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
|
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
|
||||||
ifneq ($(filter darwin%,$(TGT_OS)),)
|
SHARED_LIB_SUF=$(if $(filter darwin%,$(TGT_OS)),.dylib,.so)
|
||||||
SHARED_LIB_SUF=.dylib
|
|
||||||
else
|
|
||||||
ifneq ($(filter os2%,$(TGT_OS)),)
|
|
||||||
SHARED_LIB_SUF=_dll.a
|
|
||||||
else
|
|
||||||
SHARED_LIB_SUF=.so
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a)
|
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a)
|
||||||
$(foreach bin,$(BINS-yes),\
|
$(foreach bin,$(BINS-yes),\
|
||||||
$(eval $(bin):$(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF))\
|
$(if $(BUILD_OBJS),$(eval $(bin):\
|
||||||
$(eval $(call linker_template,$(bin),\
|
$(LIB_PATH)/lib$(CODEC_LIB)$(CODEC_LIB_SUF)))\
|
||||||
|
$(if $(BUILD_OBJS),$(eval $(call linker_template,$(bin),\
|
||||||
$(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) \
|
$(call objs,$($(notdir $(bin:$(EXE_SFX)=)).SRCS)) \
|
||||||
-l$(CODEC_LIB) $(addprefix -l,$(CODEC_EXTRA_LIBS))\
|
-l$(CODEC_LIB) $(addprefix -l,$(CODEC_EXTRA_LIBS))\
|
||||||
)))
|
)))\
|
||||||
|
$(if $(LIPO_OBJS),$(eval $(call lipo_bin_template,$(bin))))\
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# The following pairs define a mapping of locations in the distribution
|
# The following pairs define a mapping of locations in the distribution
|
||||||
# tree to locations in the source/build trees.
|
# tree to locations in the source/build trees.
|
||||||
@@ -301,8 +314,8 @@ endif
|
|||||||
# the makefiles). We may want to revisit this.
|
# the makefiles). We may want to revisit this.
|
||||||
define vcproj_template
|
define vcproj_template
|
||||||
$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX)
|
$(1): $($(1:.$(VCPROJ_SFX)=).SRCS) vpx.$(VCPROJ_SFX)
|
||||||
$(if $(quiet),@echo " [vcproj] $$@")
|
@echo " [vcproj] $$@"
|
||||||
$(qexec)$$(GEN_VCPROJ)\
|
$$(GEN_VCPROJ)\
|
||||||
--exe\
|
--exe\
|
||||||
--target=$$(TOOLCHAIN)\
|
--target=$$(TOOLCHAIN)\
|
||||||
--name=$$(@:.$(VCPROJ_SFX)=)\
|
--name=$$(@:.$(VCPROJ_SFX)=)\
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ static void print_md5(FILE *stream, unsigned char digest[16]) {
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
|
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr, "Usage: %s <infile> <outfile> <N-M|N/M>\n", exec_name);
|
fprintf(stderr, "Usage: %s <infile> <outfile> <N-M|N/M>\n", exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
138
examples/postproc.c
Normal file
138
examples/postproc.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Postprocessing Decoder
|
||||||
|
// ======================
|
||||||
|
//
|
||||||
|
// This example adds postprocessing to the simple decoder loop.
|
||||||
|
//
|
||||||
|
// Initializing Postprocessing
|
||||||
|
// ---------------------------
|
||||||
|
// You must inform the codec that you might request postprocessing at
|
||||||
|
// initialization time. This is done by passing the VPX_CODEC_USE_POSTPROC
|
||||||
|
// flag to `vpx_codec_dec_init`. If the codec does not support
|
||||||
|
// postprocessing, this call will return VPX_CODEC_INCAPABLE. For
|
||||||
|
// demonstration purposes, we also fall back to default initialization if
|
||||||
|
// the codec does not provide support.
|
||||||
|
//
|
||||||
|
// Using Adaptive Postprocessing
|
||||||
|
// -----------------------------
|
||||||
|
// VP6 provides "adaptive postprocessing." It will automatically select the
|
||||||
|
// best postprocessing filter on a frame by frame basis based on the amount
|
||||||
|
// of time remaining before the user's specified deadline expires. The
|
||||||
|
// special value 0 indicates that the codec should take as long as
|
||||||
|
// necessary to provide the best quality frame. This example gives the
|
||||||
|
// codec 15ms (15000us) to return a frame. Remember that this is a soft
|
||||||
|
// deadline, and the codec may exceed it doing its regular processing. In
|
||||||
|
// these cases, no additional postprocessing will be done.
|
||||||
|
//
|
||||||
|
// Codec Specific Postprocessing Controls
|
||||||
|
// --------------------------------------
|
||||||
|
// Some codecs provide fine grained controls over their built-in
|
||||||
|
// postprocessors. VP8 is one example. The following sample code toggles
|
||||||
|
// postprocessing on and off every 15 frames.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "vpx/vp8dx.h"
|
||||||
|
#include "vpx/vpx_decoder.h"
|
||||||
|
|
||||||
|
#include "../tools_common.h"
|
||||||
|
#include "../video_reader.h"
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
|
||||||
|
static const char *exec_name;
|
||||||
|
|
||||||
|
void usage_exit() {
|
||||||
|
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
int frame_cnt = 0;
|
||||||
|
FILE *outfile = NULL;
|
||||||
|
vpx_codec_ctx_t codec;
|
||||||
|
vpx_codec_err_t res;
|
||||||
|
VpxVideoReader *reader = NULL;
|
||||||
|
const VpxInterface *decoder = NULL;
|
||||||
|
const VpxVideoInfo *info = NULL;
|
||||||
|
|
||||||
|
exec_name = argv[0];
|
||||||
|
|
||||||
|
if (argc != 3)
|
||||||
|
die("Invalid number of arguments.");
|
||||||
|
|
||||||
|
reader = vpx_video_reader_open(argv[1]);
|
||||||
|
if (!reader)
|
||||||
|
die("Failed to open %s for reading.", argv[1]);
|
||||||
|
|
||||||
|
if (!(outfile = fopen(argv[2], "wb")))
|
||||||
|
die("Failed to open %s for writing", argv[2]);
|
||||||
|
|
||||||
|
info = vpx_video_reader_get_info(reader);
|
||||||
|
|
||||||
|
decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
|
||||||
|
if (!decoder)
|
||||||
|
die("Unknown input codec.");
|
||||||
|
|
||||||
|
printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));
|
||||||
|
|
||||||
|
res = vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL,
|
||||||
|
VPX_CODEC_USE_POSTPROC);
|
||||||
|
if (res == VPX_CODEC_INCAPABLE)
|
||||||
|
die_codec(&codec, "Postproc not supported by this decoder.");
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
die_codec(&codec, "Failed to initialize decoder.");
|
||||||
|
|
||||||
|
while (vpx_video_reader_read_frame(reader)) {
|
||||||
|
vpx_codec_iter_t iter = NULL;
|
||||||
|
vpx_image_t *img = NULL;
|
||||||
|
size_t frame_size = 0;
|
||||||
|
const unsigned char *frame = vpx_video_reader_get_frame(reader,
|
||||||
|
&frame_size);
|
||||||
|
|
||||||
|
++frame_cnt;
|
||||||
|
|
||||||
|
if (frame_cnt % 30 == 1) {
|
||||||
|
vp8_postproc_cfg_t pp = {0, 0, 0};
|
||||||
|
|
||||||
|
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
||||||
|
die_codec(&codec, "Failed to turn off postproc.");
|
||||||
|
} else if (frame_cnt % 30 == 16) {
|
||||||
|
vp8_postproc_cfg_t pp = {VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE,
|
||||||
|
4, 0};
|
||||||
|
if (vpx_codec_control(&codec, VP8_SET_POSTPROC, &pp))
|
||||||
|
die_codec(&codec, "Failed to turn on postproc.");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Decode the frame with 15ms deadline
|
||||||
|
if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 15000))
|
||||||
|
die_codec(&codec, "Failed to decode frame");
|
||||||
|
|
||||||
|
while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) {
|
||||||
|
vpx_img_write(img, outfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Processed %d frames.\n", frame_cnt);
|
||||||
|
if (vpx_codec_destroy(&codec))
|
||||||
|
die_codec(&codec, "Failed to destroy codec");
|
||||||
|
|
||||||
|
printf("Play: ffplay -f rawvideo -pix_fmt yuv420p -s %dx%d %s\n",
|
||||||
|
info->frame_width, info->frame_height, argv[2]);
|
||||||
|
|
||||||
|
vpx_video_reader_close(reader);
|
||||||
|
|
||||||
|
fclose(outfile);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../tools_common.h"
|
|
||||||
#include "../vp9/encoder/vp9_resize.h"
|
#include "../vp9/encoder/vp9_resize.h"
|
||||||
|
|
||||||
static const char *exec_name = NULL;
|
static const char *exec_name = NULL;
|
||||||
@@ -27,7 +26,7 @@ static void usage() {
|
|||||||
printf("<output_yuv> [<frames>]\n");
|
printf("<output_yuv> [<frames>]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
usage();
|
usage();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
|
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
|
fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,11 +106,11 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Usage: %s <codec> <width> <height> <infile> <outfile> "
|
"Usage: %s <codec> <width> <height> <infile> <outfile> "
|
||||||
"<keyframe-interval> <error-resilient> <frames to encode>\n"
|
"<keyframe-interval> [<error-resilient>]\nSee comments in "
|
||||||
"See comments in simple_encoder.c for more information.\n",
|
"simple_encoder.c for more information.\n",
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,6 @@ static int encode_frame(vpx_codec_ctx_t *codec,
|
|||||||
return got_pkts;
|
return got_pkts;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(tomfinegan): Improve command line parsing and add args for bitrate/fps.
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
@@ -158,11 +157,12 @@ int main(int argc, char **argv) {
|
|||||||
VpxVideoInfo info = {0};
|
VpxVideoInfo info = {0};
|
||||||
VpxVideoWriter *writer = NULL;
|
VpxVideoWriter *writer = NULL;
|
||||||
const VpxInterface *encoder = NULL;
|
const VpxInterface *encoder = NULL;
|
||||||
const int fps = 30;
|
const int fps = 30; // TODO(dkovalev) add command line argument
|
||||||
const int bitrate = 200;
|
const int bitrate = 200; // kbit/s TODO(dkovalev) add command line argument
|
||||||
int keyframe_interval = 0;
|
int keyframe_interval = 0;
|
||||||
int max_frames = 0;
|
|
||||||
int frames_encoded = 0;
|
// TODO(dkovalev): Add some simple command line parsing code to make the
|
||||||
|
// command line more flexible.
|
||||||
const char *codec_arg = NULL;
|
const char *codec_arg = NULL;
|
||||||
const char *width_arg = NULL;
|
const char *width_arg = NULL;
|
||||||
const char *height_arg = NULL;
|
const char *height_arg = NULL;
|
||||||
@@ -172,7 +172,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 9)
|
if (argc < 7)
|
||||||
die("Invalid number of arguments");
|
die("Invalid number of arguments");
|
||||||
|
|
||||||
codec_arg = argv[1];
|
codec_arg = argv[1];
|
||||||
@@ -181,7 +181,6 @@ int main(int argc, char **argv) {
|
|||||||
infile_arg = argv[4];
|
infile_arg = argv[4];
|
||||||
outfile_arg = argv[5];
|
outfile_arg = argv[5];
|
||||||
keyframe_interval_arg = argv[6];
|
keyframe_interval_arg = argv[6];
|
||||||
max_frames = strtol(argv[8], NULL, 0);
|
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder)
|
if (!encoder)
|
||||||
@@ -220,7 +219,7 @@ int main(int argc, char **argv) {
|
|||||||
cfg.g_timebase.num = info.time_base.numerator;
|
cfg.g_timebase.num = info.time_base.numerator;
|
||||||
cfg.g_timebase.den = info.time_base.denominator;
|
cfg.g_timebase.den = info.time_base.denominator;
|
||||||
cfg.rc_target_bitrate = bitrate;
|
cfg.rc_target_bitrate = bitrate;
|
||||||
cfg.g_error_resilient = strtol(argv[7], NULL, 0);
|
cfg.g_error_resilient = argc > 7 ? strtol(argv[7], NULL, 0) : 0;
|
||||||
|
|
||||||
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
writer = vpx_video_writer_open(outfile_arg, kContainerIVF, &info);
|
||||||
if (!writer)
|
if (!writer)
|
||||||
@@ -238,9 +237,6 @@ int main(int argc, char **argv) {
|
|||||||
if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
|
if (keyframe_interval > 0 && frame_count % keyframe_interval == 0)
|
||||||
flags |= VPX_EFLAG_FORCE_KF;
|
flags |= VPX_EFLAG_FORCE_KF;
|
||||||
encode_frame(&codec, &raw, frame_count++, flags, writer);
|
encode_frame(&codec, &raw, frame_count++, flags, writer);
|
||||||
frames_encoded++;
|
|
||||||
if (max_frames > 0 && frames_encoded >= max_frames)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
|
|||||||
@@ -58,10 +58,8 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Usage: %s <codec> <width> <height> <infile> <outfile>\n",
|
||||||
"Usage: %s <codec> <width> <height> <infile> <outfile> "
|
|
||||||
"<frame limit>\n",
|
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -131,8 +129,7 @@ static int encode_frame(vpx_codec_ctx_t *ctx,
|
|||||||
static vpx_fixed_buf_t pass0(vpx_image_t *raw,
|
static vpx_fixed_buf_t pass0(vpx_image_t *raw,
|
||||||
FILE *infile,
|
FILE *infile,
|
||||||
const VpxInterface *encoder,
|
const VpxInterface *encoder,
|
||||||
const vpx_codec_enc_cfg_t *cfg,
|
const vpx_codec_enc_cfg_t *cfg) {
|
||||||
int max_frames) {
|
|
||||||
vpx_codec_ctx_t codec;
|
vpx_codec_ctx_t codec;
|
||||||
int frame_count = 0;
|
int frame_count = 0;
|
||||||
vpx_fixed_buf_t stats = {NULL, 0};
|
vpx_fixed_buf_t stats = {NULL, 0};
|
||||||
@@ -145,8 +142,6 @@ static vpx_fixed_buf_t pass0(vpx_image_t *raw,
|
|||||||
++frame_count;
|
++frame_count;
|
||||||
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
get_frame_stats(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY,
|
||||||
&stats);
|
&stats);
|
||||||
if (max_frames > 0 && frame_count >= max_frames)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
@@ -164,8 +159,7 @@ static void pass1(vpx_image_t *raw,
|
|||||||
FILE *infile,
|
FILE *infile,
|
||||||
const char *outfile_name,
|
const char *outfile_name,
|
||||||
const VpxInterface *encoder,
|
const VpxInterface *encoder,
|
||||||
const vpx_codec_enc_cfg_t *cfg,
|
const vpx_codec_enc_cfg_t *cfg) {
|
||||||
int max_frames) {
|
|
||||||
VpxVideoInfo info = {
|
VpxVideoInfo info = {
|
||||||
encoder->fourcc,
|
encoder->fourcc,
|
||||||
cfg->g_w,
|
cfg->g_w,
|
||||||
@@ -187,9 +181,6 @@ static void pass1(vpx_image_t *raw,
|
|||||||
while (vpx_img_read(raw, infile)) {
|
while (vpx_img_read(raw, infile)) {
|
||||||
++frame_count;
|
++frame_count;
|
||||||
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
|
encode_frame(&codec, raw, frame_count, 1, 0, VPX_DL_GOOD_QUALITY, writer);
|
||||||
|
|
||||||
if (max_frames > 0 && frame_count >= max_frames)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush encoder.
|
// Flush encoder.
|
||||||
@@ -222,14 +213,11 @@ int main(int argc, char **argv) {
|
|||||||
const char *const height_arg = argv[3];
|
const char *const height_arg = argv[3];
|
||||||
const char *const infile_arg = argv[4];
|
const char *const infile_arg = argv[4];
|
||||||
const char *const outfile_arg = argv[5];
|
const char *const outfile_arg = argv[5];
|
||||||
int max_frames = 0;
|
|
||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
|
|
||||||
if (argc != 7)
|
if (argc != 6)
|
||||||
die("Invalid number of arguments.");
|
die("Invalid number of arguments.");
|
||||||
|
|
||||||
max_frames = strtol(argv[6], NULL, 0);
|
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
encoder = get_vpx_encoder_by_name(codec_arg);
|
||||||
if (!encoder)
|
if (!encoder)
|
||||||
die("Unsupported codec.");
|
die("Unsupported codec.");
|
||||||
@@ -261,13 +249,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
// Pass 0
|
// Pass 0
|
||||||
cfg.g_pass = VPX_RC_FIRST_PASS;
|
cfg.g_pass = VPX_RC_FIRST_PASS;
|
||||||
stats = pass0(&raw, infile, encoder, &cfg, max_frames);
|
stats = pass0(&raw, infile, encoder, &cfg);
|
||||||
|
|
||||||
// Pass 1
|
// Pass 1
|
||||||
rewind(infile);
|
rewind(infile);
|
||||||
cfg.g_pass = VPX_RC_LAST_PASS;
|
cfg.g_pass = VPX_RC_LAST_PASS;
|
||||||
cfg.rc_twopass_stats_in = stats;
|
cfg.rc_twopass_stats_in = stats;
|
||||||
pass1(&raw, infile, outfile_arg, encoder, &cfg, max_frames);
|
pass1(&raw, infile, outfile_arg, encoder, &cfg);
|
||||||
free(stats.buf);
|
free(stats.buf);
|
||||||
|
|
||||||
vpx_img_free(&raw);
|
vpx_img_free(&raw);
|
||||||
|
|||||||
737
examples/vp8_multi_resolution_encoder.c
Normal file
737
examples/vp8_multi_resolution_encoder.c
Normal file
@@ -0,0 +1,737 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an example demonstrating multi-resolution encoding in VP8.
|
||||||
|
* High-resolution input video is down-sampled to lower-resolutions. The
|
||||||
|
* encoder then encodes the video and outputs multiple bitstreams with
|
||||||
|
* different resolutions.
|
||||||
|
*
|
||||||
|
* This test also allows for settings temporal layers for each spatial layer.
|
||||||
|
* Different number of temporal layers per spatial stream may be used.
|
||||||
|
* Currently up to 3 temporal layers per spatial stream (encoder) are supported
|
||||||
|
* in this test.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
|
||||||
|
#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"
|
||||||
|
#define VPX_CODEC_DISABLE_COMPAT 1
|
||||||
|
#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() {
|
||||||
|
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"
|
||||||
|
|
||||||
|
int (*read_frame_p)(FILE *f, vpx_image_t *img);
|
||||||
|
|
||||||
|
static int read_frame(FILE *f, vpx_image_t *img) {
|
||||||
|
size_t nbytes, to_read;
|
||||||
|
int res = 1;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_frame_by_row(FILE *f, vpx_image_t *img) {
|
||||||
|
size_t nbytes, to_read;
|
||||||
|
int res = 1;
|
||||||
|
int plane;
|
||||||
|
|
||||||
|
for (plane = 0; plane < 3; plane++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
case 2:
|
||||||
|
ptr = img->planes[img->fmt==VPX_IMG_FMT_YV12?VPX_PLANE_U : VPX_PLANE_V];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ptr = img->planes[plane];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (r = 0; r < h; r++)
|
||||||
|
{
|
||||||
|
to_read = w;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += img->stride[plane];
|
||||||
|
}
|
||||||
|
if (!res)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile> <frame>\n",
|
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile> <frame>\n",
|
||||||
exec_name);
|
exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
fprintf(stderr, "lossless_encoder: Example demonstrating lossless "
|
fprintf(stderr, "vp9_lossless_encoder: Example demonstrating VP9 lossless "
|
||||||
"encoding feature. Supports raw input only.\n");
|
"encoding feature. Supports raw input only.\n");
|
||||||
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
fprintf(stderr, "Usage: %s <width> <height> <infile> <outfile>\n", exec_name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
448
examples/vp9_spatial_svc_encoder.c
Normal file
448
examples/vp9_spatial_svc_encoder.c
Normal file
@@ -0,0 +1,448 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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"
|
||||||
|
|
||||||
|
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 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 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");
|
||||||
|
|
||||||
|
#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, &lag_in_frame_arg,
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
&bitdepth_arg,
|
||||||
|
#endif
|
||||||
|
&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;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip initial frames
|
||||||
|
for (i = 0; i < app_input.frames_to_skip; ++i)
|
||||||
|
vpx_img_read(&raw, infile);
|
||||||
|
|
||||||
|
// 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, 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)
|
||||||
|
vpx_video_writer_write_frame(writer,
|
||||||
|
cx_pkt->data.frame.buf,
|
||||||
|
cx_pkt->data.frame.sz,
|
||||||
|
cx_pkt->data.frame.pts);
|
||||||
|
|
||||||
|
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 (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);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpx_img_free(&raw);
|
||||||
|
|
||||||
|
// display average size, psnr
|
||||||
|
printf("%s", vpx_svc_dump_statistics(&svc_ctx));
|
||||||
|
|
||||||
|
vpx_svc_release(&svc_ctx);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
static const char *exec_name;
|
static const char *exec_name;
|
||||||
|
|
||||||
void usage_exit(void) {
|
void usage_exit() {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ enum denoiserState {
|
|||||||
kDenoiserOnAdaptive
|
kDenoiserOnAdaptive
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mode_to_num_layers[13] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3};
|
static int mode_to_num_layers[12] = {1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3};
|
||||||
|
|
||||||
// For rate control encoding stats.
|
// For rate control encoding stats.
|
||||||
struct RateControlMetrics {
|
struct RateControlMetrics {
|
||||||
@@ -70,7 +70,6 @@ struct RateControlMetrics {
|
|||||||
int window_size;
|
int window_size;
|
||||||
// Number of window measurements.
|
// Number of window measurements.
|
||||||
int window_count;
|
int window_count;
|
||||||
int layer_target_bitrate[VPX_MAX_LAYERS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note: these rate control metrics assume only 1 key frame in the
|
// Note: these rate control metrics assume only 1 key frame in the
|
||||||
@@ -86,13 +85,13 @@ static void set_rate_control_metrics(struct RateControlMetrics *rc,
|
|||||||
// per-frame-bandwidth, for the rate control encoding stats below.
|
// per-frame-bandwidth, for the rate control encoding stats below.
|
||||||
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
const double framerate = cfg->g_timebase.den / cfg->g_timebase.num;
|
||||||
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
rc->layer_framerate[0] = framerate / cfg->ts_rate_decimator[0];
|
||||||
rc->layer_pfb[0] = 1000.0 * rc->layer_target_bitrate[0] /
|
rc->layer_pfb[0] = 1000.0 * cfg->ts_target_bitrate[0] /
|
||||||
rc->layer_framerate[0];
|
rc->layer_framerate[0];
|
||||||
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
for (i = 0; i < cfg->ts_number_layers; ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
rc->layer_framerate[i] = framerate / cfg->ts_rate_decimator[i];
|
||||||
rc->layer_pfb[i] = 1000.0 *
|
rc->layer_pfb[i] = 1000.0 *
|
||||||
(rc->layer_target_bitrate[i] - rc->layer_target_bitrate[i - 1]) /
|
(cfg->ts_target_bitrate[i] - cfg->ts_target_bitrate[i - 1]) /
|
||||||
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
(rc->layer_framerate[i] - rc->layer_framerate[i - 1]);
|
||||||
}
|
}
|
||||||
rc->layer_input_frames[i] = 0;
|
rc->layer_input_frames[i] = 0;
|
||||||
@@ -129,7 +128,7 @@ static void printout_rate_control_summary(struct RateControlMetrics *rc,
|
|||||||
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
|
rc->layer_avg_rate_mismatch[i] = 100.0 * rc->layer_avg_rate_mismatch[i] /
|
||||||
rc->layer_enc_frames[i];
|
rc->layer_enc_frames[i];
|
||||||
printf("For layer#: %d \n", i);
|
printf("For layer#: %d \n", i);
|
||||||
printf("Bitrate (target vs actual): %d %f \n", rc->layer_target_bitrate[i],
|
printf("Bitrate (target vs actual): %d %f \n", cfg->ts_target_bitrate[i],
|
||||||
rc->layer_encoding_bitrate[i]);
|
rc->layer_encoding_bitrate[i]);
|
||||||
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
|
printf("Average frame size (target vs actual): %f %f \n", rc->layer_pfb[i],
|
||||||
rc->layer_avg_frame_size[i]);
|
rc->layer_avg_frame_size[i]);
|
||||||
@@ -432,32 +431,7 @@ static void set_temporal_layer_pattern(int layering_mode,
|
|||||||
layer_flags[7] = layer_flags[3];
|
layer_flags[7] = layer_flags[3];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 11: {
|
case 11:
|
||||||
// 3-layers structure with one reference frame.
|
|
||||||
// This works same as temporal_layering_mode 3.
|
|
||||||
// This was added to compare with vp9_spatial_svc_encoder.
|
|
||||||
|
|
||||||
// 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] = 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] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
|
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
|
||||||
layer_flags[3] = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_ARF |
|
|
||||||
VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 12:
|
|
||||||
default: {
|
default: {
|
||||||
// 3-layers structure as in case 10, but no sync/refresh points for
|
// 3-layers structure as in case 10, but no sync/refresh points for
|
||||||
// layer 1 and 2.
|
// layer 1 and 2.
|
||||||
@@ -517,13 +491,13 @@ int main(int argc, char **argv) {
|
|||||||
struct RateControlMetrics rc;
|
struct RateControlMetrics rc;
|
||||||
int64_t cx_time = 0;
|
int64_t cx_time = 0;
|
||||||
const int min_args_base = 11;
|
const int min_args_base = 11;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
vpx_bit_depth_t bit_depth = VPX_BITS_8;
|
||||||
int input_bit_depth = 8;
|
int input_bit_depth = 8;
|
||||||
const int min_args = min_args_base + 1;
|
const int min_args = min_args_base + 1;
|
||||||
#else
|
#else
|
||||||
const int min_args = min_args_base;
|
const int min_args = min_args_base;
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
double sum_bitrate = 0.0;
|
double sum_bitrate = 0.0;
|
||||||
double sum_bitrate2 = 0.0;
|
double sum_bitrate2 = 0.0;
|
||||||
double framerate = 30.0;
|
double framerate = 30.0;
|
||||||
@@ -531,7 +505,7 @@ int main(int argc, char **argv) {
|
|||||||
exec_name = argv[0];
|
exec_name = argv[0];
|
||||||
// Check usage and arguments.
|
// Check usage and arguments.
|
||||||
if (argc < min_args) {
|
if (argc < min_args) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
||||||
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
|
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
|
||||||
@@ -539,7 +513,7 @@ int main(int argc, char **argv) {
|
|||||||
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
|
||||||
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
"<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
|
||||||
"<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
|
"<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(argv[3]);
|
encoder = get_vpx_encoder_by_name(argv[3]);
|
||||||
@@ -555,7 +529,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
layering_mode = strtol(argv[10], NULL, 0);
|
layering_mode = strtol(argv[10], NULL, 0);
|
||||||
if (layering_mode < 0 || layering_mode > 13) {
|
if (layering_mode < 0 || layering_mode > 12) {
|
||||||
die("Invalid layering mode (0..12) %s", argv[10]);
|
die("Invalid layering mode (0..12) %s", argv[10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,7 +537,7 @@ int main(int argc, char **argv) {
|
|||||||
die("Invalid number of arguments");
|
die("Invalid number of arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
switch (strtol(argv[argc-1], NULL, 0)) {
|
switch (strtol(argv[argc-1], NULL, 0)) {
|
||||||
case 8:
|
case 8:
|
||||||
bit_depth = VPX_BITS_8;
|
bit_depth = VPX_BITS_8;
|
||||||
@@ -590,7 +564,7 @@ int main(int argc, char **argv) {
|
|||||||
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
|
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
|
||||||
die("Failed to allocate image", width, height);
|
die("Failed to allocate image", width, height);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
// Populate encoder configuration.
|
// Populate encoder configuration.
|
||||||
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
|
||||||
@@ -603,13 +577,13 @@ int main(int argc, char **argv) {
|
|||||||
cfg.g_w = width;
|
cfg.g_w = width;
|
||||||
cfg.g_h = height;
|
cfg.g_h = height;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
if (bit_depth != VPX_BITS_8) {
|
if (bit_depth != VPX_BITS_8) {
|
||||||
cfg.g_bit_depth = bit_depth;
|
cfg.g_bit_depth = bit_depth;
|
||||||
cfg.g_input_bit_depth = input_bit_depth;
|
cfg.g_input_bit_depth = input_bit_depth;
|
||||||
cfg.g_profile = 2;
|
cfg.g_profile = 2;
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
|
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
|
||||||
cfg.g_timebase.num = strtol(argv[6], NULL, 0);
|
cfg.g_timebase.num = strtol(argv[6], NULL, 0);
|
||||||
@@ -623,16 +597,13 @@ int main(int argc, char **argv) {
|
|||||||
for (i = min_args_base;
|
for (i = min_args_base;
|
||||||
(int)i < min_args_base + mode_to_num_layers[layering_mode];
|
(int)i < min_args_base + mode_to_num_layers[layering_mode];
|
||||||
++i) {
|
++i) {
|
||||||
rc.layer_target_bitrate[i - 11] = strtol(argv[i], NULL, 0);
|
cfg.ts_target_bitrate[i - 11] = strtol(argv[i], NULL, 0);
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0)
|
|
||||||
cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
|
||||||
else if (strncmp(encoder->name, "vp9", 3) == 0)
|
|
||||||
cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Real time parameters.
|
// Real time parameters.
|
||||||
cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
|
cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
|
||||||
cfg.rc_end_usage = VPX_CBR;
|
cfg.rc_end_usage = VPX_CBR;
|
||||||
|
cfg.rc_resize_allowed = 0;
|
||||||
cfg.rc_min_quantizer = 2;
|
cfg.rc_min_quantizer = 2;
|
||||||
cfg.rc_max_quantizer = 56;
|
cfg.rc_max_quantizer = 56;
|
||||||
if (strncmp(encoder->name, "vp9", 3) == 0)
|
if (strncmp(encoder->name, "vp9", 3) == 0)
|
||||||
@@ -643,9 +614,6 @@ int main(int argc, char **argv) {
|
|||||||
cfg.rc_buf_optimal_sz = 600;
|
cfg.rc_buf_optimal_sz = 600;
|
||||||
cfg.rc_buf_sz = 1000;
|
cfg.rc_buf_sz = 1000;
|
||||||
|
|
||||||
// Disable dynamic resizing by default.
|
|
||||||
cfg.rc_resize_allowed = 0;
|
|
||||||
|
|
||||||
// Use 1 thread as default.
|
// Use 1 thread as default.
|
||||||
cfg.g_threads = 1;
|
cfg.g_threads = 1;
|
||||||
|
|
||||||
@@ -657,8 +625,6 @@ int main(int argc, char **argv) {
|
|||||||
// Disable automatic keyframe placement.
|
// Disable automatic keyframe placement.
|
||||||
cfg.kf_min_dist = cfg.kf_max_dist = 3000;
|
cfg.kf_min_dist = cfg.kf_max_dist = 3000;
|
||||||
|
|
||||||
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
|
||||||
|
|
||||||
set_temporal_layer_pattern(layering_mode,
|
set_temporal_layer_pattern(layering_mode,
|
||||||
&cfg,
|
&cfg,
|
||||||
layer_flags,
|
layer_flags,
|
||||||
@@ -667,8 +633,8 @@ int main(int argc, char **argv) {
|
|||||||
set_rate_control_metrics(&rc, &cfg);
|
set_rate_control_metrics(&rc, &cfg);
|
||||||
|
|
||||||
// Target bandwidth for the whole stream.
|
// Target bandwidth for the whole stream.
|
||||||
// Set to layer_target_bitrate for highest layer (total bitrate).
|
// Set to ts_target_bitrate for highest layer (total bitrate).
|
||||||
cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1];
|
cfg.rc_target_bitrate = cfg.ts_target_bitrate[cfg.ts_number_layers - 1];
|
||||||
|
|
||||||
// Open input file.
|
// Open input file.
|
||||||
if (!(infile = fopen(argv[1], "rb"))) {
|
if (!(infile = fopen(argv[1], "rb"))) {
|
||||||
@@ -697,37 +663,29 @@ int main(int argc, char **argv) {
|
|||||||
cfg.ss_number_layers = 1;
|
cfg.ss_number_layers = 1;
|
||||||
|
|
||||||
// Initialize codec.
|
// Initialize codec.
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
if (vpx_codec_enc_init(
|
if (vpx_codec_enc_init(
|
||||||
&codec, encoder->codec_interface(), &cfg,
|
&codec, encoder->codec_interface(), &cfg,
|
||||||
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
|
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
|
||||||
#else
|
#else
|
||||||
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
|
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
die_codec(&codec, "Failed to initialize encoder");
|
die_codec(&codec, "Failed to initialize encoder");
|
||||||
|
|
||||||
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
|
||||||
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOnYOnly);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
|
||||||
vpx_svc_extra_cfg_t svc_params;
|
|
||||||
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
|
||||||
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
|
||||||
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
|
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
|
||||||
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kDenoiserOff);
|
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
|
||||||
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
|
||||||
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
|
|
||||||
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
|
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))
|
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0)) {
|
||||||
die_codec(&codec, "Failed to set SVC");
|
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) {
|
if (strncmp(encoder->name, "vp8", 3) == 0) {
|
||||||
vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0);
|
vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0);
|
||||||
|
|||||||
@@ -1,455 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// VP10 Set Reference Frame
|
|
||||||
// ============================
|
|
||||||
//
|
|
||||||
// This is an example demonstrating how to overwrite the VP10 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. For example, run
|
|
||||||
// examples/vpx_cx_set_ref vp10 352 288 in.yuv out.ivf 4 30
|
|
||||||
// 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 <codec> <width> <height> <infile> <outfile> "
|
|
||||||
"<frame> <limit(optional)>\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
|
|
||||||
unsigned int update_frame_num = 0;
|
|
||||||
int mismatch_seen = 0;
|
|
||||||
|
|
||||||
const int fps = 30;
|
|
||||||
const int bitrate = 500;
|
|
||||||
|
|
||||||
const char *codec_arg = NULL;
|
|
||||||
const char *width_arg = NULL;
|
|
||||||
const char *height_arg = NULL;
|
|
||||||
const char *infile_arg = NULL;
|
|
||||||
const char *outfile_arg = NULL;
|
|
||||||
unsigned int limit = 0;
|
|
||||||
exec_name = argv[0];
|
|
||||||
|
|
||||||
if (argc < 7)
|
|
||||||
die("Invalid number of arguments");
|
|
||||||
|
|
||||||
codec_arg = argv[1];
|
|
||||||
width_arg = argv[2];
|
|
||||||
height_arg = argv[3];
|
|
||||||
infile_arg = argv[4];
|
|
||||||
outfile_arg = argv[5];
|
|
||||||
|
|
||||||
encoder = get_vpx_encoder_by_name(codec_arg);
|
|
||||||
if (!encoder)
|
|
||||||
die("Unsupported codec.");
|
|
||||||
|
|
||||||
update_frame_num = atoi(argv[6]);
|
|
||||||
// In VP10, the reference buffers (cm->buffer_pool->frame_bufs[i].buf) are
|
|
||||||
// allocated while calling vpx_codec_encode(), thus, setting reference for
|
|
||||||
// 1st frame isn't supported.
|
|
||||||
if (update_frame_num <= 1)
|
|
||||||
die("Couldn't parse frame number '%s'\n", argv[6]);
|
|
||||||
|
|
||||||
if (argc > 7) {
|
|
||||||
limit = atoi(argv[7]);
|
|
||||||
if (update_frame_num > limit)
|
|
||||||
die("Update frame number couldn't larger than limit\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = 3;
|
|
||||||
|
|
||||||
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_arg);
|
|
||||||
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)) {
|
|
||||||
if (limit && frame_in >= limit)
|
|
||||||
break;
|
|
||||||
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");
|
|
||||||
printf(" <SET_REF>");
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
2
ivfdec.c
2
ivfdec.c
@@ -23,7 +23,7 @@ static void fix_framerate(int *num, int *den) {
|
|||||||
// we can guess the framerate using only the timebase in this
|
// we can guess the framerate using only the timebase in this
|
||||||
// case. Other files would require reading ahead to guess the
|
// case. Other files would require reading ahead to guess the
|
||||||
// timebase, like we do for webm.
|
// timebase, like we do for webm.
|
||||||
if (*den > 0 && *den < 1000000000 && *num > 0 && *num < 1000) {
|
if (*num < 1000) {
|
||||||
// Correct for the factor of 2 applied to the timebase in the encoder.
|
// Correct for the factor of 2 applied to the timebase in the encoder.
|
||||||
if (*num & 1)
|
if (*num & 1)
|
||||||
*den *= 2;
|
*den *= 2;
|
||||||
|
|||||||
260
libs.mk
260
libs.mk
@@ -25,7 +25,7 @@ $$(BUILD_PFX)$(1).h: $$(SRC_PATH_BARE)/$(2)
|
|||||||
@echo " [CREATE] $$@"
|
@echo " [CREATE] $$@"
|
||||||
$$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \
|
$$(qexec)$$(SRC_PATH_BARE)/build/make/rtcd.pl --arch=$$(TGT_ISA) \
|
||||||
--sym=$(1) \
|
--sym=$(1) \
|
||||||
--config=$$(CONFIG_DIR)$$(target)-$$(TOOLCHAIN).mk \
|
--config=$$(CONFIG_DIR)$$(target)$$(if $$(FAT_ARCHS),,-$$(TOOLCHAIN)).mk \
|
||||||
$$(RTCD_OPTIONS) $$^ > $$@
|
$$(RTCD_OPTIONS) $$^ > $$@
|
||||||
CLEAN-OBJS += $$(BUILD_PFX)$(1).h
|
CLEAN-OBJS += $$(BUILD_PFX)$(1).h
|
||||||
RTCD += $$(BUILD_PFX)$(1).h
|
RTCD += $$(BUILD_PFX)$(1).h
|
||||||
@@ -34,6 +34,13 @@ endef
|
|||||||
CODEC_SRCS-yes += CHANGELOG
|
CODEC_SRCS-yes += CHANGELOG
|
||||||
CODEC_SRCS-yes += libs.mk
|
CODEC_SRCS-yes += libs.mk
|
||||||
|
|
||||||
|
# If this is a universal (fat) binary, then all the subarchitectures have
|
||||||
|
# already been built and our job is to stitch them together. The
|
||||||
|
# BUILD_LIBVPX variable indicates whether we should be building
|
||||||
|
# (compiling, linking) the library. The LIPO_LIBVPX variable indicates
|
||||||
|
# that we're stitching.
|
||||||
|
$(eval $(if $(filter universal%,$(TOOLCHAIN)),LIPO_LIBVPX,BUILD_LIBVPX):=yes)
|
||||||
|
|
||||||
include $(SRC_PATH_BARE)/vpx/vpx_codec.mk
|
include $(SRC_PATH_BARE)/vpx/vpx_codec.mk
|
||||||
CODEC_SRCS-yes += $(addprefix vpx/,$(call enabled,API_SRCS))
|
CODEC_SRCS-yes += $(addprefix vpx/,$(call enabled,API_SRCS))
|
||||||
CODEC_DOC_SRCS += $(addprefix vpx/,$(call enabled,API_DOC_SRCS))
|
CODEC_DOC_SRCS += $(addprefix vpx/,$(call enabled,API_DOC_SRCS))
|
||||||
@@ -47,45 +54,61 @@ CODEC_SRCS-yes += $(addprefix vpx_scale/,$(call enabled,SCALE_SRCS))
|
|||||||
include $(SRC_PATH_BARE)/vpx_ports/vpx_ports.mk
|
include $(SRC_PATH_BARE)/vpx_ports/vpx_ports.mk
|
||||||
CODEC_SRCS-yes += $(addprefix vpx_ports/,$(call enabled,PORTS_SRCS))
|
CODEC_SRCS-yes += $(addprefix vpx_ports/,$(call enabled,PORTS_SRCS))
|
||||||
|
|
||||||
include $(SRC_PATH_BARE)/vpx_dsp/vpx_dsp.mk
|
ifneq ($(CONFIG_VP8_ENCODER)$(CONFIG_VP8_DECODER),)
|
||||||
CODEC_SRCS-yes += $(addprefix vpx_dsp/,$(call enabled,DSP_SRCS))
|
VP8_PREFIX=vp8/
|
||||||
|
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8_common.mk
|
||||||
include $(SRC_PATH_BARE)/vpx_util/vpx_util.mk
|
|
||||||
CODEC_SRCS-yes += $(addprefix vpx_util/,$(call enabled,UTIL_SRCS))
|
|
||||||
|
|
||||||
# VP10 make file
|
|
||||||
ifeq ($(CONFIG_VP10),yes)
|
|
||||||
VP10_PREFIX=vp10/
|
|
||||||
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10_common.mk
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP10_ENCODER),yes)
|
ifeq ($(CONFIG_VP8_ENCODER),yes)
|
||||||
VP10_PREFIX=vp10/
|
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8cx.mk
|
||||||
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10cx.mk
|
CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_CX_SRCS))
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_CX_SRCS))
|
CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_CX_EXPORTS))
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_CX_EXPORTS))
|
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
||||||
CODEC_SRCS-yes += $(VP10_PREFIX)vp10cx.mk vpx/vp8.h vpx/vp8cx.h
|
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
|
||||||
|
CODEC_DOC_SECTIONS += vp8 vp8_encoder
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_VP8_DECODER),yes)
|
||||||
|
include $(SRC_PATH_BARE)/$(VP8_PREFIX)vp8dx.mk
|
||||||
|
CODEC_SRCS-yes += $(addprefix $(VP8_PREFIX),$(call enabled,VP8_DX_SRCS))
|
||||||
|
CODEC_EXPORTS-yes += $(addprefix $(VP8_PREFIX),$(VP8_DX_EXPORTS))
|
||||||
|
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
||||||
|
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP8_PREFIX)/%
|
||||||
|
CODEC_DOC_SECTIONS += vp8 vp8_decoder
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(CONFIG_VP9_ENCODER)$(CONFIG_VP9_DECODER),)
|
||||||
|
VP9_PREFIX=vp9/
|
||||||
|
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9_common.mk
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_VP9_ENCODER),yes)
|
||||||
|
VP9_PREFIX=vp9/
|
||||||
|
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9cx.mk
|
||||||
|
CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_CX_SRCS))
|
||||||
|
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-yes += include/vpx/vp8.h include/vpx/vp8cx.h
|
||||||
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
|
INSTALL-LIBS-$(CONFIG_SPATIAL_SVC) += include/vpx/svc_context.h
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
|
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
|
||||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
|
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_encoder
|
CODEC_DOC_SECTIONS += vp9 vp9_encoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_VP10_DECODER),yes)
|
ifeq ($(CONFIG_VP9_DECODER),yes)
|
||||||
VP10_PREFIX=vp10/
|
VP9_PREFIX=vp9/
|
||||||
include $(SRC_PATH_BARE)/$(VP10_PREFIX)vp10dx.mk
|
include $(SRC_PATH_BARE)/$(VP9_PREFIX)vp9dx.mk
|
||||||
CODEC_SRCS-yes += $(addprefix $(VP10_PREFIX),$(call enabled,VP10_DX_SRCS))
|
CODEC_SRCS-yes += $(addprefix $(VP9_PREFIX),$(call enabled,VP9_DX_SRCS))
|
||||||
CODEC_EXPORTS-yes += $(addprefix $(VP10_PREFIX),$(VP10_DX_EXPORTS))
|
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_DX_EXPORTS))
|
||||||
CODEC_SRCS-yes += $(VP10_PREFIX)vp10dx.mk vpx/vp8.h vpx/vp8dx.h
|
CODEC_SRCS-yes += $(VP9_PREFIX)vp9dx.mk vpx/vp8.h vpx/vp8dx.h
|
||||||
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8dx.h
|
||||||
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP10_PREFIX)/%
|
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
|
||||||
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
|
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8dx.h
|
||||||
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
CODEC_DOC_SECTIONS += vp9 vp9_decoder
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VP10_PREFIX=vp10/
|
VP9_PREFIX=vp9/
|
||||||
$(BUILD_PFX)$(VP10_PREFIX)%.c.o: CFLAGS += -Wextra
|
$(BUILD_PFX)$(VP9_PREFIX)%.c.o: CFLAGS += -Wextra
|
||||||
|
|
||||||
ifeq ($(CONFIG_ENCODERS),yes)
|
ifeq ($(CONFIG_ENCODERS),yes)
|
||||||
CODEC_DOC_SECTIONS += encoder
|
CODEC_DOC_SECTIONS += encoder
|
||||||
@@ -114,22 +137,19 @@ INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Release/%)
|
|||||||
INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%)
|
INSTALL_MAPS += $(foreach p,$(VS_PLATFORMS),$(LIBSUBDIR)/$(p)/% $(p)/Debug/%)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CODEC_SRCS-yes += build/make/version.sh
|
CODEC_SRCS-$(BUILD_LIBVPX) += build/make/version.sh
|
||||||
CODEC_SRCS-yes += build/make/rtcd.pl
|
CODEC_SRCS-$(BUILD_LIBVPX) += build/make/rtcd.pl
|
||||||
CODEC_SRCS-yes += vpx_ports/emmintrin_compat.h
|
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/emmintrin_compat.h
|
||||||
CODEC_SRCS-yes += vpx_ports/mem_ops.h
|
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops.h
|
||||||
CODEC_SRCS-yes += vpx_ports/mem_ops_aligned.h
|
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/mem_ops_aligned.h
|
||||||
CODEC_SRCS-yes += vpx_ports/vpx_once.h
|
CODEC_SRCS-$(BUILD_LIBVPX) += vpx_ports/vpx_once.h
|
||||||
CODEC_SRCS-yes += $(BUILD_PFX)vpx_config.c
|
CODEC_SRCS-$(BUILD_LIBVPX) += $(BUILD_PFX)vpx_config.c
|
||||||
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
INSTALL-SRCS-no += $(BUILD_PFX)vpx_config.c
|
||||||
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
ifeq ($(ARCH_X86)$(ARCH_X86_64),yes)
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += third_party/x86inc/x86inc.asm
|
||||||
endif
|
endif
|
||||||
CODEC_EXPORTS-yes += vpx/exports_com
|
CODEC_EXPORTS-$(BUILD_LIBVPX) += vpx/exports_com
|
||||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_enc
|
||||||
ifeq ($(CONFIG_SPATIAL_SVC),yes)
|
|
||||||
CODEC_EXPORTS-$(CONFIG_ENCODERS) += vpx/exports_spatial_svc
|
|
||||||
endif
|
|
||||||
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
|
CODEC_EXPORTS-$(CONFIG_DECODERS) += vpx/exports_dec
|
||||||
|
|
||||||
INSTALL-LIBS-yes += include/vpx/vpx_codec.h
|
INSTALL-LIBS-yes += include/vpx/vpx_codec.h
|
||||||
@@ -195,7 +215,7 @@ vpx.$(VCPROJ_SFX): $(CODEC_SRCS) vpx.def
|
|||||||
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
|
$(filter-out $(addprefix %, $(ASM_INCLUDES)), $^) \
|
||||||
--src-path-bare="$(SRC_PATH_BARE)" \
|
--src-path-bare="$(SRC_PATH_BARE)" \
|
||||||
|
|
||||||
PROJECTS-yes += vpx.$(VCPROJ_SFX)
|
PROJECTS-$(BUILD_LIBVPX) += vpx.$(VCPROJ_SFX)
|
||||||
|
|
||||||
vpx.$(VCPROJ_SFX): vpx_config.asm
|
vpx.$(VCPROJ_SFX): vpx_config.asm
|
||||||
vpx.$(VCPROJ_SFX): $(RTCD)
|
vpx.$(VCPROJ_SFX): $(RTCD)
|
||||||
@@ -203,49 +223,32 @@ vpx.$(VCPROJ_SFX): $(RTCD)
|
|||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
|
LIBVPX_OBJS=$(call objs,$(CODEC_SRCS))
|
||||||
OBJS-yes += $(LIBVPX_OBJS)
|
OBJS-$(BUILD_LIBVPX) += $(LIBVPX_OBJS)
|
||||||
LIBS-$(if yes,$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
LIBS-$(if $(BUILD_LIBVPX),$(CONFIG_STATIC)) += $(BUILD_PFX)libvpx.a $(BUILD_PFX)libvpx_g.a
|
||||||
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
$(BUILD_PFX)libvpx_g.a: $(LIBVPX_OBJS)
|
||||||
|
|
||||||
SO_VERSION_MAJOR := 3
|
|
||||||
SO_VERSION_MINOR := 0
|
BUILD_LIBVPX_SO := $(if $(BUILD_LIBVPX),$(CONFIG_SHARED))
|
||||||
SO_VERSION_PATCH := 0
|
|
||||||
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
ifeq ($(filter darwin%,$(TGT_OS)),$(TGT_OS))
|
||||||
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
LIBVPX_SO := libvpx.$(VERSION_MAJOR).dylib
|
||||||
SHARED_LIB_SUF := .dylib
|
|
||||||
EXPORT_FILE := libvpx.syms
|
EXPORT_FILE := libvpx.syms
|
||||||
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
||||||
libvpx.dylib )
|
libvpx.dylib )
|
||||||
else
|
else
|
||||||
ifeq ($(filter iphonesimulator%,$(TGT_OS)),$(TGT_OS))
|
LIBVPX_SO := libvpx.so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
|
||||||
LIBVPX_SO := libvpx.$(SO_VERSION_MAJOR).dylib
|
|
||||||
SHARED_LIB_SUF := .dylib
|
|
||||||
EXPORT_FILE := libvpx.syms
|
|
||||||
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, libvpx.dylib)
|
|
||||||
else
|
|
||||||
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
|
EXPORT_FILE := libvpx.ver
|
||||||
|
SYM_LINK := libvpx.so
|
||||||
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
LIBVPX_SO_SYMLINKS := $(addprefix $(LIBSUBDIR)/, \
|
||||||
libvpx.so libvpx.so.$(SO_VERSION_MAJOR) \
|
libvpx.so libvpx.so.$(VERSION_MAJOR) \
|
||||||
libvpx.so.$(SO_VERSION_MAJOR).$(SO_VERSION_MINOR))
|
libvpx.so.$(VERSION_MAJOR).$(VERSION_MINOR))
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS-$(CONFIG_SHARED) += $(BUILD_PFX)$(LIBVPX_SO)\
|
LIBS-$(BUILD_LIBVPX_SO) += $(BUILD_PFX)$(LIBVPX_SO)\
|
||||||
$(notdir $(LIBVPX_SO_SYMLINKS)) \
|
$(notdir $(LIBVPX_SO_SYMLINKS))
|
||||||
$(if $(LIBVPX_SO_IMPLIB), $(BUILD_PFX)$(LIBVPX_SO_IMPLIB))
|
|
||||||
$(BUILD_PFX)$(LIBVPX_SO): $(LIBVPX_OBJS) $(EXPORT_FILE)
|
$(BUILD_PFX)$(LIBVPX_SO): $(LIBVPX_OBJS) $(EXPORT_FILE)
|
||||||
$(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm
|
$(BUILD_PFX)$(LIBVPX_SO): extralibs += -lm
|
||||||
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(SO_VERSION_MAJOR)
|
$(BUILD_PFX)$(LIBVPX_SO): SONAME = libvpx.so.$(VERSION_MAJOR)
|
||||||
$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE)
|
$(BUILD_PFX)$(LIBVPX_SO): EXPORTS_FILE = $(EXPORT_FILE)
|
||||||
|
|
||||||
libvpx.ver: $(call enabled,CODEC_EXPORTS)
|
libvpx.ver: $(call enabled,CODEC_EXPORTS)
|
||||||
@@ -260,19 +263,6 @@ libvpx.syms: $(call enabled,CODEC_EXPORTS)
|
|||||||
$(qexec)awk '{print "_"$$2}' $^ >$@
|
$(qexec)awk '{print "_"$$2}' $^ >$@
|
||||||
CLEAN-OBJS += libvpx.syms
|
CLEAN-OBJS += libvpx.syms
|
||||||
|
|
||||||
libvpx.def: $(call enabled,CODEC_EXPORTS)
|
|
||||||
@echo " [CREATE] $@"
|
|
||||||
$(qexec)echo LIBRARY $(LIBVPX_SO:.dll=) INITINSTANCE TERMINSTANCE > $@
|
|
||||||
$(qexec)echo "DATA MULTIPLE NONSHARED" >> $@
|
|
||||||
$(qexec)echo "EXPORTS" >> $@
|
|
||||||
$(qexec)awk '!/vpx_svc_*/ {print "_"$$2}' $^ >>$@
|
|
||||||
CLEAN-OBJS += libvpx.def
|
|
||||||
|
|
||||||
libvpx_dll.a: $(LIBVPX_SO)
|
|
||||||
@echo " [IMPLIB] $@"
|
|
||||||
$(qexec)emximp -o $@ $<
|
|
||||||
CLEAN-OBJS += libvpx_dll.a
|
|
||||||
|
|
||||||
define libvpx_symlink_template
|
define libvpx_symlink_template
|
||||||
$(1): $(2)
|
$(1): $(2)
|
||||||
@echo " [LN] $(2) $$@"
|
@echo " [LN] $(2) $$@"
|
||||||
@@ -288,12 +278,11 @@ $(eval $(call libvpx_symlink_template,\
|
|||||||
$(LIBVPX_SO)))
|
$(LIBVPX_SO)))
|
||||||
|
|
||||||
|
|
||||||
INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBVPX_SO_SYMLINKS)
|
INSTALL-LIBS-$(BUILD_LIBVPX_SO) += $(LIBVPX_SO_SYMLINKS)
|
||||||
INSTALL-LIBS-$(CONFIG_SHARED) += $(LIBSUBDIR)/$(LIBVPX_SO)
|
INSTALL-LIBS-$(BUILD_LIBVPX_SO) += $(LIBSUBDIR)/$(LIBVPX_SO)
|
||||||
INSTALL-LIBS-$(CONFIG_SHARED) += $(if $(LIBVPX_SO_IMPLIB),$(LIBSUBDIR)/$(LIBVPX_SO_IMPLIB))
|
|
||||||
|
|
||||||
|
|
||||||
LIBS-yes += vpx.pc
|
LIBS-$(BUILD_LIBVPX) += vpx.pc
|
||||||
vpx.pc: config.mk libs.mk
|
vpx.pc: config.mk libs.mk
|
||||||
@echo " [CREATE] $@"
|
@echo " [CREATE] $@"
|
||||||
$(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@
|
$(qexec)echo '# pkg-config file from libvpx $(VERSION_STRING)' > $@
|
||||||
@@ -319,6 +308,9 @@ INSTALL_MAPS += $(LIBSUBDIR)/pkgconfig/%.pc %.pc
|
|||||||
CLEAN-OBJS += vpx.pc
|
CLEAN-OBJS += vpx.pc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LIBS-$(LIPO_LIBVPX) += libvpx.a
|
||||||
|
$(eval $(if $(LIPO_LIBVPX),$(call lipo_lib_template,libvpx.a)))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Rule to make assembler configuration file from C configuration file
|
# Rule to make assembler configuration file from C configuration file
|
||||||
#
|
#
|
||||||
@@ -348,12 +340,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)
|
$(shell $(SRC_PATH_BARE)/build/make/version.sh "$(SRC_PATH_BARE)" $(BUILD_PFX)vpx_version.h)
|
||||||
CLEAN-OBJS += $(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
|
## libvpx test directives
|
||||||
@@ -363,15 +349,11 @@ LIBVPX_TEST_DATA_PATH ?= .
|
|||||||
|
|
||||||
include $(SRC_PATH_BARE)/test/test.mk
|
include $(SRC_PATH_BARE)/test/test.mk
|
||||||
LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
LIBVPX_TEST_SRCS=$(addprefix test/,$(call enabled,LIBVPX_TEST_SRCS))
|
||||||
LIBVPX_TEST_BIN=./test_libvpx$(EXE_SFX)
|
LIBVPX_TEST_BINS=./test_libvpx$(EXE_SFX)
|
||||||
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
LIBVPX_TEST_DATA=$(addprefix $(LIBVPX_TEST_DATA_PATH)/,\
|
||||||
$(call enabled,LIBVPX_TEST_DATA))
|
$(call enabled,LIBVPX_TEST_DATA))
|
||||||
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
|
libvpx_test_data_url=http://downloads.webmproject.org/test_data/libvpx/$(1)
|
||||||
|
|
||||||
TEST_INTRA_PRED_SPEED_BIN=./test_intra_pred_speed$(EXE_SFX)
|
|
||||||
TEST_INTRA_PRED_SPEED_SRCS=$(addprefix test/,$(call enabled,TEST_INTRA_PRED_SPEED_SRCS))
|
|
||||||
TEST_INTRA_PRED_SPEED_OBJS := $(sort $(call objs,$(TEST_INTRA_PRED_SPEED_SRCS)))
|
|
||||||
|
|
||||||
libvpx_test_srcs.txt:
|
libvpx_test_srcs.txt:
|
||||||
@echo " [CREATE] $@"
|
@echo " [CREATE] $@"
|
||||||
@echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
@echo $(LIBVPX_TEST_SRCS) | xargs -n1 echo | LC_ALL=C sort -u > $@
|
||||||
@@ -389,10 +371,12 @@ testdata:: $(LIBVPX_TEST_DATA)
|
|||||||
if [ -n "$${sha1sum}" ]; then\
|
if [ -n "$${sha1sum}" ]; then\
|
||||||
set -e;\
|
set -e;\
|
||||||
echo "Checking test data:";\
|
echo "Checking test data:";\
|
||||||
|
if [ -n "$(LIBVPX_TEST_DATA)" ]; then\
|
||||||
for f in $(call enabled,LIBVPX_TEST_DATA); do\
|
for f in $(call enabled,LIBVPX_TEST_DATA); do\
|
||||||
grep $$f $(SRC_PATH_BARE)/test/test-data.sha1 |\
|
grep $$f $(SRC_PATH_BARE)/test/test-data.sha1 |\
|
||||||
(cd $(LIBVPX_TEST_DATA_PATH); $${sha1sum} -c);\
|
(cd $(LIBVPX_TEST_DATA_PATH); $${sha1sum} -c);\
|
||||||
done; \
|
done; \
|
||||||
|
fi; \
|
||||||
else\
|
else\
|
||||||
echo "Skipping test data integrity check, sha1sum not found.";\
|
echo "Skipping test data integrity check, sha1sum not found.";\
|
||||||
fi
|
fi
|
||||||
@@ -429,30 +413,11 @@ test_libvpx.$(VCPROJ_SFX): $(LIBVPX_TEST_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_
|
|||||||
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
|
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
|
||||||
--out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
|
--out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
|
||||||
-I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
|
-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) $^
|
-L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^
|
||||||
|
|
||||||
PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX)
|
PROJECTS-$(CONFIG_MSVS) += test_libvpx.$(VCPROJ_SFX)
|
||||||
|
|
||||||
LIBVPX_TEST_BIN := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BIN)))
|
LIBVPX_TEST_BINS := $(addprefix $(TGT_OS:win64=x64)/Release/,$(notdir $(LIBVPX_TEST_BINS)))
|
||||||
|
|
||||||
ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),)
|
|
||||||
PROJECTS-$(CONFIG_MSVS) += test_intra_pred_speed.$(VCPROJ_SFX)
|
|
||||||
test_intra_pred_speed.$(VCPROJ_SFX): $(TEST_INTRA_PRED_SPEED_SRCS) vpx.$(VCPROJ_SFX) gtest.$(VCPROJ_SFX)
|
|
||||||
@echo " [CREATE] $@"
|
|
||||||
$(qexec)$(GEN_VCPROJ) \
|
|
||||||
--exe \
|
|
||||||
--target=$(TOOLCHAIN) \
|
|
||||||
--name=test_intra_pred_speed \
|
|
||||||
-D_VARIADIC_MAX=10 \
|
|
||||||
--proj-guid=CD837F5F-52D8-4314-A370-895D614166A7 \
|
|
||||||
--ver=$(CONFIG_VS_VERSION) \
|
|
||||||
--src-path-bare="$(SRC_PATH_BARE)" \
|
|
||||||
$(if $(CONFIG_STATIC_MSVCRT),--static-crt) \
|
|
||||||
--out=$@ $(INTERNAL_CFLAGS) $(CFLAGS) \
|
|
||||||
-I. -I"$(SRC_PATH_BARE)/third_party/googletest/src/include" \
|
|
||||||
-L. -l$(CODEC_LIB) -l$(GTEST_LIB) $^
|
|
||||||
endif # TEST_INTRA_PRED_SPEED
|
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
|
|
||||||
@@ -463,54 +428,45 @@ ifeq ($(filter win%,$(TGT_OS)),$(TGT_OS))
|
|||||||
# Disabling pthreads globally will cause issues on darwin and possibly elsewhere
|
# Disabling pthreads globally will cause issues on darwin and possibly elsewhere
|
||||||
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0
|
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -DGTEST_HAS_PTHREAD=0
|
||||||
endif
|
endif
|
||||||
GTEST_INCLUDES := -I$(SRC_PATH_BARE)/third_party/googletest/src
|
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
|
||||||
GTEST_INCLUDES += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
|
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
|
||||||
$(GTEST_OBJS) $(GTEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES)
|
OBJS-$(BUILD_LIBVPX) += $(GTEST_OBJS)
|
||||||
OBJS-yes += $(GTEST_OBJS)
|
LIBS-$(BUILD_LIBVPX) += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
|
||||||
LIBS-yes += $(BUILD_PFX)libgtest.a $(BUILD_PFX)libgtest_g.a
|
|
||||||
$(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS)
|
$(BUILD_PFX)libgtest_g.a: $(GTEST_OBJS)
|
||||||
|
|
||||||
LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS)))
|
LIBVPX_TEST_OBJS=$(sort $(call objs,$(LIBVPX_TEST_SRCS)))
|
||||||
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES)
|
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src
|
||||||
OBJS-yes += $(LIBVPX_TEST_OBJS)
|
$(LIBVPX_TEST_OBJS) $(LIBVPX_TEST_OBJS:.o=.d): CXXFLAGS += -I$(SRC_PATH_BARE)/third_party/googletest/src/include
|
||||||
BINS-yes += $(LIBVPX_TEST_BIN)
|
OBJS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_OBJS)
|
||||||
|
BINS-$(BUILD_LIBVPX) += $(LIBVPX_TEST_BINS)
|
||||||
|
|
||||||
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
|
CODEC_LIB=$(if $(CONFIG_DEBUG_LIBS),vpx_g,vpx)
|
||||||
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),$(SHARED_LIB_SUF),.a)
|
CODEC_LIB_SUF=$(if $(CONFIG_SHARED),.so,.a)
|
||||||
TEST_LIBS := lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a
|
$(foreach bin,$(LIBVPX_TEST_BINS),\
|
||||||
$(LIBVPX_TEST_BIN): $(TEST_LIBS)
|
$(if $(BUILD_LIBVPX),$(eval $(bin): \
|
||||||
$(eval $(call linkerxx_template,$(LIBVPX_TEST_BIN), \
|
lib$(CODEC_LIB)$(CODEC_LIB_SUF) libgtest.a ))\
|
||||||
|
$(if $(BUILD_LIBVPX),$(eval $(call linkerxx_template,$(bin),\
|
||||||
$(LIBVPX_TEST_OBJS) \
|
$(LIBVPX_TEST_OBJS) \
|
||||||
-L. -lvpx -lgtest $(extralibs) -lm))
|
-L. -lvpx -lgtest $(extralibs) -lm)\
|
||||||
|
)))\
|
||||||
|
$(if $(LIPO_LIBS),$(eval $(call lipo_bin_template,$(bin))))\
|
||||||
|
|
||||||
ifneq ($(strip $(TEST_INTRA_PRED_SPEED_OBJS)),)
|
endif
|
||||||
$(TEST_INTRA_PRED_SPEED_OBJS) $(TEST_INTRA_PRED_SPEED_OBJS:.o=.d): CXXFLAGS += $(GTEST_INCLUDES)
|
|
||||||
OBJS-yes += $(TEST_INTRA_PRED_SPEED_OBJS)
|
|
||||||
BINS-yes += $(TEST_INTRA_PRED_SPEED_BIN)
|
|
||||||
|
|
||||||
$(TEST_INTRA_PRED_SPEED_BIN): $(TEST_LIBS)
|
|
||||||
$(eval $(call linkerxx_template,$(TEST_INTRA_PRED_SPEED_BIN), \
|
|
||||||
$(TEST_INTRA_PRED_SPEED_OBJS) \
|
|
||||||
-L. -lvpx -lgtest $(extralibs) -lm))
|
|
||||||
endif # TEST_INTRA_PRED_SPEED
|
|
||||||
|
|
||||||
endif # CONFIG_UNIT_TESTS
|
|
||||||
|
|
||||||
# Install test sources only if codec source is included
|
# Install test sources only if codec source is included
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\
|
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(patsubst $(SRC_PATH_BARE)/%,%,\
|
||||||
$(shell find $(SRC_PATH_BARE)/third_party/googletest -type f))
|
$(shell find $(SRC_PATH_BARE)/third_party/googletest -type f))
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS)
|
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(LIBVPX_TEST_SRCS)
|
||||||
INSTALL-SRCS-$(CONFIG_CODEC_SRCS) += $(TEST_INTRA_PRED_SPEED_SRCS)
|
|
||||||
|
|
||||||
define test_shard_template
|
define test_shard_template
|
||||||
test:: test_shard.$(1)
|
test:: test_shard.$(1)
|
||||||
test-no-data-check:: test_shard_ndc.$(1)
|
test_shard.$(1): $(LIBVPX_TEST_BINS) testdata
|
||||||
test_shard.$(1) test_shard_ndc.$(1): $(LIBVPX_TEST_BIN)
|
|
||||||
@set -e; \
|
@set -e; \
|
||||||
|
for t in $(LIBVPX_TEST_BINS); do \
|
||||||
export GTEST_SHARD_INDEX=$(1); \
|
export GTEST_SHARD_INDEX=$(1); \
|
||||||
export GTEST_TOTAL_SHARDS=$(2); \
|
export GTEST_TOTAL_SHARDS=$(2); \
|
||||||
$(LIBVPX_TEST_BIN)
|
$$$$t; \
|
||||||
test_shard.$(1): testdata
|
done
|
||||||
.PHONY: test_shard.$(1)
|
.PHONY: test_shard.$(1)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
@@ -555,16 +511,15 @@ ifeq ($(CONFIG_MSVS),yes)
|
|||||||
# TODO(tomfinegan): Support running the debug versions of tools?
|
# TODO(tomfinegan): Support running the debug versions of tools?
|
||||||
TEST_BIN_PATH := $(addsuffix /$(TGT_OS:win64=x64)/Release, $(TEST_BIN_PATH))
|
TEST_BIN_PATH := $(addsuffix /$(TGT_OS:win64=x64)/Release, $(TEST_BIN_PATH))
|
||||||
endif
|
endif
|
||||||
utiltest utiltest-no-data-check:
|
utiltest: testdata
|
||||||
$(qexec)$(SRC_PATH_BARE)/test/vpxdec.sh \
|
$(qexec)$(SRC_PATH_BARE)/test/vpxdec.sh \
|
||||||
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
|
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
|
||||||
--bin-path $(TEST_BIN_PATH)
|
--bin-path $(TEST_BIN_PATH)
|
||||||
$(qexec)$(SRC_PATH_BARE)/test/vpxenc.sh \
|
$(qexec)$(SRC_PATH_BARE)/test/vpxenc.sh \
|
||||||
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
|
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
|
||||||
--bin-path $(TEST_BIN_PATH)
|
--bin-path $(TEST_BIN_PATH)
|
||||||
utiltest: testdata
|
|
||||||
else
|
else
|
||||||
utiltest utiltest-no-data-check:
|
utiltest:
|
||||||
@echo Unit tests must be enabled to make the utiltest target.
|
@echo Unit tests must be enabled to make the utiltest target.
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -582,12 +537,11 @@ ifeq ($(CONFIG_MSVS),yes)
|
|||||||
# TODO(tomfinegan): Support running the debug versions of tools?
|
# TODO(tomfinegan): Support running the debug versions of tools?
|
||||||
EXAMPLES_BIN_PATH := $(TGT_OS:win64=x64)/Release
|
EXAMPLES_BIN_PATH := $(TGT_OS:win64=x64)/Release
|
||||||
endif
|
endif
|
||||||
exampletest exampletest-no-data-check: examples
|
exampletest: examples testdata
|
||||||
$(qexec)$(SRC_PATH_BARE)/test/examples.sh \
|
$(qexec)$(SRC_PATH_BARE)/test/examples.sh \
|
||||||
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
|
--test-data-path $(LIBVPX_TEST_DATA_PATH) \
|
||||||
--bin-path $(EXAMPLES_BIN_PATH)
|
--bin-path $(EXAMPLES_BIN_PATH)
|
||||||
exampletest: testdata
|
|
||||||
else
|
else
|
||||||
exampletest exampletest-no-data-check:
|
exampletest:
|
||||||
@echo Unit tests must be enabled to make the exampletest target.
|
@echo Unit tests must be enabled to make the exampletest target.
|
||||||
endif
|
endif
|
||||||
|
|||||||
17
md5_utils.c
17
md5_utils.c
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "md5_utils.h"
|
#include "md5_utils.h"
|
||||||
|
|
||||||
static void
|
void
|
||||||
byteSwap(UWORD32 *buf, unsigned words) {
|
byteSwap(UWORD32 *buf, unsigned words) {
|
||||||
md5byte *p;
|
md5byte *p;
|
||||||
|
|
||||||
@@ -150,23 +150,12 @@ MD5Final(md5byte digest[16], struct MD5Context *ctx) {
|
|||||||
#define MD5STEP(f,w,x,y,z,in,s) \
|
#define MD5STEP(f,w,x,y,z,in,s) \
|
||||||
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
|
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
|
||||||
|
|
||||||
#if defined(__clang__) && defined(__has_attribute)
|
|
||||||
#if __has_attribute(no_sanitize)
|
|
||||||
#define VPX_NO_UNSIGNED_OVERFLOW_CHECK \
|
|
||||||
__attribute__((no_sanitize("unsigned-integer-overflow")))
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VPX_NO_UNSIGNED_OVERFLOW_CHECK
|
|
||||||
#define VPX_NO_UNSIGNED_OVERFLOW_CHECK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||||
* the data and converts bytes into longwords for this routine.
|
* the data and converts bytes into longwords for this routine.
|
||||||
*/
|
*/
|
||||||
VPX_NO_UNSIGNED_OVERFLOW_CHECK void
|
void
|
||||||
MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
|
MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
|
||||||
register UWORD32 a, b, c, d;
|
register UWORD32 a, b, c, d;
|
||||||
|
|
||||||
@@ -249,6 +238,4 @@ MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) {
|
|||||||
buf[3] += d;
|
buf[3] += d;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef VPX_NO_UNSIGNED_OVERFLOW_CHECK
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -88,9 +88,6 @@ void update_rate_histogram(struct rate_hist *hist,
|
|||||||
if (now < cfg->rc_buf_initial_sz)
|
if (now < cfg->rc_buf_initial_sz)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!cfg->rc_target_bitrate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
then = now;
|
then = now;
|
||||||
|
|
||||||
/* Sum the size over the past rc_buf_sz ms */
|
/* Sum the size over the past rc_buf_sz ms */
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ class ACMRandom {
|
|||||||
return (value >> 15) & 0xffff;
|
return (value >> 15) & 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t Rand9Signed(void) {
|
|
||||||
// Use 9 bits: values between 255 (0x0FF) and -256 (0x100).
|
|
||||||
const uint32_t value = random_.Generate(512);
|
|
||||||
return static_cast<int16_t>(value) - 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Rand8(void) {
|
uint8_t Rand8(void) {
|
||||||
const uint32_t value =
|
const uint32_t value =
|
||||||
random_.Generate(testing::internal::Random::kMaxRange);
|
random_.Generate(testing::internal::Random::kMaxRange);
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
#include <algorithm>
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "test/y4m_video_source.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Check if any pixel in a 16x16 macroblock varies between frames.
|
|
||||||
int CheckMb(const vpx_image_t ¤t, const vpx_image_t &previous,
|
|
||||||
int mb_r, int mb_c) {
|
|
||||||
for (int plane = 0; plane < 3; plane++) {
|
|
||||||
int r = 16 * mb_r;
|
|
||||||
int c0 = 16 * mb_c;
|
|
||||||
int r_top = std::min(r + 16, static_cast<int>(current.d_h));
|
|
||||||
int c_top = std::min(c0 + 16, static_cast<int>(current.d_w));
|
|
||||||
r = std::max(r, 0);
|
|
||||||
c0 = std::max(c0, 0);
|
|
||||||
if (plane > 0 && current.x_chroma_shift) {
|
|
||||||
c_top = (c_top + 1) >> 1;
|
|
||||||
c0 >>= 1;
|
|
||||||
}
|
|
||||||
if (plane > 0 && current.y_chroma_shift) {
|
|
||||||
r_top = (r_top + 1) >> 1;
|
|
||||||
r >>= 1;
|
|
||||||
}
|
|
||||||
for (; r < r_top; ++r) {
|
|
||||||
for (int c = c0; c < c_top; ++c) {
|
|
||||||
if (current.planes[plane][current.stride[plane] * r + c] !=
|
|
||||||
previous.planes[plane][previous.stride[plane] * r + c])
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateMap(int mb_rows, int mb_cols, const vpx_image_t ¤t,
|
|
||||||
const vpx_image_t &previous, uint8_t *map) {
|
|
||||||
for (int mb_r = 0; mb_r < mb_rows; ++mb_r) {
|
|
||||||
for (int mb_c = 0; mb_c < mb_cols; ++mb_c) {
|
|
||||||
map[mb_r * mb_cols + mb_c] = CheckMb(current, previous, mb_r, mb_c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int kAqModeCyclicRefresh = 3;
|
|
||||||
|
|
||||||
class ActiveMapRefreshTest
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
|
||||||
protected:
|
|
||||||
ActiveMapRefreshTest() : EncoderTest(GET_PARAM(0)) {}
|
|
||||||
virtual ~ActiveMapRefreshTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(GET_PARAM(1));
|
|
||||||
cpu_used_ = GET_PARAM(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
|
||||||
::libvpx_test::Encoder *encoder) {
|
|
||||||
::libvpx_test::Y4mVideoSource *y4m_video =
|
|
||||||
static_cast<libvpx_test::Y4mVideoSource *>(video);
|
|
||||||
if (video->frame() == 1) {
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
|
||||||
encoder->Control(VP9E_SET_AQ_MODE, kAqModeCyclicRefresh);
|
|
||||||
} else if (video->frame() >= 2 && video->img()) {
|
|
||||||
vpx_image_t *current = video->img();
|
|
||||||
vpx_image_t *previous = y4m_holder_->img();
|
|
||||||
ASSERT_TRUE(previous != NULL);
|
|
||||||
vpx_active_map_t map = vpx_active_map_t();
|
|
||||||
const int width = static_cast<int>(current->d_w);
|
|
||||||
const int height = static_cast<int>(current->d_h);
|
|
||||||
const int mb_width = (width + 15) / 16;
|
|
||||||
const int mb_height = (height + 15) / 16;
|
|
||||||
uint8_t *active_map = new uint8_t[mb_width * mb_height];
|
|
||||||
GenerateMap(mb_height, mb_width, *current, *previous, active_map);
|
|
||||||
map.cols = mb_width;
|
|
||||||
map.rows = mb_height;
|
|
||||||
map.active_map = active_map;
|
|
||||||
encoder->Control(VP8E_SET_ACTIVEMAP, &map);
|
|
||||||
delete[] active_map;
|
|
||||||
}
|
|
||||||
if (video->img()) {
|
|
||||||
y4m_video->SwapBuffers(y4m_holder_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cpu_used_;
|
|
||||||
::libvpx_test::Y4mVideoSource *y4m_holder_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(ActiveMapRefreshTest, Test) {
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
cfg_.g_profile = 1;
|
|
||||||
cfg_.rc_target_bitrate = 600;
|
|
||||||
cfg_.rc_resize_allowed = 0;
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 30;
|
|
||||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.kf_max_dist = 90000;
|
|
||||||
|
|
||||||
#if CONFIG_VP10
|
|
||||||
const int nframes = codec_ == &libvpx_test::kVP10 ? 10 : 30;
|
|
||||||
#else
|
|
||||||
const int nframes = 30;
|
|
||||||
#endif // CONFIG_VP10
|
|
||||||
::libvpx_test::Y4mVideoSource video("desktop_credits.y4m", 0, nframes);
|
|
||||||
::libvpx_test::Y4mVideoSource video_holder("desktop_credits.y4m", 0, nframes);
|
|
||||||
video_holder.Begin();
|
|
||||||
y4m_holder_ = &video_holder;
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_VP10
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(ActiveMapRefreshTest,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
|
||||||
::testing::Range(5, 6));
|
|
||||||
#endif // CONFIG_VP10
|
|
||||||
} // namespace
|
|
||||||
@@ -65,7 +65,10 @@ class ActiveMapTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoTest() {
|
int cpu_used_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(ActiveMapTest, Test) {
|
||||||
// Validate that this non multiple of 64 wide clip encodes
|
// Validate that this non multiple of 64 wide clip encodes
|
||||||
cfg_.g_lag_in_frames = 0;
|
cfg_.g_lag_in_frames = 0;
|
||||||
cfg_.rc_target_bitrate = 400;
|
cfg_.rc_target_bitrate = 400;
|
||||||
@@ -73,31 +76,14 @@ class ActiveMapTest
|
|||||||
cfg_.g_pass = VPX_RC_ONE_PASS;
|
cfg_.g_pass = VPX_RC_ONE_PASS;
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.kf_max_dist = 90000;
|
cfg_.kf_max_dist = 90000;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", kWidth, kHeight, 30,
|
||||||
1, 0, 20);
|
1, 0, 20);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
int cpu_used_;
|
VP9_INSTANTIATE_TEST_CASE(ActiveMapTest,
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(ActiveMapTest, Test) {
|
|
||||||
DoTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActiveMapTestLarge : public ActiveMapTest {};
|
|
||||||
|
|
||||||
TEST_P(ActiveMapTestLarge, Test) {
|
|
||||||
DoTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(ActiveMapTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
::testing::Values(::libvpx_test::kRealTime),
|
||||||
::testing::Range(0, 5));
|
::testing::Range(0, 6));
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(ActiveMapTest,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
|
||||||
::testing::Range(5, 9));
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,155 +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.
|
|
||||||
*/
|
|
||||||
#include <math.h>
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_dsp/postproc.h"
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// TODO(jimbankoski): make width and height integers not unsigned.
|
|
||||||
typedef void (*AddNoiseFunc)(unsigned char *start, char *noise,
|
|
||||||
char blackclamp[16], char whiteclamp[16],
|
|
||||||
char bothclamp[16], unsigned int width,
|
|
||||||
unsigned int height, int pitch);
|
|
||||||
|
|
||||||
class AddNoiseTest
|
|
||||||
: public ::testing::TestWithParam<AddNoiseFunc> {
|
|
||||||
public:
|
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
virtual ~AddNoiseTest() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
double stddev6(char a, char b, char c, char d, char e, char f) {
|
|
||||||
const double n = (a + b + c + d + e + f) / 6.0;
|
|
||||||
const double v = ((a - n) * (a - n) + (b - n) * (b - n) + (c - n) * (c - n) +
|
|
||||||
(d - n) * (d - n) + (e - n) * (e - n) + (f - n) * (f - n)) /
|
|
||||||
6.0;
|
|
||||||
return sqrt(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AddNoiseTest, CheckNoiseAdded) {
|
|
||||||
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, bothclamp[16]);
|
|
||||||
const int width = 64;
|
|
||||||
const int height = 64;
|
|
||||||
const int image_size = width * height;
|
|
||||||
char noise[3072];
|
|
||||||
const int clamp = vpx_setup_noise(4.4, sizeof(noise), noise);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
blackclamp[i] = clamp;
|
|
||||||
whiteclamp[i] = clamp;
|
|
||||||
bothclamp[i] = 2 * clamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
|
||||||
memset(s, 99, image_size);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
|
||||||
bothclamp, width, height, width));
|
|
||||||
|
|
||||||
// Check to make sure we don't end up having either the same or no added
|
|
||||||
// noise either vertically or horizontally.
|
|
||||||
for (int i = 0; i < image_size - 6 * width - 6; ++i) {
|
|
||||||
const double hd = stddev6(s[i] - 99, s[i + 1] - 99, s[i + 2] - 99,
|
|
||||||
s[i + 3] - 99, s[i + 4] - 99, s[i + 5] - 99);
|
|
||||||
const double vd = stddev6(s[i] - 99, s[i + width] - 99,
|
|
||||||
s[i + 2 * width] - 99, s[i + 3 * width] - 99,
|
|
||||||
s[i + 4 * width] - 99, s[i + 5 * width] - 99);
|
|
||||||
|
|
||||||
EXPECT_NE(hd, 0);
|
|
||||||
EXPECT_NE(vd, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize pixels in the image to 255 and check for roll over.
|
|
||||||
memset(s, 255, image_size);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
|
||||||
bothclamp, width, height, width));
|
|
||||||
|
|
||||||
// Check to make sure don't roll over.
|
|
||||||
for (int i = 0; i < image_size; ++i) {
|
|
||||||
EXPECT_GT(static_cast<int>(s[i]), clamp) << "i = " << i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize pixels in the image to 0 and check for roll under.
|
|
||||||
memset(s, 0, image_size);
|
|
||||||
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
|
||||||
bothclamp, width, height, width));
|
|
||||||
|
|
||||||
// Check to make sure don't roll under.
|
|
||||||
for (int i = 0; i < image_size; ++i) {
|
|
||||||
EXPECT_LT(static_cast<int>(s[i]), 255 - clamp) << "i = " << i;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AddNoiseTest, CheckCvsAssembly) {
|
|
||||||
DECLARE_ALIGNED(16, char, blackclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, whiteclamp[16]);
|
|
||||||
DECLARE_ALIGNED(16, char, bothclamp[16]);
|
|
||||||
const int width = 64;
|
|
||||||
const int height = 64;
|
|
||||||
const int image_size = width * height;
|
|
||||||
char noise[3072];
|
|
||||||
|
|
||||||
const int clamp = vpx_setup_noise(4.4, sizeof(noise), noise);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
blackclamp[i] = clamp;
|
|
||||||
whiteclamp[i] = clamp;
|
|
||||||
bothclamp[i] = 2 * clamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *const s = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
|
||||||
uint8_t *const d = reinterpret_cast<uint8_t *>(vpx_calloc(image_size, 1));
|
|
||||||
|
|
||||||
memset(s, 99, image_size);
|
|
||||||
memset(d, 99, image_size);
|
|
||||||
|
|
||||||
srand(0);
|
|
||||||
ASM_REGISTER_STATE_CHECK(GetParam()(s, noise, blackclamp, whiteclamp,
|
|
||||||
bothclamp, width, height, width));
|
|
||||||
srand(0);
|
|
||||||
ASM_REGISTER_STATE_CHECK(vpx_plane_add_noise_c(d, noise, blackclamp,
|
|
||||||
whiteclamp, bothclamp,
|
|
||||||
width, height, width));
|
|
||||||
|
|
||||||
for (int i = 0; i < image_size; ++i) {
|
|
||||||
EXPECT_EQ(static_cast<int>(s[i]), static_cast<int>(d[i])) << "i = " << i;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_free(d);
|
|
||||||
vpx_free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, AddNoiseTest,
|
|
||||||
::testing::Values(vpx_plane_add_noise_c));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, AddNoiseTest,
|
|
||||||
::testing::Values(vpx_plane_add_noise_sse2));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, AddNoiseTest,
|
|
||||||
::testing::Values(vpx_plane_add_noise_msa));
|
|
||||||
#endif
|
|
||||||
} // namespace
|
|
||||||
@@ -14,86 +14,56 @@
|
|||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class AltRefForcedKeyTestLarge
|
// lookahead range: [kLookAheadMin, kLookAheadMax).
|
||||||
: public ::libvpx_test::EncoderTest,
|
const int kLookAheadMin = 5;
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
const int kLookAheadMax = 26;
|
||||||
|
|
||||||
|
class AltRefTest : public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<int> {
|
||||||
protected:
|
protected:
|
||||||
AltRefForcedKeyTestLarge()
|
AltRefTest() : EncoderTest(GET_PARAM(0)), altref_count_(0) {}
|
||||||
: EncoderTest(GET_PARAM(0)),
|
virtual ~AltRefTest() {}
|
||||||
encoding_mode_(GET_PARAM(1)),
|
|
||||||
cpu_used_(GET_PARAM(2)),
|
|
||||||
forced_kf_frame_num_(1),
|
|
||||||
frame_num_(0) {}
|
|
||||||
virtual ~AltRefForcedKeyTestLarge() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
InitializeConfig();
|
InitializeConfig();
|
||||||
SetMode(encoding_mode_);
|
SetMode(libvpx_test::kTwoPassGood);
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.g_threads = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
virtual void BeginPassHook(unsigned int pass) {
|
||||||
::libvpx_test::Encoder *encoder) {
|
altref_count_ = 0;
|
||||||
if (video->frame() == 0) {
|
}
|
||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
|
||||||
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||||
|
libvpx_test::Encoder *encoder) {
|
||||||
|
if (video->frame() == 1) {
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
// override test default for tile columns if necessary.
|
encoder->Control(VP8E_SET_CPUUSED, 3);
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
if (GET_PARAM(0) == &libvpx_test::kVP10) {
|
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 6);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
frame_flags_ =
|
|
||||||
(video->frame() == forced_kf_frame_num_) ? VPX_EFLAG_FORCE_KF : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (frame_num_ == forced_kf_frame_num_) {
|
if (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ++altref_count_;
|
||||||
ASSERT_TRUE(!!(pkt->data.frame.flags & VPX_FRAME_IS_KEY))
|
|
||||||
<< "Frame #" << frame_num_ << " isn't a keyframe!";
|
|
||||||
}
|
|
||||||
++frame_num_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::libvpx_test::TestMode encoding_mode_;
|
int altref_count() const { return altref_count_; }
|
||||||
int cpu_used_;
|
|
||||||
unsigned int forced_kf_frame_num_;
|
private:
|
||||||
unsigned int frame_num_;
|
int altref_count_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(AltRefForcedKeyTestLarge, Frame1IsKey) {
|
TEST_P(AltRefTest, MonotonicTimestamps) {
|
||||||
const vpx_rational timebase = { 1, 30 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
const int lag_values[] = { 3, 15, 25, -1 };
|
cfg_.g_timebase = timebase;
|
||||||
|
cfg_.rc_target_bitrate = 1000;
|
||||||
|
cfg_.g_lag_in_frames = GET_PARAM(1);
|
||||||
|
|
||||||
forced_kf_frame_num_ = 1;
|
|
||||||
for (int i = 0; lag_values[i] != -1; ++i) {
|
|
||||||
frame_num_ = 0;
|
|
||||||
cfg_.g_lag_in_frames = lag_values[i];
|
|
||||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
timebase.den, timebase.num, 0, 30);
|
timebase.den, timebase.num, 0, 30);
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
EXPECT_GE(altref_count(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AltRefForcedKeyTestLarge, ForcedFrameIsKey) {
|
|
||||||
const vpx_rational timebase = { 1, 30 };
|
|
||||||
const int lag_values[] = { 3, 15, 25, -1 };
|
|
||||||
|
|
||||||
for (int i = 0; lag_values[i] != -1; ++i) {
|
|
||||||
frame_num_ = 0;
|
|
||||||
forced_kf_frame_num_ = lag_values[i] - 1;
|
|
||||||
cfg_.g_lag_in_frames = lag_values[i];
|
|
||||||
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
timebase.den, timebase.num, 0, 30);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
|
||||||
AltRefForcedKeyTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(0, 9));
|
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(AltRefTest,
|
||||||
|
::testing::Range(kLookAheadMin, kLookAheadMax));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -40,17 +40,9 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
LOCAL_MODULE := libvpx_test
|
LOCAL_MODULE := libvpx_test
|
||||||
LOCAL_STATIC_LIBRARIES := gtest libwebm
|
LOCAL_STATIC_LIBRARIES := gtest libwebm
|
||||||
|
|
||||||
ifeq ($(ENABLE_SHARED),1)
|
|
||||||
LOCAL_SHARED_LIBRARIES := vpx
|
LOCAL_SHARED_LIBRARIES := vpx
|
||||||
else
|
|
||||||
LOCAL_STATIC_LIBRARIES += vpx
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(LOCAL_PATH)/test/test.mk
|
include $(LOCAL_PATH)/test/test.mk
|
||||||
LOCAL_C_INCLUDES := $(BINDINGS_DIR)
|
LOCAL_C_INCLUDES := $(BINDINGS_DIR)
|
||||||
FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes)))
|
FILTERED_SRC := $(sort $(filter %.cc %.c, $(LIBVPX_TEST_SRCS-yes)))
|
||||||
LOCAL_SRC_FILES := $(addprefix ./test/, $(FILTERED_SRC))
|
LOCAL_SRC_FILES := $(addprefix ./test/, $(FILTERED_SRC))
|
||||||
# some test files depend on *_rtcd.h, ensure they're generated first.
|
|
||||||
$(eval $(call rtcd_dep_template))
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|||||||
@@ -38,22 +38,6 @@ class AqSegmentTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoTest(int aq_mode) {
|
|
||||||
aq_mode_ = aq_mode;
|
|
||||||
cfg_.kf_max_dist = 12;
|
|
||||||
cfg_.rc_min_quantizer = 8;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.g_lag_in_frames = 6;
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_target_bitrate = 300;
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv",
|
|
||||||
352, 288, 30, 1, 0, 15);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
int set_cpu_used_;
|
int set_cpu_used_;
|
||||||
int aq_mode_;
|
int aq_mode_;
|
||||||
};
|
};
|
||||||
@@ -61,42 +45,65 @@ class AqSegmentTest
|
|||||||
// Validate that this AQ segmentation mode (AQ=1, variance_ap)
|
// Validate that this AQ segmentation mode (AQ=1, variance_ap)
|
||||||
// encodes and decodes without a mismatch.
|
// encodes and decodes without a mismatch.
|
||||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ1) {
|
TEST_P(AqSegmentTest, TestNoMisMatchAQ1) {
|
||||||
DoTest(1);
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 1;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that this AQ segmentation mode (AQ=2, complexity_aq)
|
// Validate that this AQ segmentation mode (AQ=2, complexity_aq)
|
||||||
// encodes and decodes without a mismatch.
|
// encodes and decodes without a mismatch.
|
||||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ2) {
|
TEST_P(AqSegmentTest, TestNoMisMatchAQ2) {
|
||||||
DoTest(2);
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 2;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq)
|
// Validate that this AQ segmentation mode (AQ=3, cyclic_refresh_aq)
|
||||||
// encodes and decodes without a mismatch.
|
// encodes and decodes without a mismatch.
|
||||||
TEST_P(AqSegmentTest, TestNoMisMatchAQ3) {
|
TEST_P(AqSegmentTest, TestNoMisMatchAQ3) {
|
||||||
DoTest(3);
|
cfg_.rc_min_quantizer = 8;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
|
cfg_.g_lag_in_frames = 0;
|
||||||
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
|
cfg_.rc_buf_sz = 1000;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
|
||||||
|
aq_mode_ = 3;
|
||||||
|
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 100);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
class AqSegmentTestLarge : public AqSegmentTest {};
|
VP9_INSTANTIATE_TEST_CASE(AqSegmentTest,
|
||||||
|
|
||||||
TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ1) {
|
|
||||||
DoTest(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ2) {
|
|
||||||
DoTest(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AqSegmentTestLarge, TestNoMisMatchAQ3) {
|
|
||||||
DoTest(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(AqSegmentTest,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime,
|
::testing::Values(::libvpx_test::kRealTime,
|
||||||
::libvpx_test::kOnePassGood),
|
::libvpx_test::kOnePassGood),
|
||||||
::testing::Range(5, 9));
|
::testing::Range(3, 9));
|
||||||
VP10_INSTANTIATE_TEST_CASE(AqSegmentTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime,
|
|
||||||
::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(3, 5));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,249 +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 "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "test/y4m_video_source.h"
|
|
||||||
#include "test/yuv_video_source.h"
|
|
||||||
#include "vp10/encoder/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_VPX_HIGHBITDEPTH
|
|
||||||
// Add list of profile 2/3 test videos here ...
|
|
||||||
#endif // CONFIG_VPX_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 ArfFreqTestLarge
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith3Params<TestVideoParam, \
|
|
||||||
TestEncodeParam, int> {
|
|
||||||
protected:
|
|
||||||
ArfFreqTestLarge()
|
|
||||||
: EncoderTest(GET_PARAM(0)),
|
|
||||||
test_video_param_(GET_PARAM(1)),
|
|
||||||
test_encode_param_(GET_PARAM(2)),
|
|
||||||
min_arf_requested_(GET_PARAM(3)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~ArfFreqTestLarge() {}
|
|
||||||
|
|
||||||
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_run_ = 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_run_ == ARF_NOT_SEEN) {
|
|
||||||
min_run_ = ARF_SEEN_ONCE;
|
|
||||||
} else if (min_run_ == ARF_SEEN_ONCE ||
|
|
||||||
run_of_visible_frames_ < min_run_) {
|
|
||||||
min_run_ = run_of_visible_frames_;
|
|
||||||
}
|
|
||||||
run_of_visible_frames_ = 1;
|
|
||||||
} else {
|
|
||||||
min_run_ = 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 GetMinVisibleRun() const {
|
|
||||||
return min_run_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetMinArfDistanceRequested() const {
|
|
||||||
if (min_arf_requested_)
|
|
||||||
return min_arf_requested_;
|
|
||||||
else
|
|
||||||
return vp10_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_run_;
|
|
||||||
int run_of_visible_frames_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(ArfFreqTestLarge, 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;
|
|
||||||
|
|
||||||
testing::internal::scoped_ptr<libvpx_test::VideoSource> video;
|
|
||||||
if (is_extension_y4m(test_video_param_.filename)) {
|
|
||||||
video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename,
|
|
||||||
0, kFrames));
|
|
||||||
} else {
|
|
||||||
video.reset(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.get()));
|
|
||||||
const int min_run = GetMinVisibleRun();
|
|
||||||
const int min_arf_dist_requested = GetMinArfDistanceRequested();
|
|
||||||
if (min_run != ARF_NOT_SEEN && min_run != ARF_SEEN_ONCE) {
|
|
||||||
const int min_arf_dist = min_run + 1;
|
|
||||||
EXPECT_GE(min_arf_dist, min_arf_dist_requested);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH || CONFIG_EXT_REFS
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
// TODO(angiebird): 25-29 fail in high bitdepth mode.
|
|
||||||
// TODO(zoeliu): This ArfFreqTest does not work with BWDREF_FRAME, as
|
|
||||||
// BWDREF_FRAME is also a non-show frame, and the minimum run between two
|
|
||||||
// consecutive BWDREF_FRAME's may vary between 1 and any arbitrary positive
|
|
||||||
// number as long as it does not exceed the gf_group interval.
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
DISABLED_VP10, ArfFreqTestLarge,
|
|
||||||
::testing::Combine(
|
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory *>(
|
|
||||||
&libvpx_test::kVP10)),
|
|
||||||
::testing::ValuesIn(kTestVectors),
|
|
||||||
::testing::ValuesIn(kEncodeVectors),
|
|
||||||
::testing::ValuesIn(kMinArfVectors)));
|
|
||||||
#endif // CONFIG_VP10_ENCODER
|
|
||||||
#else
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
|
||||||
ArfFreqTestLarge,
|
|
||||||
::testing::ValuesIn(kTestVectors),
|
|
||||||
::testing::ValuesIn(kEncodeVectors),
|
|
||||||
::testing::ValuesIn(kMinArfVectors));
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH || CONFIG_EXT_REFS
|
|
||||||
} // namespace
|
|
||||||
411
test/avg_test.cc
411
test/avg_test.cc
@@ -1,411 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
class AverageTestBase : public ::testing::Test {
|
|
||||||
public:
|
|
||||||
AverageTestBase(int width, int height) : width_(width), height_(height) {}
|
|
||||||
|
|
||||||
static void SetUpTestCase() {
|
|
||||||
source_data_ = reinterpret_cast<uint8_t*>(
|
|
||||||
vpx_memalign(kDataAlignment, kDataBlockSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TearDownTestCase() {
|
|
||||||
vpx_free(source_data_);
|
|
||||||
source_data_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Handle blocks up to 4 blocks 64x64 with stride up to 128
|
|
||||||
static const int kDataAlignment = 16;
|
|
||||||
static const int kDataBlockSize = 64 * 128;
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
source_stride_ = (width_ + 31) & ~31;
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum Pixels
|
|
||||||
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)
|
|
||||||
average += source[h * pitch + w];
|
|
||||||
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 * pitch + w];
|
|
||||||
return ((average + 8) >> 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillConstant(uint8_t fill_constant) {
|
|
||||||
for (int i = 0; i < width_ * height_; ++i) {
|
|
||||||
source_data_[i] = fill_constant;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom() {
|
|
||||||
for (int i = 0; i < width_ * height_; ++i) {
|
|
||||||
source_data_[i] = rnd_.Rand8();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int width_, height_;
|
|
||||||
static uint8_t* source_data_;
|
|
||||||
int source_stride_;
|
|
||||||
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
typedef unsigned int (*AverageFunction)(const uint8_t* s, int pitch);
|
|
||||||
|
|
||||||
typedef std::tr1::tuple<int, int, int, int, AverageFunction> AvgFunc;
|
|
||||||
|
|
||||||
class AverageTest
|
|
||||||
: public AverageTestBase,
|
|
||||||
public ::testing::WithParamInterface<AvgFunc>{
|
|
||||||
public:
|
|
||||||
AverageTest() : AverageTestBase(GET_PARAM(0), GET_PARAM(1)) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void CheckAverages() {
|
|
||||||
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(4)(source_data_+ GET_PARAM(2),
|
|
||||||
source_stride_));
|
|
||||||
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_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int (*SatdFunc)(const int16_t *coeffs, int length);
|
|
||||||
typedef std::tr1::tuple<int, SatdFunc> SatdTestParam;
|
|
||||||
|
|
||||||
class SatdTest
|
|
||||||
: public ::testing::Test,
|
|
||||||
public ::testing::WithParamInterface<SatdTestParam> {
|
|
||||||
protected:
|
|
||||||
virtual void SetUp() {
|
|
||||||
satd_size_ = GET_PARAM(0);
|
|
||||||
satd_func_ = GET_PARAM(1);
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
src_ = reinterpret_cast<int16_t*>(
|
|
||||||
vpx_memalign(16, sizeof(*src_) * satd_size_));
|
|
||||||
ASSERT_TRUE(src_ != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
vpx_free(src_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillConstant(const int16_t val) {
|
|
||||||
for (int i = 0; i < satd_size_; ++i) src_[i] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FillRandom() {
|
|
||||||
for (int i = 0; i < satd_size_; ++i) src_[i] = rnd_.Rand16();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Check(const int expected) {
|
|
||||||
int total;
|
|
||||||
ASM_REGISTER_STATE_CHECK(total = satd_func_(src_, satd_size_));
|
|
||||||
EXPECT_EQ(expected, total);
|
|
||||||
}
|
|
||||||
|
|
||||||
int satd_size_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
int16_t *src_;
|
|
||||||
SatdFunc satd_func_;
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t* AverageTestBase::source_data_ = NULL;
|
|
||||||
|
|
||||||
TEST_P(AverageTest, MinValue) {
|
|
||||||
FillConstant(0);
|
|
||||||
CheckAverages();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AverageTest, MaxValue) {
|
|
||||||
FillConstant(255);
|
|
||||||
CheckAverages();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(AverageTest, Random) {
|
|
||||||
// The reference frame, but not the source frame, may be unaligned for
|
|
||||||
// certain types of searches.
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
|
||||||
FillRandom();
|
|
||||||
CheckAverages();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_P(SatdTest, MinValue) {
|
|
||||||
const int kMin = -32640;
|
|
||||||
const int expected = -kMin * satd_size_;
|
|
||||||
FillConstant(kMin);
|
|
||||||
Check(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(SatdTest, MaxValue) {
|
|
||||||
const int kMax = 32640;
|
|
||||||
const int expected = kMax * satd_size_;
|
|
||||||
FillConstant(kMax);
|
|
||||||
Check(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(SatdTest, Random) {
|
|
||||||
int expected;
|
|
||||||
switch (satd_size_) {
|
|
||||||
case 16: expected = 205298; break;
|
|
||||||
case 64: expected = 1113950; break;
|
|
||||||
case 256: expected = 4268415; break;
|
|
||||||
case 1024: expected = 16954082; break;
|
|
||||||
default:
|
|
||||||
FAIL() << "Invalid satd size (" << satd_size_
|
|
||||||
<< ") valid: 16/64/256/1024";
|
|
||||||
}
|
|
||||||
FillRandom();
|
|
||||||
Check(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, AverageTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, 16, 1, 8, &vpx_avg_8x8_c),
|
|
||||||
make_tuple(16, 16, 1, 4, &vpx_avg_4x4_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, SatdTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, &vpx_satd_c),
|
|
||||||
make_tuple(64, &vpx_satd_c),
|
|
||||||
make_tuple(256, &vpx_satd_c),
|
|
||||||
make_tuple(1024, &vpx_satd_c)));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, AverageTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_sse2),
|
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_sse2),
|
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_sse2),
|
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_sse2),
|
|
||||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_sse2),
|
|
||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_sse2)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, IntProRowTest, ::testing::Values(
|
|
||||||
make_tuple(16, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
|
||||||
make_tuple(32, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c),
|
|
||||||
make_tuple(64, &vpx_int_pro_row_sse2, &vpx_int_pro_row_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, IntProColTest, ::testing::Values(
|
|
||||||
make_tuple(16, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
|
||||||
make_tuple(32, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c),
|
|
||||||
make_tuple(64, &vpx_int_pro_col_sse2, &vpx_int_pro_col_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE2, SatdTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, &vpx_satd_sse2),
|
|
||||||
make_tuple(64, &vpx_satd_sse2),
|
|
||||||
make_tuple(256, &vpx_satd_sse2),
|
|
||||||
make_tuple(1024, &vpx_satd_sse2)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, AverageTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_neon),
|
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_neon),
|
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_neon),
|
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_neon),
|
|
||||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_neon),
|
|
||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_neon)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, IntProRowTest, ::testing::Values(
|
|
||||||
make_tuple(16, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
|
||||||
make_tuple(32, &vpx_int_pro_row_neon, &vpx_int_pro_row_c),
|
|
||||||
make_tuple(64, &vpx_int_pro_row_neon, &vpx_int_pro_row_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, IntProColTest, ::testing::Values(
|
|
||||||
make_tuple(16, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
|
||||||
make_tuple(32, &vpx_int_pro_col_neon, &vpx_int_pro_col_c),
|
|
||||||
make_tuple(64, &vpx_int_pro_col_neon, &vpx_int_pro_col_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
NEON, SatdTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, &vpx_satd_neon),
|
|
||||||
make_tuple(64, &vpx_satd_neon),
|
|
||||||
make_tuple(256, &vpx_satd_neon),
|
|
||||||
make_tuple(1024, &vpx_satd_neon)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, AverageTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(16, 16, 0, 8, &vpx_avg_8x8_msa),
|
|
||||||
make_tuple(16, 16, 5, 8, &vpx_avg_8x8_msa),
|
|
||||||
make_tuple(32, 32, 15, 8, &vpx_avg_8x8_msa),
|
|
||||||
make_tuple(16, 16, 0, 4, &vpx_avg_4x4_msa),
|
|
||||||
make_tuple(16, 16, 5, 4, &vpx_avg_4x4_msa),
|
|
||||||
make_tuple(32, 32, 15, 4, &vpx_avg_4x4_msa)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@@ -1,367 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
|
|
||||||
#include "test/function_equivalence_test.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
|
|
||||||
#include "vp10/common/enums.h"
|
|
||||||
|
|
||||||
#include "vpx_dsp/blend.h"
|
|
||||||
|
|
||||||
using libvpx_test::FunctionEquivalenceTest;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
template<typename F, typename T>
|
|
||||||
class BlendA64Mask1DTest : public FunctionEquivalenceTest<F> {
|
|
||||||
public:
|
|
||||||
static const int kIterations = 10000;
|
|
||||||
static const int kMaxWidth = MAX_SB_SIZE * 5; // * 5 to cover longer strides
|
|
||||||
static const int kMaxHeight = MAX_SB_SIZE;
|
|
||||||
static const int kBufSize = kMaxWidth * kMaxHeight;
|
|
||||||
static const int kMaxMaskWidth = 2 * MAX_SB_SIZE;
|
|
||||||
static const int kMaxMaskSize = kMaxMaskWidth;
|
|
||||||
|
|
||||||
virtual ~BlendA64Mask1DTest() {}
|
|
||||||
|
|
||||||
virtual void Execute(const T *p_src0, const T *p_src1) = 0;
|
|
||||||
|
|
||||||
void Common() {
|
|
||||||
w_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
|
||||||
h_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
|
||||||
|
|
||||||
dst_offset_ = this->rng_(33);
|
|
||||||
dst_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
|
||||||
|
|
||||||
src0_offset_ = this->rng_(33);
|
|
||||||
src0_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
|
||||||
|
|
||||||
src1_offset_ = this->rng_(33);
|
|
||||||
src1_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
|
||||||
|
|
||||||
T *p_src0;
|
|
||||||
T *p_src1;
|
|
||||||
|
|
||||||
switch (this->rng_(3)) {
|
|
||||||
case 0: // Separate sources
|
|
||||||
p_src0 = src0_;
|
|
||||||
p_src1 = src1_;
|
|
||||||
break;
|
|
||||||
case 1: // src0 == dst
|
|
||||||
p_src0 = dst_tst_;
|
|
||||||
src0_stride_ = dst_stride_;
|
|
||||||
src0_offset_ = dst_offset_;
|
|
||||||
p_src1 = src1_;
|
|
||||||
break;
|
|
||||||
case 2: // src1 == dst
|
|
||||||
p_src0 = src0_;
|
|
||||||
p_src1 = dst_tst_;
|
|
||||||
src1_stride_ = dst_stride_;
|
|
||||||
src1_offset_ = dst_offset_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FAIL();
|
|
||||||
}
|
|
||||||
|
|
||||||
Execute(p_src0, p_src1);
|
|
||||||
|
|
||||||
for (int r = 0 ; r < h_ ; ++r) {
|
|
||||||
for (int c = 0 ; c < w_ ; ++c) {
|
|
||||||
ASSERT_EQ(dst_ref_[dst_offset_ + r * dst_stride_ + c],
|
|
||||||
dst_tst_[dst_offset_ + r * dst_stride_ + c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T dst_ref_[kBufSize];
|
|
||||||
T dst_tst_[kBufSize];
|
|
||||||
size_t dst_stride_;
|
|
||||||
size_t dst_offset_;
|
|
||||||
|
|
||||||
T src0_[kBufSize];
|
|
||||||
size_t src0_stride_;
|
|
||||||
size_t src0_offset_;
|
|
||||||
|
|
||||||
T src1_[kBufSize];
|
|
||||||
size_t src1_stride_;
|
|
||||||
size_t src1_offset_;
|
|
||||||
|
|
||||||
uint8_t mask_[kMaxMaskSize];
|
|
||||||
|
|
||||||
int w_;
|
|
||||||
int h_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 8 bit version
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef void (*F8B)(uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, int h, int w);
|
|
||||||
typedef libvpx_test::FuncParam<F8B> TestFuncs;
|
|
||||||
|
|
||||||
class BlendA64Mask1DTest8B : public BlendA64Mask1DTest<F8B, uint8_t> {
|
|
||||||
protected:
|
|
||||||
void Execute(const uint8_t *p_src0, const uint8_t *p_src1) {
|
|
||||||
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_,
|
|
||||||
p_src0 + src0_offset_, src0_stride_,
|
|
||||||
p_src1 + src1_offset_, src1_stride_, mask_, h_, w_);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
params_.tst_func(dst_tst_ + dst_offset_, dst_stride_,
|
|
||||||
p_src0 + src0_offset_, src0_stride_,
|
|
||||||
p_src1 + src1_offset_, src1_stride_, mask_, h_, w_));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(BlendA64Mask1DTest8B, RandomValues) {
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_.Rand8();
|
|
||||||
dst_tst_[i] = rng_.Rand8();
|
|
||||||
|
|
||||||
src0_[i] = rng_.Rand8();
|
|
||||||
src1_[i] = rng_.Rand8();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlendA64Mask1DTest8B, ExtremeValues) {
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_(2) + 254;
|
|
||||||
dst_tst_[i] = rng_(2) + 254;
|
|
||||||
src0_[i] = rng_(2) + 254;
|
|
||||||
src1_[i] = rng_(2) + 254;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void blend_a64_hmask_ref(
|
|
||||||
uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, int h, int w) {
|
|
||||||
uint8_t mask2d[BlendA64Mask1DTest8B::kMaxMaskSize]
|
|
||||||
[BlendA64Mask1DTest8B::kMaxMaskSize];
|
|
||||||
|
|
||||||
for (int row = 0 ; row < h ; ++row)
|
|
||||||
for (int col = 0 ; col < w ; ++col)
|
|
||||||
mask2d[row][col] = mask[col];
|
|
||||||
|
|
||||||
vpx_blend_a64_mask_c(dst, dst_stride,
|
|
||||||
src0, src0_stride,
|
|
||||||
src1, src1_stride,
|
|
||||||
&mask2d[0][0], BlendA64Mask1DTest8B::kMaxMaskSize,
|
|
||||||
h, w, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void blend_a64_vmask_ref(
|
|
||||||
uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, int h, int w) {
|
|
||||||
uint8_t mask2d[BlendA64Mask1DTest8B::kMaxMaskSize]
|
|
||||||
[BlendA64Mask1DTest8B::kMaxMaskSize];
|
|
||||||
|
|
||||||
for (int row = 0 ; row < h ; ++row)
|
|
||||||
for (int col = 0 ; col < w ; ++col)
|
|
||||||
mask2d[row][col] = mask[row];
|
|
||||||
|
|
||||||
vpx_blend_a64_mask_c(dst, dst_stride,
|
|
||||||
src0, src0_stride,
|
|
||||||
src1, src1_stride,
|
|
||||||
&mask2d[0][0], BlendA64Mask1DTest8B::kMaxMaskSize,
|
|
||||||
h, w, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, BlendA64Mask1DTest8B,
|
|
||||||
::testing::Values(TestFuncs(blend_a64_hmask_ref, vpx_blend_a64_hmask_c),
|
|
||||||
TestFuncs(blend_a64_vmask_ref, vpx_blend_a64_vmask_c)));
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE4_1, BlendA64Mask1DTest8B,
|
|
||||||
::testing::Values(
|
|
||||||
TestFuncs(blend_a64_hmask_ref, vpx_blend_a64_hmask_sse4_1),
|
|
||||||
TestFuncs(blend_a64_vmask_ref, vpx_blend_a64_vmask_sse4_1)));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// High bit-depth version
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef void (*FHBD)(uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, int h, int w, int bd);
|
|
||||||
typedef libvpx_test::FuncParam<FHBD> TestFuncsHBD;
|
|
||||||
|
|
||||||
class BlendA64Mask1DTestHBD : public BlendA64Mask1DTest<FHBD, uint16_t> {
|
|
||||||
protected:
|
|
||||||
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
|
|
||||||
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
|
||||||
mask_, h_, w_, bit_depth_);
|
|
||||||
ASM_REGISTER_STATE_CHECK(params_.tst_func(
|
|
||||||
CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
|
||||||
mask_, h_, w_, bit_depth_));
|
|
||||||
}
|
|
||||||
|
|
||||||
int bit_depth_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(BlendA64Mask1DTestHBD, RandomValues) {
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
|
||||||
switch (rng_(3)) {
|
|
||||||
case 0:
|
|
||||||
bit_depth_ = 8;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bit_depth_ = 10;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bit_depth_ = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int hi = 1 << bit_depth_;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_(hi);
|
|
||||||
dst_tst_[i] = rng_(hi);
|
|
||||||
src0_[i] = rng_(hi);
|
|
||||||
src1_[i] = rng_(hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlendA64Mask1DTestHBD, ExtremeValues) {
|
|
||||||
for (int iter = 0 ; iter < 1000 && !HasFatalFailure(); ++iter) {
|
|
||||||
switch (rng_(3)) {
|
|
||||||
case 0:
|
|
||||||
bit_depth_ = 8;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bit_depth_ = 10;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bit_depth_ = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int hi = 1 << bit_depth_;
|
|
||||||
const int lo = hi - 2;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_(hi - lo) + lo;
|
|
||||||
dst_tst_[i] = rng_(hi - lo) + lo;
|
|
||||||
src0_[i] = rng_(hi - lo) + lo;
|
|
||||||
src1_[i] = rng_(hi - lo) + lo;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void highbd_blend_a64_hmask_ref(
|
|
||||||
uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, int h, int w, int bd) {
|
|
||||||
uint8_t mask2d[BlendA64Mask1DTestHBD::kMaxMaskSize]
|
|
||||||
[BlendA64Mask1DTestHBD::kMaxMaskSize];
|
|
||||||
|
|
||||||
for (int row = 0 ; row < h ; ++row)
|
|
||||||
for (int col = 0 ; col < w ; ++col)
|
|
||||||
mask2d[row][col] = mask[col];
|
|
||||||
|
|
||||||
vpx_highbd_blend_a64_mask_c(dst, dst_stride,
|
|
||||||
src0, src0_stride,
|
|
||||||
src1, src1_stride,
|
|
||||||
&mask2d[0][0],
|
|
||||||
BlendA64Mask1DTestHBD::kMaxMaskSize,
|
|
||||||
h, w, 0, 0, bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void highbd_blend_a64_vmask_ref(
|
|
||||||
uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, int h, int w, int bd) {
|
|
||||||
uint8_t mask2d[BlendA64Mask1DTestHBD::kMaxMaskSize]
|
|
||||||
[BlendA64Mask1DTestHBD::kMaxMaskSize];
|
|
||||||
|
|
||||||
for (int row = 0 ; row < h ; ++row)
|
|
||||||
for (int col = 0 ; col < w ; ++col)
|
|
||||||
mask2d[row][col] = mask[row];
|
|
||||||
|
|
||||||
vpx_highbd_blend_a64_mask_c(dst, dst_stride,
|
|
||||||
src0, src0_stride,
|
|
||||||
src1, src1_stride,
|
|
||||||
&mask2d[0][0],
|
|
||||||
BlendA64Mask1DTestHBD::kMaxMaskSize,
|
|
||||||
h, w, 0, 0, bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, BlendA64Mask1DTestHBD,
|
|
||||||
::testing::Values(
|
|
||||||
TestFuncsHBD(highbd_blend_a64_hmask_ref, vpx_highbd_blend_a64_hmask_c),
|
|
||||||
TestFuncsHBD(highbd_blend_a64_vmask_ref, vpx_highbd_blend_a64_vmask_c)));
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE4_1, BlendA64Mask1DTestHBD,
|
|
||||||
::testing::Values(
|
|
||||||
TestFuncsHBD(highbd_blend_a64_hmask_ref,
|
|
||||||
vpx_highbd_blend_a64_hmask_sse4_1),
|
|
||||||
TestFuncsHBD(highbd_blend_a64_vmask_ref,
|
|
||||||
vpx_highbd_blend_a64_vmask_sse4_1)));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
} // namespace
|
|
||||||
@@ -1,288 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
|
|
||||||
#include "test/function_equivalence_test.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
|
|
||||||
#include "vp10/common/enums.h"
|
|
||||||
|
|
||||||
#include "vpx_dsp/blend.h"
|
|
||||||
|
|
||||||
using libvpx_test::FunctionEquivalenceTest;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
template<typename F, typename T>
|
|
||||||
class BlendA64MaskTest : public FunctionEquivalenceTest<F> {
|
|
||||||
protected:
|
|
||||||
static const int kIterations = 10000;
|
|
||||||
static const int kMaxWidth = MAX_SB_SIZE * 5; // * 5 to cover longer strides
|
|
||||||
static const int kMaxHeight = MAX_SB_SIZE;
|
|
||||||
static const int kBufSize = kMaxWidth * kMaxHeight;
|
|
||||||
static const int kMaxMaskWidth = 2 * MAX_SB_SIZE;
|
|
||||||
static const int kMaxMaskSize = kMaxMaskWidth * kMaxMaskWidth;
|
|
||||||
|
|
||||||
virtual ~BlendA64MaskTest() {}
|
|
||||||
|
|
||||||
virtual void Execute(const T *p_src0, const T *p_src1) = 0;
|
|
||||||
|
|
||||||
void Common() {
|
|
||||||
w_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
|
||||||
h_ = 1 << this->rng_(MAX_SB_SIZE_LOG2 + 1);
|
|
||||||
|
|
||||||
subx_ = this->rng_(2);
|
|
||||||
suby_ = this->rng_(2);
|
|
||||||
|
|
||||||
dst_offset_ = this->rng_(33);
|
|
||||||
dst_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
|
||||||
|
|
||||||
src0_offset_ = this->rng_(33);
|
|
||||||
src0_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
|
||||||
|
|
||||||
src1_offset_ = this->rng_(33);
|
|
||||||
src1_stride_ = this->rng_(kMaxWidth + 1 - w_) + w_;
|
|
||||||
|
|
||||||
mask_stride_ = this->rng_(kMaxWidth + 1 - w_ * (subx_ ? 2 : 1)) +
|
|
||||||
w_ * (subx_ ? 2 : 1);
|
|
||||||
|
|
||||||
T *p_src0;
|
|
||||||
T *p_src1;
|
|
||||||
|
|
||||||
switch (this->rng_(3)) {
|
|
||||||
case 0: // Separate sources
|
|
||||||
p_src0 = src0_;
|
|
||||||
p_src1 = src1_;
|
|
||||||
break;
|
|
||||||
case 1: // src0 == dst
|
|
||||||
p_src0 = dst_tst_;
|
|
||||||
src0_stride_ = dst_stride_;
|
|
||||||
src0_offset_ = dst_offset_;
|
|
||||||
p_src1 = src1_;
|
|
||||||
break;
|
|
||||||
case 2: // src1 == dst
|
|
||||||
p_src0 = src0_;
|
|
||||||
p_src1 = dst_tst_;
|
|
||||||
src1_stride_ = dst_stride_;
|
|
||||||
src1_offset_ = dst_offset_;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FAIL();
|
|
||||||
}
|
|
||||||
|
|
||||||
Execute(p_src0, p_src1);
|
|
||||||
|
|
||||||
for (int r = 0 ; r < h_ ; ++r) {
|
|
||||||
for (int c = 0 ; c < w_ ; ++c) {
|
|
||||||
ASSERT_EQ(dst_ref_[dst_offset_ + r * dst_stride_ + c],
|
|
||||||
dst_tst_[dst_offset_ + r * dst_stride_ + c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T dst_ref_[kBufSize];
|
|
||||||
T dst_tst_[kBufSize];
|
|
||||||
size_t dst_stride_;
|
|
||||||
size_t dst_offset_;
|
|
||||||
|
|
||||||
T src0_[kBufSize];
|
|
||||||
size_t src0_stride_;
|
|
||||||
size_t src0_offset_;
|
|
||||||
|
|
||||||
T src1_[kBufSize];
|
|
||||||
size_t src1_stride_;
|
|
||||||
size_t src1_offset_;
|
|
||||||
|
|
||||||
uint8_t mask_[kMaxMaskSize];
|
|
||||||
size_t mask_stride_;
|
|
||||||
|
|
||||||
int w_;
|
|
||||||
int h_;
|
|
||||||
|
|
||||||
bool suby_;
|
|
||||||
bool subx_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 8 bit version
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef void (*F8B)(uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, uint32_t mask_stride,
|
|
||||||
int h, int w, int suby, int subx);
|
|
||||||
typedef libvpx_test::FuncParam<F8B> TestFuncs;
|
|
||||||
|
|
||||||
class BlendA64MaskTest8B : public BlendA64MaskTest<F8B, uint8_t> {
|
|
||||||
protected:
|
|
||||||
void Execute(const uint8_t *p_src0, const uint8_t *p_src1) {
|
|
||||||
params_.ref_func(dst_ref_ + dst_offset_, dst_stride_,
|
|
||||||
p_src0 + src0_offset_, src0_stride_,
|
|
||||||
p_src1 + src1_offset_, src1_stride_,
|
|
||||||
mask_, kMaxMaskWidth, h_, w_, suby_, subx_);
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
params_.tst_func(dst_tst_ + dst_offset_, dst_stride_,
|
|
||||||
p_src0 + src0_offset_, src0_stride_,
|
|
||||||
p_src1 + src1_offset_, src1_stride_,
|
|
||||||
mask_, kMaxMaskWidth, h_, w_, suby_, subx_));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(BlendA64MaskTest8B, RandomValues) {
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_.Rand8();
|
|
||||||
dst_tst_[i] = rng_.Rand8();
|
|
||||||
|
|
||||||
src0_[i] = rng_.Rand8();
|
|
||||||
src1_[i] = rng_.Rand8();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlendA64MaskTest8B, ExtremeValues) {
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_(2) + 254;
|
|
||||||
dst_tst_[i] = rng_(2) + 254;
|
|
||||||
src0_[i] = rng_(2) + 254;
|
|
||||||
src1_[i] = rng_(2) + 254;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE4_1_C_COMPARE, BlendA64MaskTest8B,
|
|
||||||
::testing::Values(
|
|
||||||
TestFuncs(vpx_blend_a64_mask_c, vpx_blend_a64_mask_sse4_1)));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
// High bit-depth version
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
typedef void (*FHBD)(uint8_t *dst, uint32_t dst_stride,
|
|
||||||
const uint8_t *src0, uint32_t src0_stride,
|
|
||||||
const uint8_t *src1, uint32_t src1_stride,
|
|
||||||
const uint8_t *mask, uint32_t mask_stride,
|
|
||||||
int h, int w, int suby, int subx, int bd);
|
|
||||||
typedef libvpx_test::FuncParam<FHBD> TestFuncsHBD;
|
|
||||||
|
|
||||||
class BlendA64MaskTestHBD : public BlendA64MaskTest<FHBD, uint16_t> {
|
|
||||||
protected:
|
|
||||||
void Execute(const uint16_t *p_src0, const uint16_t *p_src1) {
|
|
||||||
params_.ref_func(CONVERT_TO_BYTEPTR(dst_ref_ + dst_offset_), dst_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
|
||||||
mask_, kMaxMaskWidth, h_, w_, suby_, subx_, bit_depth_);
|
|
||||||
ASM_REGISTER_STATE_CHECK(params_.tst_func(
|
|
||||||
CONVERT_TO_BYTEPTR(dst_tst_ + dst_offset_), dst_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src0 + src0_offset_), src0_stride_,
|
|
||||||
CONVERT_TO_BYTEPTR(p_src1 + src1_offset_), src1_stride_,
|
|
||||||
mask_, kMaxMaskWidth, h_, w_, suby_, subx_, bit_depth_));
|
|
||||||
}
|
|
||||||
|
|
||||||
int bit_depth_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(BlendA64MaskTestHBD, RandomValues) {
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure(); ++iter) {
|
|
||||||
switch (rng_(3)) {
|
|
||||||
case 0:
|
|
||||||
bit_depth_ = 8;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bit_depth_ = 10;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bit_depth_ = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int hi = 1 << bit_depth_;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_(hi);
|
|
||||||
dst_tst_[i] = rng_(hi);
|
|
||||||
src0_[i] = rng_(hi);
|
|
||||||
src1_[i] = rng_(hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(VPX_BLEND_A64_MAX_ALPHA + 1);
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(BlendA64MaskTestHBD, ExtremeValues) {
|
|
||||||
for (int iter = 0 ; iter < 1000 && !HasFatalFailure(); ++iter) {
|
|
||||||
switch (rng_(3)) {
|
|
||||||
case 0:
|
|
||||||
bit_depth_ = 8;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bit_depth_ = 10;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bit_depth_ = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int hi = 1 << bit_depth_;
|
|
||||||
const int lo = hi - 2;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kBufSize ; ++i) {
|
|
||||||
dst_ref_[i] = rng_(hi - lo) + lo;
|
|
||||||
dst_tst_[i] = rng_(hi - lo) + lo;
|
|
||||||
src0_[i] = rng_(hi - lo) + lo;
|
|
||||||
src1_[i] = rng_(hi - lo) + lo;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < kMaxMaskSize ; ++i)
|
|
||||||
mask_[i] = rng_(2) + VPX_BLEND_A64_MAX_ALPHA - 1;
|
|
||||||
|
|
||||||
Common();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSE4_1_C_COMPARE, BlendA64MaskTestHBD,
|
|
||||||
::testing::Values(
|
|
||||||
TestFuncsHBD(vpx_highbd_blend_a64_mask_c,
|
|
||||||
vpx_highbd_blend_a64_mask_sse4_1)));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
} // namespace
|
|
||||||
@@ -52,7 +52,7 @@ TEST_P(BordersTest, TestEncodeHighBitrate) {
|
|||||||
// extend into the border and test the border condition.
|
// extend into the border and test the border condition.
|
||||||
cfg_.g_lag_in_frames = 25;
|
cfg_.g_lag_in_frames = 25;
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||||
cfg_.rc_target_bitrate = 2000;
|
cfg_.rc_target_bitrate = 2000;
|
||||||
cfg_.rc_max_quantizer = 10;
|
cfg_.rc_max_quantizer = 10;
|
||||||
|
|
||||||
@@ -78,6 +78,6 @@ TEST_P(BordersTest, TestLowBitrate) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
|
VP9_INSTANTIATE_TEST_CASE(BordersTest, ::testing::Values(
|
||||||
::libvpx_test::kTwoPassGood));
|
::libvpx_test::kTwoPassGood));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
189
test/byte_alignment_test.cc
Normal file
189
test/byte_alignment_test.cc
Normal 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
|
||||||
@@ -13,10 +13,10 @@
|
|||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "vpx/vpx_decoder.h"
|
#include "vpx/vpx_decoder.h"
|
||||||
#include "vpx/vpx_encoder.h"
|
#include "vpx/vpx_encoder.h"
|
||||||
#if CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_VP10_DECODER
|
#if CONFIG_VP8_DECODER || CONFIG_VP9_DECODER
|
||||||
#include "vpx/vp8dx.h"
|
#include "vpx/vp8dx.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -69,47 +69,47 @@ class CodecTestWith3Params : public ::testing::TestWithParam<
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VP10 Codec Definitions
|
* VP8 Codec Definitions
|
||||||
*/
|
*/
|
||||||
#if CONFIG_VP10
|
#if CONFIG_VP8
|
||||||
class VP10Decoder : public Decoder {
|
class VP8Decoder : public Decoder {
|
||||||
public:
|
public:
|
||||||
VP10Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
||||||
: Decoder(cfg, deadline) {}
|
: Decoder(cfg, deadline) {}
|
||||||
|
|
||||||
VP10Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
|
||||||
unsigned long deadline) // NOLINT
|
unsigned long deadline) // NOLINT
|
||||||
: Decoder(cfg, flag, deadline) {}
|
: Decoder(cfg, flag, deadline) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
#if CONFIG_VP10_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
return &vpx_codec_vp10_dx_algo;
|
return &vpx_codec_vp8_dx_algo;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VP10Encoder : public Encoder {
|
class VP8Encoder : public Encoder {
|
||||||
public:
|
public:
|
||||||
VP10Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
VP8Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
||||||
const unsigned long init_flags, TwopassStatsStore *stats)
|
const unsigned long init_flags, TwopassStatsStore *stats)
|
||||||
: Encoder(cfg, deadline, init_flags, stats) {}
|
: Encoder(cfg, deadline, init_flags, stats) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
#if CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return &vpx_codec_vp10_cx_algo;
|
return &vpx_codec_vp8_cx_algo;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VP10CodecFactory : public CodecFactory {
|
class VP8CodecFactory : public CodecFactory {
|
||||||
public:
|
public:
|
||||||
VP10CodecFactory() : CodecFactory() {}
|
VP8CodecFactory() : CodecFactory() {}
|
||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
unsigned long deadline) const {
|
unsigned long deadline) const {
|
||||||
@@ -119,8 +119,8 @@ class VP10CodecFactory : public CodecFactory {
|
|||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
const vpx_codec_flags_t flags,
|
const vpx_codec_flags_t flags,
|
||||||
unsigned long deadline) const { // NOLINT
|
unsigned long deadline) const { // NOLINT
|
||||||
#if CONFIG_VP10_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
return new VP10Decoder(cfg, flags, deadline);
|
return new VP8Decoder(cfg, flags, deadline);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
@@ -130,8 +130,8 @@ class VP10CodecFactory : public CodecFactory {
|
|||||||
unsigned long deadline,
|
unsigned long deadline,
|
||||||
const unsigned long init_flags,
|
const unsigned long init_flags,
|
||||||
TwopassStatsStore *stats) const {
|
TwopassStatsStore *stats) const {
|
||||||
#if CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return new VP10Encoder(cfg, deadline, init_flags, stats);
|
return new VP8Encoder(cfg, deadline, init_flags, stats);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
@@ -139,25 +139,119 @@ class VP10CodecFactory : public CodecFactory {
|
|||||||
|
|
||||||
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
||||||
int usage) const {
|
int usage) const {
|
||||||
#if CONFIG_VP10_ENCODER
|
#if CONFIG_VP8_ENCODER
|
||||||
return vpx_codec_enc_config_default(&vpx_codec_vp10_cx_algo, cfg, usage);
|
return vpx_codec_enc_config_default(&vpx_codec_vp8_cx_algo, cfg, usage);
|
||||||
#else
|
#else
|
||||||
return VPX_CODEC_INCAPABLE;
|
return VPX_CODEC_INCAPABLE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const libvpx_test::VP10CodecFactory kVP10;
|
const libvpx_test::VP8CodecFactory kVP8;
|
||||||
|
|
||||||
#define VP10_INSTANTIATE_TEST_CASE(test, ...)\
|
#define VP8_INSTANTIATE_TEST_CASE(test, ...)\
|
||||||
INSTANTIATE_TEST_CASE_P(VP10, test, \
|
INSTANTIATE_TEST_CASE_P(VP8, test, \
|
||||||
::testing::Combine( \
|
::testing::Combine( \
|
||||||
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
|
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
|
||||||
&libvpx_test::kVP10)), \
|
&libvpx_test::kVP8)), \
|
||||||
__VA_ARGS__))
|
__VA_ARGS__))
|
||||||
#else
|
#else
|
||||||
#define VP10_INSTANTIATE_TEST_CASE(test, ...)
|
#define VP8_INSTANTIATE_TEST_CASE(test, ...)
|
||||||
#endif // CONFIG_VP10
|
#endif // CONFIG_VP8
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VP9 Codec Definitions
|
||||||
|
*/
|
||||||
|
#if CONFIG_VP9
|
||||||
|
class VP9Decoder : public Decoder {
|
||||||
|
public:
|
||||||
|
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
|
||||||
|
return &vpx_codec_vp9_dx_algo;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VP9Encoder : public Encoder {
|
||||||
|
public:
|
||||||
|
VP9Encoder(vpx_codec_enc_cfg_t cfg, unsigned long deadline,
|
||||||
|
const unsigned long init_flags, TwopassStatsStore *stats)
|
||||||
|
: Encoder(cfg, deadline, init_flags, stats) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
|
#if CONFIG_VP9_ENCODER
|
||||||
|
return &vpx_codec_vp9_cx_algo;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class VP9CodecFactory : public CodecFactory {
|
||||||
|
public:
|
||||||
|
VP9CodecFactory() : 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, flags, deadline);
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
||||||
|
unsigned long deadline,
|
||||||
|
const unsigned long init_flags,
|
||||||
|
TwopassStatsStore *stats) const {
|
||||||
|
#if CONFIG_VP9_ENCODER
|
||||||
|
return new VP9Encoder(cfg, deadline, init_flags, stats);
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual vpx_codec_err_t DefaultEncoderConfig(vpx_codec_enc_cfg_t *cfg,
|
||||||
|
int usage) const {
|
||||||
|
#if CONFIG_VP9_ENCODER
|
||||||
|
return vpx_codec_enc_config_default(&vpx_codec_vp9_cx_algo, cfg, usage);
|
||||||
|
#else
|
||||||
|
return VPX_CODEC_INCAPABLE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const libvpx_test::VP9CodecFactory kVP9;
|
||||||
|
|
||||||
|
#define VP9_INSTANTIATE_TEST_CASE(test, ...)\
|
||||||
|
INSTANTIATE_TEST_CASE_P(VP9, test, \
|
||||||
|
::testing::Combine( \
|
||||||
|
::testing::Values(static_cast<const libvpx_test::CodecFactory*>( \
|
||||||
|
&libvpx_test::kVP9)), \
|
||||||
|
__VA_ARGS__))
|
||||||
|
#else
|
||||||
|
#define VP9_INSTANTIATE_TEST_CASE(test, ...)
|
||||||
|
#endif // CONFIG_VP9
|
||||||
|
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|
||||||
#endif // TEST_CODEC_FACTORY_H_
|
#endif // TEST_CODEC_FACTORY_H_
|
||||||
|
|||||||
60
test/config_test.cc
Normal file
60
test/config_test.cc
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#include "test/video_source.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class ConfigTest : public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
|
protected:
|
||||||
|
ConfigTest() : EncoderTest(GET_PARAM(0)),
|
||||||
|
frame_count_in_(0), frame_count_out_(0), frame_count_max_(0) {}
|
||||||
|
virtual ~ConfigTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
SetMode(GET_PARAM(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||||
|
frame_count_in_ = 0;
|
||||||
|
frame_count_out_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource* /*video*/) {
|
||||||
|
++frame_count_in_;
|
||||||
|
abort_ |= (frame_count_in_ >= frame_count_max_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t* /*pkt*/) {
|
||||||
|
++frame_count_out_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int frame_count_in_;
|
||||||
|
unsigned int frame_count_out_;
|
||||||
|
unsigned int frame_count_max_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(ConfigTest, LagIsDisabled) {
|
||||||
|
frame_count_max_ = 2;
|
||||||
|
cfg_.g_lag_in_frames = 15;
|
||||||
|
|
||||||
|
libvpx_test::DummyVideoSource video;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
EXPECT_EQ(frame_count_in_, frame_count_out_);
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(ConfigTest, ONE_PASS_TEST_MODES);
|
||||||
|
} // namespace
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,7 @@ class CpuSpeedTest
|
|||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
encoding_mode_(GET_PARAM(1)),
|
encoding_mode_(GET_PARAM(1)),
|
||||||
set_cpu_used_(GET_PARAM(2)),
|
set_cpu_used_(GET_PARAM(2)),
|
||||||
min_psnr_(kMaxPSNR),
|
min_psnr_(kMaxPSNR) {}
|
||||||
tune_content_(VPX_CONTENT_DEFAULT) {}
|
|
||||||
virtual ~CpuSpeedTest() {}
|
virtual ~CpuSpeedTest() {}
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
@@ -50,7 +49,6 @@ class CpuSpeedTest
|
|||||||
::libvpx_test::Encoder *encoder) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
if (video->frame() == 1) {
|
if (video->frame() == 1) {
|
||||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
|
|
||||||
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
if (encoding_mode_ != ::libvpx_test::kRealTime) {
|
||||||
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1);
|
||||||
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7);
|
||||||
@@ -68,7 +66,6 @@ class CpuSpeedTest
|
|||||||
::libvpx_test::TestMode encoding_mode_;
|
::libvpx_test::TestMode encoding_mode_;
|
||||||
int set_cpu_used_;
|
int set_cpu_used_;
|
||||||
double min_psnr_;
|
double min_psnr_;
|
||||||
int tune_content_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(CpuSpeedTest, TestQ0) {
|
TEST_P(CpuSpeedTest, TestQ0) {
|
||||||
@@ -77,13 +74,13 @@ TEST_P(CpuSpeedTest, TestQ0) {
|
|||||||
// the encoder to producing lots of big partitions which will likely
|
// the encoder to producing lots of big partitions which will likely
|
||||||
// extend into the border and test the border condition.
|
// extend into the border and test the border condition.
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||||
cfg_.rc_target_bitrate = 400;
|
cfg_.rc_target_bitrate = 400;
|
||||||
cfg_.rc_max_quantizer = 0;
|
cfg_.rc_max_quantizer = 0;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
10);
|
20);
|
||||||
|
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
|
||||||
@@ -92,10 +89,10 @@ TEST_P(CpuSpeedTest, TestQ0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
||||||
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 10);
|
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 25);
|
||||||
cfg_.g_timebase = video.timebase();
|
cfg_.g_timebase = video.timebase();
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||||
cfg_.rc_target_bitrate = 400;
|
cfg_.rc_target_bitrate = 400;
|
||||||
cfg_.rc_max_quantizer = 0;
|
cfg_.rc_max_quantizer = 0;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
@@ -106,34 +103,19 @@ TEST_P(CpuSpeedTest, TestScreencastQ0) {
|
|||||||
EXPECT_GE(min_psnr_, kMaxPSNR);
|
EXPECT_GE(min_psnr_, kMaxPSNR);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(CpuSpeedTest, TestTuneScreen) {
|
|
||||||
::libvpx_test::Y4mVideoSource video("screendata.y4m", 0, 10);
|
|
||||||
cfg_.g_timebase = video.timebase();
|
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
|
||||||
cfg_.rc_target_bitrate = 2000;
|
|
||||||
cfg_.rc_max_quantizer = 63;
|
|
||||||
cfg_.rc_min_quantizer = 0;
|
|
||||||
tune_content_ = VPX_CONTENT_SCREEN;
|
|
||||||
|
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CpuSpeedTest, TestEncodeHighBitrate) {
|
TEST_P(CpuSpeedTest, TestEncodeHighBitrate) {
|
||||||
// Validate that this non multiple of 64 wide clip encodes and decodes
|
// Validate that this non multiple of 64 wide clip encodes and decodes
|
||||||
// without a mismatch when passing in a very low max q. This pushes
|
// without a mismatch when passing in a very low max q. This pushes
|
||||||
// the encoder to producing lots of big partitions which will likely
|
// the encoder to producing lots of big partitions which will likely
|
||||||
// extend into the border and test the border condition.
|
// extend into the border and test the border condition.
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||||
cfg_.rc_target_bitrate = 12000;
|
cfg_.rc_target_bitrate = 12000;
|
||||||
cfg_.rc_max_quantizer = 10;
|
cfg_.rc_max_quantizer = 10;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_min_quantizer = 0;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
10);
|
20);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
@@ -143,18 +125,19 @@ TEST_P(CpuSpeedTest, TestLowBitrate) {
|
|||||||
// when passing in a very high min q. This pushes the encoder to producing
|
// when passing in a very high min q. This pushes the encoder to producing
|
||||||
// lots of small partitions which might will test the other condition.
|
// lots of small partitions which might will test the other condition.
|
||||||
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
cfg_.rc_2pass_vbr_minsection_pct = 5;
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
cfg_.rc_2pass_vbr_minsection_pct = 2000;
|
||||||
cfg_.rc_target_bitrate = 200;
|
cfg_.rc_target_bitrate = 200;
|
||||||
cfg_.rc_min_quantizer = 40;
|
cfg_.rc_min_quantizer = 40;
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
||||||
10);
|
20);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
CpuSpeedTest,
|
CpuSpeedTest,
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood,
|
||||||
::testing::Range(0, 3));
|
::libvpx_test::kRealTime),
|
||||||
|
::testing::Range(0, 9));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
134
test/cq_test.cc
Normal file
134
test/cq_test.cc
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* 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 <cmath>
|
||||||
|
#include <map>
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/i420_video_source.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// CQ level range: [kCQLevelMin, kCQLevelMax).
|
||||||
|
const int kCQLevelMin = 4;
|
||||||
|
const int kCQLevelMax = 63;
|
||||||
|
const int kCQLevelStep = 8;
|
||||||
|
const unsigned int kCQTargetBitrate = 2000;
|
||||||
|
|
||||||
|
class CQTest : public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<int> {
|
||||||
|
public:
|
||||||
|
// maps the cqlevel to the bitrate produced.
|
||||||
|
typedef std::map<int, uint32_t> BitrateMap;
|
||||||
|
|
||||||
|
static void SetUpTestCase() {
|
||||||
|
bitrates_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TearDownTestCase() {
|
||||||
|
ASSERT_TRUE(!HasFailure())
|
||||||
|
<< "skipping bitrate validation due to earlier failure.";
|
||||||
|
uint32_t prev_actual_bitrate = kCQTargetBitrate;
|
||||||
|
for (BitrateMap::const_iterator iter = bitrates_.begin();
|
||||||
|
iter != bitrates_.end(); ++iter) {
|
||||||
|
const uint32_t cq_actual_bitrate = iter->second;
|
||||||
|
EXPECT_LE(cq_actual_bitrate, prev_actual_bitrate)
|
||||||
|
<< "cq_level: " << iter->first
|
||||||
|
<< ", bitrate should decrease with increase in CQ level.";
|
||||||
|
prev_actual_bitrate = cq_actual_bitrate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CQTest() : EncoderTest(GET_PARAM(0)), cq_level_(GET_PARAM(1)) {
|
||||||
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CQTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
SetMode(libvpx_test::kTwoPassGood);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||||
|
file_size_ = 0;
|
||||||
|
psnr_ = 0.0;
|
||||||
|
n_frames_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||||
|
libvpx_test::Encoder *encoder) {
|
||||||
|
if (video->frame() == 1) {
|
||||||
|
if (cfg_.rc_end_usage == VPX_CQ) {
|
||||||
|
encoder->Control(VP8E_SET_CQ_LEVEL, cq_level_);
|
||||||
|
}
|
||||||
|
encoder->Control(VP8E_SET_CPUUSED, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
|
psnr_ += pow(10.0, pkt->data.psnr.psnr[0] / 10.0);
|
||||||
|
n_frames_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
|
file_size_ += pkt->data.frame.sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
double GetLinearPSNROverBitrate() const {
|
||||||
|
double avg_psnr = log10(psnr_ / n_frames_) * 10.0;
|
||||||
|
return pow(10.0, avg_psnr / 10.0) / file_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cq_level() const { return cq_level_; }
|
||||||
|
size_t file_size() const { return file_size_; }
|
||||||
|
int n_frames() const { return n_frames_; }
|
||||||
|
|
||||||
|
static BitrateMap bitrates_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int cq_level_;
|
||||||
|
size_t file_size_;
|
||||||
|
double psnr_;
|
||||||
|
int n_frames_;
|
||||||
|
};
|
||||||
|
|
||||||
|
CQTest::BitrateMap CQTest::bitrates_;
|
||||||
|
|
||||||
|
TEST_P(CQTest, LinearPSNRIsHigherForCQLevel) {
|
||||||
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
|
cfg_.g_timebase = timebase;
|
||||||
|
cfg_.rc_target_bitrate = kCQTargetBitrate;
|
||||||
|
cfg_.g_lag_in_frames = 25;
|
||||||
|
|
||||||
|
cfg_.rc_end_usage = VPX_CQ;
|
||||||
|
libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
timebase.den, timebase.num, 0, 30);
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
const double cq_psnr_lin = GetLinearPSNROverBitrate();
|
||||||
|
const unsigned int cq_actual_bitrate =
|
||||||
|
static_cast<unsigned int>(file_size()) * 8 * 30 / (n_frames() * 1000);
|
||||||
|
EXPECT_LE(cq_actual_bitrate, kCQTargetBitrate);
|
||||||
|
bitrates_[cq_level()] = cq_actual_bitrate;
|
||||||
|
|
||||||
|
// try targeting the approximate same bitrate with VBR mode
|
||||||
|
cfg_.rc_end_usage = VPX_VBR;
|
||||||
|
cfg_.rc_target_bitrate = cq_actual_bitrate;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
const double vbr_psnr_lin = GetLinearPSNROverBitrate();
|
||||||
|
EXPECT_GE(cq_psnr_lin, vbr_psnr_lin);
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(CQTest,
|
||||||
|
::testing::Range(kCQLevelMin, kCQLevelMax,
|
||||||
|
kCQLevelStep));
|
||||||
|
} // namespace
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
##
|
|
||||||
## 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.
|
|
||||||
##
|
|
||||||
## This file tests the libvpx cx_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).
|
|
||||||
##
|
|
||||||
. $(dirname $0)/tools_common.sh
|
|
||||||
|
|
||||||
# Environment check: $YUV_RAW_INPUT is required.
|
|
||||||
cx_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.
|
|
||||||
vpx_set_ref() {
|
|
||||||
local codec="$1"
|
|
||||||
local encoder="${LIBVPX_BIN_PATH}/vpxcx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
|
||||||
|
|
||||||
if [ "$codec" = "vp8" ]; then
|
|
||||||
encoder="${LIBVPX_BIN_PATH}/vp8cx_set_ref${VPX_TEST_EXE_SUFFIX}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local output_file="${VPX_TEST_OUTPUT_DIR}/${codec}cx_set_ref_${codec}.ivf"
|
|
||||||
local ref_frame_num=90
|
|
||||||
|
|
||||||
if [ ! -x "${encoder}" ]; then
|
|
||||||
elog "${encoder} does not exist or is not executable."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$codec" = "vp8" ]; then
|
|
||||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${YUV_RAW_INPUT_WIDTH}" \
|
|
||||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
|
||||||
"${ref_frame_num}" ${devnull}
|
|
||||||
else
|
|
||||||
eval "${VPX_TEST_PREFIX}" "${encoder}" "${codec}" "${YUV_RAW_INPUT_WIDTH}" \
|
|
||||||
"${YUV_RAW_INPUT_HEIGHT}" "${YUV_RAW_INPUT}" "${output_file}" \
|
|
||||||
"${ref_frame_num}" ${devnull}
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -e "${output_file}" ] || return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cx_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
|
|
||||||
}
|
|
||||||
|
|
||||||
cx_set_ref_vp10() {
|
|
||||||
if [ "$(vp10_encode_available)" = "yes" ]; then
|
|
||||||
vpx_set_ref vp10 || return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cx_set_ref_tests="cx_set_ref_vp8 cx_set_ref_vp9 cx_set_ref_vp10"
|
|
||||||
|
|
||||||
run_tests cx_set_ref_verify_environment "${cx_set_ref_tests}"
|
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
#include "test/i420_video_source.h"
|
#include "test/i420_video_source.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "test/y4m_video_source.h"
|
#include "test/y4m_video_source.h"
|
||||||
#include "vpx/vpx_codec.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -90,7 +89,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
<< pkt->data.frame.pts;
|
<< pkt->data.frame.pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||||
|
|
||||||
// Subtract from the buffer the bits associated with a played back frame.
|
// Subtract from the buffer the bits associated with a played back frame.
|
||||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||||
@@ -135,12 +134,65 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
double duration_;
|
double duration_;
|
||||||
double file_datarate_;
|
double file_datarate_;
|
||||||
double effective_datarate_;
|
double effective_datarate_;
|
||||||
int64_t bits_in_last_frame_;
|
size_t bits_in_last_frame_;
|
||||||
int denoiser_on_;
|
int denoiser_on_;
|
||||||
int denoiser_offon_test_;
|
int denoiser_offon_test_;
|
||||||
int denoiser_offon_period_;
|
int denoiser_offon_period_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if CONFIG_TEMPORAL_DENOISING
|
||||||
|
// Check basic datarate targeting, for a single bitrate, but loop over the
|
||||||
|
// various denoiser settings.
|
||||||
|
TEST_P(DatarateTestLarge, DenoiserLevels) {
|
||||||
|
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, 140);
|
||||||
|
for (int j = 1; j < 5; ++j) {
|
||||||
|
// Run over the denoiser levels.
|
||||||
|
// For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
|
||||||
|
// refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
|
||||||
|
// denoiserOnAggressive, and denoiserOnAdaptive.
|
||||||
|
// For the spatial denoiser (if !CONFIG_TEMPORAL_DENOISING), the level j
|
||||||
|
// refers to the blur thresholds: 20, 40, 60 80.
|
||||||
|
// The j = 0 case (denoiser off) is covered in the tests below.
|
||||||
|
denoiser_on_ = j;
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
|
ResetModel();
|
||||||
|
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!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
TEST_P(DatarateTestLarge, BasicBufferModel) {
|
||||||
denoiser_on_ = 0;
|
denoiser_on_ = 0;
|
||||||
@@ -319,7 +371,9 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
encoder->Control(VP9E_SET_SVC, 1);
|
encoder->Control(VP9E_SET_SVC, 1);
|
||||||
}
|
}
|
||||||
vpx_svc_layer_id_t layer_id;
|
vpx_svc_layer_id_t layer_id;
|
||||||
|
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
|
||||||
layer_id.spatial_layer_id = 0;
|
layer_id.spatial_layer_id = 0;
|
||||||
|
#endif
|
||||||
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
||||||
layer_id.temporal_layer_id = SetLayerId(video->frame(),
|
layer_id.temporal_layer_id = SetLayerId(video->frame(),
|
||||||
cfg_.ts_number_layers);
|
cfg_.ts_number_layers);
|
||||||
@@ -397,28 +451,7 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
|||||||
int denoiser_offon_period_;
|
int denoiser_offon_period_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check basic rate targeting for VBR mode.
|
// Check basic rate targeting,
|
||||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBR) {
|
|
||||||
cfg_.rc_min_quantizer = 0;
|
|
||||||
cfg_.rc_max_quantizer = 63;
|
|
||||||
cfg_.g_error_resilient = 0;
|
|
||||||
cfg_.rc_end_usage = VPX_VBR;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 300);
|
|
||||||
for (int i = 400; i <= 800; i += 400) {
|
|
||||||
cfg_.rc_target_bitrate = i;
|
|
||||||
ResetModel();
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
|
||||||
<< " The datarate for the file is lower than target by too much!";
|
|
||||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
|
||||||
<< " The datarate for the file is greater than target by too much!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check basic rate targeting for CBR,
|
|
||||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
@@ -442,7 +475,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check basic rate targeting for CBR.
|
// Check basic rate targeting,
|
||||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
||||||
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
|
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
|
||||||
|
|
||||||
@@ -487,9 +520,6 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
|
|||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.rc_target_bitrate = 200;
|
cfg_.rc_target_bitrate = 200;
|
||||||
cfg_.g_lag_in_frames = 0;
|
cfg_.g_lag_in_frames = 0;
|
||||||
// TODO(marpan): Investigate datarate target failures with a smaller keyframe
|
|
||||||
// interval (128).
|
|
||||||
cfg_.kf_max_dist = 9999;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 140);
|
30, 1, 0, 140);
|
||||||
@@ -509,7 +539,7 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
|
|||||||
<< " The first dropped frame for drop_thresh " << i
|
<< " The first dropped frame for drop_thresh " << i
|
||||||
<< " > first dropped frame for drop_thresh "
|
<< " > first dropped frame for drop_thresh "
|
||||||
<< i - kDropFrameThreshTestStep;
|
<< i - kDropFrameThreshTestStep;
|
||||||
ASSERT_GE(num_drops_, last_num_drops * 0.85)
|
ASSERT_GE(num_drops_, last_num_drops * 0.90)
|
||||||
<< " The number of dropped frames for drop_thresh " << i
|
<< " The number of dropped frames for drop_thresh " << i
|
||||||
<< " < number of dropped frames for drop_thresh "
|
<< " < number of dropped frames for drop_thresh "
|
||||||
<< i - kDropFrameThreshTestStep;
|
<< i - kDropFrameThreshTestStep;
|
||||||
@@ -535,8 +565,6 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
|||||||
cfg_.ts_rate_decimator[0] = 2;
|
cfg_.ts_rate_decimator[0] = 2;
|
||||||
cfg_.ts_rate_decimator[1] = 1;
|
cfg_.ts_rate_decimator[1] = 1;
|
||||||
|
|
||||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
|
||||||
|
|
||||||
if (deadline_ == VPX_DL_REALTIME)
|
if (deadline_ == VPX_DL_REALTIME)
|
||||||
cfg_.g_error_resilient = 1;
|
cfg_.g_error_resilient = 1;
|
||||||
|
|
||||||
@@ -546,14 +574,14 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
|||||||
cfg_.rc_target_bitrate = i;
|
cfg_.rc_target_bitrate = i;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
// 60-40 bitrate allocation for 2 temporal layers.
|
// 60-40 bitrate allocation for 2 temporal layers.
|
||||||
cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
|
cfg_.ts_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
|
||||||
cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
|
cfg_.ts_target_bitrate[1] = cfg_.rc_target_bitrate;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: " << j;
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: " << j;
|
||||||
}
|
}
|
||||||
@@ -578,27 +606,25 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
|
|||||||
cfg_.ts_rate_decimator[1] = 2;
|
cfg_.ts_rate_decimator[1] = 2;
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
cfg_.ts_rate_decimator[2] = 1;
|
||||||
|
|
||||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 200);
|
30, 1, 0, 200);
|
||||||
for (int i = 200; i <= 800; i += 200) {
|
for (int i = 200; i <= 800; i += 200) {
|
||||||
cfg_.rc_target_bitrate = i;
|
cfg_.rc_target_bitrate = i;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
// 40-20-40 bitrate allocation for 3 temporal layers.
|
// 40-20-40 bitrate allocation for 3 temporal layers.
|
||||||
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
||||||
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
||||||
cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
|
cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
// TODO(yaowu): Work out more stable rc control strategy and
|
// TODO(yaowu): Work out more stable rc control strategy and
|
||||||
// Adjust the thresholds to be tighter than .75.
|
// Adjust the thresholds to be tighter than .75.
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
|
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.75)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: " << j;
|
||||||
// TODO(yaowu): Work out more stable rc control strategy and
|
// TODO(yaowu): Work out more stable rc control strategy and
|
||||||
// Adjust the thresholds to be tighter than 1.25.
|
// Adjust the thresholds to be tighter than 1.25.
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
|
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.25)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: " << j;
|
||||||
}
|
}
|
||||||
@@ -626,22 +652,20 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
|
|||||||
cfg_.ts_rate_decimator[1] = 2;
|
cfg_.ts_rate_decimator[1] = 2;
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
cfg_.ts_rate_decimator[2] = 1;
|
||||||
|
|
||||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
|
||||||
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 200);
|
30, 1, 0, 200);
|
||||||
cfg_.rc_target_bitrate = 200;
|
cfg_.rc_target_bitrate = 200;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
// 40-20-40 bitrate allocation for 3 temporal layers.
|
// 40-20-40 bitrate allocation for 3 temporal layers.
|
||||||
cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
cfg_.ts_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
|
||||||
cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
cfg_.ts_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
|
||||||
cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
|
cfg_.ts_target_bitrate[2] = cfg_.rc_target_bitrate;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
ASSERT_GE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 0.85)
|
||||||
<< " The datarate for the file is lower than target by too much, "
|
<< " The datarate for the file is lower than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: " << j;
|
||||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
ASSERT_LE(effective_datarate_[j], cfg_.ts_target_bitrate[j] * 1.15)
|
||||||
<< " The datarate for the file is greater than target by too much, "
|
<< " The datarate for the file is greater than target by too much, "
|
||||||
"for layer: " << j;
|
"for layer: " << j;
|
||||||
// Expect some frame drops in this test: for this 200 frames test,
|
// Expect some frame drops in this test: for this 200 frames test,
|
||||||
@@ -651,388 +675,71 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
// Check basic datarate targeting, for a single bitrate, when denoiser is on.
|
||||||
public:
|
TEST_P(DatarateTestVP9Large, DenoiserLevels) {
|
||||||
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {}
|
|
||||||
virtual ~DatarateOnePassCbrSvc() {}
|
|
||||||
protected:
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(GET_PARAM(1));
|
|
||||||
speed_setting_ = GET_PARAM(2);
|
|
||||||
ResetModel();
|
|
||||||
}
|
|
||||||
virtual void ResetModel() {
|
|
||||||
last_pts_ = 0;
|
|
||||||
bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
|
|
||||||
frame_number_ = 0;
|
|
||||||
first_drop_ = 0;
|
|
||||||
bits_total_ = 0;
|
|
||||||
duration_ = 0.0;
|
|
||||||
mismatch_psnr_ = 0.0;
|
|
||||||
mismatch_nframes_ = 0;
|
|
||||||
}
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
|
||||||
}
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
|
||||||
::libvpx_test::Encoder *encoder) {
|
|
||||||
if (video->frame() == 0) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < VPX_MAX_LAYERS; ++i) {
|
|
||||||
svc_params_.max_quantizers[i] = 63;
|
|
||||||
svc_params_.min_quantizers[i] = 0;
|
|
||||||
}
|
|
||||||
encoder->Control(VP9E_SET_SVC, 1);
|
|
||||||
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
|
|
||||||
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
|
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
|
|
||||||
}
|
|
||||||
const vpx_rational_t tb = video->timebase();
|
|
||||||
timebase_ = static_cast<double>(tb.num) / tb.den;
|
|
||||||
duration_ = 0;
|
|
||||||
}
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
|
||||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
|
||||||
if (last_pts_ == 0)
|
|
||||||
duration = 1;
|
|
||||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
|
||||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
|
||||||
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
|
|
||||||
? true: false;
|
|
||||||
if (!key_frame) {
|
|
||||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
|
||||||
<< pkt->data.frame.pts;
|
|
||||||
}
|
|
||||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
|
||||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
|
||||||
bits_total_ += frame_size_in_bits;
|
|
||||||
if (!first_drop_ && duration > 1)
|
|
||||||
first_drop_ = last_pts_ + 1;
|
|
||||||
last_pts_ = pkt->data.frame.pts;
|
|
||||||
bits_in_last_frame_ = frame_size_in_bits;
|
|
||||||
++frame_number_;
|
|
||||||
}
|
|
||||||
virtual void EndPassHook(void) {
|
|
||||||
if (bits_total_) {
|
|
||||||
const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
|
|
||||||
duration_ = (last_pts_ + 1) * timebase_;
|
|
||||||
file_datarate_ = file_size_in_kb / duration_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void MismatchHook(const vpx_image_t *img1,
|
|
||||||
const vpx_image_t *img2) {
|
|
||||||
double mismatch_psnr = compute_psnr(img1, img2);
|
|
||||||
mismatch_psnr_ += mismatch_psnr;
|
|
||||||
++mismatch_nframes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int GetMismatchFrames() {
|
|
||||||
return mismatch_nframes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_codec_pts_t last_pts_;
|
|
||||||
int64_t bits_in_buffer_model_;
|
|
||||||
double timebase_;
|
|
||||||
int frame_number_;
|
|
||||||
vpx_codec_pts_t first_drop_;
|
|
||||||
int64_t bits_total_;
|
|
||||||
double duration_;
|
|
||||||
double file_datarate_;
|
|
||||||
size_t bits_in_last_frame_;
|
|
||||||
vpx_svc_extra_cfg_t svc_params_;
|
|
||||||
int speed_setting_;
|
|
||||||
double mismatch_psnr_;
|
|
||||||
int mismatch_nframes_;
|
|
||||||
};
|
|
||||||
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
|
|
||||||
const vpx_svc_extra_cfg_t *svc_params,
|
|
||||||
int spatial_layers,
|
|
||||||
int temporal_layers,
|
|
||||||
int temporal_layering_mode) {
|
|
||||||
int sl, spatial_layer_target;
|
|
||||||
float total = 0;
|
|
||||||
float alloc_ratio[VPX_MAX_LAYERS] = {0};
|
|
||||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
|
||||||
if (svc_params->scaling_factor_den[sl] > 0) {
|
|
||||||
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] *
|
|
||||||
1.0 / svc_params->scaling_factor_den[sl]);
|
|
||||||
total += alloc_ratio[sl];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
|
||||||
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
|
|
||||||
(unsigned int)(enc_cfg->rc_target_bitrate *
|
|
||||||
alloc_ratio[sl] / total);
|
|
||||||
const int index = sl * temporal_layers;
|
|
||||||
if (temporal_layering_mode == 3) {
|
|
||||||
enc_cfg->layer_target_bitrate[index] =
|
|
||||||
spatial_layer_target >> 1;
|
|
||||||
enc_cfg->layer_target_bitrate[index + 1] =
|
|
||||||
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
|
|
||||||
enc_cfg->layer_target_bitrate[index + 2] =
|
|
||||||
spatial_layer_target;
|
|
||||||
} else if (temporal_layering_mode == 2) {
|
|
||||||
enc_cfg->layer_target_bitrate[index] =
|
|
||||||
spatial_layer_target * 2 / 3;
|
|
||||||
enc_cfg->layer_target_bitrate[index + 1] =
|
|
||||||
spatial_layer_target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
|
|
||||||
// 3 temporal layers. Run CIF clip with 1 thread.
|
|
||||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
cfg_.rc_buf_sz = 1000;
|
cfg_.rc_buf_sz = 1000;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_dropframe_thresh = 1;
|
||||||
cfg_.rc_max_quantizer = 63;
|
cfg_.rc_min_quantizer = 2;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.g_lag_in_frames = 0;
|
cfg_.g_lag_in_frames = 0;
|
||||||
cfg_.ss_number_layers = 2;
|
|
||||||
cfg_.ts_number_layers = 3;
|
|
||||||
cfg_.ts_rate_decimator[0] = 4;
|
|
||||||
cfg_.ts_rate_decimator[1] = 2;
|
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
cfg_.g_threads = 1;
|
|
||||||
cfg_.temporal_layering_mode = 3;
|
|
||||||
svc_params_.scaling_factor_num[0] = 144;
|
|
||||||
svc_params_.scaling_factor_den[0] = 288;
|
|
||||||
svc_params_.scaling_factor_num[1] = 288;
|
|
||||||
svc_params_.scaling_factor_den[1] = 288;
|
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
|
||||||
cfg_.kf_max_dist = 9999;
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 200);
|
30, 1, 0, 140);
|
||||||
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
|
|
||||||
// layer target_bitrate.
|
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||||
for (int i = 200; i <= 800; i += 200) {
|
// there is only one denoiser mode: denoiserYonly(which is 1),
|
||||||
cfg_.rc_target_bitrate = i;
|
// but may add more modes in the future.
|
||||||
|
cfg_.rc_target_bitrate = 300;
|
||||||
ResetModel();
|
ResetModel();
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
// Turn on the denoiser.
|
||||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
denoiser_on_ = 1;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||||
<< " The datarate for the file exceeds the target by too much!";
|
<< " The datarate for the file is lower than target by too much!";
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||||
<< " The datarate for the file is lower than the target by too much!";
|
<< " The datarate for the file is greater than target by too much!";
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
|
// Check basic datarate targeting, for a single bitrate, when denoiser is off
|
||||||
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
|
// and on.
|
||||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayersSmallKf) {
|
TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_buf_initial_sz = 500;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
cfg_.rc_buf_optimal_sz = 500;
|
||||||
cfg_.rc_buf_sz = 1000;
|
cfg_.rc_buf_sz = 1000;
|
||||||
cfg_.rc_min_quantizer = 0;
|
cfg_.rc_dropframe_thresh = 1;
|
||||||
cfg_.rc_max_quantizer = 63;
|
cfg_.rc_min_quantizer = 2;
|
||||||
|
cfg_.rc_max_quantizer = 56;
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
cfg_.rc_end_usage = VPX_CBR;
|
||||||
cfg_.g_lag_in_frames = 0;
|
cfg_.g_lag_in_frames = 0;
|
||||||
cfg_.ss_number_layers = 2;
|
|
||||||
cfg_.ts_number_layers = 3;
|
|
||||||
cfg_.ts_rate_decimator[0] = 4;
|
|
||||||
cfg_.ts_rate_decimator[1] = 2;
|
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
cfg_.g_threads = 1;
|
|
||||||
cfg_.temporal_layering_mode = 3;
|
|
||||||
svc_params_.scaling_factor_num[0] = 144;
|
|
||||||
svc_params_.scaling_factor_den[0] = 288;
|
|
||||||
svc_params_.scaling_factor_num[1] = 288;
|
|
||||||
svc_params_.scaling_factor_den[1] = 288;
|
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 200);
|
30, 1, 0, 299);
|
||||||
cfg_.rc_target_bitrate = 400;
|
|
||||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
|
||||||
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
|
||||||
for (int j = 64; j <= 67; j++) {
|
|
||||||
cfg_.kf_max_dist = j;
|
|
||||||
ResetModel();
|
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
|
||||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
|
||||||
<< " The datarate for the file exceeds the target by too much!";
|
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
|
||||||
<< " The datarate for the file is lower than the target by too much!";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
|
// For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
|
||||||
// 3 temporal layers. Run HD clip with 4 threads.
|
// there is only one denoiser mode: denoiserYonly(which is 1),
|
||||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
// but may add more modes in the future.
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
cfg_.rc_target_bitrate = 300;
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_min_quantizer = 0;
|
|
||||||
cfg_.rc_max_quantizer = 63;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
cfg_.ss_number_layers = 2;
|
|
||||||
cfg_.ts_number_layers = 3;
|
|
||||||
cfg_.ts_rate_decimator[0] = 4;
|
|
||||||
cfg_.ts_rate_decimator[1] = 2;
|
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
cfg_.g_threads = 4;
|
|
||||||
cfg_.temporal_layering_mode = 3;
|
|
||||||
svc_params_.scaling_factor_num[0] = 144;
|
|
||||||
svc_params_.scaling_factor_den[0] = 288;
|
|
||||||
svc_params_.scaling_factor_num[1] = 288;
|
|
||||||
svc_params_.scaling_factor_den[1] = 288;
|
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
|
||||||
cfg_.kf_max_dist = 9999;
|
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
|
||||||
ResetModel();
|
ResetModel();
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
// The denoiser is off by default.
|
||||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
denoiser_on_ = 0;
|
||||||
|
// Set the offon test flag.
|
||||||
|
denoiser_offon_test_ = 1;
|
||||||
|
denoiser_offon_period_ = 100;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||||
<< " The datarate for the file exceeds the target by too much!";
|
<< " The datarate for the file is lower than target by too much!";
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||||
<< " The datarate for the file is lower than the target by too much!";
|
<< " The datarate for the file is greater than target by too much!";
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
}
|
||||||
|
#endif // CONFIG_VP9_TEMPORAL_DENOISING
|
||||||
|
|
||||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
|
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES);
|
||||||
// 3 temporal layers. Run CIF clip with 1 thread.
|
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
|
||||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
|
::testing::Values(::libvpx_test::kOnePassGood,
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
::libvpx_test::kRealTime),
|
||||||
cfg_.rc_buf_optimal_sz = 500;
|
::testing::Range(2, 7));
|
||||||
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 = 3;
|
|
||||||
cfg_.ts_number_layers = 3;
|
|
||||||
cfg_.ts_rate_decimator[0] = 4;
|
|
||||||
cfg_.ts_rate_decimator[1] = 2;
|
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
cfg_.g_threads = 1;
|
|
||||||
cfg_.temporal_layering_mode = 3;
|
|
||||||
svc_params_.scaling_factor_num[0] = 72;
|
|
||||||
svc_params_.scaling_factor_den[0] = 288;
|
|
||||||
svc_params_.scaling_factor_num[1] = 144;
|
|
||||||
svc_params_.scaling_factor_den[1] = 288;
|
|
||||||
svc_params_.scaling_factor_num[2] = 288;
|
|
||||||
svc_params_.scaling_factor_den[2] = 288;
|
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
|
||||||
cfg_.kf_max_dist = 9999;
|
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
|
||||||
ResetModel();
|
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
|
||||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
|
||||||
<< " The datarate for the file exceeds the target by too much!";
|
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
|
|
||||||
<< " The datarate for the file is lower than the target by too much!";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
|
|
||||||
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
|
|
||||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
|
|
||||||
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 = 3;
|
|
||||||
cfg_.ts_number_layers = 3;
|
|
||||||
cfg_.ts_rate_decimator[0] = 4;
|
|
||||||
cfg_.ts_rate_decimator[1] = 2;
|
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
cfg_.g_threads = 1;
|
|
||||||
cfg_.temporal_layering_mode = 3;
|
|
||||||
svc_params_.scaling_factor_num[0] = 72;
|
|
||||||
svc_params_.scaling_factor_den[0] = 288;
|
|
||||||
svc_params_.scaling_factor_num[1] = 144;
|
|
||||||
svc_params_.scaling_factor_den[1] = 288;
|
|
||||||
svc_params_.scaling_factor_num[2] = 288;
|
|
||||||
svc_params_.scaling_factor_den[2] = 288;
|
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
|
||||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
|
||||||
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
|
||||||
for (int j = 32; j <= 35; j++) {
|
|
||||||
cfg_.kf_max_dist = j;
|
|
||||||
ResetModel();
|
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
|
||||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
|
||||||
<< " The datarate for the file exceeds the target by too much!";
|
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
|
|
||||||
<< " The datarate for the file is lower than the target by too much!";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
|
|
||||||
// 3 temporal layers. Run HD clip with 4 threads.
|
|
||||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
|
||||||
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 = 3;
|
|
||||||
cfg_.ts_number_layers = 3;
|
|
||||||
cfg_.ts_rate_decimator[0] = 4;
|
|
||||||
cfg_.ts_rate_decimator[1] = 2;
|
|
||||||
cfg_.ts_rate_decimator[2] = 1;
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
cfg_.g_threads = 4;
|
|
||||||
cfg_.temporal_layering_mode = 3;
|
|
||||||
svc_params_.scaling_factor_num[0] = 72;
|
|
||||||
svc_params_.scaling_factor_den[0] = 288;
|
|
||||||
svc_params_.scaling_factor_num[1] = 144;
|
|
||||||
svc_params_.scaling_factor_den[1] = 288;
|
|
||||||
svc_params_.scaling_factor_num[2] = 288;
|
|
||||||
svc_params_.scaling_factor_den[2] = 288;
|
|
||||||
cfg_.rc_dropframe_thresh = 10;
|
|
||||||
cfg_.kf_max_dist = 9999;
|
|
||||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
|
||||||
30, 1, 0, 300);
|
|
||||||
cfg_.rc_target_bitrate = 800;
|
|
||||||
ResetModel();
|
|
||||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
|
||||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
|
||||||
<< " The datarate for the file exceeds the target by too much!";
|
|
||||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
|
|
||||||
<< " The datarate for the file is lower than the target by too much!";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* VP10 does not support multiple layers yet.
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
|
||||||
::testing::Range(5, 8));
|
|
||||||
*/
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -13,25 +13,54 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp10/common/entropy.h"
|
|
||||||
#include "vp10/common/scan.h"
|
#include "./vp9_rtcd.h"
|
||||||
|
#include "vp9/common/vp9_entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
#include "vpx_ports/msvc.h" // for round()
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
static int round(double x) {
|
||||||
|
if (x < 0)
|
||||||
|
return static_cast<int>(ceil(x - 0.5));
|
||||||
|
else
|
||||||
|
return static_cast<int>(floor(x + 0.5));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const int kNumCoeffs = 256;
|
const int kNumCoeffs = 256;
|
||||||
|
const double PI = 3.1415926535898;
|
||||||
|
void reference2_16x16_idct_2d(double *input, double *output) {
|
||||||
|
double x;
|
||||||
|
for (int l = 0; l < 16; ++l) {
|
||||||
|
for (int k = 0; k < 16; ++k) {
|
||||||
|
double s = 0;
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
for (int j = 0; j < 16; ++j) {
|
||||||
|
x = cos(PI * j * (l + 0.5) / 16.0) *
|
||||||
|
cos(PI * i * (k + 0.5) / 16.0) *
|
||||||
|
input[i * 16 + j] / 256;
|
||||||
|
if (i != 0)
|
||||||
|
x *= sqrt(2.0);
|
||||||
|
if (j != 0)
|
||||||
|
x *= sqrt(2.0);
|
||||||
|
s += x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output[k*16+l] = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const double C1 = 0.995184726672197;
|
const double C1 = 0.995184726672197;
|
||||||
const double C2 = 0.98078528040323;
|
const double C2 = 0.98078528040323;
|
||||||
const double C3 = 0.956940335732209;
|
const double C3 = 0.956940335732209;
|
||||||
@@ -240,31 +269,31 @@ typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t>
|
|||||||
|
|
||||||
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int /*tx_type*/) {
|
||||||
vpx_fdct16x16_c(in, out, stride);
|
vp9_fdct16x16_c(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||||
int /*tx_type*/) {
|
int /*tx_type*/) {
|
||||||
vpx_idct16x16_256_add_c(in, dest, stride);
|
vp9_idct16x16_256_add_c(in, dest, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
int tx_type) {
|
int tx_type) {
|
||||||
vp10_fht16x16_c(in, out, stride, tx_type);
|
vp9_fht16x16_c(in, out, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
|
||||||
int tx_type) {
|
int tx_type) {
|
||||||
vp10_iht16x16_256_add_c(in, dest, stride, tx_type);
|
vp9_iht16x16_256_add_c(in, dest, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 10);
|
vp9_highbd_idct16x16_256_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_c(in, out, stride, 12);
|
vp9_highbd_idct16x16_256_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
|
||||||
@@ -278,39 +307,39 @@ void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp10_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
|
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp10_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
|
vp9_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
|
vp9_highbd_idct16x16_10_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_c(in, out, stride, 12);
|
vp9_highbd_idct16x16_10_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
|
vp9_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
|
vp9_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
|
vp9_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
|
vp9_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
class Trans16x16TestBase {
|
class Trans16x16TestBase {
|
||||||
public:
|
public:
|
||||||
@@ -327,13 +356,13 @@ class Trans16x16TestBase {
|
|||||||
int64_t total_error = 0;
|
int64_t total_error = 0;
|
||||||
const int count_test_block = 10000;
|
const int count_test_block = 10000;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
@@ -342,7 +371,7 @@ class Trans16x16TestBase {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -356,7 +385,7 @@ class Trans16x16TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, dst, pitch_));
|
RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
@@ -364,11 +393,11 @@ class Trans16x16TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int32_t diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int32_t diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error)
|
||||||
@@ -387,9 +416,9 @@ class Trans16x16TestBase {
|
|||||||
void RunCoeffCheck() {
|
void RunCoeffCheck() {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
@@ -408,13 +437,15 @@ class Trans16x16TestBase {
|
|||||||
void RunMemCheck() {
|
void RunMemCheck() {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -441,19 +472,24 @@ class Trans16x16TestBase {
|
|||||||
void RunQuantCheck(int dc_thred, int ac_thred) {
|
void RunQuantCheck(int dc_thred, int ac_thred) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 100000;
|
const int count_test_block = 100000;
|
||||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
|
||||||
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
if (bit_depth_ == VPX_BITS_8)
|
||||||
|
input_block[j] = rnd.Rand8() - rnd.Rand8();
|
||||||
|
else
|
||||||
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
@@ -466,11 +502,11 @@ class Trans16x16TestBase {
|
|||||||
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
|
|
||||||
// clear reconstructed pixel buffers
|
// clear reconstructed pixel buffers
|
||||||
memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
|
vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
|
||||||
memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
|
vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
|
vpx_memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
|
||||||
memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
|
vpx_memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// quantization with maximum allowed step sizes
|
// quantization with maximum allowed step sizes
|
||||||
@@ -480,7 +516,7 @@ class Trans16x16TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
|
||||||
tx_type_);
|
tx_type_);
|
||||||
@@ -491,7 +527,7 @@ class Trans16x16TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
EXPECT_EQ(ref[j], dst[j]);
|
EXPECT_EQ(ref[j], dst[j]);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
EXPECT_EQ(ref16[j], dst16[j]);
|
EXPECT_EQ(ref16[j], dst16[j]);
|
||||||
@@ -503,14 +539,14 @@ class Trans16x16TestBase {
|
|||||||
void RunInvAccuracyCheck() {
|
void RunInvAccuracyCheck() {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
double out_r[kNumCoeffs];
|
double out_r[kNumCoeffs];
|
||||||
@@ -521,12 +557,12 @@ class Trans16x16TestBase {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
in[j] = src[j] - dst[j];
|
in[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
in[j] = src16[j] - dst16[j];
|
in[j] = src16[j] - dst16[j];
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,20 +572,20 @@ class Trans16x16TestBase {
|
|||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
16));
|
16));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u, error)
|
EXPECT_GE(1u, error)
|
||||||
<< "Error: 16x16 IDCT has error " << error
|
<< "Error: 16x16 IDCT has error " << error
|
||||||
@@ -562,14 +598,14 @@ class Trans16x16TestBase {
|
|||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 10000;
|
const int count_test_block = 10000;
|
||||||
const int eob = 10;
|
const int eob = 10;
|
||||||
const int16_t *scan = vp10_default_scan_orders[TX_16X16].scan;
|
const int16_t *scan = vp9_default_scan_orders[TX_16X16].scan;
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -582,31 +618,31 @@ class Trans16x16TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
dst[j] = 0;
|
dst[j] = 0;
|
||||||
ref[j] = 0;
|
ref[j] = 0;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
dst16[j] = 0;
|
dst16[j] = 0;
|
||||||
ref16[j] = 0;
|
ref16[j] = 0;
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ref_txfm(coeff, ref, pitch_);
|
ref_txfm(coeff, ref, pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
} else {
|
} else {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
pitch_));
|
pitch_));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||||
#else
|
#else
|
||||||
const uint32_t diff = dst[j] - ref[j];
|
const uint32_t diff = dst[j] - ref[j];
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error)
|
EXPECT_EQ(0u, error)
|
||||||
<< "Error: 16x16 IDCT Comparison has error " << error
|
<< "Error: 16x16 IDCT Comparison has error " << error
|
||||||
@@ -638,7 +674,7 @@ class Trans16x16DCT
|
|||||||
fwd_txfm_ref = fdct16x16_ref;
|
fwd_txfm_ref = fdct16x16_ref;
|
||||||
inv_txfm_ref = idct16x16_ref;
|
inv_txfm_ref = idct16x16_ref;
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
switch (bit_depth_) {
|
switch (bit_depth_) {
|
||||||
case VPX_BITS_10:
|
case VPX_BITS_10:
|
||||||
inv_txfm_ref = idct16x16_10_ref;
|
inv_txfm_ref = idct16x16_10_ref;
|
||||||
@@ -705,7 +741,7 @@ class Trans16x16HT
|
|||||||
fwd_txfm_ref = fht16x16_ref;
|
fwd_txfm_ref = fht16x16_ref;
|
||||||
inv_txfm_ref = iht16x16_ref;
|
inv_txfm_ref = iht16x16_ref;
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
switch (bit_depth_) {
|
switch (bit_depth_) {
|
||||||
case VPX_BITS_10:
|
case VPX_BITS_10:
|
||||||
inv_txfm_ref = iht16x16_10;
|
inv_txfm_ref = iht16x16_10;
|
||||||
@@ -784,171 +820,104 @@ TEST_P(InvTrans16x16DCT, CompareReference) {
|
|||||||
CompareInvReference(ref_txfm_, thresh_);
|
CompareInvReference(ref_txfm_, thresh_);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PartialTrans16x16Test
|
|
||||||
: public ::testing::TestWithParam<
|
|
||||||
std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
|
|
||||||
public:
|
|
||||||
virtual ~PartialTrans16x16Test() {}
|
|
||||||
virtual void SetUp() {
|
|
||||||
fwd_txfm_ = GET_PARAM(0);
|
|
||||||
bit_depth_ = GET_PARAM(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
vpx_bit_depth_t bit_depth_;
|
|
||||||
FdctFunc fwd_txfm_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(PartialTrans16x16Test, Extremes) {
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
const int16_t maxval =
|
|
||||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
|
||||||
#else
|
|
||||||
const int16_t maxval = 255;
|
|
||||||
#endif
|
|
||||||
const int minval = -maxval;
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
|
||||||
|
|
||||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
|
||||||
output[0] = 0;
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
|
||||||
EXPECT_EQ((maxval * kNumCoeffs) >> 1, output[0]);
|
|
||||||
|
|
||||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
|
||||||
output[0] = 0;
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
|
||||||
EXPECT_EQ((minval * kNumCoeffs) >> 1, output[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(PartialTrans16x16Test, Random) {
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
const int16_t maxval =
|
|
||||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
|
||||||
#else
|
|
||||||
const int16_t maxval = 255;
|
|
||||||
#endif
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < kNumCoeffs; ++i) {
|
|
||||||
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
|
||||||
input[i] = val;
|
|
||||||
sum += val;
|
|
||||||
}
|
|
||||||
output[0] = 0;
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
|
|
||||||
EXPECT_EQ(sum >> 1, output[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16DCT,
|
C, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16DCT,
|
C, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16HT,
|
C, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, PartialTrans16x16Test,
|
|
||||||
::testing::Values(make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_12)));
|
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans16x16HT,
|
C, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_c,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans16x16DCT,
|
NEON, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
&vp9_idct16x16_256_add_neon, 0, VPX_BITS_8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16DCT,
|
SSE2, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct16x16_sse2,
|
make_tuple(&vp9_fdct16x16_sse2,
|
||||||
&vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
&vp9_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16HT,
|
SSE2, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 0,
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0,
|
||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 1,
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1,
|
||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 2,
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2,
|
||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_sse2, 3,
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16DCT,
|
SSE2, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2,
|
make_tuple(&vp9_highbd_fdct16x16_sse2,
|
||||||
&idct16x16_10, 0, VPX_BITS_10),
|
&idct16x16_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
make_tuple(&vp9_highbd_fdct16x16_c,
|
||||||
&idct16x16_256_add_10_sse2, 0, VPX_BITS_10),
|
&idct16x16_256_add_10_sse2, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_sse2,
|
make_tuple(&vp9_highbd_fdct16x16_sse2,
|
||||||
&idct16x16_12, 0, VPX_BITS_12),
|
&idct16x16_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct16x16_c,
|
make_tuple(&vp9_highbd_fdct16x16_c,
|
||||||
&idct16x16_256_add_12_sse2, 0, VPX_BITS_12),
|
&idct16x16_256_add_12_sse2, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct16x16_sse2,
|
make_tuple(&vp9_fdct16x16_sse2,
|
||||||
&vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
&vp9_idct16x16_256_add_c, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans16x16HT,
|
SSE2, Trans16x16HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht16x16_sse2,
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 0, VPX_BITS_10),
|
||||||
&vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp10_fht16x16_sse2,
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 2, VPX_BITS_10),
|
||||||
&vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp10_fht16x16_sse2,
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 0, VPX_BITS_12),
|
||||||
&vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_c, 3,
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 2, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_highbd_fht16x16_sse2, &iht16x16_12, 3, VPX_BITS_12),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 1, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 2, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_c, 3,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
// Optimizations take effect at a threshold of 3155, so we use a value close to
|
// Optimizations take effect at a threshold of 3155, so we use a value close to
|
||||||
// that to test both branches.
|
// that to test both branches.
|
||||||
@@ -963,30 +932,13 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
&idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
|
||||||
make_tuple(&idct16x16_12,
|
make_tuple(&idct16x16_12,
|
||||||
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
|
&idct16x16_256_add_12_sse2, 3167, VPX_BITS_12)));
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, Trans16x16DCT,
|
SSSE3, Trans16x16DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct16x16_msa,
|
make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0,
|
||||||
&vpx_idct16x16_256_add_msa, 0, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Trans16x16HT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp10_fht16x16_msa,
|
|
||||||
&vp10_iht16x16_256_add_msa, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht16x16_msa,
|
|
||||||
&vp10_iht16x16_256_add_msa, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht16x16_msa,
|
|
||||||
&vp10_iht16x16_256_add_msa, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht16x16_msa,
|
|
||||||
&vp10_iht16x16_256_add_msa, 3, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans16x16Test,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct16x16_1_msa,
|
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -13,23 +13,28 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp10/common/entropy.h"
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vp9_rtcd.h"
|
||||||
|
#include "vp9/common/vp9_entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
#include "vpx_ports/msvc.h" // for round()
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
static int round(double x) {
|
||||||
|
if (x < 0)
|
||||||
|
return static_cast<int>(ceil(x - 0.5));
|
||||||
|
else
|
||||||
|
return static_cast<int>(floor(x + 0.5));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const int kNumCoeffs = 1024;
|
const int kNumCoeffs = 1024;
|
||||||
const double kPi = 3.141592653589793238462643383279502884;
|
const double kPi = 3.141592653589793238462643383279502884;
|
||||||
@@ -73,15 +78,19 @@ typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
|
|||||||
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t>
|
||||||
Trans32x32Param;
|
Trans32x32Param;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
void idct32x32_8(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
|
vp9_highbd_idct32x32_1024_add_c(in, out, stride, 8);
|
||||||
|
}
|
||||||
|
|
||||||
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 10);
|
vp9_highbd_idct32x32_1024_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct32x32_1024_add_c(in, out, stride, 12);
|
vp9_highbd_idct32x32_1024_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
|
class Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> {
|
||||||
public:
|
public:
|
||||||
@@ -110,13 +119,13 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
uint32_t max_error = 0;
|
uint32_t max_error = 0;
|
||||||
int64_t total_error = 0;
|
int64_t total_error = 0;
|
||||||
const int count_test_block = 10000;
|
const int count_test_block = 10000;
|
||||||
DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -126,7 +135,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -138,7 +147,7 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block,
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block,
|
||||||
CONVERT_TO_BYTEPTR(dst16), 32));
|
CONVERT_TO_BYTEPTR(dst16), 32));
|
||||||
@@ -146,11 +155,11 @@ TEST_P(Trans32x32Test, AccuracyCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int32_t diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int32_t diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
if (max_error < error)
|
if (max_error < error)
|
||||||
@@ -175,16 +184,16 @@ TEST_P(Trans32x32Test, CoeffCheck) {
|
|||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j)
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
|
|
||||||
const int stride = 32;
|
const int stride = 32;
|
||||||
vpx_fdct32x32_c(input_block, output_ref_block, stride);
|
vp9_fdct32x32_c(input_block, output_ref_block, stride);
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
|
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride));
|
||||||
|
|
||||||
if (version_ == 0) {
|
if (version_ == 0) {
|
||||||
@@ -203,13 +212,15 @@ TEST_P(Trans32x32Test, MemCheck) {
|
|||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 2000;
|
const int count_test_block = 2000;
|
||||||
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs);
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
// Initialize a test block with input range [-mask_, mask_].
|
// Initialize a test block with input range [-mask_, mask_].
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
|
||||||
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_;
|
||||||
}
|
}
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -221,7 +232,7 @@ TEST_P(Trans32x32Test, MemCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int stride = 32;
|
const int stride = 32;
|
||||||
vpx_fdct32x32_c(input_extreme_block, output_ref_block, stride);
|
vp9_fdct32x32_c(input_extreme_block, output_ref_block, stride);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
fwd_txfm_(input_extreme_block, output_block, stride));
|
fwd_txfm_(input_extreme_block, output_block, stride));
|
||||||
|
|
||||||
@@ -246,13 +257,13 @@ TEST_P(Trans32x32Test, MemCheck) {
|
|||||||
TEST_P(Trans32x32Test, InverseAccuracy) {
|
TEST_P(Trans32x32Test, InverseAccuracy) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -264,7 +275,7 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
in[j] = src[j] - dst[j];
|
in[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -278,13 +289,13 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32));
|
ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
@@ -298,165 +309,77 @@ TEST_P(Trans32x32Test, InverseAccuracy) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PartialTrans32x32Test
|
|
||||||
: public ::testing::TestWithParam<
|
|
||||||
std::tr1::tuple<FwdTxfmFunc, vpx_bit_depth_t> > {
|
|
||||||
public:
|
|
||||||
virtual ~PartialTrans32x32Test() {}
|
|
||||||
virtual void SetUp() {
|
|
||||||
fwd_txfm_ = GET_PARAM(0);
|
|
||||||
bit_depth_ = GET_PARAM(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
vpx_bit_depth_t bit_depth_;
|
|
||||||
FwdTxfmFunc fwd_txfm_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(PartialTrans32x32Test, Extremes) {
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
const int16_t maxval =
|
|
||||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
|
||||||
#else
|
|
||||||
const int16_t maxval = 255;
|
|
||||||
#endif
|
|
||||||
const int minval = -maxval;
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
|
||||||
|
|
||||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
|
|
||||||
output[0] = 0;
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
|
||||||
EXPECT_EQ((maxval * kNumCoeffs) >> 3, output[0]);
|
|
||||||
|
|
||||||
for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
|
|
||||||
output[0] = 0;
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
|
||||||
EXPECT_EQ((minval * kNumCoeffs) >> 3, output[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(PartialTrans32x32Test, Random) {
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
const int16_t maxval =
|
|
||||||
static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
|
|
||||||
#else
|
|
||||||
const int16_t maxval = 255;
|
|
||||||
#endif
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
|
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < kNumCoeffs; ++i) {
|
|
||||||
const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
|
|
||||||
input[i] = val;
|
|
||||||
sum += val;
|
|
||||||
}
|
|
||||||
output[0] = 0;
|
|
||||||
ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 32));
|
|
||||||
EXPECT_EQ(sum >> 3, output[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
make_tuple(&vp9_highbd_fdct32x32_c,
|
||||||
&idct32x32_10, 0, VPX_BITS_10),
|
&idct32x32_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_c,
|
make_tuple(&vp9_highbd_fdct32x32_rd_c,
|
||||||
&idct32x32_10, 1, VPX_BITS_10),
|
&idct32x32_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_c,
|
make_tuple(&vp9_highbd_fdct32x32_c,
|
||||||
&idct32x32_12, 0, VPX_BITS_12),
|
&idct32x32_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_c,
|
make_tuple(&vp9_highbd_fdct32x32_rd_c,
|
||||||
&idct32x32_12, 1, VPX_BITS_12),
|
&idct32x32_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
&vp9_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
make_tuple(&vp9_fdct32x32_rd_c,
|
||||||
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
&vp9_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
C, PartialTrans32x32Test,
|
|
||||||
::testing::Values(make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_fdct32x32_1_c, VPX_BITS_12)));
|
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans32x32Test,
|
C, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
&vp9_idct32x32_1024_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
make_tuple(&vp9_fdct32x32_rd_c,
|
||||||
&vpx_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
&vp9_idct32x32_1024_add_c, 1, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(C, PartialTrans32x32Test,
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_c,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans32x32Test,
|
NEON, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
&vp9_idct32x32_1024_add_neon, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_c,
|
make_tuple(&vp9_fdct32x32_rd_c,
|
||||||
&vpx_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
&vp9_idct32x32_1024_add_neon, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans32x32Test,
|
SSE2, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_sse2,
|
make_tuple(&vp9_fdct32x32_sse2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2,
|
make_tuple(&vp9_fdct32x32_rd_sse2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans32x32Test,
|
SSE2, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_10, 0, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fdct32x32_sse2, &idct32x32_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_10, 1,
|
make_tuple(&vp9_highbd_fdct32x32_rd_sse2, &idct32x32_10, 1,
|
||||||
VPX_BITS_10),
|
VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_sse2, &idct32x32_12, 0, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fdct32x32_sse2, &idct32x32_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct32x32_rd_sse2, &idct32x32_12, 1,
|
make_tuple(&vp9_highbd_fdct32x32_rd_sse2, &idct32x32_12, 1,
|
||||||
VPX_BITS_12),
|
VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct32x32_sse2, &vpx_idct32x32_1024_add_c, 0,
|
make_tuple(&vp9_fdct32x32_sse2, &vp9_idct32x32_1024_add_c, 0,
|
||||||
VPX_BITS_8),
|
VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_sse2, &vpx_idct32x32_1024_add_c, 1,
|
make_tuple(&vp9_fdct32x32_rd_sse2, &vp9_idct32x32_1024_add_c, 1,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans32x32Test,
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_sse2,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_AVX2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AVX2, Trans32x32Test,
|
AVX2, Trans32x32Test,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_avx2,
|
make_tuple(&vp9_fdct32x32_avx2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
&vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_fdct32x32_rd_avx2,
|
make_tuple(&vp9_fdct32x32_rd_avx2,
|
||||||
&vpx_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
&vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8)));
|
||||||
#endif // HAVE_AVX2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Trans32x32Test,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct32x32_msa,
|
|
||||||
&vpx_idct32x32_1024_add_msa, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_fdct32x32_rd_msa,
|
|
||||||
&vpx_idct32x32_1024_add_msa, 1, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans32x32Test,
|
|
||||||
::testing::Values(make_tuple(&vpx_fdct32x32_1_msa,
|
|
||||||
VPX_BITS_8)));
|
|
||||||
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -7,11 +7,10 @@
|
|||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "test/ivf_video_source.h"
|
#include "test/ivf_video_source.h"
|
||||||
|
#include "./vpx_config.h"
|
||||||
#include "vpx/vp8dx.h"
|
#include "vpx/vp8dx.h"
|
||||||
#include "vpx/vpx_decoder.h"
|
#include "vpx/vpx_decoder.h"
|
||||||
|
|
||||||
@@ -21,8 +20,11 @@ namespace {
|
|||||||
|
|
||||||
TEST(DecodeAPI, InvalidParams) {
|
TEST(DecodeAPI, InvalidParams) {
|
||||||
static const vpx_codec_iface_t *kCodecs[] = {
|
static const vpx_codec_iface_t *kCodecs[] = {
|
||||||
#if CONFIG_VP10_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
&vpx_codec_vp10_dx_algo,
|
&vpx_codec_vp8_dx_algo,
|
||||||
|
#endif
|
||||||
|
#if CONFIG_VP9_DECODER
|
||||||
|
&vpx_codec_vp9_dx_algo,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
uint8_t buf[1] = {0};
|
uint8_t buf[1] = {0};
|
||||||
@@ -55,4 +57,86 @@ 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.
|
||||||
|
void TestVp9Controls(vpx_codec_ctx_t *dec) {
|
||||||
|
static const int kControls[] = {
|
||||||
|
VP8D_GET_LAST_REF_UPDATES,
|
||||||
|
VP8D_GET_FRAME_CORRUPTED,
|
||||||
|
VP9D_GET_DISPLAY_SIZE,
|
||||||
|
VP9D_GET_FRAME_SIZE
|
||||||
|
};
|
||||||
|
int val[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < NELEMENTS(kControls); ++i) {
|
||||||
|
const vpx_codec_err_t res = vpx_codec_control_(dec, kControls[i], val);
|
||||||
|
switch (kControls[i]) {
|
||||||
|
case VP8D_GET_FRAME_CORRUPTED:
|
||||||
|
EXPECT_EQ(VPX_CODEC_ERROR, res) << kControls[i];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK, res) << kControls[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
vpx_codec_control_(dec, kControls[i], NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
vp9_ref_frame_t ref;
|
||||||
|
ref.idx = 0;
|
||||||
|
EXPECT_EQ(VPX_CODEC_ERROR, vpx_codec_control(dec, VP9_GET_REFERENCE, &ref));
|
||||||
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
vpx_codec_control(dec, VP9_GET_REFERENCE, NULL));
|
||||||
|
|
||||||
|
vpx_ref_frame_t ref_copy;
|
||||||
|
const int width = 352;
|
||||||
|
const int height = 288;
|
||||||
|
ASSERT_TRUE(
|
||||||
|
vpx_img_alloc(&ref_copy.img, VPX_IMG_FMT_I420, width, height, 1) != NULL);
|
||||||
|
ref_copy.frame_type = VP8_LAST_FRAME;
|
||||||
|
EXPECT_EQ(VPX_CODEC_ERROR,
|
||||||
|
vpx_codec_control(dec, VP8_COPY_REFERENCE, &ref_copy));
|
||||||
|
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
vpx_codec_control(dec, VP8_COPY_REFERENCE, NULL));
|
||||||
|
vpx_img_free(&ref_copy.img);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DecodeAPI, Vp9InvalidDecode) {
|
||||||
|
const vpx_codec_iface_t *const codec = &vpx_codec_vp9_dx_algo;
|
||||||
|
const char filename[] =
|
||||||
|
"invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf";
|
||||||
|
libvpx_test::IVFVideoSource video(filename);
|
||||||
|
video.Init();
|
||||||
|
video.Begin();
|
||||||
|
ASSERT_TRUE(!HasFailure());
|
||||||
|
|
||||||
|
vpx_codec_ctx_t dec;
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_dec_init(&dec, codec, NULL, 0));
|
||||||
|
const uint32_t frame_size = static_cast<uint32_t>(video.frame_size());
|
||||||
|
EXPECT_EQ(VPX_CODEC_MEM_ERROR,
|
||||||
|
vpx_codec_decode(&dec, video.cxdata(), frame_size, NULL, 0));
|
||||||
|
vpx_codec_iter_t iter = NULL;
|
||||||
|
EXPECT_EQ(NULL, vpx_codec_get_frame(&dec, &iter));
|
||||||
|
|
||||||
|
TestVp9Controls(&dec);
|
||||||
|
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&dec));
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_DECODER
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -268,6 +268,6 @@ TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
|
|||||||
printf("}\n");
|
printf("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
VP9NewEncodeDecodePerfTest, ::testing::Values(::libvpx_test::kTwoPassGood));
|
VP9NewEncodeDecodePerfTest, ::testing::Values(::libvpx_test::kTwoPassGood));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -7,18 +7,15 @@
|
|||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "test/codec_factory.h"
|
#include "test/codec_factory.h"
|
||||||
#include "test/decode_test_driver.h"
|
#include "test/decode_test_driver.h"
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/video_source.h"
|
#include "test/video_source.h"
|
||||||
|
|
||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
|
|
||||||
const char kVP8Name[] = "WebM Project VP8";
|
const char kVP8Name[] = "WebM Project VP8";
|
||||||
const char kVP10Name[] = "WebM Project VP10";
|
|
||||||
|
|
||||||
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
vpx_codec_err_t Decoder::PeekStream(const uint8_t *cxdata, size_t size,
|
||||||
vpx_codec_stream_info_t *stream_info) {
|
vpx_codec_stream_info_t *stream_info) {
|
||||||
@@ -47,11 +44,6 @@ bool Decoder::IsVP8() const {
|
|||||||
return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
return strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Decoder::IsVP10() const {
|
|
||||||
const char *codec_name = GetDecoderName();
|
|
||||||
return strncmp(kVP10Name, codec_name, sizeof(kVP10Name) - 1) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
void DecoderTest::HandlePeekResult(Decoder *const decoder,
|
||||||
CompressedVideoSource *video,
|
CompressedVideoSource *video,
|
||||||
const vpx_codec_err_t res_peek) {
|
const vpx_codec_err_t res_peek) {
|
||||||
|
|||||||
@@ -107,8 +107,6 @@ class Decoder {
|
|||||||
|
|
||||||
bool IsVP8() const;
|
bool IsVP8() const;
|
||||||
|
|
||||||
bool IsVP10() const;
|
|
||||||
|
|
||||||
vpx_codec_ctx_t * GetDecoder() {
|
vpx_codec_ctx_t * GetDecoder() {
|
||||||
return &decoder_;
|
return &decoder_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "vpx/vp8cx.h"
|
|
||||||
#include "vpx/vpx_encoder.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
|
|
||||||
|
|
||||||
TEST(EncodeAPI, InvalidParams) {
|
|
||||||
static const vpx_codec_iface_t *kCodecs[] = {
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
&vpx_codec_vp10_cx_algo,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
uint8_t buf[1] = {0};
|
|
||||||
vpx_image_t img;
|
|
||||||
vpx_codec_ctx_t enc;
|
|
||||||
vpx_codec_enc_cfg_t cfg;
|
|
||||||
|
|
||||||
EXPECT_EQ(&img, vpx_img_wrap(&img, VPX_IMG_FMT_I420, 1, 1, 1, buf));
|
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(NULL, NULL, NULL, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_enc_init(&enc, NULL, NULL, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, NULL, 0, 0, 0, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_encode(NULL, &img, 0, 0, 0, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM, vpx_codec_destroy(NULL));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_enc_config_default(NULL, NULL, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_enc_config_default(NULL, &cfg, 0));
|
|
||||||
EXPECT_TRUE(vpx_codec_error(NULL) != NULL);
|
|
||||||
|
|
||||||
for (int i = 0; i < NELEMENTS(kCodecs); ++i) {
|
|
||||||
SCOPED_TRACE(vpx_codec_iface_name(kCodecs[i]));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_enc_init(NULL, kCodecs[i], NULL, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_enc_init(&enc, kCodecs[i], NULL, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_enc_config_default(kCodecs[i], &cfg, 1));
|
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(kCodecs[i], &cfg, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, kCodecs[i], &cfg, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_encode(&enc, NULL, 0, 0, 0, 0));
|
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@@ -197,6 +197,6 @@ TEST_P(VP9EncodePerfTest, PerfTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
VP9_INSTANTIATE_TEST_CASE(
|
||||||
VP9EncodePerfTest, ::testing::Values(::libvpx_test::kRealTime));
|
VP9EncodePerfTest, ::testing::Values(::libvpx_test::kRealTime));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -10,15 +10,13 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
#include "test/codec_factory.h"
|
#include "test/codec_factory.h"
|
||||||
#include "test/decode_test_driver.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/decode_test_driver.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/video_source.h"
|
#include "test/video_source.h"
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
void Encoder::InitEncoder(VideoSource *video) {
|
void Encoder::InitEncoder(VideoSource *video) {
|
||||||
@@ -31,23 +29,26 @@ void Encoder::InitEncoder(VideoSource *video) {
|
|||||||
cfg_.g_timebase = video->timebase();
|
cfg_.g_timebase = video->timebase();
|
||||||
cfg_.rc_twopass_stats_in = stats_->buf();
|
cfg_.rc_twopass_stats_in = stats_->buf();
|
||||||
|
|
||||||
|
// Default to 1 thread.
|
||||||
|
cfg_.g_threads = 1;
|
||||||
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
|
res = vpx_codec_enc_init(&encoder_, CodecInterface(), &cfg_,
|
||||||
init_flags_);
|
init_flags_);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
|
|
||||||
#if CONFIG_VP10_ENCODER
|
#if CONFIG_VP9_ENCODER
|
||||||
if (CodecInterface() == &vpx_codec_vp10_cx_algo) {
|
if (CodecInterface() == &vpx_codec_vp9_cx_algo) {
|
||||||
// Default to 1 tile column for VP10. With CONFIG_EXT_TILE, the
|
// Default to 1 tile column for VP9.
|
||||||
// default is already the largest possible tile size
|
|
||||||
#if !CONFIG_EXT_TILE
|
|
||||||
const int log2_tile_columns = 0;
|
const int log2_tile_columns = 0;
|
||||||
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
|
res = vpx_codec_control_(&encoder_, VP9E_SET_TILE_COLUMNS,
|
||||||
log2_tile_columns);
|
log2_tile_columns);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
#endif // !CONFIG_EXT_TILE
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#if CONFIG_VP8_ENCODER
|
||||||
|
ASSERT_EQ(&vpx_codec_vp8_cx_algo, CodecInterface())
|
||||||
|
<< "Unknown Codec Interface";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,120 +130,38 @@ void EncoderTest::SetMode(TestMode mode) {
|
|||||||
else
|
else
|
||||||
passes_ = 1;
|
passes_ = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool compare_plane(const uint8_t *const buf1, const int stride1,
|
|
||||||
const uint8_t *const buf2, const int stride2,
|
|
||||||
const int w, const int h,
|
|
||||||
int *const mismatch_row,
|
|
||||||
int *const mismatch_col,
|
|
||||||
int *const mismatch_pix1,
|
|
||||||
int *const mismatch_pix2) {
|
|
||||||
int r, c;
|
|
||||||
|
|
||||||
for (r = 0; r < h; ++r) {
|
|
||||||
for (c = 0; c < w; ++c) {
|
|
||||||
const int pix1 = buf1[r * stride1 + c];
|
|
||||||
const int pix2 = buf2[r * stride2 + c];
|
|
||||||
|
|
||||||
if (pix1 != pix2) {
|
|
||||||
if (mismatch_row != NULL)
|
|
||||||
*mismatch_row = r;
|
|
||||||
if (mismatch_col != NULL)
|
|
||||||
*mismatch_col = c;
|
|
||||||
if (mismatch_pix1 != NULL)
|
|
||||||
*mismatch_pix1 = pix1;
|
|
||||||
if (mismatch_pix2 != NULL)
|
|
||||||
*mismatch_pix2 = pix2;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The function should return "true" most of the time, therefore no early
|
// The function should return "true" most of the time, therefore no early
|
||||||
// break-out is implemented within the match checking process.
|
// break-out is implemented within the match checking process.
|
||||||
static bool compare_img(const vpx_image_t *img1,
|
static bool compare_img(const vpx_image_t *img1,
|
||||||
const vpx_image_t *img2,
|
const vpx_image_t *img2) {
|
||||||
int *const mismatch_row,
|
bool match = (img1->fmt == img2->fmt) &&
|
||||||
int *const mismatch_col,
|
(img1->cs == img2->cs) &&
|
||||||
int *const mismatch_plane,
|
(img1->d_w == img2->d_w) &&
|
||||||
int *const mismatch_pix1,
|
(img1->d_h == img2->d_h);
|
||||||
int *const mismatch_pix2) {
|
|
||||||
|
|
||||||
const unsigned int w_y = img1->d_w;
|
const unsigned int width_y = img1->d_w;
|
||||||
const unsigned int h_y = img1->d_h;
|
const unsigned int height_y = img1->d_h;
|
||||||
const unsigned int w_uv = ROUND_POWER_OF_TWO(w_y, img1->x_chroma_shift);
|
unsigned int i;
|
||||||
const unsigned int h_uv = ROUND_POWER_OF_TWO(h_y, img1->y_chroma_shift);
|
for (i = 0; i < height_y; ++i)
|
||||||
|
match = (memcmp(img1->planes[VPX_PLANE_Y] + i * img1->stride[VPX_PLANE_Y],
|
||||||
if (img1->fmt != img2->fmt
|
img2->planes[VPX_PLANE_Y] + i * img2->stride[VPX_PLANE_Y],
|
||||||
|| img1->cs != img2->cs
|
width_y) == 0) && match;
|
||||||
|| img1->d_w != img2->d_w
|
const unsigned int width_uv = (img1->d_w + 1) >> 1;
|
||||||
|| img1->d_h != img2->d_h) {
|
const unsigned int height_uv = (img1->d_h + 1) >> 1;
|
||||||
if (mismatch_row != NULL)
|
for (i = 0; i < height_uv; ++i)
|
||||||
*mismatch_row = -1;
|
match = (memcmp(img1->planes[VPX_PLANE_U] + i * img1->stride[VPX_PLANE_U],
|
||||||
if (mismatch_col != NULL)
|
img2->planes[VPX_PLANE_U] + i * img2->stride[VPX_PLANE_U],
|
||||||
*mismatch_col = -1;
|
width_uv) == 0) && match;
|
||||||
return false;
|
for (i = 0; i < height_uv; ++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],
|
||||||
|
width_uv) == 0) && match;
|
||||||
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compare_plane(img1->planes[VPX_PLANE_Y], img1->stride[VPX_PLANE_Y],
|
void EncoderTest::MismatchHook(const vpx_image_t* /*img1*/,
|
||||||
img2->planes[VPX_PLANE_Y], img2->stride[VPX_PLANE_Y],
|
const vpx_image_t* /*img2*/) {
|
||||||
w_y, h_y,
|
ASSERT_TRUE(0) << "Encode/Decode mismatch found";
|
||||||
mismatch_row, mismatch_col,
|
|
||||||
mismatch_pix1, mismatch_pix2)) {
|
|
||||||
if (mismatch_plane != NULL)
|
|
||||||
*mismatch_plane = VPX_PLANE_Y;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compare_plane(img1->planes[VPX_PLANE_U], img1->stride[VPX_PLANE_U],
|
|
||||||
img2->planes[VPX_PLANE_U], img2->stride[VPX_PLANE_U],
|
|
||||||
w_uv, h_uv,
|
|
||||||
mismatch_row, mismatch_col,
|
|
||||||
mismatch_pix1, mismatch_pix2)) {
|
|
||||||
if (mismatch_plane != NULL)
|
|
||||||
*mismatch_plane = VPX_PLANE_U;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compare_plane(img1->planes[VPX_PLANE_V], img1->stride[VPX_PLANE_V],
|
|
||||||
img2->planes[VPX_PLANE_V], img2->stride[VPX_PLANE_V],
|
|
||||||
w_uv, h_uv,
|
|
||||||
mismatch_row, mismatch_col,
|
|
||||||
mismatch_pix1, mismatch_pix2)) {
|
|
||||||
if (mismatch_plane != NULL)
|
|
||||||
*mismatch_plane = VPX_PLANE_U;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EncoderTest::MismatchHook(const vpx_image_t* img_enc,
|
|
||||||
const vpx_image_t* img_dec) {
|
|
||||||
int mismatch_row = 0;
|
|
||||||
int mismatch_col = 0;
|
|
||||||
int mismatch_plane = 0;
|
|
||||||
int mismatch_pix_enc = 0;
|
|
||||||
int mismatch_pix_dec = 0;
|
|
||||||
|
|
||||||
ASSERT_FALSE(compare_img(img_enc, img_dec,
|
|
||||||
&mismatch_row, &mismatch_col,
|
|
||||||
&mismatch_plane,
|
|
||||||
&mismatch_pix_enc,
|
|
||||||
&mismatch_pix_dec));
|
|
||||||
|
|
||||||
GTEST_FAIL()
|
|
||||||
<< "Encode/Decode mismatch found:"
|
|
||||||
<< std::endl
|
|
||||||
<< " pixel value enc/dec: " << mismatch_pix_enc << "/" << mismatch_pix_dec
|
|
||||||
<< std::endl
|
|
||||||
<< " plane: " << mismatch_plane
|
|
||||||
<< std::endl
|
|
||||||
<< " row/col: " << mismatch_row << "/" << mismatch_col
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncoderTest::RunLoop(VideoSource *video) {
|
void EncoderTest::RunLoop(VideoSource *video) {
|
||||||
@@ -262,36 +181,25 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
cfg_.g_pass = VPX_RC_LAST_PASS;
|
cfg_.g_pass = VPX_RC_LAST_PASS;
|
||||||
|
|
||||||
BeginPassHook(pass);
|
BeginPassHook(pass);
|
||||||
testing::internal::scoped_ptr<Encoder> encoder(
|
Encoder* const encoder = codec_->CreateEncoder(cfg_, deadline_, init_flags_,
|
||||||
codec_->CreateEncoder(cfg_, deadline_, init_flags_, &stats_));
|
&stats_);
|
||||||
ASSERT_TRUE(encoder.get() != NULL);
|
ASSERT_TRUE(encoder != NULL);
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(video->Begin());
|
video->Begin();
|
||||||
encoder->InitEncoder(video);
|
encoder->InitEncoder(video);
|
||||||
ASSERT_FALSE(::testing::Test::HasFatalFailure());
|
|
||||||
|
|
||||||
unsigned long dec_init_flags = 0; // NOLINT
|
unsigned long dec_init_flags = 0; // NOLINT
|
||||||
// Use fragment decoder if encoder outputs partitions.
|
// Use fragment decoder if encoder outputs partitions.
|
||||||
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
// NOTE: fragment decoder and partition encoder are only supported by VP8.
|
||||||
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION)
|
if (init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION)
|
||||||
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
dec_init_flags |= VPX_CODEC_USE_INPUT_FRAGMENTS;
|
||||||
testing::internal::scoped_ptr<Decoder> decoder(
|
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, dec_init_flags, 0);
|
||||||
codec_->CreateDecoder(dec_cfg, dec_init_flags, 0));
|
|
||||||
#if CONFIG_VP10 && CONFIG_EXT_TILE
|
|
||||||
if (decoder->IsVP10()) {
|
|
||||||
// Set dec_cfg.tile_row = -1 and dec_cfg.tile_col = -1 so that the whole
|
|
||||||
// frame is decoded.
|
|
||||||
decoder->Control(VP10_SET_DECODE_TILE_ROW, -1);
|
|
||||||
decoder->Control(VP10_SET_DECODE_TILE_COL, -1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool again;
|
bool again;
|
||||||
for (again = true; again; video->Next()) {
|
for (again = true; again; video->Next()) {
|
||||||
again = (video->img() != NULL);
|
again = (video->img() != NULL);
|
||||||
|
|
||||||
PreEncodeFrameHook(video);
|
PreEncodeFrameHook(video);
|
||||||
PreEncodeFrameHook(video, encoder.get());
|
PreEncodeFrameHook(video, encoder);
|
||||||
encoder->EncodeFrame(video, frame_flags_);
|
encoder->EncodeFrame(video, frame_flags_);
|
||||||
|
|
||||||
CxDataIterator iter = encoder->GetCxData();
|
CxDataIterator iter = encoder->GetCxData();
|
||||||
@@ -304,11 +212,11 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
switch (pkt->kind) {
|
switch (pkt->kind) {
|
||||||
case VPX_CODEC_CX_FRAME_PKT:
|
case VPX_CODEC_CX_FRAME_PKT:
|
||||||
has_cxdata = true;
|
has_cxdata = true;
|
||||||
if (decoder.get() != NULL && DoDecode()) {
|
if (decoder && DoDecode()) {
|
||||||
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
vpx_codec_err_t res_dec = decoder->DecodeFrame(
|
||||||
(const uint8_t*)pkt->data.frame.buf, pkt->data.frame.sz);
|
(const uint8_t*)pkt->data.frame.buf, pkt->data.frame.sz);
|
||||||
|
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder.get()))
|
if (!HandleDecodeResult(res_dec, *video, decoder))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
has_dxdata = true;
|
has_dxdata = true;
|
||||||
@@ -330,7 +238,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
// Flush the decoder when there are no more fragments.
|
// Flush the decoder when there are no more fragments.
|
||||||
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
if ((init_flags_ & VPX_CODEC_USE_OUTPUT_PARTITION) && has_dxdata) {
|
||||||
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
const vpx_codec_err_t res_dec = decoder->DecodeFrame(NULL, 0);
|
||||||
if (!HandleDecodeResult(res_dec, *video, decoder.get()))
|
if (!HandleDecodeResult(res_dec, *video, decoder))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,8 +247,7 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
DxDataIterator dec_iter = decoder->GetDxData();
|
DxDataIterator dec_iter = decoder->GetDxData();
|
||||||
const vpx_image_t *img_dec = dec_iter.Next();
|
const vpx_image_t *img_dec = dec_iter.Next();
|
||||||
if (img_enc && img_dec) {
|
if (img_enc && img_dec) {
|
||||||
const bool res = compare_img(img_enc, img_dec,
|
const bool res = compare_img(img_enc, img_dec);
|
||||||
NULL, NULL, NULL, NULL, NULL);
|
|
||||||
if (!res) { // Mismatch
|
if (!res) { // Mismatch
|
||||||
MismatchHook(img_enc, img_dec);
|
MismatchHook(img_enc, img_dec);
|
||||||
}
|
}
|
||||||
@@ -354,6 +261,10 @@ void EncoderTest::RunLoop(VideoSource *video) {
|
|||||||
|
|
||||||
EndPassHook();
|
EndPassHook();
|
||||||
|
|
||||||
|
if (decoder)
|
||||||
|
delete decoder;
|
||||||
|
delete encoder;
|
||||||
|
|
||||||
if (!Continue())
|
if (!Continue())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#if CONFIG_VP10_ENCODER
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "vpx/vpx_encoder.h"
|
||||||
|
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||||
#include "vpx/vp8cx.h"
|
#include "vpx/vp8cx.h"
|
||||||
#endif
|
#endif
|
||||||
#include "vpx/vpx_encoder.h"
|
|
||||||
|
|
||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
|
|
||||||
@@ -124,11 +123,6 @@ class Encoder {
|
|||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control(int ctrl_id, int *arg) {
|
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Control(int ctrl_id, struct vpx_scaling_mode *arg) {
|
void Control(int ctrl_id, struct vpx_scaling_mode *arg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
@@ -139,11 +133,7 @@ class Encoder {
|
|||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control(int ctrl_id, struct vpx_svc_parameters *arg) {
|
#if CONFIG_VP8_ENCODER || CONFIG_VP9_ENCODER
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
|
||||||
}
|
|
||||||
#if CONFIG_VP10_ENCODER
|
|
||||||
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
void Control(int ctrl_id, vpx_active_map_t *arg) {
|
||||||
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
|
||||||
@@ -193,10 +183,7 @@ class EncoderTest {
|
|||||||
protected:
|
protected:
|
||||||
explicit EncoderTest(const CodecFactory *codec)
|
explicit EncoderTest(const CodecFactory *codec)
|
||||||
: codec_(codec), abort_(false), init_flags_(0), frame_flags_(0),
|
: codec_(codec), abort_(false), init_flags_(0), frame_flags_(0),
|
||||||
last_pts_(0) {
|
last_pts_(0) {}
|
||||||
// Default to 1 thread.
|
|
||||||
cfg_.g_threads = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~EncoderTest() {}
|
virtual ~EncoderTest() {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "test/y4m_video_source.h"
|
|
||||||
#include "vp10/vp10_dx_iface.c"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
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_range_t color_range;
|
|
||||||
vpx_color_space_t cs;
|
|
||||||
int render_size[2];
|
|
||||||
// TODO(JBB): quantizers / bitrate
|
|
||||||
};
|
|
||||||
|
|
||||||
const EncodeParameters kVP9EncodeParameterSet[] = {
|
|
||||||
{0, 0, 0, 1, 0, VPX_CR_STUDIO_RANGE, VPX_CS_BT_601, { 0, 0 }},
|
|
||||||
{0, 0, 0, 0, 0, VPX_CR_FULL_RANGE, VPX_CS_BT_709, { 0, 0 }},
|
|
||||||
{0, 0, 1, 0, 0, VPX_CR_FULL_RANGE, VPX_CS_BT_2020, { 0, 0 }},
|
|
||||||
{0, 2, 0, 0, 1, VPX_CR_STUDIO_RANGE, VPX_CS_UNKNOWN, { 640, 480 }},
|
|
||||||
// TODO(JBB): Test profiles (requires more work).
|
|
||||||
};
|
|
||||||
|
|
||||||
class VpxEncoderParmsGetToDecoder
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<EncodeParameters,
|
|
||||||
EncodePerfTestVideo> {
|
|
||||||
protected:
|
|
||||||
VpxEncoderParmsGetToDecoder()
|
|
||||||
: EncoderTest(GET_PARAM(0)), encode_parms(GET_PARAM(1)) {}
|
|
||||||
|
|
||||||
virtual ~VpxEncoderParmsGetToDecoder() {}
|
|
||||||
|
|
||||||
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_COLOR_RANGE, encode_parms.color_range);
|
|
||||||
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);
|
|
||||||
if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0)
|
|
||||||
encoder->Control(VP9E_SET_RENDER_SIZE, encode_parms.render_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
|
|
||||||
const libvpx_test::VideoSource & /*video*/,
|
|
||||||
libvpx_test::Decoder *decoder) {
|
|
||||||
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
|
||||||
vpx_codec_alg_priv_t *const priv =
|
|
||||||
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
|
||||||
FrameWorkerData *const worker_data =
|
|
||||||
reinterpret_cast<FrameWorkerData *>(priv->frame_workers[0].data1);
|
|
||||||
VP10_COMMON *const common = &worker_data->pbi->common;
|
|
||||||
|
|
||||||
if (encode_parms.lossless) {
|
|
||||||
EXPECT_EQ(0, common->base_qindex);
|
|
||||||
EXPECT_EQ(0, common->y_dc_delta_q);
|
|
||||||
EXPECT_EQ(0, common->uv_dc_delta_q);
|
|
||||||
EXPECT_EQ(0, common->uv_ac_delta_q);
|
|
||||||
EXPECT_EQ(ONLY_4X4, common->tx_mode);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(encode_parms.error_resilient, common->error_resilient_mode);
|
|
||||||
if (encode_parms.error_resilient) {
|
|
||||||
EXPECT_EQ(0, common->use_prev_frame_mvs);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(encode_parms.color_range, common->color_range);
|
|
||||||
EXPECT_EQ(encode_parms.cs, common->color_space);
|
|
||||||
if (encode_parms.render_size[0] > 0 && encode_parms.render_size[1] > 0) {
|
|
||||||
EXPECT_EQ(encode_parms.render_size[0], common->render_width);
|
|
||||||
EXPECT_EQ(encode_parms.render_size[1], common->render_height);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(encode_parms.tile_cols, common->log2_tile_cols);
|
|
||||||
EXPECT_EQ(encode_parms.tile_rows, common->log2_tile_rows);
|
|
||||||
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
|
|
||||||
return VPX_CODEC_OK == res_dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
EncodePerfTestVideo test_video_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
EncodeParameters encode_parms;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(VpxEncoderParmsGetToDecoder, BitstreamParms) {
|
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
|
||||||
|
|
||||||
libvpx_test::VideoSource *const video =
|
|
||||||
new libvpx_test::Y4mVideoSource(test_video_.name, 0, test_video_.frames);
|
|
||||||
ASSERT_TRUE(video != NULL);
|
|
||||||
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
|
||||||
delete video;
|
|
||||||
}
|
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(VpxEncoderParmsGetToDecoder,
|
|
||||||
::testing::ValuesIn(kVP9EncodeParameterSet),
|
|
||||||
::testing::ValuesIn(kVP9EncodePerfTestVectors));
|
|
||||||
} // namespace
|
|
||||||
@@ -20,11 +20,10 @@ const int kMaxErrorFrames = 12;
|
|||||||
const int kMaxDroppableFrames = 12;
|
const int kMaxDroppableFrames = 12;
|
||||||
|
|
||||||
class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, bool> {
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
protected:
|
protected:
|
||||||
ErrorResilienceTestLarge()
|
ErrorResilienceTestLarge()
|
||||||
: EncoderTest(GET_PARAM(0)),
|
: EncoderTest(GET_PARAM(0)),
|
||||||
svc_support_(GET_PARAM(2)),
|
|
||||||
psnr_(0.0),
|
psnr_(0.0),
|
||||||
nframes_(0),
|
nframes_(0),
|
||||||
mismatch_psnr_(0.0),
|
mismatch_psnr_(0.0),
|
||||||
@@ -100,7 +99,7 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||||
::libvpx_test::Encoder * /*encoder*/) {
|
::libvpx_test::Encoder *encoder) {
|
||||||
frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
|
frame_flags_ &= ~(VP8_EFLAG_NO_UPD_LAST |
|
||||||
VP8_EFLAG_NO_UPD_GF |
|
VP8_EFLAG_NO_UPD_GF |
|
||||||
VP8_EFLAG_NO_UPD_ARF);
|
VP8_EFLAG_NO_UPD_ARF);
|
||||||
@@ -164,7 +163,6 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
mismatch_psnr_ += mismatch_psnr;
|
mismatch_psnr_ += mismatch_psnr;
|
||||||
++mismatch_nframes_;
|
++mismatch_nframes_;
|
||||||
// std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
|
// std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
|
||||||
::libvpx_test::EncoderTest::MismatchHook(img1, img2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetErrorFrames(int num, unsigned int *list) {
|
void SetErrorFrames(int num, unsigned int *list) {
|
||||||
@@ -195,8 +193,6 @@ class ErrorResilienceTestLarge : public ::libvpx_test::EncoderTest,
|
|||||||
pattern_switch_ = frame_switch;
|
pattern_switch_ = frame_switch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool svc_support_;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double psnr_;
|
double psnr_;
|
||||||
unsigned int nframes_;
|
unsigned int nframes_;
|
||||||
@@ -306,10 +302,6 @@ TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
|
|||||||
// two layer temporal pattern. The base layer does not predict from the top
|
// two layer temporal pattern. The base layer does not predict from the top
|
||||||
// layer, so successful decoding is expected.
|
// layer, so successful decoding is expected.
|
||||||
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
||||||
// This test doesn't run if SVC is not supported.
|
|
||||||
if (!svc_support_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
cfg_.g_timebase = timebase;
|
cfg_.g_timebase = timebase;
|
||||||
cfg_.rc_target_bitrate = 500;
|
cfg_.rc_target_bitrate = 500;
|
||||||
@@ -355,10 +347,6 @@ TEST_P(ErrorResilienceTestLarge, 2LayersDropEnhancement) {
|
|||||||
// for a two layer temporal pattern, where at some point in the
|
// for a two layer temporal pattern, where at some point in the
|
||||||
// sequence, the LAST ref is not used anymore.
|
// sequence, the LAST ref is not used anymore.
|
||||||
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
TEST_P(ErrorResilienceTestLarge, 2LayersNoRefLast) {
|
||||||
// This test doesn't run if SVC is not supported.
|
|
||||||
if (!svc_support_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const vpx_rational timebase = { 33333333, 1000000000 };
|
const vpx_rational timebase = { 33333333, 1000000000 };
|
||||||
cfg_.g_timebase = timebase;
|
cfg_.g_timebase = timebase;
|
||||||
cfg_.rc_target_bitrate = 500;
|
cfg_.rc_target_bitrate = 500;
|
||||||
@@ -591,7 +579,8 @@ TEST_P(ErrorResilienceTestLargeCodecControls, CodecControl3TemporalLayers) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SVC-related tests don't run for VP10 since SVC is not supported.
|
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
|
||||||
VP10_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES,
|
VP8_INSTANTIATE_TEST_CASE(ErrorResilienceTestLargeCodecControls,
|
||||||
::testing::Values(false));
|
ONE_PASS_TEST_MODES);
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, ONE_PASS_TEST_MODES);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,192 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <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 VPxEncoderThreadTest
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
|
||||||
protected:
|
|
||||||
VPxEncoderThreadTest()
|
|
||||||
: EncoderTest(GET_PARAM(0)),
|
|
||||||
encoder_initialized_(false),
|
|
||||||
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);
|
|
||||||
#if CONFIG_VP10 && CONFIG_EXT_TILE
|
|
||||||
if (decoder_->IsVP10()) {
|
|
||||||
decoder_->Control(VP10_SET_DECODE_TILE_ROW, -1);
|
|
||||||
decoder_->Control(VP10_SET_DECODE_TILE_COL, -1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_enc_.clear();
|
|
||||||
md5_dec_.clear();
|
|
||||||
md5_enc_.clear();
|
|
||||||
}
|
|
||||||
virtual ~VPxEncoderThreadTest() {
|
|
||||||
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_maxsection_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_) {
|
|
||||||
#if CONFIG_VP10 && CONFIG_EXT_TILE
|
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 1);
|
|
||||||
if (codec_ == &libvpx_test::kVP10) {
|
|
||||||
// TODO(geza): Start using multiple tile rows when the multi-threaded
|
|
||||||
// encoder can handle them
|
|
||||||
encoder->Control(VP9E_SET_TILE_ROWS, 32);
|
|
||||||
} else {
|
|
||||||
encoder->Control(VP9E_SET_TILE_ROWS, 0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Encode 4 tile columns.
|
|
||||||
encoder->Control(VP9E_SET_TILE_COLUMNS, 2);
|
|
||||||
encoder->Control(VP9E_SET_TILE_ROWS, 0);
|
|
||||||
#endif // CONFIG_VP10 && CONFIG_EXT_TILE
|
|
||||||
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) {
|
|
||||||
size_enc_.push_back(pkt->data.frame.sz);
|
|
||||||
|
|
||||||
::libvpx_test::MD5 md5_enc;
|
|
||||||
md5_enc.Add(reinterpret_cast<uint8_t*>(pkt->data.frame.buf),
|
|
||||||
pkt->data.frame.sz);
|
|
||||||
md5_enc_.push_back(md5_enc.Get());
|
|
||||||
|
|
||||||
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_dec_.push_back(md5_res.Get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoTest() {
|
|
||||||
::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 15, 18);
|
|
||||||
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));
|
|
||||||
std::vector<size_t> single_thr_size_enc;
|
|
||||||
std::vector<std::string> single_thr_md5_enc;
|
|
||||||
std::vector<std::string> single_thr_md5_dec;
|
|
||||||
single_thr_size_enc = size_enc_;
|
|
||||||
single_thr_md5_enc = md5_enc_;
|
|
||||||
single_thr_md5_dec = md5_dec_;
|
|
||||||
size_enc_.clear();
|
|
||||||
md5_enc_.clear();
|
|
||||||
md5_dec_.clear();
|
|
||||||
|
|
||||||
// Encode using multiple threads.
|
|
||||||
cfg_.g_threads = 4;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
std::vector<size_t> multi_thr_size_enc;
|
|
||||||
std::vector<std::string> multi_thr_md5_enc;
|
|
||||||
std::vector<std::string> multi_thr_md5_dec;
|
|
||||||
multi_thr_size_enc = size_enc_;
|
|
||||||
multi_thr_md5_enc = md5_enc_;
|
|
||||||
multi_thr_md5_dec = md5_dec_;
|
|
||||||
size_enc_.clear();
|
|
||||||
md5_enc_.clear();
|
|
||||||
md5_dec_.clear();
|
|
||||||
|
|
||||||
// Check that the vectors are equal.
|
|
||||||
ASSERT_EQ(single_thr_size_enc, multi_thr_size_enc);
|
|
||||||
ASSERT_EQ(single_thr_md5_enc, multi_thr_md5_enc);
|
|
||||||
ASSERT_EQ(single_thr_md5_dec, multi_thr_md5_dec);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool encoder_initialized_;
|
|
||||||
::libvpx_test::TestMode encoding_mode_;
|
|
||||||
int set_cpu_used_;
|
|
||||||
::libvpx_test::Decoder *decoder_;
|
|
||||||
std::vector<size_t> size_enc_;
|
|
||||||
std::vector<std::string> md5_enc_;
|
|
||||||
std::vector<std::string> md5_dec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
|
|
||||||
DoTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
class VPxEncoderThreadTestLarge : public VPxEncoderThreadTest {};
|
|
||||||
|
|
||||||
TEST_P(VPxEncoderThreadTestLarge, EncoderResultTest) {
|
|
||||||
DoTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
|
||||||
VPxEncoderThreadTest,
|
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(3, 9));
|
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(
|
|
||||||
VPxEncoderThreadTestLarge,
|
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(1, 3));
|
|
||||||
} // namespace
|
|
||||||
488
test/external_frame_buffer_test.cc
Normal file
488
test/external_frame_buffer_test.cc
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
/*
|
||||||
|
* 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/ivf_video_source.h"
|
||||||
|
#include "test/md5_helper.h"
|
||||||
|
#include "test/test_vectors.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
#if CONFIG_WEBM_IO
|
||||||
|
#include "test/webm_video_source.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int kVideoNameParam = 1;
|
||||||
|
const char kVP9TestFile[] = "vp90-2-02-size-lf-1920x1080.webm";
|
||||||
|
|
||||||
|
struct ExternalFrameBuffer {
|
||||||
|
uint8_t *data;
|
||||||
|
size_t size;
|
||||||
|
int in_use;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Class to manipulate a list of external frame buffers.
|
||||||
|
class ExternalFrameBufferList {
|
||||||
|
public:
|
||||||
|
ExternalFrameBufferList()
|
||||||
|
: num_buffers_(0),
|
||||||
|
ext_fb_list_(NULL) {}
|
||||||
|
|
||||||
|
virtual ~ExternalFrameBufferList() {
|
||||||
|
for (int i = 0; i < num_buffers_; ++i) {
|
||||||
|
delete [] ext_fb_list_[i].data;
|
||||||
|
}
|
||||||
|
delete [] ext_fb_list_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates the list to hold the external buffers. Returns true on success.
|
||||||
|
bool CreateBufferList(int num_buffers) {
|
||||||
|
if (num_buffers < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
num_buffers_ = num_buffers;
|
||||||
|
ext_fb_list_ = new ExternalFrameBuffer[num_buffers_];
|
||||||
|
EXPECT_TRUE(ext_fb_list_ != NULL);
|
||||||
|
memset(ext_fb_list_, 0, sizeof(ext_fb_list_[0]) * num_buffers_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches the frame buffer list for a free frame buffer. Makes sure
|
||||||
|
// that the frame buffer is at least |min_size| in bytes. Marks that the
|
||||||
|
// frame buffer is in use by libvpx. Finally sets |fb| to point to the
|
||||||
|
// external frame buffer. Returns < 0 on an error.
|
||||||
|
int GetFreeFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
||||||
|
EXPECT_TRUE(fb != NULL);
|
||||||
|
const int idx = FindFreeBufferIndex();
|
||||||
|
if (idx == num_buffers_)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ext_fb_list_[idx].size < min_size) {
|
||||||
|
delete [] ext_fb_list_[idx].data;
|
||||||
|
ext_fb_list_[idx].data = new uint8_t[min_size];
|
||||||
|
memset(ext_fb_list_[idx].data, 0, min_size);
|
||||||
|
ext_fb_list_[idx].size = min_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFrameBuffer(idx, fb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test function that will not allocate any data for the frame buffer.
|
||||||
|
// Returns < 0 on an error.
|
||||||
|
int GetZeroFrameBuffer(size_t min_size, vpx_codec_frame_buffer_t *fb) {
|
||||||
|
EXPECT_TRUE(fb != NULL);
|
||||||
|
const int idx = FindFreeBufferIndex();
|
||||||
|
if (idx == num_buffers_)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ext_fb_list_[idx].size < min_size) {
|
||||||
|
delete [] ext_fb_list_[idx].data;
|
||||||
|
ext_fb_list_[idx].data = NULL;
|
||||||
|
ext_fb_list_[idx].size = min_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFrameBuffer(idx, fb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
if (fb == NULL) {
|
||||||
|
EXPECT_TRUE(fb != NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ExternalFrameBuffer *const ext_fb =
|
||||||
|
reinterpret_cast<ExternalFrameBuffer*>(fb->priv);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks that the ximage data is contained within the external frame buffer
|
||||||
|
// private data passed back in the ximage.
|
||||||
|
void CheckXImageFrameBuffer(const vpx_image_t *img) {
|
||||||
|
if (img->fb_priv != NULL) {
|
||||||
|
const struct ExternalFrameBuffer *const ext_fb =
|
||||||
|
reinterpret_cast<ExternalFrameBuffer*>(img->fb_priv);
|
||||||
|
|
||||||
|
ASSERT_TRUE(img->planes[0] >= ext_fb->data &&
|
||||||
|
img->planes[0] < (ext_fb->data + ext_fb->size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Returns the index of the first free frame buffer. Returns |num_buffers_|
|
||||||
|
// if there are no free frame buffers.
|
||||||
|
int FindFreeBufferIndex() {
|
||||||
|
int i;
|
||||||
|
// Find a free frame buffer.
|
||||||
|
for (i = 0; i < num_buffers_; ++i) {
|
||||||
|
if (!ext_fb_list_[i].in_use)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets |fb| to an external frame buffer. idx is the index into the frame
|
||||||
|
// buffer list.
|
||||||
|
void SetFrameBuffer(int idx, vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ASSERT_TRUE(fb != NULL);
|
||||||
|
fb->data = ext_fb_list_[idx].data;
|
||||||
|
fb->size = ext_fb_list_[idx].size;
|
||||||
|
ASSERT_EQ(0, ext_fb_list_[idx].in_use);
|
||||||
|
ext_fb_list_[idx].in_use = 1;
|
||||||
|
fb->priv = &ext_fb_list_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_buffers_;
|
||||||
|
ExternalFrameBuffer *ext_fb_list_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Callback used by libvpx to request the application to return a frame
|
||||||
|
// buffer of at least |min_size| in bytes.
|
||||||
|
int get_vp9_frame_buffer(void *user_priv, size_t min_size,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ExternalFrameBufferList *const fb_list =
|
||||||
|
reinterpret_cast<ExternalFrameBufferList*>(user_priv);
|
||||||
|
return fb_list->GetFreeFrameBuffer(min_size, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback used by libvpx to tell the application that |fb| is not needed
|
||||||
|
// anymore.
|
||||||
|
int release_vp9_frame_buffer(void *user_priv,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ExternalFrameBufferList *const fb_list =
|
||||||
|
reinterpret_cast<ExternalFrameBufferList*>(user_priv);
|
||||||
|
return fb_list->ReturnFrameBuffer(fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback will not allocate data for frame buffer.
|
||||||
|
int get_vp9_zero_frame_buffer(void *user_priv, size_t min_size,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ExternalFrameBufferList *const fb_list =
|
||||||
|
reinterpret_cast<ExternalFrameBufferList*>(user_priv);
|
||||||
|
return fb_list->GetZeroFrameBuffer(min_size, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback will allocate one less byte than |min_size|.
|
||||||
|
int get_vp9_one_less_byte_frame_buffer(void *user_priv, size_t min_size,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ExternalFrameBufferList *const fb_list =
|
||||||
|
reinterpret_cast<ExternalFrameBufferList*>(user_priv);
|
||||||
|
return fb_list->GetFreeFrameBuffer(min_size - 1, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback will not release the external frame buffer.
|
||||||
|
int do_not_release_vp9_frame_buffer(void *user_priv,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
(void)user_priv;
|
||||||
|
(void)fb;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class for testing passing in external frame buffers to libvpx.
|
||||||
|
class ExternalFrameBufferMD5Test
|
||||||
|
: public ::libvpx_test::DecoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<const char*> {
|
||||||
|
protected:
|
||||||
|
ExternalFrameBufferMD5Test()
|
||||||
|
: DecoderTest(GET_PARAM(::libvpx_test::kCodecFactoryParam)),
|
||||||
|
md5_file_(NULL),
|
||||||
|
num_buffers_(0) {}
|
||||||
|
|
||||||
|
virtual ~ExternalFrameBufferMD5Test() {
|
||||||
|
if (md5_file_ != NULL)
|
||||||
|
fclose(md5_file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreDecodeFrameHook(
|
||||||
|
const libvpx_test::CompressedVideoSource &video,
|
||||||
|
libvpx_test::Decoder *decoder) {
|
||||||
|
if (num_buffers_ > 0 && video.frame_number() == 0) {
|
||||||
|
// Have libvpx use frame buffers we create.
|
||||||
|
ASSERT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
decoder->SetFrameBufferFunctions(
|
||||||
|
GetVP9FrameBuffer, ReleaseVP9FrameBuffer, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
||||||
|
const unsigned int frame_number) {
|
||||||
|
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: frame number = " << frame_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback to get a free external frame buffer. Return value < 0 is an
|
||||||
|
// error.
|
||||||
|
static int GetVP9FrameBuffer(void *user_priv, size_t min_size,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ExternalFrameBufferMD5Test *const md5Test =
|
||||||
|
reinterpret_cast<ExternalFrameBufferMD5Test*>(user_priv);
|
||||||
|
return md5Test->fb_list_.GetFreeFrameBuffer(min_size, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback to release an external frame buffer. Return value < 0 is an
|
||||||
|
// error.
|
||||||
|
static int ReleaseVP9FrameBuffer(void *user_priv,
|
||||||
|
vpx_codec_frame_buffer_t *fb) {
|
||||||
|
ExternalFrameBufferMD5Test *const md5Test =
|
||||||
|
reinterpret_cast<ExternalFrameBufferMD5Test*>(user_priv);
|
||||||
|
return md5Test->fb_list_.ReturnFrameBuffer(fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_num_buffers(int num_buffers) { num_buffers_ = num_buffers; }
|
||||||
|
int num_buffers() const { return num_buffers_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *md5_file_;
|
||||||
|
int num_buffers_;
|
||||||
|
ExternalFrameBufferList fb_list_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CONFIG_WEBM_IO
|
||||||
|
// Class for testing passing in external frame buffers to libvpx.
|
||||||
|
class ExternalFrameBufferTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
ExternalFrameBufferTest()
|
||||||
|
: video_(NULL),
|
||||||
|
decoder_(NULL),
|
||||||
|
num_buffers_(0) {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
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();
|
||||||
|
decoder_ = new libvpx_test::VP9Decoder(cfg, 0);
|
||||||
|
ASSERT_TRUE(decoder_ != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() {
|
||||||
|
delete decoder_;
|
||||||
|
delete video_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passes the external frame buffer information to libvpx.
|
||||||
|
vpx_codec_err_t SetFrameBufferFunctions(
|
||||||
|
int num_buffers,
|
||||||
|
vpx_get_frame_buffer_cb_fn_t cb_get,
|
||||||
|
vpx_release_frame_buffer_cb_fn_t cb_release) {
|
||||||
|
if (num_buffers > 0) {
|
||||||
|
num_buffers_ = num_buffers;
|
||||||
|
EXPECT_TRUE(fb_list_.CreateBufferList(num_buffers_));
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoder_->SetFrameBufferFunctions(cb_get, cb_release, &fb_list_);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpx_codec_err_t DecodeOneFrame() {
|
||||||
|
const vpx_codec_err_t res =
|
||||||
|
decoder_->DecodeFrame(video_->cxdata(), video_->frame_size());
|
||||||
|
CheckDecodedFrames();
|
||||||
|
if (res == VPX_CODEC_OK)
|
||||||
|
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;
|
||||||
|
CheckDecodedFrames();
|
||||||
|
}
|
||||||
|
return VPX_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CheckDecodedFrames() {
|
||||||
|
libvpx_test::DxDataIterator dec_iter = decoder_->GetDxData();
|
||||||
|
const vpx_image_t *img = NULL;
|
||||||
|
|
||||||
|
// Get decompressed data
|
||||||
|
while ((img = dec_iter.Next()) != NULL) {
|
||||||
|
fb_list_.CheckXImageFrameBuffer(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libvpx_test::WebMVideoSource *video_;
|
||||||
|
libvpx_test::VP9Decoder *decoder_;
|
||||||
|
int num_buffers_;
|
||||||
|
ExternalFrameBufferList fb_list_;
|
||||||
|
};
|
||||||
|
#endif // CONFIG_WEBM_IO
|
||||||
|
|
||||||
|
// This test runs through the set of test vectors, and decodes them.
|
||||||
|
// Libvpx will call into the application to allocate a frame buffer when
|
||||||
|
// needed. The md5 checksums are computed for each frame in the video file.
|
||||||
|
// If md5 checksums match the correct md5 data, then the test is passed.
|
||||||
|
// Otherwise, the test failed.
|
||||||
|
TEST_P(ExternalFrameBufferMD5Test, ExtFBMD5Match) {
|
||||||
|
const std::string filename = GET_PARAM(kVideoNameParam);
|
||||||
|
libvpx_test::CompressedVideoSource *video = NULL;
|
||||||
|
|
||||||
|
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
||||||
|
// #VPX_MAXIMUM_WORK_BUFFERS + four jitter buffers.
|
||||||
|
const int jitter_buffers = 4;
|
||||||
|
const int num_buffers =
|
||||||
|
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
||||||
|
set_num_buffers(num_buffers);
|
||||||
|
|
||||||
|
#if CONFIG_VP8_DECODER
|
||||||
|
// Tell compiler we are not using kVP8TestVectors.
|
||||||
|
(void)libvpx_test::kVP8TestVectors;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Open compressed video file.
|
||||||
|
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||||
|
video = new libvpx_test::IVFVideoSource(filename);
|
||||||
|
} else {
|
||||||
|
#if CONFIG_WEBM_IO
|
||||||
|
video = new libvpx_test::WebMVideoSource(filename);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||||
|
filename.c_str());
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(video != NULL);
|
||||||
|
video->Init();
|
||||||
|
|
||||||
|
// Construct md5 file name.
|
||||||
|
const std::string md5_filename = filename + ".md5";
|
||||||
|
OpenMD5File(md5_filename);
|
||||||
|
|
||||||
|
// Decode frame, and check the md5 matching.
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
||||||
|
delete video;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_WEBM_IO
|
||||||
|
TEST_F(ExternalFrameBufferTest, MinFrameBuffers) {
|
||||||
|
// Minimum number of external frame buffers for VP9 is
|
||||||
|
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS.
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
SetFrameBufferFunctions(
|
||||||
|
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, EightJitterBuffers) {
|
||||||
|
// Number of buffers equals #VP9_MAXIMUM_REF_BUFFERS +
|
||||||
|
// #VPX_MAXIMUM_WORK_BUFFERS + eight jitter buffers.
|
||||||
|
const int jitter_buffers = 8;
|
||||||
|
const int num_buffers =
|
||||||
|
VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS + jitter_buffers;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
SetFrameBufferFunctions(
|
||||||
|
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, DecodeRemainingFrames());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, NotEnoughBuffers) {
|
||||||
|
// Minimum number of external frame buffers for VP9 is
|
||||||
|
// #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS. Most files will
|
||||||
|
// only use 5 frame buffers at one time.
|
||||||
|
const int num_buffers = 2;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
SetFrameBufferFunctions(
|
||||||
|
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||||
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, NoRelease) {
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer,
|
||||||
|
do_not_release_vp9_frame_buffer));
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||||
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeRemainingFrames());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, NullRealloc) {
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
SetFrameBufferFunctions(num_buffers, get_vp9_zero_frame_buffer,
|
||||||
|
release_vp9_frame_buffer));
|
||||||
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, ReallocOneLessByte) {
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK,
|
||||||
|
SetFrameBufferFunctions(
|
||||||
|
num_buffers, get_vp9_one_less_byte_frame_buffer,
|
||||||
|
release_vp9_frame_buffer));
|
||||||
|
ASSERT_EQ(VPX_CODEC_MEM_ERROR, DecodeOneFrame());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, NullGetFunction) {
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
SetFrameBufferFunctions(num_buffers, NULL,
|
||||||
|
release_vp9_frame_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, NullReleaseFunction) {
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_INVALID_PARAM,
|
||||||
|
SetFrameBufferFunctions(num_buffers, get_vp9_frame_buffer, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ExternalFrameBufferTest, SetAfterDecode) {
|
||||||
|
const int num_buffers = VP9_MAXIMUM_REF_BUFFERS + VPX_MAXIMUM_WORK_BUFFERS;
|
||||||
|
ASSERT_EQ(VPX_CODEC_OK, DecodeOneFrame());
|
||||||
|
ASSERT_EQ(VPX_CODEC_ERROR,
|
||||||
|
SetFrameBufferFunctions(
|
||||||
|
num_buffers, get_vp9_frame_buffer, release_vp9_frame_buffer));
|
||||||
|
}
|
||||||
|
#endif // CONFIG_WEBM_IO
|
||||||
|
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(ExternalFrameBufferMD5Test,
|
||||||
|
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
||||||
|
libvpx_test::kVP9TestVectors +
|
||||||
|
libvpx_test::kNumVP9TestVectors));
|
||||||
|
} // namespace
|
||||||
@@ -13,86 +13,272 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/transform_test_base.h"
|
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp10/common/entropy.h"
|
|
||||||
|
#include "./vp9_rtcd.h"
|
||||||
|
#include "vp9/common/vp9_entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
const int kNumCoeffs = 16;
|
||||||
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
|
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 (*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,
|
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
|
||||||
int tx_type);
|
int tx_type);
|
||||||
using libvpx_test::FhtFunc;
|
|
||||||
|
|
||||||
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t, int>
|
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct4x4Param;
|
||||||
Dct4x4Param;
|
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht4x4Param;
|
||||||
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t, int>
|
|
||||||
Ht4x4Param;
|
|
||||||
|
|
||||||
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fdct4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int tx_type) {
|
||||||
vpx_fdct4x4_c(in, out, stride);
|
vp9_fdct4x4_c(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
void fht4x4_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
vp10_fht4x4_c(in, out, stride, tx_type);
|
vp9_fht4x4_c(in, out, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
void fwht4x4_ref(const int16_t *in, tran_low_t *out, int stride,
|
||||||
int /*tx_type*/) {
|
int tx_type) {
|
||||||
vp10_fwht4x4_c(in, out, stride);
|
vp9_fwht4x4_c(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct4x4_16_add_c(in, out, stride, 10);
|
vp9_highbd_idct4x4_16_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct4x4_16_add_c(in, out, stride, 12);
|
vp9_highbd_idct4x4_16_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht4x4_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp10_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 10);
|
vp9_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht4x4_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht4x4_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp10_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 12);
|
vp9_highbd_iht4x4_16_add_c(in, out, stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void iwht4x4_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 10);
|
vp9_highbd_iwht4x4_16_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void iwht4x4_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_iwht4x4_16_add_c(in, out, stride, 12);
|
vp9_highbd_iwht4x4_16_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct4x4_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 10);
|
vp9_highbd_idct4x4_16_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct4x4_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
|
vp9_highbd_idct4x4_16_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
|
class Trans4x4TestBase {
|
||||||
|
public:
|
||||||
|
virtual ~Trans4x4TestBase() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void RunFwdTxfm(const int16_t *in, tran_low_t *out, int stride) = 0;
|
||||||
|
|
||||||
|
virtual void RunInvTxfm(const tran_low_t *out, uint8_t *dst, int stride) = 0;
|
||||||
|
|
||||||
|
void RunAccuracyCheck(int limit) {
|
||||||
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
|
uint32_t max_error = 0;
|
||||||
|
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);
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialize a test block with input range [-255, 255].
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
src[j] = rnd.Rand8();
|
||||||
|
dst[j] = rnd.Rand8();
|
||||||
|
test_input_block[j] = src[j] - dst[j];
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
|
test_input_block[j] = src16[j] - dst16[j];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
|
||||||
|
test_temp_block, pitch_));
|
||||||
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block,
|
||||||
|
CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
const uint32_t diff =
|
||||||
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
|
#else
|
||||||
|
const uint32_t diff = dst[j] - src[j];
|
||||||
|
#endif
|
||||||
|
const uint32_t error = diff * diff;
|
||||||
|
if (max_error < error)
|
||||||
|
max_error = error;
|
||||||
|
total_error += error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_GE(static_cast<uint32_t>(limit), max_error)
|
||||||
|
<< "Error: 4x4 FHT/IHT has an individual round trip error > "
|
||||||
|
<< limit;
|
||||||
|
|
||||||
|
EXPECT_GE(count_test_block * limit, total_error)
|
||||||
|
<< "Error: 4x4 FHT/IHT has average round trip error > " << limit
|
||||||
|
<< " per block";
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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_);
|
||||||
|
|
||||||
|
fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
|
||||||
|
|
||||||
|
// The minimum quant value is 4.
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
input_extreme_block[j] = mask_;
|
||||||
|
} else if (i == 1) {
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j)
|
||||||
|
input_extreme_block[j] = -mask_;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
|
||||||
|
output_block, pitch_));
|
||||||
|
|
||||||
|
// The minimum quant value is 4.
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
EXPECT_EQ(output_block[j], output_ref_block[j]);
|
||||||
|
EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j]))
|
||||||
|
<< "Error: 4x4 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 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) {
|
||||||
|
src[j] = rnd.Rand8();
|
||||||
|
dst[j] = rnd.Rand8();
|
||||||
|
in[j] = src[j] - dst[j];
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
|
in[j] = src16[j] - dst16[j];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fwd_txfm_ref(in, coeff, pitch_, tx_type_);
|
||||||
|
|
||||||
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
} else {
|
||||||
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
|
pitch_));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
const uint32_t diff =
|
||||||
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
|
#else
|
||||||
|
const uint32_t diff = dst[j] - src[j];
|
||||||
|
#endif
|
||||||
|
const uint32_t error = diff * diff;
|
||||||
|
EXPECT_GE(static_cast<uint32_t>(limit), error)
|
||||||
|
<< "Error: 4x4 IDCT has error " << error
|
||||||
|
<< " at index " << j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pitch_;
|
||||||
|
int tx_type_;
|
||||||
|
FhtFunc fwd_txfm_ref;
|
||||||
|
vpx_bit_depth_t bit_depth_;
|
||||||
|
int mask_;
|
||||||
|
};
|
||||||
|
|
||||||
class Trans4x4DCT
|
class Trans4x4DCT
|
||||||
: public libvpx_test::TransformTestBase,
|
: public Trans4x4TestBase,
|
||||||
public ::testing::TestWithParam<Dct4x4Param> {
|
public ::testing::TestWithParam<Dct4x4Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans4x4DCT() {}
|
virtual ~Trans4x4DCT() {}
|
||||||
@@ -105,7 +291,6 @@ class Trans4x4DCT
|
|||||||
fwd_txfm_ref = fdct4x4_ref;
|
fwd_txfm_ref = fdct4x4_ref;
|
||||||
bit_depth_ = GET_PARAM(3);
|
bit_depth_ = GET_PARAM(3);
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
num_coeffs_ = GET_PARAM(4);
|
|
||||||
}
|
}
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
@@ -138,7 +323,7 @@ TEST_P(Trans4x4DCT, InvAccuracyCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Trans4x4HT
|
class Trans4x4HT
|
||||||
: public libvpx_test::TransformTestBase,
|
: public Trans4x4TestBase,
|
||||||
public ::testing::TestWithParam<Ht4x4Param> {
|
public ::testing::TestWithParam<Ht4x4Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans4x4HT() {}
|
virtual ~Trans4x4HT() {}
|
||||||
@@ -151,7 +336,6 @@ class Trans4x4HT
|
|||||||
fwd_txfm_ref = fht4x4_ref;
|
fwd_txfm_ref = fht4x4_ref;
|
||||||
bit_depth_ = GET_PARAM(3);
|
bit_depth_ = GET_PARAM(3);
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
num_coeffs_ = GET_PARAM(4);
|
|
||||||
}
|
}
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
@@ -185,7 +369,7 @@ TEST_P(Trans4x4HT, InvAccuracyCheck) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Trans4x4WHT
|
class Trans4x4WHT
|
||||||
: public libvpx_test::TransformTestBase,
|
: public Trans4x4TestBase,
|
||||||
public ::testing::TestWithParam<Dct4x4Param> {
|
public ::testing::TestWithParam<Dct4x4Param> {
|
||||||
public:
|
public:
|
||||||
virtual ~Trans4x4WHT() {}
|
virtual ~Trans4x4WHT() {}
|
||||||
@@ -198,7 +382,6 @@ class Trans4x4WHT
|
|||||||
fwd_txfm_ref = fwht4x4_ref;
|
fwd_txfm_ref = fwht4x4_ref;
|
||||||
bit_depth_ = GET_PARAM(3);
|
bit_depth_ = GET_PARAM(3);
|
||||||
mask_ = (1 << bit_depth_) - 1;
|
mask_ = (1 << bit_depth_) - 1;
|
||||||
num_coeffs_ = GET_PARAM(4);
|
|
||||||
}
|
}
|
||||||
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
virtual void TearDown() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
@@ -231,155 +414,126 @@ TEST_P(Trans4x4WHT, InvAccuracyCheck) {
|
|||||||
}
|
}
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans4x4DCT,
|
C, Trans4x4DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12, 16),
|
make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
make_tuple(&vp9_fdct4x4_c, &vp9_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans4x4DCT,
|
C, Trans4x4DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct4x4_c, &vpx_idct4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
make_tuple(&vp9_fdct4x4_c, &vp9_idct4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans4x4HT,
|
C, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 0, VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 1, VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 2, VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 2, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_10, 3, VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 0, VPX_BITS_12, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 1, VPX_BITS_12, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 2, VPX_BITS_12, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 2, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht4x4_c, &iht4x4_12, 3, VPX_BITS_12, 16),
|
make_tuple(&vp9_highbd_fht4x4_c, &iht4x4_12, 3, VPX_BITS_12),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 0, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 1, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 2, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 3, VPX_BITS_8, 16)));
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans4x4HT,
|
C, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 0, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 1, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 2, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_c, 3, VPX_BITS_8, 16)));
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans4x4WHT,
|
C, Trans4x4WHT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12, 16),
|
make_tuple(&vp9_highbd_fwht4x4_c, &iwht4x4_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
make_tuple(&vp9_fwht4x4_c, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, Trans4x4WHT,
|
C, Trans4x4WHT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_c, 0, VPX_BITS_8, 16)));
|
make_tuple(&vp9_fwht4x4_c, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans4x4DCT,
|
NEON, Trans4x4DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
make_tuple(&vp9_fdct4x4_c,
|
||||||
&vpx_idct4x4_16_add_neon, 0, VPX_BITS_8, 16)));
|
&vp9_idct4x4_16_add_neon, 0, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Trans4x4HT,
|
NEON, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 0, VPX_BITS_8),
|
||||||
0, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 2, VPX_BITS_8),
|
||||||
1, VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_c, &vp9_iht4x4_16_add_neon, 3, VPX_BITS_8)));
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
2, VPX_BITS_8, 16),
|
|
||||||
make_tuple(&vp10_fht4x4_c, &vp10_iht4x4_16_add_neon,
|
|
||||||
3, VPX_BITS_8, 16)));
|
|
||||||
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_EMULATE_HARDWARE
|
#if CONFIG_USE_X86INC && HAVE_MMX && !CONFIG_VP9_HIGHBITDEPTH && \
|
||||||
|
!CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4WHT,
|
MMX, Trans4x4WHT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_c,
|
make_tuple(&vp9_fwht4x4_mmx, &vp9_iwht4x4_16_add_c, 0, VPX_BITS_8)));
|
||||||
0, VPX_BITS_8, 16),
|
|
||||||
make_tuple(&vp10_fwht4x4_c, &vpx_iwht4x4_16_add_sse2,
|
|
||||||
0, VPX_BITS_8, 16)));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4DCT,
|
SSE2, Trans4x4DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct4x4_sse2,
|
make_tuple(&vp9_fdct4x4_sse2,
|
||||||
&vpx_idct4x4_16_add_sse2, 0, VPX_BITS_8, 16)));
|
&vp9_idct4x4_16_add_sse2, 0, VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4HT,
|
SSE2, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 0,
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 0, VPX_BITS_8),
|
||||||
VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 1,
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 2, VPX_BITS_8),
|
||||||
VPX_BITS_8, 16),
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_sse2, 3, VPX_BITS_8)));
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 2,
|
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
VPX_BITS_8, 16),
|
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_sse2, 3,
|
|
||||||
VPX_BITS_8, 16)));
|
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4DCT,
|
SSE2, Trans4x4DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_10_sse2, 0,
|
make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_10_sse2, 0, VPX_BITS_10),
|
||||||
VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_10_sse2, 0,
|
make_tuple(&vp9_highbd_fdct4x4_c, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||||
VPX_BITS_10, 16),
|
make_tuple(&vp9_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct4x4_c, &idct4x4_12_sse2, 0,
|
make_tuple(&vp9_fdct4x4_sse2, &vp9_idct4x4_16_add_c, 0,
|
||||||
VPX_BITS_12, 16),
|
VPX_BITS_8)));
|
||||||
make_tuple(&vpx_highbd_fdct4x4_sse2, &idct4x4_12_sse2, 0,
|
|
||||||
VPX_BITS_12, 16),
|
|
||||||
make_tuple(&vpx_fdct4x4_sse2, &vpx_idct4x4_16_add_c, 0,
|
|
||||||
VPX_BITS_8, 16)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Trans4x4HT,
|
SSE2, Trans4x4HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 0, VPX_BITS_10),
|
||||||
0, VPX_BITS_8, 16),
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 2, VPX_BITS_10),
|
||||||
1, VPX_BITS_8, 16),
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 0, VPX_BITS_12),
|
||||||
2, VPX_BITS_8, 16),
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp10_fht4x4_sse2, &vp10_iht4x4_16_add_c,
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 2, VPX_BITS_12),
|
||||||
3, VPX_BITS_8, 16)));
|
make_tuple(&vp9_highbd_fht4x4_sse2, &iht4x4_12, 3, VPX_BITS_12),
|
||||||
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 0, VPX_BITS_8),
|
||||||
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 1, VPX_BITS_8),
|
||||||
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 2, VPX_BITS_8),
|
||||||
INSTANTIATE_TEST_CASE_P(
|
make_tuple(&vp9_fht4x4_sse2, &vp9_iht4x4_16_add_c, 3, VPX_BITS_8)));
|
||||||
MSA, Trans4x4DCT,
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct4x4_msa, &vpx_idct4x4_16_add_msa, 0,
|
|
||||||
VPX_BITS_8, 16)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Trans4x4HT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 0,
|
|
||||||
VPX_BITS_8, 16),
|
|
||||||
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 1,
|
|
||||||
VPX_BITS_8, 16),
|
|
||||||
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 2,
|
|
||||||
VPX_BITS_8, 16),
|
|
||||||
make_tuple(&vp10_fht4x4_msa, &vp10_iht4x4_16_add_msa, 3,
|
|
||||||
VPX_BITS_8, 16)));
|
|
||||||
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -13,41 +13,19 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp10/common/entropy.h"
|
|
||||||
#include "vp10/common/scan.h"
|
#include "./vp9_rtcd.h"
|
||||||
|
#include "vp9/common/vp9_entropy.h"
|
||||||
#include "vpx/vpx_codec.h"
|
#include "vpx/vpx_codec.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const int kNumCoeffs = 64;
|
const int kNumCoeffs = 64;
|
||||||
const double kPi = 3.141592653589793238462643383279502884;
|
const double kPi = 3.141592653589793238462643383279502884;
|
||||||
|
void reference_8x8_dct_1d(const double in[8], double out[8], int stride) {
|
||||||
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]) {
|
|
||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
for (int k = 0; k < 8; k++) {
|
for (int k = 0; k < 8; k++) {
|
||||||
out[k] = 0.0;
|
out[k] = 0.0;
|
||||||
@@ -65,7 +43,7 @@ void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
|
|||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j)
|
||||||
temp_in[j] = input[j*8 + i];
|
temp_in[j] = input[j*8 + i];
|
||||||
reference_8x8_dct_1d(temp_in, temp_out);
|
reference_8x8_dct_1d(temp_in, temp_out, 1);
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j)
|
||||||
output[j * 8 + i] = temp_out[j];
|
output[j * 8 + i] = temp_out[j];
|
||||||
}
|
}
|
||||||
@@ -74,67 +52,82 @@ void reference_8x8_dct_2d(const int16_t input[kNumCoeffs],
|
|||||||
double temp_in[8], temp_out[8];
|
double temp_in[8], temp_out[8];
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j)
|
||||||
temp_in[j] = output[j + i*8];
|
temp_in[j] = output[j + i*8];
|
||||||
reference_8x8_dct_1d(temp_in, temp_out);
|
reference_8x8_dct_1d(temp_in, temp_out, 1);
|
||||||
// Scale by some magic number
|
// Scale by some magic number
|
||||||
for (int j = 0; j < 8; ++j)
|
for (int j = 0; j < 8; ++j)
|
||||||
output[j + i * 8] = temp_out[j] * 2;
|
output[j + i * 8] = temp_out[j] * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
void fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride,
|
namespace {
|
||||||
int /*tx_type*/) {
|
|
||||||
vpx_fdct8x8_c(in, out, stride);
|
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 fdct8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
|
vp9_fdct8x8_c(in, out, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
void fht8x8_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
|
||||||
vp10_fht8x8_c(in, out, stride, tx_type);
|
vp9_fht8x8_c(in, out, stride, tx_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 10);
|
vp9_highbd_idct8x8_64_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_12(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_c(in, out, stride, 12);
|
vp9_highbd_idct8x8_64_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht8x8_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp10_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 10);
|
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
void iht8x8_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
|
||||||
vp10_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 12);
|
vp9_highbd_iht8x8_64_add_c(in, out, stride, tx_type, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
|
|
||||||
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_c(in, out, stride, 10);
|
vp9_highbd_idct8x8_10_add_c(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_c(in, out, stride, 12);
|
vp9_highbd_idct8x8_10_add_c(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
|
vp9_highbd_idct8x8_10_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_10_add_sse2(in, out, stride, 12);
|
vp9_highbd_idct8x8_10_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
|
vp9_highbd_idct8x8_64_add_sse2(in, out, stride, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
void idct8x8_64_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
|
||||||
vpx_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
|
vp9_highbd_idct8x8_64_add_sse2(in, out, stride, 12);
|
||||||
}
|
}
|
||||||
#endif // HAVE_SSE2
|
#endif // HAVE_SSE2
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
class FwdTrans8x8TestBase {
|
class FwdTrans8x8TestBase {
|
||||||
public:
|
public:
|
||||||
@@ -146,8 +139,8 @@ class FwdTrans8x8TestBase {
|
|||||||
|
|
||||||
void RunSignBiasCheck() {
|
void RunSignBiasCheck() {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_output_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_output_block, 64);
|
||||||
int count_sign_block[64][2];
|
int count_sign_block[64][2];
|
||||||
const int count_test_block = 100000;
|
const int count_test_block = 100000;
|
||||||
|
|
||||||
@@ -217,13 +210,13 @@ class FwdTrans8x8TestBase {
|
|||||||
int max_error = 0;
|
int max_error = 0;
|
||||||
int total_error = 0;
|
int total_error = 0;
|
||||||
const int count_test_block = 100000;
|
const int count_test_block = 100000;
|
||||||
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -233,7 +226,7 @@ class FwdTrans8x8TestBase {
|
|||||||
src[j] = rnd.Rand8();
|
src[j] = rnd.Rand8();
|
||||||
dst[j] = rnd.Rand8();
|
dst[j] = rnd.Rand8();
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand16() & mask_;
|
src16[j] = rnd.Rand16() & mask_;
|
||||||
dst16[j] = rnd.Rand16() & mask_;
|
dst16[j] = rnd.Rand16() & mask_;
|
||||||
@@ -258,7 +251,7 @@ class FwdTrans8x8TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, dst, pitch_));
|
RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
@@ -266,7 +259,7 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
@@ -294,14 +287,14 @@ class FwdTrans8x8TestBase {
|
|||||||
int total_error = 0;
|
int total_error = 0;
|
||||||
int total_coeff_error = 0;
|
int total_coeff_error = 0;
|
||||||
const int count_test_block = 100000;
|
const int count_test_block = 100000;
|
||||||
DECLARE_ALIGNED(16, int16_t, test_input_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_temp_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, 64);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, ref_temp_block[64]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_temp_block, 64);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, 64);
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[64]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, 64);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -319,7 +312,7 @@ class FwdTrans8x8TestBase {
|
|||||||
dst[j] = rnd.Rand8() % 2 ? 255 : 0;
|
dst[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||||
}
|
}
|
||||||
test_input_block[j] = src[j] - dst[j];
|
test_input_block[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
src16[j] = mask_;
|
src16[j] = mask_;
|
||||||
@@ -343,7 +336,7 @@ class FwdTrans8x8TestBase {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, dst, pitch_));
|
RunInvTxfm(test_temp_block, dst, pitch_));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
|
||||||
@@ -351,7 +344,7 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int diff =
|
const int diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
@@ -383,13 +376,13 @@ class FwdTrans8x8TestBase {
|
|||||||
void RunInvAccuracyCheck() {
|
void RunInvAccuracyCheck() {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -401,7 +394,7 @@ class FwdTrans8x8TestBase {
|
|||||||
src[j] = rnd.Rand8() % 2 ? 255 : 0;
|
src[j] = rnd.Rand8() % 2 ? 255 : 0;
|
||||||
dst[j] = src[j] > 0 ? 0 : 255;
|
dst[j] = src[j] > 0 ? 0 : 255;
|
||||||
in[j] = src[j] - dst[j];
|
in[j] = src[j] - dst[j];
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
src16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
src16[j] = rnd.Rand8() % 2 ? mask_ : 0;
|
||||||
dst16[j] = src16[j] > 0 ? 0 : mask_;
|
dst16[j] = src16[j] > 0 ? 0 : mask_;
|
||||||
@@ -416,7 +409,7 @@ class FwdTrans8x8TestBase {
|
|||||||
|
|
||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
pitch_));
|
pitch_));
|
||||||
@@ -424,11 +417,11 @@ class FwdTrans8x8TestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
|
||||||
#else
|
#else
|
||||||
const int diff = dst[j] - src[j];
|
const uint32_t diff = dst[j] - src[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
EXPECT_GE(1u << 2 * (bit_depth_ - 8), error)
|
||||||
@@ -441,9 +434,9 @@ class FwdTrans8x8TestBase {
|
|||||||
void RunFwdAccuracyCheck() {
|
void RunFwdAccuracyCheck() {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff_r[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_r, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
double out_r[kNumCoeffs];
|
double out_r[kNumCoeffs];
|
||||||
@@ -458,7 +451,7 @@ class FwdTrans8x8TestBase {
|
|||||||
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
coeff_r[j] = static_cast<tran_low_t>(round(out_r[j]));
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
const int32_t diff = coeff[j] - coeff_r[j];
|
const uint32_t diff = coeff[j] - coeff_r[j];
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
EXPECT_GE(9u << 2 * (bit_depth_ - 8), error)
|
||||||
<< "Error: 8x8 DCT has error " << error
|
<< "Error: 8x8 DCT has error " << error
|
||||||
@@ -471,14 +464,14 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
|||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 10000;
|
const int count_test_block = 10000;
|
||||||
const int eob = 12;
|
const int eob = 12;
|
||||||
DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs);
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref16, kNumCoeffs);
|
||||||
#endif
|
#endif
|
||||||
const int16_t *scan = vp10_default_scan_orders[TX_8X8].scan;
|
const int16_t *scan = vp9_default_scan_orders[TX_8X8].scan;
|
||||||
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
@@ -491,7 +484,7 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
dst[j] = 0;
|
dst[j] = 0;
|
||||||
ref[j] = 0;
|
ref[j] = 0;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
dst16[j] = 0;
|
dst16[j] = 0;
|
||||||
ref16[j] = 0;
|
ref16[j] = 0;
|
||||||
@@ -501,7 +494,7 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
|||||||
if (bit_depth_ == VPX_BITS_8) {
|
if (bit_depth_ == VPX_BITS_8) {
|
||||||
ref_txfm(coeff, ref, pitch_);
|
ref_txfm(coeff, ref, pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
} else {
|
} else {
|
||||||
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
|
||||||
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16),
|
||||||
@@ -510,11 +503,11 @@ void CompareInvReference(IdctFunc ref_txfm, int thresh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int diff =
|
const uint32_t diff =
|
||||||
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
|
||||||
#else
|
#else
|
||||||
const int diff = dst[j] - ref[j];
|
const uint32_t diff = dst[j] - ref[j];
|
||||||
#endif
|
#endif
|
||||||
const uint32_t error = diff * diff;
|
const uint32_t error = diff * diff;
|
||||||
EXPECT_EQ(0u, error)
|
EXPECT_EQ(0u, error)
|
||||||
@@ -643,7 +636,7 @@ class InvTrans8x8DCT
|
|||||||
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
|
||||||
inv_txfm_(out, dst, stride);
|
inv_txfm_(out, dst, stride);
|
||||||
}
|
}
|
||||||
void RunFwdTxfm(int16_t * /*out*/, tran_low_t * /*dst*/, int /*stride*/) {}
|
void RunFwdTxfm(int16_t *out, tran_low_t *dst, int stride) {}
|
||||||
|
|
||||||
IdctFunc ref_txfm_;
|
IdctFunc ref_txfm_;
|
||||||
IdctFunc inv_txfm_;
|
IdctFunc inv_txfm_;
|
||||||
@@ -656,104 +649,108 @@ TEST_P(InvTrans8x8DCT, CompareReference) {
|
|||||||
|
|
||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8DCT,
|
C, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
make_tuple(&vp9_highbd_fdct8x8_c, &idct8x8_12, 0, VPX_BITS_12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8DCT,
|
C, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_c, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8)));
|
make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8HT,
|
C, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 0, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 1, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 2, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_10, 3, VPX_BITS_10),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 0, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 1, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 2, VPX_BITS_12),
|
||||||
make_tuple(&vp10_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12),
|
make_tuple(&vp9_highbd_fht8x8_c, &iht8x8_12, 3, VPX_BITS_12),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
#else
|
#else
|
||||||
|
// TODO(jingning): re-enable after this handles the expanded range [0, 65535]
|
||||||
|
// returned from Rand16().
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, FwdTrans8x8HT,
|
C, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
#if HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#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(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, FwdTrans8x8DCT,
|
NEON, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_neon, &vpx_idct8x8_64_add_neon, 0,
|
make_tuple(&vp9_fdct8x8_neon, &vp9_idct8x8_64_add_neon, 0,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON_ASM && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, FwdTrans8x8HT,
|
NEON, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 0, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_c, &vp10_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3, VPX_BITS_8)));
|
||||||
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VPX_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(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8DCT,
|
SSE2, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_sse2, 0,
|
make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_sse2, 0,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8HT,
|
SSE2, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 0, VPX_BITS_8),
|
||||||
0, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2, VPX_BITS_8),
|
||||||
1, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3, VPX_BITS_8)));
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
#endif // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_sse2,
|
|
||||||
3, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
#if HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8DCT,
|
SSE2, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_sse2, &vpx_idct8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
make_tuple(&vp9_highbd_fdct8x8_c,
|
||||||
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
make_tuple(&vp9_highbd_fdct8x8_sse2,
|
||||||
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
&idct8x8_64_add_10_sse2, 12, VPX_BITS_10),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_c,
|
make_tuple(&vp9_highbd_fdct8x8_c,
|
||||||
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
|
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12),
|
||||||
make_tuple(&vpx_highbd_fdct8x8_sse2,
|
make_tuple(&vp9_highbd_fdct8x8_sse2,
|
||||||
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
&idct8x8_64_add_12_sse2, 12, VPX_BITS_12)));
|
||||||
|
|
||||||
|
// TODO(jingning): re-enable after these handle the expanded range [0, 65535]
|
||||||
|
// returned from Rand16().
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, FwdTrans8x8HT,
|
SSE2, FwdTrans8x8HT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 0, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 0, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 1, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 1, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 2, VPX_BITS_8),
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 2, VPX_BITS_8),
|
||||||
make_tuple(&vp10_fht8x8_sse2, &vp10_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_c, 3, VPX_BITS_8)));
|
||||||
|
|
||||||
// Optimizations take effect at a threshold of 6201, so we use a value close to
|
// Optimizations take effect at a threshold of 6201, so we use a value close to
|
||||||
// that to test both branches.
|
// that to test both branches.
|
||||||
@@ -768,28 +765,16 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
&idct8x8_10_add_12_sse2, 6225, VPX_BITS_12),
|
&idct8x8_10_add_12_sse2, 6225, VPX_BITS_12),
|
||||||
make_tuple(&idct8x8_12,
|
make_tuple(&idct8x8_12,
|
||||||
&idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
&idct8x8_64_add_12_sse2, 6225, VPX_BITS_12)));
|
||||||
#endif // HAVE_SSE2 && CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
|
|
||||||
#if HAVE_SSSE3 && ARCH_X86_64 && \
|
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
|
||||||
!CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
!CONFIG_EMULATE_HARDWARE
|
||||||
|
// TODO(jingning): re-enable after this handles the expanded range [0, 65535]
|
||||||
|
// returned from Rand16().
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSSE3, FwdTrans8x8DCT,
|
SSSE3, FwdTrans8x8DCT,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_ssse3, &vpx_idct8x8_64_add_ssse3, 0,
|
make_tuple(&vp9_fdct8x8_ssse3, &vp9_idct8x8_64_add_ssse3, 0,
|
||||||
VPX_BITS_8)));
|
VPX_BITS_8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, FwdTrans8x8DCT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_fdct8x8_msa, &vpx_idct8x8_64_add_msa, 0, VPX_BITS_8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, FwdTrans8x8HT,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 0, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 1, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 2, VPX_BITS_8),
|
|
||||||
make_tuple(&vp10_fht8x8_msa, &vp10_iht8x8_64_add_msa, 3, VPX_BITS_8)));
|
|
||||||
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class VP9FrameSizeTestsLarge
|
|||||||
: public ::libvpx_test::EncoderTest,
|
: public ::libvpx_test::EncoderTest,
|
||||||
public ::testing::Test {
|
public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
VP9FrameSizeTestsLarge() : EncoderTest(&::libvpx_test::kVP10),
|
VP9FrameSizeTestsLarge() : EncoderTest(&::libvpx_test::kVP9),
|
||||||
expected_res_(VPX_CODEC_OK) {}
|
expected_res_(VPX_CODEC_OK) {}
|
||||||
virtual ~VP9FrameSizeTestsLarge() {}
|
virtual ~VP9FrameSizeTestsLarge() {}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ TEST_F(VP9FrameSizeTestsLarge, ValidSizes) {
|
|||||||
// size or almost 1 gig of memory.
|
// size or almost 1 gig of memory.
|
||||||
// In total the allocations will exceed 2GiB which may cause a failure with
|
// In total the allocations will exceed 2GiB which may cause a failure with
|
||||||
// mingw + wine, use a smaller size in that case.
|
// mingw + wine, use a smaller size in that case.
|
||||||
#if defined(_WIN32) && !defined(_WIN64) || defined(__OS2__)
|
#if defined(_WIN32) && !defined(_WIN64)
|
||||||
video.SetSize(4096, 3072);
|
video.SetSize(4096, 3072);
|
||||||
#else
|
#else
|
||||||
video.SetSize(4096, 4096);
|
video.SetSize(4096, 4096);
|
||||||
|
|||||||
@@ -1,65 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TEST_FUNCTION_EQUIVALENCE_TEST_H_
|
|
||||||
#define TEST_FUNCTION_EQUIVALENCE_TEST_H_
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/clear_system_state.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace libvpx_test {
|
|
||||||
// Base class for tests that compare 2 implementations of the same function
|
|
||||||
// for equivalence. The template parameter should be pointer to a function
|
|
||||||
// that is being tested.
|
|
||||||
//
|
|
||||||
// The test takes a 3-parameters encapsulating struct 'FuncParam', containing:
|
|
||||||
// - Pointer to reference function
|
|
||||||
// - Pointer to tested function
|
|
||||||
// - Integer bit depth (default to 0).
|
|
||||||
//
|
|
||||||
// These values are then accessible in the tests as member of params_:
|
|
||||||
// params_.ref_func, params_.tst_func, and params_.bit_depth.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct FuncParam {
|
|
||||||
FuncParam(T ref = NULL, T tst = NULL, int bit_depth = 0)
|
|
||||||
: ref_func(ref), tst_func(tst), bit_depth(bit_depth) {}
|
|
||||||
T ref_func;
|
|
||||||
T tst_func;
|
|
||||||
int bit_depth;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class FunctionEquivalenceTest : public ::testing::TestWithParam<FuncParam<T> > {
|
|
||||||
public:
|
|
||||||
FunctionEquivalenceTest() : rng_(ACMRandom::DeterministicSeed()) {}
|
|
||||||
|
|
||||||
virtual ~FunctionEquivalenceTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
params_ = this->GetParam();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void TearDown() {
|
|
||||||
libvpx_test::ClearSystemState();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ACMRandom rng_;
|
|
||||||
FuncParam<T> params_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace libvpx_test
|
|
||||||
#endif // TEST_FUNCTION_EQUIVALENCE_TEST_H_
|
|
||||||
@@ -1,220 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
typedef void (*HadamardFunc)(const int16_t *a, int a_stride, int16_t *b);
|
|
||||||
|
|
||||||
void hadamard_loop(const int16_t *a, int a_stride, int16_t *out) {
|
|
||||||
int16_t b[8];
|
|
||||||
for (int i = 0; i < 8; i += 2) {
|
|
||||||
b[i + 0] = a[i * a_stride] + a[(i + 1) * a_stride];
|
|
||||||
b[i + 1] = a[i * a_stride] - a[(i + 1) * a_stride];
|
|
||||||
}
|
|
||||||
int16_t c[8];
|
|
||||||
for (int i = 0; i < 8; i += 4) {
|
|
||||||
c[i + 0] = b[i + 0] + b[i + 2];
|
|
||||||
c[i + 1] = b[i + 1] + b[i + 3];
|
|
||||||
c[i + 2] = b[i + 0] - b[i + 2];
|
|
||||||
c[i + 3] = b[i + 1] - b[i + 3];
|
|
||||||
}
|
|
||||||
out[0] = c[0] + c[4];
|
|
||||||
out[7] = c[1] + c[5];
|
|
||||||
out[3] = c[2] + c[6];
|
|
||||||
out[4] = c[3] + c[7];
|
|
||||||
out[2] = c[0] - c[4];
|
|
||||||
out[6] = c[1] - c[5];
|
|
||||||
out[1] = c[2] - c[6];
|
|
||||||
out[5] = c[3] - c[7];
|
|
||||||
}
|
|
||||||
|
|
||||||
void reference_hadamard8x8(const int16_t *a, int a_stride, int16_t *b) {
|
|
||||||
int16_t buf[64];
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
hadamard_loop(a + i, a_stride, buf + i * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
hadamard_loop(buf + i, 8, b + i * 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reference_hadamard16x16(const int16_t *a, int a_stride, int16_t *b) {
|
|
||||||
/* The source is a 16x16 block. The destination is rearranged to 8x32.
|
|
||||||
* Input is 9 bit. */
|
|
||||||
reference_hadamard8x8(a + 0 + 0 * a_stride, a_stride, b + 0);
|
|
||||||
reference_hadamard8x8(a + 8 + 0 * a_stride, a_stride, b + 64);
|
|
||||||
reference_hadamard8x8(a + 0 + 8 * a_stride, a_stride, b + 128);
|
|
||||||
reference_hadamard8x8(a + 8 + 8 * a_stride, a_stride, b + 192);
|
|
||||||
|
|
||||||
/* Overlay the 8x8 blocks and combine. */
|
|
||||||
for (int i = 0; i < 64; ++i) {
|
|
||||||
/* 8x8 steps the range up to 15 bits. */
|
|
||||||
const int16_t a0 = b[0];
|
|
||||||
const int16_t a1 = b[64];
|
|
||||||
const int16_t a2 = b[128];
|
|
||||||
const int16_t a3 = b[192];
|
|
||||||
|
|
||||||
/* Prevent the result from escaping int16_t. */
|
|
||||||
const int16_t b0 = (a0 + a1) >> 1;
|
|
||||||
const int16_t b1 = (a0 - a1) >> 1;
|
|
||||||
const int16_t b2 = (a2 + a3) >> 1;
|
|
||||||
const int16_t b3 = (a2 - a3) >> 1;
|
|
||||||
|
|
||||||
/* Store a 16 bit value. */
|
|
||||||
b[ 0] = b0 + b2;
|
|
||||||
b[ 64] = b1 + b3;
|
|
||||||
b[128] = b0 - b2;
|
|
||||||
b[192] = b1 - b3;
|
|
||||||
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HadamardTestBase : public ::testing::TestWithParam<HadamardFunc> {
|
|
||||||
public:
|
|
||||||
virtual void SetUp() {
|
|
||||||
h_func_ = GetParam();
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
HadamardFunc h_func_;
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Hadamard8x8Test : public HadamardTestBase {};
|
|
||||||
|
|
||||||
TEST_P(Hadamard8x8Test, CompareReferenceRandom) {
|
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64]);
|
|
||||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
|
||||||
int16_t b_ref[64];
|
|
||||||
for (int i = 0; i < 64; ++i) {
|
|
||||||
a[i] = rnd_.Rand9Signed();
|
|
||||||
}
|
|
||||||
memset(b, 0, sizeof(b));
|
|
||||||
memset(b_ref, 0, sizeof(b_ref));
|
|
||||||
|
|
||||||
reference_hadamard8x8(a, 8, b_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 8, b));
|
|
||||||
|
|
||||||
// The order of the output is not important. Sort before checking.
|
|
||||||
std::sort(b, b + 64);
|
|
||||||
std::sort(b_ref, b_ref + 64);
|
|
||||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Hadamard8x8Test, VaryStride) {
|
|
||||||
DECLARE_ALIGNED(16, int16_t, a[64 * 8]);
|
|
||||||
DECLARE_ALIGNED(16, int16_t, b[64]);
|
|
||||||
int16_t b_ref[64];
|
|
||||||
for (int i = 0; i < 64 * 8; ++i) {
|
|
||||||
a[i] = rnd_.Rand9Signed();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 8; i < 64; i += 8) {
|
|
||||||
memset(b, 0, sizeof(b));
|
|
||||||
memset(b_ref, 0, sizeof(b_ref));
|
|
||||||
|
|
||||||
reference_hadamard8x8(a, i, b_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
|
||||||
|
|
||||||
// The order of the output is not important. Sort before checking.
|
|
||||||
std::sort(b, b + 64);
|
|
||||||
std::sort(b_ref, b_ref + 64);
|
|
||||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, Hadamard8x8Test,
|
|
||||||
::testing::Values(&vpx_hadamard_8x8_c));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard8x8Test,
|
|
||||||
::testing::Values(&vpx_hadamard_8x8_sse2));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_SSSE3 && ARCH_X86_64
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSSE3, Hadamard8x8Test,
|
|
||||||
::testing::Values(&vpx_hadamard_8x8_ssse3));
|
|
||||||
#endif // HAVE_SSSE3 && ARCH_X86_64
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard8x8Test,
|
|
||||||
::testing::Values(&vpx_hadamard_8x8_neon));
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
|
|
||||||
class Hadamard16x16Test : public HadamardTestBase {};
|
|
||||||
|
|
||||||
TEST_P(Hadamard16x16Test, CompareReferenceRandom) {
|
|
||||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16]);
|
|
||||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
|
||||||
int16_t b_ref[16 * 16];
|
|
||||||
for (int i = 0; i < 16 * 16; ++i) {
|
|
||||||
a[i] = rnd_.Rand9Signed();
|
|
||||||
}
|
|
||||||
memset(b, 0, sizeof(b));
|
|
||||||
memset(b_ref, 0, sizeof(b_ref));
|
|
||||||
|
|
||||||
reference_hadamard16x16(a, 16, b_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(h_func_(a, 16, b));
|
|
||||||
|
|
||||||
// The order of the output is not important. Sort before checking.
|
|
||||||
std::sort(b, b + 16 * 16);
|
|
||||||
std::sort(b_ref, b_ref + 16 * 16);
|
|
||||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(Hadamard16x16Test, VaryStride) {
|
|
||||||
DECLARE_ALIGNED(16, int16_t, a[16 * 16 * 8]);
|
|
||||||
DECLARE_ALIGNED(16, int16_t, b[16 * 16]);
|
|
||||||
int16_t b_ref[16 * 16];
|
|
||||||
for (int i = 0; i < 16 * 16 * 8; ++i) {
|
|
||||||
a[i] = rnd_.Rand9Signed();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 8; i < 64; i += 8) {
|
|
||||||
memset(b, 0, sizeof(b));
|
|
||||||
memset(b_ref, 0, sizeof(b_ref));
|
|
||||||
|
|
||||||
reference_hadamard16x16(a, i, b_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(h_func_(a, i, b));
|
|
||||||
|
|
||||||
// The order of the output is not important. Sort before checking.
|
|
||||||
std::sort(b, b + 16 * 16);
|
|
||||||
std::sort(b_ref, b_ref + 16 * 16);
|
|
||||||
EXPECT_EQ(0, memcmp(b, b_ref, sizeof(b)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
|
|
||||||
::testing::Values(&vpx_hadamard_16x16_c));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
|
|
||||||
::testing::Values(&vpx_hadamard_16x16_sse2));
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
|
|
||||||
::testing::Values(&vpx_hadamard_16x16_neon));
|
|
||||||
#endif // HAVE_NEON
|
|
||||||
} // namespace
|
|
||||||
@@ -1,251 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "vpx_dsp/psnr.h"
|
|
||||||
#include "vpx_dsp/ssim.h"
|
|
||||||
#include "vpx_ports/mem.h"
|
|
||||||
#include "vpx_ports/msvc.h"
|
|
||||||
#include "vpx_scale/yv12config.h"
|
|
||||||
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef double (*LBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest);
|
|
||||||
typedef double (*HBDMetricFunc)(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest,
|
|
||||||
uint32_t in_bd, uint32_t bd);
|
|
||||||
|
|
||||||
double compute_hbd_psnr(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest,
|
|
||||||
uint32_t in_bd, uint32_t bd) {
|
|
||||||
PSNR_STATS psnr;
|
|
||||||
vpx_calc_highbd_psnr(source, dest, &psnr, bd, in_bd);
|
|
||||||
return psnr.psnr[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_psnr(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest) {
|
|
||||||
PSNR_STATS psnr;
|
|
||||||
vpx_calc_psnr(source, dest, &psnr);
|
|
||||||
return psnr.psnr[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_hbd_psnrhvs(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest,
|
|
||||||
uint32_t in_bd, uint32_t bd) {
|
|
||||||
double tempy, tempu, tempv;
|
|
||||||
return vpx_psnrhvs(source, dest,
|
|
||||||
&tempy, &tempu, &tempv, bd, in_bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_psnrhvs(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest) {
|
|
||||||
double tempy, tempu, tempv;
|
|
||||||
return vpx_psnrhvs(source, dest,
|
|
||||||
&tempy, &tempu, &tempv, 8, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_hbd_fastssim(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest,
|
|
||||||
uint32_t in_bd, uint32_t bd) {
|
|
||||||
double tempy, tempu, tempv;
|
|
||||||
return vpx_calc_fastssim(source, dest,
|
|
||||||
&tempy, &tempu, &tempv, bd, in_bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_fastssim(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest) {
|
|
||||||
double tempy, tempu, tempv;
|
|
||||||
return vpx_calc_fastssim(source, dest,
|
|
||||||
&tempy, &tempu, &tempv, 8, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_hbd_vpxssim(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest,
|
|
||||||
uint32_t in_bd, uint32_t bd) {
|
|
||||||
double ssim, weight;
|
|
||||||
ssim = vpx_highbd_calc_ssim(source, dest, &weight, bd, in_bd);
|
|
||||||
return 100 * pow(ssim / weight, 8.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
double compute_vpxssim(const YV12_BUFFER_CONFIG *source,
|
|
||||||
const YV12_BUFFER_CONFIG *dest) {
|
|
||||||
double ssim, weight;
|
|
||||||
ssim = vpx_calc_ssim(source, dest, &weight);
|
|
||||||
return 100 * pow(ssim / weight, 8.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class HBDMetricsTestBase {
|
|
||||||
public:
|
|
||||||
virtual ~HBDMetricsTestBase() {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void RunAccuracyCheck() {
|
|
||||||
const int width = 1920;
|
|
||||||
const int height = 1080;
|
|
||||||
int i = 0;
|
|
||||||
const uint8_t kPixFiller = 128;
|
|
||||||
YV12_BUFFER_CONFIG lbd_src, lbd_dst;
|
|
||||||
YV12_BUFFER_CONFIG hbd_src, hbd_dst;
|
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
|
||||||
double lbd_db, hbd_db;
|
|
||||||
|
|
||||||
memset(&lbd_src, 0, sizeof(lbd_src));
|
|
||||||
memset(&lbd_dst, 0, sizeof(lbd_dst));
|
|
||||||
memset(&hbd_src, 0, sizeof(hbd_src));
|
|
||||||
memset(&hbd_dst, 0, sizeof(hbd_dst));
|
|
||||||
|
|
||||||
vpx_alloc_frame_buffer(&lbd_src, width, height, 1, 1, 0, 32, 16);
|
|
||||||
vpx_alloc_frame_buffer(&lbd_dst, width, height, 1, 1, 0, 32, 16);
|
|
||||||
vpx_alloc_frame_buffer(&hbd_src, width, height, 1, 1, 1, 32, 16);
|
|
||||||
vpx_alloc_frame_buffer(&hbd_dst, width, height, 1, 1, 1, 32, 16);
|
|
||||||
|
|
||||||
memset(lbd_src.buffer_alloc, kPixFiller, lbd_src.buffer_alloc_sz);
|
|
||||||
while (i < lbd_src.buffer_alloc_sz) {
|
|
||||||
uint16_t spel, dpel;
|
|
||||||
spel = lbd_src.buffer_alloc[i];
|
|
||||||
// Create some distortion for dst buffer.
|
|
||||||
dpel = rnd.Rand8();
|
|
||||||
lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
|
|
||||||
((uint16_t*)(hbd_src.buffer_alloc))[i] = spel << (bit_depth_ - 8);
|
|
||||||
((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
|
|
||||||
hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
|
|
||||||
EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < lbd_src.buffer_alloc_sz) {
|
|
||||||
uint16_t dpel;
|
|
||||||
// Create some small distortion for dst buffer.
|
|
||||||
dpel = 120 + (rnd.Rand8() >> 4);
|
|
||||||
lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
|
|
||||||
((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
|
|
||||||
hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
|
|
||||||
EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (i < lbd_src.buffer_alloc_sz) {
|
|
||||||
uint16_t dpel;
|
|
||||||
// Create some small distortion for dst buffer.
|
|
||||||
dpel = 126 + (rnd.Rand8() >> 6);
|
|
||||||
lbd_dst.buffer_alloc[i] = (uint8_t)dpel;
|
|
||||||
((uint16_t*)(hbd_dst.buffer_alloc))[i] = dpel << (bit_depth_ - 8);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
lbd_db = lbd_metric_(&lbd_src, &lbd_dst);
|
|
||||||
hbd_db = hbd_metric_(&hbd_src, &hbd_dst, input_bit_depth_, bit_depth_);
|
|
||||||
EXPECT_LE(fabs(lbd_db - hbd_db), threshold_);
|
|
||||||
|
|
||||||
vpx_free_frame_buffer(&lbd_src);
|
|
||||||
vpx_free_frame_buffer(&lbd_dst);
|
|
||||||
vpx_free_frame_buffer(&hbd_src);
|
|
||||||
vpx_free_frame_buffer(&hbd_dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
int input_bit_depth_;
|
|
||||||
int bit_depth_;
|
|
||||||
double threshold_;
|
|
||||||
LBDMetricFunc lbd_metric_;
|
|
||||||
HBDMetricFunc hbd_metric_;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::tr1::tuple<LBDMetricFunc,
|
|
||||||
HBDMetricFunc, int, int, double> MetricTestTParam;
|
|
||||||
class HBDMetricsTest
|
|
||||||
: public HBDMetricsTestBase,
|
|
||||||
public ::testing::TestWithParam<MetricTestTParam> {
|
|
||||||
public:
|
|
||||||
virtual void SetUp() {
|
|
||||||
lbd_metric_ = GET_PARAM(0);
|
|
||||||
hbd_metric_ = GET_PARAM(1);
|
|
||||||
input_bit_depth_ = GET_PARAM(2);
|
|
||||||
bit_depth_ = GET_PARAM(3);
|
|
||||||
threshold_ = GET_PARAM(4);
|
|
||||||
}
|
|
||||||
virtual void TearDown() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(HBDMetricsTest, RunAccuracyCheck) {
|
|
||||||
RunAccuracyCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow small variation due to floating point operations.
|
|
||||||
static const double kSsim_thresh = 0.001;
|
|
||||||
// Allow some additional errors accumulated in floating point operations.
|
|
||||||
static const double kFSsim_thresh = 0.03;
|
|
||||||
// Allow some extra variation due to rounding error accumulated in dct.
|
|
||||||
static const double kPhvs_thresh = 0.3;
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
VPXSSIM, HBDMetricsTest,
|
|
||||||
::testing::Values(
|
|
||||||
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 8, 10,
|
|
||||||
kSsim_thresh),
|
|
||||||
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 10, 10,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 8, 12,
|
|
||||||
kSsim_thresh),
|
|
||||||
MetricTestTParam(&compute_vpxssim, &compute_hbd_vpxssim, 12, 12,
|
|
||||||
kPhvs_thresh)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
FASTSSIM, HBDMetricsTest,
|
|
||||||
::testing::Values(
|
|
||||||
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 8, 10,
|
|
||||||
kFSsim_thresh),
|
|
||||||
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 10, 10,
|
|
||||||
kFSsim_thresh),
|
|
||||||
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 8, 12,
|
|
||||||
kFSsim_thresh),
|
|
||||||
MetricTestTParam(&compute_fastssim, &compute_hbd_fastssim, 12, 12,
|
|
||||||
kFSsim_thresh)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
PSNRHVS, HBDMetricsTest,
|
|
||||||
::testing::Values(
|
|
||||||
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 8, 10,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 10, 10,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 8, 12,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_psnrhvs, &compute_hbd_psnrhvs, 12, 12,
|
|
||||||
kPhvs_thresh)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
PSNR, HBDMetricsTest,
|
|
||||||
::testing::Values(
|
|
||||||
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 10,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 10, 10,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 8, 12,
|
|
||||||
kPhvs_thresh),
|
|
||||||
MetricTestTParam(&compute_psnr, &compute_hbd_psnr, 12, 12,
|
|
||||||
kPhvs_thresh)));
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
@@ -14,15 +14,24 @@
|
|||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
#include "./vp9_rtcd.h"
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
#include "vpx_ports/msvc.h" // for round()
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
static int round(double x) {
|
||||||
|
if (x < 0)
|
||||||
|
return static_cast<int>(ceil(x - 0.5));
|
||||||
|
else
|
||||||
|
return static_cast<int>(floor(x + 0.5));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void reference_dct_1d(double input[8], double output[8]) {
|
void reference_dct_1d(double input[8], double output[8]) {
|
||||||
const double kPi = 3.141592653589793238462643383279502884;
|
const double kPi = 3.141592653589793238462643383279502884;
|
||||||
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
const double kInvSqrt2 = 0.707106781186547524400844362104;
|
||||||
@@ -59,6 +68,43 @@ void reference_dct_2d(int16_t input[64], double output[64]) {
|
|||||||
output[i] *= 2;
|
output[i] *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reference_idct_1d(double input[8], double output[8]) {
|
||||||
|
const double kPi = 3.141592653589793238462643383279502884;
|
||||||
|
const double kSqrt2 = 1.414213562373095048801688724209698;
|
||||||
|
for (int k = 0; k < 8; k++) {
|
||||||
|
output[k] = 0.0;
|
||||||
|
for (int n = 0; n < 8; n++) {
|
||||||
|
output[k] += input[n]*cos(kPi*(2*k+1)*n/16.0);
|
||||||
|
if (n == 0)
|
||||||
|
output[k] = output[k]/kSqrt2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reference_idct_2d(double input[64], int16_t output[64]) {
|
||||||
|
double out[64], out2[64];
|
||||||
|
// First transform rows
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
double temp_in[8], temp_out[8];
|
||||||
|
for (int j = 0; j < 8; ++j)
|
||||||
|
temp_in[j] = input[j + i*8];
|
||||||
|
reference_idct_1d(temp_in, temp_out);
|
||||||
|
for (int j = 0; j < 8; ++j)
|
||||||
|
out[j + i*8] = temp_out[j];
|
||||||
|
}
|
||||||
|
// Then transform columns
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
double temp_in[8], temp_out[8];
|
||||||
|
for (int j = 0; j < 8; ++j)
|
||||||
|
temp_in[j] = out[j*8 + i];
|
||||||
|
reference_idct_1d(temp_in, temp_out);
|
||||||
|
for (int j = 0; j < 8; ++j)
|
||||||
|
out2[j*8 + i] = temp_out[j];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 64; ++i)
|
||||||
|
output[i] = round(out2[i]/32);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
TEST(VP9Idct8x8Test, AccuracyCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = 10000;
|
const int count_test_block = 10000;
|
||||||
@@ -78,8 +124,8 @@ TEST(VP9Idct8x8Test, AccuracyCheck) {
|
|||||||
|
|
||||||
reference_dct_2d(input, output_r);
|
reference_dct_2d(input, output_r);
|
||||||
for (int j = 0; j < 64; ++j)
|
for (int j = 0; j < 64; ++j)
|
||||||
coeff[j] = static_cast<tran_low_t>(round(output_r[j]));
|
coeff[j] = round(output_r[j]);
|
||||||
vpx_idct8x8_64_add_c(coeff, dst, 8);
|
vp9_idct8x8_64_add_c(coeff, dst, 8);
|
||||||
for (int j = 0; j < 64; ++j) {
|
for (int j = 0; j < 64; ++j) {
|
||||||
const int diff = dst[j] - src[j];
|
const int diff = dst[j] - src[j];
|
||||||
const int error = diff * diff;
|
const int error = diff * diff;
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
|
#include "./vp8_rtcd.h"
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
typedef void (*IdctFunc)(int16_t *input, unsigned char *pred_ptr,
|
||||||
@@ -113,8 +113,4 @@ INSTANTIATE_TEST_CASE_P(C, IDCTTest, ::testing::Values(vp8_short_idct4x4llm_c));
|
|||||||
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
INSTANTIATE_TEST_CASE_P(MMX, IDCTTest,
|
||||||
::testing::Values(vp8_short_idct4x4llm_mmx));
|
::testing::Values(vp8_short_idct4x4llm_mmx));
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(MSA, IDCTTest,
|
|
||||||
::testing::Values(vp8_short_idct4x4llm_msa));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by a BSD-style license
|
* 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
|
* that can be found in the LICENSE file in the root of the source
|
||||||
@@ -8,205 +8,389 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include <string.h>
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
#include "vp10/common/blockd.h"
|
|
||||||
#include "vp10/common/pred_common.h"
|
#include "./vpx_config.h"
|
||||||
|
#include "./vp8_rtcd.h"
|
||||||
|
#include "vp8/common/blockd.h"
|
||||||
#include "vpx_mem/vpx_mem.h"
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
|
|
||||||
const int count_test_block = 100000;
|
class IntraPredBase {
|
||||||
|
public:
|
||||||
|
virtual ~IntraPredBase() { libvpx_test::ClearSystemState(); }
|
||||||
|
|
||||||
typedef void (*IntraPred)(uint16_t* dst, ptrdiff_t stride,
|
protected:
|
||||||
const uint16_t* above, const uint16_t* left,
|
void SetupMacroblock(MACROBLOCKD *mbptr,
|
||||||
int bps);
|
MODE_INFO *miptr,
|
||||||
|
uint8_t *data,
|
||||||
|
int block_size,
|
||||||
|
int stride,
|
||||||
|
int num_planes) {
|
||||||
|
mbptr_ = mbptr;
|
||||||
|
miptr_ = miptr;
|
||||||
|
mbptr_->up_available = 1;
|
||||||
|
mbptr_->left_available = 1;
|
||||||
|
mbptr_->mode_info_context = miptr_;
|
||||||
|
stride_ = stride;
|
||||||
|
block_size_ = block_size;
|
||||||
|
num_planes_ = num_planes;
|
||||||
|
for (int p = 0; p < num_planes; p++)
|
||||||
|
data_ptr_[p] = data + stride * (block_size + 1) * p +
|
||||||
|
stride + block_size;
|
||||||
|
}
|
||||||
|
|
||||||
struct IntraPredFunc {
|
void FillRandom() {
|
||||||
IntraPredFunc(IntraPred pred = NULL, IntraPred ref = NULL,
|
// Fill edges with random data
|
||||||
int block_size_value = 0, int bit_depth_value = 0)
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
: pred_fn(pred), ref_fn(ref),
|
for (int p = 0; p < num_planes_; p++) {
|
||||||
block_size(block_size_value), bit_depth(bit_depth_value) {}
|
for (int x = -1 ; x <= block_size_; x++)
|
||||||
|
data_ptr_[p][x - stride_] = rnd.Rand8();
|
||||||
|
for (int y = 0; y < block_size_; y++)
|
||||||
|
data_ptr_[p][y * stride_ - 1] = rnd.Rand8();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IntraPred pred_fn;
|
virtual void Predict(MB_PREDICTION_MODE mode) = 0;
|
||||||
IntraPred ref_fn;
|
|
||||||
int block_size;
|
void SetLeftUnavailable() {
|
||||||
int bit_depth;
|
mbptr_->left_available = 0;
|
||||||
|
for (int p = 0; p < num_planes_; p++)
|
||||||
|
for (int i = -1; i < block_size_; ++i)
|
||||||
|
data_ptr_[p][stride_ * i - 1] = 129;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetTopUnavailable() {
|
||||||
|
mbptr_->up_available = 0;
|
||||||
|
for (int p = 0; p < num_planes_; p++)
|
||||||
|
memset(&data_ptr_[p][-1 - stride_], 127, block_size_ + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetTopLeftUnavailable() {
|
||||||
|
SetLeftUnavailable();
|
||||||
|
SetTopUnavailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BlockSizeLog2Min1() const {
|
||||||
|
switch (block_size_) {
|
||||||
|
case 16:
|
||||||
|
return 3;
|
||||||
|
case 8:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check DC prediction output against a reference
|
||||||
|
void CheckDCPrediction() const {
|
||||||
|
for (int p = 0; p < num_planes_; p++) {
|
||||||
|
// calculate expected DC
|
||||||
|
int expected;
|
||||||
|
if (mbptr_->up_available || mbptr_->left_available) {
|
||||||
|
int sum = 0, shift = BlockSizeLog2Min1() + mbptr_->up_available +
|
||||||
|
mbptr_->left_available;
|
||||||
|
if (mbptr_->up_available)
|
||||||
|
for (int x = 0; x < block_size_; x++)
|
||||||
|
sum += data_ptr_[p][x - stride_];
|
||||||
|
if (mbptr_->left_available)
|
||||||
|
for (int y = 0; y < block_size_; y++)
|
||||||
|
sum += data_ptr_[p][y * stride_ - 1];
|
||||||
|
expected = (sum + (1 << (shift - 1))) >> shift;
|
||||||
|
} else {
|
||||||
|
expected = 0x80;
|
||||||
|
}
|
||||||
|
// check that all subsequent lines are equal to the first
|
||||||
|
for (int y = 1; y < block_size_; ++y)
|
||||||
|
ASSERT_EQ(0, memcmp(data_ptr_[p], &data_ptr_[p][y * stride_],
|
||||||
|
block_size_));
|
||||||
|
// within the first line, ensure that each pixel has the same value
|
||||||
|
for (int x = 1; x < block_size_; ++x)
|
||||||
|
ASSERT_EQ(data_ptr_[p][0], data_ptr_[p][x]);
|
||||||
|
// now ensure that that pixel has the expected (DC) value
|
||||||
|
ASSERT_EQ(expected, data_ptr_[p][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check V prediction output against a reference
|
||||||
|
void CheckVPrediction() const {
|
||||||
|
// check that all lines equal the top border
|
||||||
|
for (int p = 0; p < num_planes_; p++)
|
||||||
|
for (int y = 0; y < block_size_; y++)
|
||||||
|
ASSERT_EQ(0, memcmp(&data_ptr_[p][-stride_],
|
||||||
|
&data_ptr_[p][y * stride_], block_size_));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check H prediction output against a reference
|
||||||
|
void CheckHPrediction() const {
|
||||||
|
// for each line, ensure that each pixel is equal to the left border
|
||||||
|
for (int p = 0; p < num_planes_; p++)
|
||||||
|
for (int y = 0; y < block_size_; y++)
|
||||||
|
for (int x = 0; x < block_size_; x++)
|
||||||
|
ASSERT_EQ(data_ptr_[p][-1 + y * stride_],
|
||||||
|
data_ptr_[p][x + y * stride_]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ClipByte(int value) {
|
||||||
|
if (value > 255)
|
||||||
|
return 255;
|
||||||
|
else if (value < 0)
|
||||||
|
return 0;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check TM prediction output against a reference
|
||||||
|
void CheckTMPrediction() const {
|
||||||
|
for (int p = 0; p < num_planes_; p++)
|
||||||
|
for (int y = 0; y < block_size_; y++)
|
||||||
|
for (int x = 0; x < block_size_; x++) {
|
||||||
|
const int expected = ClipByte(data_ptr_[p][x - stride_]
|
||||||
|
+ data_ptr_[p][stride_ * y - 1]
|
||||||
|
- data_ptr_[p][-1 - stride_]);
|
||||||
|
ASSERT_EQ(expected, data_ptr_[p][y * stride_ + x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actual test
|
||||||
|
void RunTest() {
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("DC_PRED");
|
||||||
|
FillRandom();
|
||||||
|
Predict(DC_PRED);
|
||||||
|
CheckDCPrediction();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("DC_PRED LEFT");
|
||||||
|
FillRandom();
|
||||||
|
SetLeftUnavailable();
|
||||||
|
Predict(DC_PRED);
|
||||||
|
CheckDCPrediction();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("DC_PRED TOP");
|
||||||
|
FillRandom();
|
||||||
|
SetTopUnavailable();
|
||||||
|
Predict(DC_PRED);
|
||||||
|
CheckDCPrediction();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("DC_PRED TOP_LEFT");
|
||||||
|
FillRandom();
|
||||||
|
SetTopLeftUnavailable();
|
||||||
|
Predict(DC_PRED);
|
||||||
|
CheckDCPrediction();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("H_PRED");
|
||||||
|
FillRandom();
|
||||||
|
Predict(H_PRED);
|
||||||
|
CheckHPrediction();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("V_PRED");
|
||||||
|
FillRandom();
|
||||||
|
Predict(V_PRED);
|
||||||
|
CheckVPrediction();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SCOPED_TRACE("TM_PRED");
|
||||||
|
FillRandom();
|
||||||
|
Predict(TM_PRED);
|
||||||
|
CheckTMPrediction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MACROBLOCKD *mbptr_;
|
||||||
|
MODE_INFO *miptr_;
|
||||||
|
uint8_t *data_ptr_[2]; // in the case of Y, only [0] is used
|
||||||
|
int stride_;
|
||||||
|
int block_size_;
|
||||||
|
int num_planes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VP9IntraPredTest : public ::testing::TestWithParam<IntraPredFunc> {
|
typedef void (*IntraPredYFunc)(MACROBLOCKD *x,
|
||||||
|
uint8_t *yabove_row,
|
||||||
|
uint8_t *yleft,
|
||||||
|
int left_stride,
|
||||||
|
uint8_t *ypred_ptr,
|
||||||
|
int y_stride);
|
||||||
|
|
||||||
|
class IntraPredYTest
|
||||||
|
: public IntraPredBase,
|
||||||
|
public ::testing::TestWithParam<IntraPredYFunc> {
|
||||||
public:
|
public:
|
||||||
void RunTest(uint16_t* left_col, uint16_t* above_data,
|
static void SetUpTestCase() {
|
||||||
uint16_t* dst, uint16_t* ref_dst) {
|
mb_ = reinterpret_cast<MACROBLOCKD*>(
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
vpx_memalign(32, sizeof(MACROBLOCKD)));
|
||||||
const int block_size = params_.block_size;
|
mi_ = reinterpret_cast<MODE_INFO*>(
|
||||||
above_row_ = above_data + 16;
|
vpx_memalign(32, sizeof(MODE_INFO)));
|
||||||
left_col_ = left_col;
|
data_array_ = reinterpret_cast<uint8_t*>(
|
||||||
dst_ = dst;
|
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||||
ref_dst_ = ref_dst;
|
|
||||||
int error_count = 0;
|
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
|
||||||
// Fill edges with random data, try first with saturated values.
|
|
||||||
for (int x = -1; x <= block_size * 2; x++) {
|
|
||||||
if (i == 0) {
|
|
||||||
above_row_[x] = mask_;
|
|
||||||
} else {
|
|
||||||
above_row_[x] = rnd.Rand16() & mask_;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (int y = 0; y < block_size; y++) {
|
static void TearDownTestCase() {
|
||||||
if (i == 0) {
|
vpx_free(data_array_);
|
||||||
left_col_[y] = mask_;
|
vpx_free(mi_);
|
||||||
} else {
|
vpx_free(mb_);
|
||||||
left_col_[y] = rnd.Rand16() & mask_;
|
data_array_ = NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
Predict();
|
|
||||||
CheckPrediction(i, &error_count);
|
|
||||||
}
|
|
||||||
ASSERT_EQ(0, error_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static const int kBlockSize = 16;
|
||||||
|
static const int kDataAlignment = 16;
|
||||||
|
static const int kStride = kBlockSize * 3;
|
||||||
|
// We use 48 so that the data pointer of the first pixel in each row of
|
||||||
|
// each macroblock is 16-byte aligned, and this gives us access to the
|
||||||
|
// top-left and top-right corner pixels belonging to the top-left/right
|
||||||
|
// macroblocks.
|
||||||
|
// We use 17 lines so we have one line above us for top-prediction.
|
||||||
|
static const int kDataBufferSize = kStride * (kBlockSize + 1);
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
params_ = GetParam();
|
pred_fn_ = GetParam();
|
||||||
stride_ = params_.block_size * 3;
|
SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 1);
|
||||||
mask_ = (1 << params_.bit_depth) - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Predict() {
|
virtual void Predict(MB_PREDICTION_MODE mode) {
|
||||||
const int bit_depth = params_.bit_depth;
|
mbptr_->mode_info_context->mbmi.mode = mode;
|
||||||
params_.ref_fn(ref_dst_, stride_, above_row_, left_col_, bit_depth);
|
ASM_REGISTER_STATE_CHECK(pred_fn_(mbptr_,
|
||||||
ASM_REGISTER_STATE_CHECK(params_.pred_fn(dst_, stride_,
|
data_ptr_[0] - kStride,
|
||||||
above_row_, left_col_, bit_depth));
|
data_ptr_[0] - 1, kStride,
|
||||||
|
data_ptr_[0], kStride));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckPrediction(int test_case_number, int *error_count) const {
|
IntraPredYFunc pred_fn_;
|
||||||
// For each pixel ensure that the calculated value is the same as reference.
|
static uint8_t* data_array_;
|
||||||
const int block_size = params_.block_size;
|
static MACROBLOCKD * mb_;
|
||||||
for (int y = 0; y < block_size; y++) {
|
static MODE_INFO *mi_;
|
||||||
for (int x = 0; x < block_size; x++) {
|
|
||||||
*error_count += ref_dst_[x + y * stride_] != dst_[x + y * stride_];
|
|
||||||
if (*error_count == 1) {
|
|
||||||
ASSERT_EQ(ref_dst_[x + y * stride_], dst_[x + y * stride_])
|
|
||||||
<< " Failed on Test Case Number "<< test_case_number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t *above_row_;
|
|
||||||
uint16_t *left_col_;
|
|
||||||
uint16_t *dst_;
|
|
||||||
uint16_t *ref_dst_;
|
|
||||||
ptrdiff_t stride_;
|
|
||||||
int mask_;
|
|
||||||
|
|
||||||
IntraPredFunc params_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(VP9IntraPredTest, IntraPredTests) {
|
MACROBLOCKD* IntraPredYTest::mb_ = NULL;
|
||||||
// max block size is 32
|
MODE_INFO* IntraPredYTest::mi_ = NULL;
|
||||||
DECLARE_ALIGNED(16, uint16_t, left_col[2*32]);
|
uint8_t* IntraPredYTest::data_array_ = NULL;
|
||||||
DECLARE_ALIGNED(16, uint16_t, above_data[2*32+32]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, dst[3 * 32 * 32]);
|
TEST_P(IntraPredYTest, IntraPredTests) {
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_dst[3 * 32 * 32]);
|
RunTest();
|
||||||
RunTest(left_col, above_data, dst, ref_dst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(C, IntraPredYTest,
|
||||||
|
::testing::Values(
|
||||||
|
vp8_build_intra_predictors_mby_s_c));
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
INSTANTIATE_TEST_CASE_P(SSE2, IntraPredYTest,
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2_TO_C_8, VP9IntraPredTest,
|
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_32x32_sse2,
|
vp8_build_intra_predictors_mby_s_sse2));
|
||||||
&vpx_highbd_dc_predictor_32x32_c, 32, 8),
|
#endif
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_16x16_sse2,
|
#if HAVE_SSSE3
|
||||||
&vpx_highbd_tm_predictor_16x16_c, 16, 8),
|
INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredYTest,
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_32x32_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_32x32_c, 32, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_dc_predictor_4x4_c, 4, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_8x8_sse2,
|
|
||||||
&vpx_highbd_dc_predictor_8x8_c, 8, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_16x16_sse2,
|
|
||||||
&vpx_highbd_dc_predictor_16x16_c, 16, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_v_predictor_4x4_c, 4, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_8x8_sse2,
|
|
||||||
&vpx_highbd_v_predictor_8x8_c, 8, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_16x16_sse2,
|
|
||||||
&vpx_highbd_v_predictor_16x16_c, 16, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_32x32_sse2,
|
|
||||||
&vpx_highbd_v_predictor_32x32_c, 32, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_4x4_c, 4, 8),
|
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_8x8_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_8x8_c, 8, 8)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2_TO_C_10, VP9IntraPredTest,
|
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_32x32_sse2,
|
vp8_build_intra_predictors_mby_s_ssse3));
|
||||||
&vpx_highbd_dc_predictor_32x32_c, 32, 10),
|
#endif
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_16x16_sse2,
|
#if HAVE_NEON
|
||||||
&vpx_highbd_tm_predictor_16x16_c, 16, 10),
|
INSTANTIATE_TEST_CASE_P(NEON, IntraPredYTest,
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_32x32_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_32x32_c, 32, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_dc_predictor_4x4_c, 4, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_8x8_sse2,
|
|
||||||
&vpx_highbd_dc_predictor_8x8_c, 8, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_16x16_sse2,
|
|
||||||
&vpx_highbd_dc_predictor_16x16_c, 16, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_v_predictor_4x4_c, 4, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_8x8_sse2,
|
|
||||||
&vpx_highbd_v_predictor_8x8_c, 8, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_16x16_sse2,
|
|
||||||
&vpx_highbd_v_predictor_16x16_c, 16, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_32x32_sse2,
|
|
||||||
&vpx_highbd_v_predictor_32x32_c, 32, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_4x4_c, 4, 10),
|
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_8x8_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_8x8_c, 8, 10)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2_TO_C_12, VP9IntraPredTest,
|
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_32x32_sse2,
|
vp8_build_intra_predictors_mby_s_neon));
|
||||||
&vpx_highbd_dc_predictor_32x32_c, 32, 12),
|
#endif
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_16x16_sse2,
|
|
||||||
&vpx_highbd_tm_predictor_16x16_c, 16, 12),
|
typedef void (*IntraPredUvFunc)(MACROBLOCKD *x,
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_32x32_sse2,
|
uint8_t *uabove_row,
|
||||||
&vpx_highbd_tm_predictor_32x32_c, 32, 12),
|
uint8_t *vabove_row,
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_4x4_sse2,
|
uint8_t *uleft,
|
||||||
&vpx_highbd_dc_predictor_4x4_c, 4, 12),
|
uint8_t *vleft,
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_8x8_sse2,
|
int left_stride,
|
||||||
&vpx_highbd_dc_predictor_8x8_c, 8, 12),
|
uint8_t *upred_ptr,
|
||||||
IntraPredFunc(&vpx_highbd_dc_predictor_16x16_sse2,
|
uint8_t *vpred_ptr,
|
||||||
&vpx_highbd_dc_predictor_16x16_c, 16, 12),
|
int pred_stride);
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_4x4_sse2,
|
|
||||||
&vpx_highbd_v_predictor_4x4_c, 4, 12),
|
class IntraPredUVTest
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_8x8_sse2,
|
: public IntraPredBase,
|
||||||
&vpx_highbd_v_predictor_8x8_c, 8, 12),
|
public ::testing::TestWithParam<IntraPredUvFunc> {
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_16x16_sse2,
|
public:
|
||||||
&vpx_highbd_v_predictor_16x16_c, 16, 12),
|
static void SetUpTestCase() {
|
||||||
IntraPredFunc(&vpx_highbd_v_predictor_32x32_sse2,
|
mb_ = reinterpret_cast<MACROBLOCKD*>(
|
||||||
&vpx_highbd_v_predictor_32x32_c, 32, 12),
|
vpx_memalign(32, sizeof(MACROBLOCKD)));
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_4x4_sse2,
|
mi_ = reinterpret_cast<MODE_INFO*>(
|
||||||
&vpx_highbd_tm_predictor_4x4_c, 4, 12),
|
vpx_memalign(32, sizeof(MODE_INFO)));
|
||||||
IntraPredFunc(&vpx_highbd_tm_predictor_8x8_sse2,
|
data_array_ = reinterpret_cast<uint8_t*>(
|
||||||
&vpx_highbd_tm_predictor_8x8_c, 8, 12)));
|
vpx_memalign(kDataAlignment, kDataBufferSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TearDownTestCase() {
|
||||||
|
vpx_free(data_array_);
|
||||||
|
vpx_free(mi_);
|
||||||
|
vpx_free(mb_);
|
||||||
|
data_array_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static const int kBlockSize = 8;
|
||||||
|
static const int kDataAlignment = 8;
|
||||||
|
static const int kStride = kBlockSize * 3;
|
||||||
|
// We use 24 so that the data pointer of the first pixel in each row of
|
||||||
|
// each macroblock is 8-byte aligned, and this gives us access to the
|
||||||
|
// top-left and top-right corner pixels belonging to the top-left/right
|
||||||
|
// macroblocks.
|
||||||
|
// We use 9 lines so we have one line above us for top-prediction.
|
||||||
|
// [0] = U, [1] = V
|
||||||
|
static const int kDataBufferSize = 2 * kStride * (kBlockSize + 1);
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
pred_fn_ = GetParam();
|
||||||
|
SetupMacroblock(mb_, mi_, data_array_, kBlockSize, kStride, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Predict(MB_PREDICTION_MODE mode) {
|
||||||
|
mbptr_->mode_info_context->mbmi.uv_mode = mode;
|
||||||
|
pred_fn_(mbptr_, data_ptr_[0] - kStride, data_ptr_[1] - kStride,
|
||||||
|
data_ptr_[0] - 1, data_ptr_[1] - 1, kStride,
|
||||||
|
data_ptr_[0], data_ptr_[1], kStride);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntraPredUvFunc pred_fn_;
|
||||||
|
// We use 24 so that the data pointer of the first pixel in each row of
|
||||||
|
// each macroblock is 8-byte aligned, and this gives us access to the
|
||||||
|
// top-left and top-right corner pixels belonging to the top-left/right
|
||||||
|
// macroblocks.
|
||||||
|
// We use 9 lines so we have one line above us for top-prediction.
|
||||||
|
// [0] = U, [1] = V
|
||||||
|
static uint8_t* data_array_;
|
||||||
|
static MACROBLOCKD* mb_;
|
||||||
|
static MODE_INFO* mi_;
|
||||||
|
};
|
||||||
|
|
||||||
|
MACROBLOCKD* IntraPredUVTest::mb_ = NULL;
|
||||||
|
MODE_INFO* IntraPredUVTest::mi_ = NULL;
|
||||||
|
uint8_t* IntraPredUVTest::data_array_ = NULL;
|
||||||
|
|
||||||
|
TEST_P(IntraPredUVTest, IntraPredTests) {
|
||||||
|
RunTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(C, IntraPredUVTest,
|
||||||
|
::testing::Values(
|
||||||
|
vp8_build_intra_predictors_mbuv_s_c));
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, IntraPredUVTest,
|
||||||
|
::testing::Values(
|
||||||
|
vp8_build_intra_predictors_mbuv_s_sse2));
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSSE3
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSSE3, IntraPredUVTest,
|
||||||
|
::testing::Values(
|
||||||
|
vp8_build_intra_predictors_mbuv_s_ssse3));
|
||||||
|
#endif
|
||||||
|
#if HAVE_NEON
|
||||||
|
INSTANTIATE_TEST_CASE_P(NEON, IntraPredUVTest,
|
||||||
|
::testing::Values(
|
||||||
|
vp8_build_intra_predictors_mbuv_s_neon));
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_SSE2
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
167
test/invalid_file_test.cc
Normal file
167
test/invalid_file_test.cc
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* 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 <vector>
|
||||||
|
#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/util.h"
|
||||||
|
#if CONFIG_WEBM_IO
|
||||||
|
#include "test/webm_video_source.h"
|
||||||
|
#endif
|
||||||
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct DecodeParam {
|
||||||
|
int threads;
|
||||||
|
const char *filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const DecodeParam &dp) {
|
||||||
|
return os << "threads: " << dp.threads << " file: " << dp.filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InvalidFileTest
|
||||||
|
: public ::libvpx_test::DecoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||||
|
protected:
|
||||||
|
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
|
||||||
|
|
||||||
|
virtual ~InvalidFileTest() {
|
||||||
|
if (res_file_ != NULL)
|
||||||
|
fclose(res_file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenResFile(const std::string &res_file_name_) {
|
||||||
|
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
|
||||||
|
ASSERT_TRUE(res_file_ != NULL) << "Result file open failed. Filename: "
|
||||||
|
<< res_file_name_;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool HandleDecodeResult(
|
||||||
|
const vpx_codec_err_t res_dec,
|
||||||
|
const libvpx_test::CompressedVideoSource &video,
|
||||||
|
libvpx_test::Decoder *decoder) {
|
||||||
|
EXPECT_TRUE(res_file_ != NULL);
|
||||||
|
int expected_res_dec;
|
||||||
|
|
||||||
|
// Read integer result.
|
||||||
|
const int res = fscanf(res_file_, "%d", &expected_res_dec);
|
||||||
|
EXPECT_NE(res, EOF) << "Read result data failed";
|
||||||
|
|
||||||
|
// Check results match.
|
||||||
|
EXPECT_EQ(expected_res_dec, res_dec)
|
||||||
|
<< "Results don't match: frame number = " << video.frame_number()
|
||||||
|
<< ". (" << decoder->DecodeError() << ")";
|
||||||
|
|
||||||
|
return !HasFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunTest() {
|
||||||
|
const DecodeParam input = GET_PARAM(1);
|
||||||
|
libvpx_test::CompressedVideoSource *video = NULL;
|
||||||
|
vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
|
||||||
|
cfg.threads = input.threads;
|
||||||
|
const std::string filename = input.filename;
|
||||||
|
|
||||||
|
// Open compressed video file.
|
||||||
|
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||||
|
video = new libvpx_test::IVFVideoSource(filename);
|
||||||
|
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
|
||||||
|
#if CONFIG_WEBM_IO
|
||||||
|
video = new libvpx_test::WebMVideoSource(filename);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
|
||||||
|
filename.c_str());
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
video->Init();
|
||||||
|
|
||||||
|
// Construct result file name. The file holds a list of expected integer
|
||||||
|
// results, one for each decoded frame. Any result that doesn't match
|
||||||
|
// the files list will cause a test failure.
|
||||||
|
const std::string res_filename = filename + ".res";
|
||||||
|
OpenResFile(res_filename);
|
||||||
|
|
||||||
|
// Decode frame, and check the md5 matching.
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video, cfg));
|
||||||
|
delete video;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *res_file_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(InvalidFileTest, ReturnCode) {
|
||||||
|
RunTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DecodeParam kVP9InvalidFileTests[] = {
|
||||||
|
{1, "invalid-vp90-02-v2.webm"},
|
||||||
|
{1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"},
|
||||||
|
{1, "invalid-vp90-03-v3.webm"},
|
||||||
|
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"},
|
||||||
|
{1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"},
|
||||||
|
{1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf"},
|
||||||
|
{1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf"},
|
||||||
|
{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,
|
||||||
|
::testing::ValuesIn(kVP9InvalidFileTests));
|
||||||
|
|
||||||
|
// This class will include test vectors that are expected to fail
|
||||||
|
// peek. However they are still expected to have no fatal failures.
|
||||||
|
class InvalidFileInvalidPeekTest : public InvalidFileTest {
|
||||||
|
protected:
|
||||||
|
InvalidFileInvalidPeekTest() : InvalidFileTest() {}
|
||||||
|
virtual void HandlePeekResult(libvpx_test::Decoder *const /*decoder*/,
|
||||||
|
libvpx_test::CompressedVideoSource* /*video*/,
|
||||||
|
const vpx_codec_err_t /*res_peek*/) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(InvalidFileInvalidPeekTest, ReturnCode) {
|
||||||
|
RunTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const DecodeParam kVP9InvalidFileInvalidPeekTests[] = {
|
||||||
|
{1, "invalid-vp90-01-v2.webm"},
|
||||||
|
};
|
||||||
|
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(InvalidFileInvalidPeekTest,
|
||||||
|
::testing::ValuesIn(kVP9InvalidFileInvalidPeekTests));
|
||||||
|
|
||||||
|
const DecodeParam kMultiThreadedVP9InvalidFileTests[] = {
|
||||||
|
{4, "invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm"},
|
||||||
|
{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"},
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(
|
||||||
|
VP9MultiThreaded, InvalidFileTest,
|
||||||
|
::testing::Combine(
|
||||||
|
::testing::Values(
|
||||||
|
static_cast<const libvpx_test::CodecFactory*>(&libvpx_test::kVP9)),
|
||||||
|
::testing::ValuesIn(kMultiThreadedVP9InvalidFileTests)));
|
||||||
|
} // namespace
|
||||||
145
test/keyframe_test.cc
Normal file
145
test/keyframe_test.cc
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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 <climits>
|
||||||
|
#include <vector>
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "test/codec_factory.h"
|
||||||
|
#include "test/encode_test_driver.h"
|
||||||
|
#include "test/i420_video_source.h"
|
||||||
|
#include "test/util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class KeyframeTest : public ::libvpx_test::EncoderTest,
|
||||||
|
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||||
|
protected:
|
||||||
|
KeyframeTest() : EncoderTest(GET_PARAM(0)) {}
|
||||||
|
virtual ~KeyframeTest() {}
|
||||||
|
|
||||||
|
virtual void SetUp() {
|
||||||
|
InitializeConfig();
|
||||||
|
SetMode(GET_PARAM(1));
|
||||||
|
kf_count_ = 0;
|
||||||
|
kf_count_max_ = INT_MAX;
|
||||||
|
kf_do_force_kf_ = false;
|
||||||
|
set_cpu_used_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||||
|
::libvpx_test::Encoder *encoder) {
|
||||||
|
if (kf_do_force_kf_)
|
||||||
|
frame_flags_ = (video->frame() % 3) ? 0 : VPX_EFLAG_FORCE_KF;
|
||||||
|
if (set_cpu_used_ && video->frame() == 1)
|
||||||
|
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
|
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
|
||||||
|
kf_pts_list_.push_back(pkt->data.frame.pts);
|
||||||
|
kf_count_++;
|
||||||
|
abort_ |= kf_count_ > kf_count_max_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool kf_do_force_kf_;
|
||||||
|
int kf_count_;
|
||||||
|
int kf_count_max_;
|
||||||
|
std::vector<vpx_codec_pts_t> kf_pts_list_;
|
||||||
|
int set_cpu_used_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_P(KeyframeTest, TestRandomVideoSource) {
|
||||||
|
// Validate that encoding the RandomVideoSource produces multiple keyframes.
|
||||||
|
// This validates the results of the TestDisableKeyframes test.
|
||||||
|
kf_count_max_ = 2; // early exit successful tests.
|
||||||
|
|
||||||
|
::libvpx_test::RandomVideoSource video;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||||
|
// bother with this check if(GetParam() > 0)
|
||||||
|
if (GET_PARAM(1) > 0)
|
||||||
|
EXPECT_GT(kf_count_, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(KeyframeTest, TestDisableKeyframes) {
|
||||||
|
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||||
|
kf_count_max_ = 1; // early exit failed tests.
|
||||||
|
|
||||||
|
::libvpx_test::RandomVideoSource video;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
EXPECT_EQ(1, kf_count_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(KeyframeTest, TestForceKeyframe) {
|
||||||
|
cfg_.kf_mode = VPX_KF_DISABLED;
|
||||||
|
kf_do_force_kf_ = true;
|
||||||
|
|
||||||
|
::libvpx_test::DummyVideoSource video;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
// verify that every third frame is a keyframe.
|
||||||
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
|
ASSERT_EQ(0, *iter % 3) << "Unexpected keyframe at frame " << *iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(KeyframeTest, TestKeyframeMaxDistance) {
|
||||||
|
cfg_.kf_max_dist = 25;
|
||||||
|
|
||||||
|
::libvpx_test::DummyVideoSource video;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
// verify that keyframe interval matches kf_max_dist
|
||||||
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
|
ASSERT_EQ(0, *iter % 25) << "Unexpected keyframe at frame " << *iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(KeyframeTest, TestAutoKeyframe) {
|
||||||
|
cfg_.kf_mode = VPX_KF_AUTO;
|
||||||
|
kf_do_force_kf_ = false;
|
||||||
|
|
||||||
|
// Force a deterministic speed step in Real Time mode, as the faster modes
|
||||||
|
// may not produce a keyframe like we expect. This is necessary when running
|
||||||
|
// on very slow environments (like Valgrind). The step -11 was determined
|
||||||
|
// experimentally as the fastest mode that still throws the keyframe.
|
||||||
|
if (deadline_ == VPX_DL_REALTIME)
|
||||||
|
set_cpu_used_ = -11;
|
||||||
|
|
||||||
|
// This clip has a cut scene every 30 frames -> Frame 0, 30, 60, 90, 120.
|
||||||
|
// I check only the first 40 frames to make sure there's a keyframe at frame
|
||||||
|
// 0 and 30.
|
||||||
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
|
30, 1, 0, 40);
|
||||||
|
|
||||||
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
|
// In realtime mode - auto placed keyframes are exceedingly rare, don't
|
||||||
|
// bother with this check
|
||||||
|
if (GET_PARAM(1) > 0)
|
||||||
|
EXPECT_EQ(2u, kf_pts_list_.size()) << " Not the right number of keyframes ";
|
||||||
|
|
||||||
|
// Verify that keyframes match the file keyframes in the file.
|
||||||
|
for (std::vector<vpx_codec_pts_t>::const_iterator iter = kf_pts_list_.begin();
|
||||||
|
iter != kf_pts_list_.end(); ++iter) {
|
||||||
|
if (deadline_ == VPX_DL_REALTIME && *iter > 0)
|
||||||
|
EXPECT_EQ(0, (*iter - 1) % 30) << "Unexpected keyframe at frame "
|
||||||
|
<< *iter;
|
||||||
|
else
|
||||||
|
EXPECT_EQ(0, *iter % 30) << "Unexpected keyframe at frame " << *iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8_INSTANTIATE_TEST_CASE(KeyframeTest, ALL_TEST_MODES);
|
||||||
|
} // namespace
|
||||||
@@ -1,119 +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.
|
|
||||||
*/
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/i420_video_source.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
class LevelTest
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
|
||||||
protected:
|
|
||||||
LevelTest()
|
|
||||||
: EncoderTest(GET_PARAM(0)),
|
|
||||||
encoding_mode_(GET_PARAM(1)),
|
|
||||||
cpu_used_(GET_PARAM(2)),
|
|
||||||
min_gf_internal_(24),
|
|
||||||
target_level_(0),
|
|
||||||
level_(0) {}
|
|
||||||
virtual ~LevelTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(encoding_mode_);
|
|
||||||
if (encoding_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_2pass_vbr_minsection_pct = 5;
|
|
||||||
cfg_.rc_2pass_vbr_maxsection_pct = 2000;
|
|
||||||
cfg_.rc_target_bitrate = 400;
|
|
||||||
cfg_.rc_max_quantizer = 63;
|
|
||||||
cfg_.rc_min_quantizer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
|
||||||
::libvpx_test::Encoder *encoder) {
|
|
||||||
if (video->frame() == 0) {
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, cpu_used_);
|
|
||||||
encoder->Control(VP9E_SET_TARGET_LEVEL, target_level_);
|
|
||||||
encoder->Control(VP9E_SET_MIN_GF_INTERVAL, min_gf_internal_);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
encoder->Control(VP9E_GET_LEVEL, &level_);
|
|
||||||
ASSERT_LE(level_, 51);
|
|
||||||
ASSERT_GE(level_, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
::libvpx_test::TestMode encoding_mode_;
|
|
||||||
int cpu_used_;
|
|
||||||
int min_gf_internal_;
|
|
||||||
int target_level_;
|
|
||||||
int level_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test for keeping level stats only
|
|
||||||
TEST_P(LevelTest, TestTargetLevel0) {
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
|
||||||
40);
|
|
||||||
target_level_ = 0;
|
|
||||||
min_gf_internal_ = 4;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_EQ(11, level_);
|
|
||||||
|
|
||||||
cfg_.rc_target_bitrate = 1600;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
ASSERT_EQ(20, level_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for level control being turned off
|
|
||||||
TEST_P(LevelTest, TestTargetLevel255) {
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0,
|
|
||||||
30);
|
|
||||||
target_level_ = 255;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(LevelTest, TestTargetLevelApi) {
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_odd.yuv", 208, 144, 30, 1, 0, 1);
|
|
||||||
static const vpx_codec_iface_t *codec = &vpx_codec_vp9_cx_algo;
|
|
||||||
vpx_codec_ctx_t enc;
|
|
||||||
vpx_codec_enc_cfg_t cfg;
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_config_default(codec, &cfg, 0));
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_enc_init(&enc, codec, &cfg, 0));
|
|
||||||
for (int level = 0; level <= 256; ++level) {
|
|
||||||
if (level == 10 || level == 11 || level == 20 || level == 21 ||
|
|
||||||
level == 30 || level == 31 || level == 40 || level == 41 ||
|
|
||||||
level == 50 || level == 51 || level == 52 || level == 60 ||
|
|
||||||
level == 61 || level == 62 || level == 0 || level == 255)
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK,
|
|
||||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
|
||||||
else
|
|
||||||
EXPECT_EQ(VPX_CODEC_INVALID_PARAM,
|
|
||||||
vpx_codec_control(&enc, VP9E_SET_TARGET_LEVEL, level));
|
|
||||||
}
|
|
||||||
EXPECT_EQ(VPX_CODEC_OK, vpx_codec_destroy(&enc));
|
|
||||||
}
|
|
||||||
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(LevelTest,
|
|
||||||
::testing::Values(::libvpx_test::kTwoPassGood,
|
|
||||||
::libvpx_test::kOnePassGood),
|
|
||||||
::testing::Range(0, 9));
|
|
||||||
} // namespace
|
|
||||||
@@ -13,15 +13,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp10/common/entropy.h"
|
|
||||||
#include "vp10/common/loopfilter.h"
|
#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"
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
@@ -34,26 +34,109 @@ const int kNumCoeffs = 1024;
|
|||||||
|
|
||||||
const int number_of_iterations = 10000;
|
const int number_of_iterations = 10000;
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
typedef void (*loop_op_t)(uint16_t *s, int p, const uint8_t *blimit,
|
typedef void (*loop_op_t)(uint16_t *s, int p, const uint8_t *blimit,
|
||||||
const uint8_t *limit, const uint8_t *thresh,
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
int bd);
|
int count, int bd);
|
||||||
typedef void (*dual_loop_op_t)(uint16_t *s, int p, const uint8_t *blimit0,
|
typedef void (*dual_loop_op_t)(uint16_t *s, int p, const uint8_t *blimit0,
|
||||||
const uint8_t *limit0, const uint8_t *thresh0,
|
const uint8_t *limit0, const uint8_t *thresh0,
|
||||||
const uint8_t *blimit1, const uint8_t *limit1,
|
const uint8_t *blimit1, const uint8_t *limit1,
|
||||||
const uint8_t *thresh1, int bd);
|
const uint8_t *thresh1, int bd);
|
||||||
#else
|
#else
|
||||||
typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit,
|
typedef void (*loop_op_t)(uint8_t *s, int p, const uint8_t *blimit,
|
||||||
const uint8_t *limit, const uint8_t *thresh);
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count);
|
||||||
typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
|
typedef void (*dual_loop_op_t)(uint8_t *s, int p, const uint8_t *blimit0,
|
||||||
const uint8_t *limit0, const uint8_t *thresh0,
|
const uint8_t *limit0, const uint8_t *thresh0,
|
||||||
const uint8_t *blimit1, const uint8_t *limit1,
|
const uint8_t *blimit1, const uint8_t *limit1,
|
||||||
const uint8_t *thresh1);
|
const uint8_t *thresh1);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#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> loop8_param_t;
|
||||||
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
typedef std::tr1::tuple<dual_loop_op_t, dual_loop_op_t, int> dualloop8_param_t;
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
void wrapper_vertical_16_sse2(uint16_t *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count, int bd) {
|
||||||
|
vp9_highbd_lpf_vertical_16_sse2(s, p, blimit, limit, thresh, bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrapper_vertical_16_c(uint16_t *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count, int bd) {
|
||||||
|
vp9_highbd_lpf_vertical_16_c(s, p, blimit, limit, thresh, bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrapper_vertical_16_dual_sse2(uint16_t *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count, int bd) {
|
||||||
|
vp9_highbd_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh, bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrapper_vertical_16_dual_c(uint16_t *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count, int bd) {
|
||||||
|
vp9_highbd_lpf_vertical_16_dual_c(s, p, blimit, limit, thresh, bd);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void wrapper_vertical_16_sse2(uint8_t *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count) {
|
||||||
|
vp9_lpf_vertical_16_sse2(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_sse2(uint8_t *s, int p, const uint8_t *blimit,
|
||||||
|
const uint8_t *limit, const uint8_t *thresh,
|
||||||
|
int count) {
|
||||||
|
vp9_lpf_vertical_16_dual_sse2(s, p, blimit, limit, thresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wrapper_vertical_16_dual_c(uint8_t *s, int p, const uint8_t *blimit,
|
||||||
|
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_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
|
||||||
|
|
||||||
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
class Loop8Test6Param : public ::testing::TestWithParam<loop8_param_t> {
|
||||||
public:
|
public:
|
||||||
virtual ~Loop8Test6Param() {}
|
virtual ~Loop8Test6Param() {}
|
||||||
@@ -95,14 +178,14 @@ class Loop8Test9Param : public ::testing::TestWithParam<dualloop8_param_t> {
|
|||||||
TEST_P(Loop8Test6Param, OperationCheck) {
|
TEST_P(Loop8Test6Param, OperationCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = number_of_iterations;
|
const int count_test_block = number_of_iterations;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
int32_t bd = bit_depth_;
|
int32_t bd = bit_depth_;
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
|
||||||
#else
|
#else
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
int err_count_total = 0;
|
int err_count_total = 0;
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -123,6 +206,7 @@ TEST_P(Loop8Test6Param, OperationCheck) {
|
|||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
||||||
};
|
};
|
||||||
int32_t p = kNumCoeffs/32;
|
int32_t p = kNumCoeffs/32;
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
uint16_t tmp_s[kNumCoeffs];
|
uint16_t tmp_s[kNumCoeffs];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
@@ -153,15 +237,15 @@ TEST_P(Loop8Test6Param, OperationCheck) {
|
|||||||
}
|
}
|
||||||
ref_s[j] = s[j];
|
ref_s[j] = s[j];
|
||||||
}
|
}
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bd);
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count, bd);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bd));
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count, bd));
|
||||||
#else
|
#else
|
||||||
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh);
|
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
err_count += ref_s[j] != s[j];
|
err_count += ref_s[j] != s[j];
|
||||||
@@ -180,14 +264,14 @@ TEST_P(Loop8Test6Param, OperationCheck) {
|
|||||||
TEST_P(Loop8Test6Param, ValueCheck) {
|
TEST_P(Loop8Test6Param, ValueCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = number_of_iterations;
|
const int count_test_block = number_of_iterations;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int32_t bd = bit_depth_;
|
const int32_t bd = bit_depth_;
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
|
||||||
#else
|
#else
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
int err_count_total = 0;
|
int err_count_total = 0;
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
|
|
||||||
@@ -195,7 +279,7 @@ TEST_P(Loop8Test6Param, ValueCheck) {
|
|||||||
// function of sharpness_lvl and the loopfilter lvl as:
|
// function of sharpness_lvl and the loopfilter lvl as:
|
||||||
// block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
|
// block_inside_limit = lvl >> ((sharpness_lvl > 0) + (sharpness_lvl > 4));
|
||||||
// ...
|
// ...
|
||||||
// memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
|
// vpx_memset(lfi->lfthr[lvl].mblim, (2 * (lvl + 2) + block_inside_limit),
|
||||||
// SIMD_WIDTH);
|
// SIMD_WIDTH);
|
||||||
// This means that the largest value for mblim will occur when sharpness_lvl
|
// 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).
|
// is equal to 0, and lvl is equal to its greatest value (MAX_LOOP_FILTER).
|
||||||
@@ -221,19 +305,20 @@ TEST_P(Loop8Test6Param, ValueCheck) {
|
|||||||
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
tmp, tmp, tmp, tmp, tmp, tmp, tmp, tmp
|
||||||
};
|
};
|
||||||
int32_t p = kNumCoeffs / 32;
|
int32_t p = kNumCoeffs / 32;
|
||||||
|
int count = 1;
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
s[j] = rnd.Rand16() & mask_;
|
s[j] = rnd.Rand16() & mask_;
|
||||||
ref_s[j] = s[j];
|
ref_s[j] = s[j];
|
||||||
}
|
}
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, bd);
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit, limit, thresh, count, bd);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, bd));
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count, bd));
|
||||||
#else
|
#else
|
||||||
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh);
|
ref_loopfilter_op_(ref_s+8+p*8, p, blimit, limit, thresh, count);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh));
|
loopfilter_op_(s + 8 + p * 8, p, blimit, limit, thresh, count));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
err_count += ref_s[j] != s[j];
|
err_count += ref_s[j] != s[j];
|
||||||
}
|
}
|
||||||
@@ -251,14 +336,14 @@ TEST_P(Loop8Test6Param, ValueCheck) {
|
|||||||
TEST_P(Loop8Test9Param, OperationCheck) {
|
TEST_P(Loop8Test9Param, OperationCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = number_of_iterations;
|
const int count_test_block = number_of_iterations;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int32_t bd = bit_depth_;
|
const int32_t bd = bit_depth_;
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
|
||||||
#else
|
#else
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
int err_count_total = 0;
|
int err_count_total = 0;
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -324,7 +409,7 @@ TEST_P(Loop8Test9Param, OperationCheck) {
|
|||||||
}
|
}
|
||||||
ref_s[j] = s[j];
|
ref_s[j] = s[j];
|
||||||
}
|
}
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
||||||
blimit1, limit1, thresh1, bd);
|
blimit1, limit1, thresh1, bd);
|
||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
@@ -336,7 +421,7 @@ TEST_P(Loop8Test9Param, OperationCheck) {
|
|||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
||||||
blimit1, limit1, thresh1));
|
blimit1, limit1, thresh1));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
err_count += ref_s[j] != s[j];
|
err_count += ref_s[j] != s[j];
|
||||||
}
|
}
|
||||||
@@ -354,13 +439,13 @@ TEST_P(Loop8Test9Param, OperationCheck) {
|
|||||||
TEST_P(Loop8Test9Param, ValueCheck) {
|
TEST_P(Loop8Test9Param, ValueCheck) {
|
||||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||||
const int count_test_block = number_of_iterations;
|
const int count_test_block = number_of_iterations;
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
DECLARE_ALIGNED(16, uint16_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_s, kNumCoeffs);
|
||||||
#else
|
#else
|
||||||
DECLARE_ALIGNED(8, uint8_t, s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, s, kNumCoeffs);
|
||||||
DECLARE_ALIGNED(8, uint8_t, ref_s[kNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(8, uint8_t, ref_s, kNumCoeffs);
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
int err_count_total = 0;
|
int err_count_total = 0;
|
||||||
int first_failure = -1;
|
int first_failure = -1;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -400,7 +485,7 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
|||||||
s[j] = rnd.Rand16() & mask_;
|
s[j] = rnd.Rand16() & mask_;
|
||||||
ref_s[j] = s[j];
|
ref_s[j] = s[j];
|
||||||
}
|
}
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
const int32_t bd = bit_depth_;
|
const int32_t bd = bit_depth_;
|
||||||
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
ref_loopfilter_op_(ref_s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
||||||
blimit1, limit1, thresh1, bd);
|
blimit1, limit1, thresh1, bd);
|
||||||
@@ -413,7 +498,7 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
|||||||
ASM_REGISTER_STATE_CHECK(
|
ASM_REGISTER_STATE_CHECK(
|
||||||
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
loopfilter_op_(s + 8 + p * 8, p, blimit0, limit0, thresh0,
|
||||||
blimit1, limit1, thresh1));
|
blimit1, limit1, thresh1));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
for (int j = 0; j < kNumCoeffs; ++j) {
|
for (int j = 0; j < kNumCoeffs; ++j) {
|
||||||
err_count += ref_s[j] != s[j];
|
err_count += ref_s[j] != s[j];
|
||||||
}
|
}
|
||||||
@@ -431,137 +516,116 @@ TEST_P(Loop8Test9Param, ValueCheck) {
|
|||||||
using std::tr1::make_tuple;
|
using std::tr1::make_tuple;
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Loop8Test6Param,
|
SSE2, Loop8Test6Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_4_c, 8),
|
&vp9_highbd_lpf_horizontal_4_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
|
||||||
&vpx_highbd_lpf_vertical_4_c, 8),
|
&vp9_highbd_lpf_vertical_4_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 8),
|
&vp9_highbd_lpf_horizontal_8_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 8),
|
&vp9_highbd_lpf_horizontal_16_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 8),
|
&vp9_highbd_lpf_vertical_8_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
make_tuple(&wrapper_vertical_16_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_c, 8),
|
&wrapper_vertical_16_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
|
||||||
&vpx_highbd_lpf_vertical_16_c, 8),
|
&vp9_highbd_lpf_horizontal_4_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_4_c, 10),
|
&vp9_highbd_lpf_vertical_4_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
|
||||||
&vpx_highbd_lpf_vertical_4_c, 10),
|
&vp9_highbd_lpf_horizontal_8_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 10),
|
&vp9_highbd_lpf_horizontal_16_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 10),
|
&vp9_highbd_lpf_vertical_8_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
make_tuple(&wrapper_vertical_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 10),
|
&wrapper_vertical_16_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_4_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_c, 10),
|
&vp9_highbd_lpf_horizontal_4_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_4_sse2,
|
||||||
&vpx_highbd_lpf_vertical_16_c, 10),
|
&vp9_highbd_lpf_vertical_4_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_4_c, 12),
|
&vp9_highbd_lpf_horizontal_8_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_16_sse2,
|
||||||
&vpx_highbd_lpf_vertical_4_c, 12),
|
&vp9_highbd_lpf_horizontal_16_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_8_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_c, 12),
|
&vp9_highbd_lpf_vertical_8_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_8_sse2,
|
make_tuple(&wrapper_vertical_16_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_8_c, 12),
|
&wrapper_vertical_16_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_edge_16_sse2,
|
make_tuple(&wrapper_vertical_16_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_edge_16_c, 12),
|
&wrapper_vertical_16_dual_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_sse2,
|
make_tuple(&wrapper_vertical_16_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_c, 12),
|
&wrapper_vertical_16_dual_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_sse2,
|
make_tuple(&wrapper_vertical_16_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_16_c, 12),
|
&wrapper_vertical_16_dual_c, 12)));
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_dual_c, 8),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_dual_c, 10),
|
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_highbd_lpf_vertical_16_dual_c, 12)));
|
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Loop8Test6Param,
|
SSE2, Loop8Test6Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_4_sse2,
|
make_tuple(&vp9_lpf_horizontal_8_sse2, &vp9_lpf_horizontal_8_c, 8),
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
make_tuple(&vp9_lpf_horizontal_16_sse2, &vp9_lpf_horizontal_16_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_8_sse2,
|
make_tuple(&vp9_lpf_vertical_8_sse2, &vp9_lpf_vertical_8_c, 8),
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
make_tuple(&wrapper_vertical_16_sse2, &wrapper_vertical_16_c, 8)));
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_sse2,
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_sse2,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_sse2,
|
|
||||||
&vpx_lpf_vertical_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_sse2,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_sse2,
|
|
||||||
&vpx_lpf_vertical_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_sse2,
|
|
||||||
&vpx_lpf_vertical_16_dual_c, 8)));
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_AVX2 && (!CONFIG_VPX_HIGHBITDEPTH)
|
#if HAVE_AVX2 && (!CONFIG_VP9_HIGHBITDEPTH)
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
AVX2, Loop8Test6Param,
|
AVX2, Loop8Test6Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_avx2,
|
make_tuple(&vp9_lpf_horizontal_16_avx2, &vp9_lpf_horizontal_16_c, 8)));
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_avx2,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8)));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSE2
|
#if HAVE_SSE2
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Loop8Test9Param,
|
SSE2, Loop8Test9Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_4_dual_c, 8),
|
&vp9_highbd_lpf_horizontal_4_dual_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_dual_c, 8),
|
&vp9_highbd_lpf_horizontal_8_dual_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_4_dual_c, 8),
|
&vp9_highbd_lpf_vertical_4_dual_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_dual_c, 8),
|
&vp9_highbd_lpf_vertical_8_dual_c, 8),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_4_dual_c, 10),
|
&vp9_highbd_lpf_horizontal_4_dual_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_dual_c, 10),
|
&vp9_highbd_lpf_horizontal_8_dual_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_4_dual_c, 10),
|
&vp9_highbd_lpf_vertical_4_dual_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_dual_c, 10),
|
&vp9_highbd_lpf_vertical_8_dual_c, 10),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_4_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_4_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_4_dual_c, 12),
|
&vp9_highbd_lpf_horizontal_4_dual_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_horizontal_8_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_horizontal_8_dual_sse2,
|
||||||
&vpx_highbd_lpf_horizontal_8_dual_c, 12),
|
&vp9_highbd_lpf_horizontal_8_dual_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_4_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_4_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_4_dual_c, 12),
|
&vp9_highbd_lpf_vertical_4_dual_c, 12),
|
||||||
make_tuple(&vpx_highbd_lpf_vertical_8_dual_sse2,
|
make_tuple(&vp9_highbd_lpf_vertical_8_dual_sse2,
|
||||||
&vpx_highbd_lpf_vertical_8_dual_c, 12)));
|
&vp9_highbd_lpf_vertical_8_dual_c, 12)));
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, Loop8Test9Param,
|
SSE2, Loop8Test9Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_sse2,
|
make_tuple(&vp9_lpf_horizontal_4_dual_sse2,
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
&vp9_lpf_horizontal_4_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_sse2,
|
make_tuple(&vp9_lpf_horizontal_8_dual_sse2,
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
&vp9_lpf_horizontal_8_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_sse2,
|
make_tuple(&vp9_lpf_vertical_4_dual_sse2,
|
||||||
&vpx_lpf_vertical_4_dual_c, 8),
|
&vp9_lpf_vertical_4_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_sse2,
|
make_tuple(&vp9_lpf_vertical_8_dual_sse2,
|
||||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
&vp9_lpf_vertical_8_dual_c, 8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_NEON
|
#if HAVE_NEON
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
// No neon high bitdepth functions.
|
// No neon high bitdepth functions.
|
||||||
#else
|
#else
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
@@ -570,103 +634,35 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
#if HAVE_NEON_ASM
|
#if HAVE_NEON_ASM
|
||||||
// Using #if inside the macro is unsupported on MSVS but the tests are not
|
// Using #if inside the macro is unsupported on MSVS but the tests are not
|
||||||
// currently built for MSVS with ARM and NEON.
|
// currently built for MSVS with ARM and NEON.
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_neon,
|
make_tuple(&vp9_lpf_horizontal_16_neon,
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
&vp9_lpf_horizontal_16_c, 8),
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_neon,
|
make_tuple(&wrapper_vertical_16_neon,
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
&wrapper_vertical_16_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_16_neon,
|
make_tuple(&wrapper_vertical_16_dual_neon,
|
||||||
&vpx_lpf_vertical_16_c, 8),
|
&wrapper_vertical_16_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_neon,
|
make_tuple(&vp9_lpf_horizontal_8_neon,
|
||||||
&vpx_lpf_vertical_16_dual_c, 8),
|
&vp9_lpf_horizontal_8_c, 8),
|
||||||
|
make_tuple(&vp9_lpf_vertical_8_neon,
|
||||||
|
&vp9_lpf_vertical_8_c, 8),
|
||||||
#endif // HAVE_NEON_ASM
|
#endif // HAVE_NEON_ASM
|
||||||
make_tuple(&vpx_lpf_horizontal_8_neon,
|
make_tuple(&vp9_lpf_horizontal_4_neon,
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
&vp9_lpf_horizontal_4_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_8_neon,
|
make_tuple(&vp9_lpf_vertical_4_neon,
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
&vp9_lpf_vertical_4_c, 8)));
|
||||||
make_tuple(&vpx_lpf_horizontal_4_neon,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_neon,
|
|
||||||
&vpx_lpf_vertical_4_c, 8)));
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, Loop8Test9Param,
|
NEON, Loop8Test9Param,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
#if HAVE_NEON_ASM
|
#if HAVE_NEON_ASM
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_neon,
|
make_tuple(&vp9_lpf_horizontal_8_dual_neon,
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
&vp9_lpf_horizontal_8_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_neon,
|
make_tuple(&vp9_lpf_vertical_8_dual_neon,
|
||||||
&vpx_lpf_vertical_8_dual_c, 8),
|
&vp9_lpf_vertical_8_dual_c, 8),
|
||||||
#endif // HAVE_NEON_ASM
|
#endif // HAVE_NEON_ASM
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_neon,
|
make_tuple(&vp9_lpf_horizontal_4_dual_neon,
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
&vp9_lpf_horizontal_4_dual_c, 8),
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_neon,
|
make_tuple(&vp9_lpf_vertical_4_dual_neon,
|
||||||
&vpx_lpf_vertical_4_dual_c, 8)));
|
&vp9_lpf_vertical_4_dual_c, 8)));
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
#endif // HAVE_NEON
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
#if HAVE_DSPR2 && !CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
DSPR2, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dspr2,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dspr2,
|
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8,
|
|
||||||
&vpx_lpf_horizontal_edge_8, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16,
|
|
||||||
&vpx_lpf_horizontal_edge_16, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dspr2,
|
|
||||||
&vpx_lpf_vertical_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dspr2,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dspr2,
|
|
||||||
&vpx_lpf_vertical_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_dual_dspr2,
|
|
||||||
&vpx_lpf_vertical_16_dual_c, 8)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
DSPR2, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_dspr2,
|
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_dspr2,
|
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_dspr2,
|
|
||||||
&vpx_lpf_vertical_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_dspr2,
|
|
||||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
|
||||||
#endif // HAVE_DSPR2 && !CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#if HAVE_MSA && (!CONFIG_VPX_HIGHBITDEPTH)
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Loop8Test6Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_msa,
|
|
||||||
&vpx_lpf_horizontal_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_msa,
|
|
||||||
&vpx_lpf_horizontal_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_8_msa,
|
|
||||||
&vpx_lpf_horizontal_edge_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_edge_16_msa,
|
|
||||||
&vpx_lpf_horizontal_edge_16_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_msa,
|
|
||||||
&vpx_lpf_vertical_4_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_msa,
|
|
||||||
&vpx_lpf_vertical_8_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_16_msa,
|
|
||||||
&vpx_lpf_vertical_16_c, 8)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, Loop8Test9Param,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vpx_lpf_horizontal_4_dual_msa,
|
|
||||||
&vpx_lpf_horizontal_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_horizontal_8_dual_msa,
|
|
||||||
&vpx_lpf_horizontal_8_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_4_dual_msa,
|
|
||||||
&vpx_lpf_vertical_4_dual_c, 8),
|
|
||||||
make_tuple(&vpx_lpf_vertical_8_dual_msa,
|
|
||||||
&vpx_lpf_vertical_8_dual_c, 8)));
|
|
||||||
#endif // HAVE_MSA && (!CONFIG_VPX_HIGHBITDEPTH)
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,225 +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 "./vpx_dsp_rtcd.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(16, uint8_t, src_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
int err_count = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
int src_stride = MAX_SB_SIZE;
|
|
||||||
int ref_stride = MAX_SB_SIZE;
|
|
||||||
int msk_stride = MAX_SB_SIZE;
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
for (int j = 0; j < MAX_SB_SIZE*MAX_SB_SIZE; j++) {
|
|
||||||
src_ptr[j] = rnd.Rand8();
|
|
||||||
ref_ptr[j] = rnd.Rand8();
|
|
||||||
msk_ptr[j] = ((rnd.Rand8()&0x7f) > 64) ? rnd.Rand8()&0x3f : 64;
|
|
||||||
assert(msk_ptr[j] <= 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_VPX_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(16, uint16_t, src_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE*MAX_SB_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_SB_SIZE;
|
|
||||||
int ref_stride = MAX_SB_SIZE;
|
|
||||||
int msk_stride = MAX_SB_SIZE;
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
for (int j = 0; j < MAX_SB_SIZE*MAX_SB_SIZE; 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_VPX_HIGHBITDEPTH
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
#if HAVE_SSSE3
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3_C_COMPARE, MaskedSADTest,
|
|
||||||
::testing::Values(
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_masked_sad128x128_ssse3,
|
|
||||||
&vpx_masked_sad128x128_c),
|
|
||||||
make_tuple(&vpx_masked_sad128x64_ssse3,
|
|
||||||
&vpx_masked_sad128x64_c),
|
|
||||||
make_tuple(&vpx_masked_sad64x128_ssse3,
|
|
||||||
&vpx_masked_sad64x128_c),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_masked_sad64x64_ssse3,
|
|
||||||
&vpx_masked_sad64x64_c),
|
|
||||||
make_tuple(&vpx_masked_sad64x32_ssse3,
|
|
||||||
&vpx_masked_sad64x32_c),
|
|
||||||
make_tuple(&vpx_masked_sad32x64_ssse3,
|
|
||||||
&vpx_masked_sad32x64_c),
|
|
||||||
make_tuple(&vpx_masked_sad32x32_ssse3,
|
|
||||||
&vpx_masked_sad32x32_c),
|
|
||||||
make_tuple(&vpx_masked_sad32x16_ssse3,
|
|
||||||
&vpx_masked_sad32x16_c),
|
|
||||||
make_tuple(&vpx_masked_sad16x32_ssse3,
|
|
||||||
&vpx_masked_sad16x32_c),
|
|
||||||
make_tuple(&vpx_masked_sad16x16_ssse3,
|
|
||||||
&vpx_masked_sad16x16_c),
|
|
||||||
make_tuple(&vpx_masked_sad16x8_ssse3,
|
|
||||||
&vpx_masked_sad16x8_c),
|
|
||||||
make_tuple(&vpx_masked_sad8x16_ssse3,
|
|
||||||
&vpx_masked_sad8x16_c),
|
|
||||||
make_tuple(&vpx_masked_sad8x8_ssse3,
|
|
||||||
&vpx_masked_sad8x8_c),
|
|
||||||
make_tuple(&vpx_masked_sad8x4_ssse3,
|
|
||||||
&vpx_masked_sad8x4_c),
|
|
||||||
make_tuple(&vpx_masked_sad4x8_ssse3,
|
|
||||||
&vpx_masked_sad4x8_c),
|
|
||||||
make_tuple(&vpx_masked_sad4x4_ssse3,
|
|
||||||
&vpx_masked_sad4x4_c)));
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3_C_COMPARE, HighbdMaskedSADTest,
|
|
||||||
::testing::Values(
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_masked_sad128x128_ssse3,
|
|
||||||
&vpx_highbd_masked_sad128x128_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad128x64_ssse3,
|
|
||||||
&vpx_highbd_masked_sad128x64_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad64x128_ssse3,
|
|
||||||
&vpx_highbd_masked_sad64x128_c),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_masked_sad64x64_ssse3,
|
|
||||||
&vpx_highbd_masked_sad64x64_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad64x32_ssse3,
|
|
||||||
&vpx_highbd_masked_sad64x32_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad32x64_ssse3,
|
|
||||||
&vpx_highbd_masked_sad32x64_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad32x32_ssse3,
|
|
||||||
&vpx_highbd_masked_sad32x32_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad32x16_ssse3,
|
|
||||||
&vpx_highbd_masked_sad32x16_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad16x32_ssse3,
|
|
||||||
&vpx_highbd_masked_sad16x32_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad16x16_ssse3,
|
|
||||||
&vpx_highbd_masked_sad16x16_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad16x8_ssse3,
|
|
||||||
&vpx_highbd_masked_sad16x8_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad8x16_ssse3,
|
|
||||||
&vpx_highbd_masked_sad8x16_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad8x8_ssse3,
|
|
||||||
&vpx_highbd_masked_sad8x8_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad8x4_ssse3,
|
|
||||||
&vpx_highbd_masked_sad8x4_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad4x8_ssse3,
|
|
||||||
&vpx_highbd_masked_sad4x8_c),
|
|
||||||
make_tuple(&vpx_highbd_masked_sad4x4_ssse3,
|
|
||||||
&vpx_highbd_masked_sad4x4_c)));
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
#endif // HAVE_SSSE3
|
|
||||||
} // namespace
|
|
||||||
@@ -1,816 +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 "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_codec.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
#include "vpx_dsp/vpx_filter.h"
|
|
||||||
#include "vpx_mem/vpx_mem.h"
|
|
||||||
|
|
||||||
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(16, uint8_t, src_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
int err_count = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
int src_stride = MAX_SB_SIZE;
|
|
||||||
int ref_stride = MAX_SB_SIZE;
|
|
||||||
int msk_stride = MAX_SB_SIZE;
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
for (int j = 0; j < MAX_SB_SIZE*MAX_SB_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(16, uint8_t, src_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
int err_count = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
int src_stride = MAX_SB_SIZE;
|
|
||||||
int ref_stride = MAX_SB_SIZE;
|
|
||||||
int msk_stride = MAX_SB_SIZE;
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
memset(src_ptr, (i & 0x1) ? 255 : 0, MAX_SB_SIZE*MAX_SB_SIZE);
|
|
||||||
memset(ref_ptr, (i & 0x2) ? 255 : 0, MAX_SB_SIZE*MAX_SB_SIZE);
|
|
||||||
memset(msk_ptr, (i & 0x4) ? 64 : 0, MAX_SB_SIZE*MAX_SB_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(16, uint8_t, src_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
int err_count = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
int src_stride = (MAX_SB_SIZE+1);
|
|
||||||
int ref_stride = (MAX_SB_SIZE+1);
|
|
||||||
int msk_stride = (MAX_SB_SIZE+1);
|
|
||||||
int xoffset;
|
|
||||||
int yoffset;
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
int xoffsets[] = {0, 4, rnd(BIL_SUBPEL_SHIFTS)};
|
|
||||||
int yoffsets[] = {0, 4, rnd(BIL_SUBPEL_SHIFTS)};
|
|
||||||
for (int j = 0; j < (MAX_SB_SIZE+1)*(MAX_SB_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(16, uint8_t, src_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, ref_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
int first_failure_x = -1;
|
|
||||||
int first_failure_y = -1;
|
|
||||||
int err_count = 0;
|
|
||||||
int first_failure = -1;
|
|
||||||
int src_stride = (MAX_SB_SIZE+1);
|
|
||||||
int ref_stride = (MAX_SB_SIZE+1);
|
|
||||||
int msk_stride = (MAX_SB_SIZE+1);
|
|
||||||
|
|
||||||
for (int xoffset = 0 ; xoffset < BIL_SUBPEL_SHIFTS ; xoffset++) {
|
|
||||||
for (int yoffset = 0 ; yoffset < BIL_SUBPEL_SHIFTS ; yoffset++) {
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
memset(src_ptr, (i & 0x1) ? 255 : 0, (MAX_SB_SIZE+1)*(MAX_SB_SIZE+1));
|
|
||||||
memset(ref_ptr, (i & 0x2) ? 255 : 0, (MAX_SB_SIZE+1)*(MAX_SB_SIZE+1));
|
|
||||||
memset(msk_ptr, (i & 0x4) ? 64 : 0, (MAX_SB_SIZE+1)*(MAX_SB_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_VPX_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(16, uint16_t, src_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE*MAX_SB_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_SB_SIZE;
|
|
||||||
int ref_stride = MAX_SB_SIZE;
|
|
||||||
int msk_stride = MAX_SB_SIZE;
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
for (int j = 0; j < MAX_SB_SIZE*MAX_SB_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(16, uint16_t, src_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_ptr[MAX_SB_SIZE*MAX_SB_SIZE]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[MAX_SB_SIZE*MAX_SB_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_SB_SIZE;
|
|
||||||
int ref_stride = MAX_SB_SIZE;
|
|
||||||
int msk_stride = MAX_SB_SIZE;
|
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
vpx_memset16(src_ptr, (i & 0x1) ? ((1 << bit_depth_) - 1) : 0,
|
|
||||||
MAX_SB_SIZE*MAX_SB_SIZE);
|
|
||||||
vpx_memset16(ref_ptr, (i & 0x2) ? ((1 << bit_depth_) - 1) : 0,
|
|
||||||
MAX_SB_SIZE*MAX_SB_SIZE);
|
|
||||||
memset(msk_ptr, (i & 0x4) ? 64 : 0, MAX_SB_SIZE*MAX_SB_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(16, uint16_t, src_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[(MAX_SB_SIZE+1)*(MAX_SB_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_SB_SIZE+1);
|
|
||||||
int ref_stride = (MAX_SB_SIZE+1);
|
|
||||||
int msk_stride = (MAX_SB_SIZE+1);
|
|
||||||
int xoffset, yoffset;
|
|
||||||
|
|
||||||
for (int i = 0; i < number_of_iterations; ++i) {
|
|
||||||
for (xoffset = 0; xoffset < BIL_SUBPEL_SHIFTS; xoffset++) {
|
|
||||||
for (yoffset = 0; yoffset < BIL_SUBPEL_SHIFTS; yoffset++) {
|
|
||||||
for (int j = 0; j < (MAX_SB_SIZE+1)*(MAX_SB_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(16, uint16_t, src_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint16_t, ref_ptr[(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1)]);
|
|
||||||
DECLARE_ALIGNED(16, uint8_t, msk_ptr[(MAX_SB_SIZE+1)*(MAX_SB_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_SB_SIZE+1);
|
|
||||||
int ref_stride = (MAX_SB_SIZE+1);
|
|
||||||
int msk_stride = (MAX_SB_SIZE+1);
|
|
||||||
|
|
||||||
for (int xoffset = 0 ; xoffset < BIL_SUBPEL_SHIFTS ; xoffset++) {
|
|
||||||
for (int yoffset = 0 ; yoffset < BIL_SUBPEL_SHIFTS ; yoffset++) {
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
vpx_memset16(src_ptr, (i & 0x1) ? ((1 << bit_depth_) - 1) : 0,
|
|
||||||
(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1));
|
|
||||||
vpx_memset16(ref_ptr, (i & 0x2) ? ((1 << bit_depth_) - 1) : 0,
|
|
||||||
(MAX_SB_SIZE+1)*(MAX_SB_SIZE+1));
|
|
||||||
memset(msk_ptr, (i & 0x4) ? 64 : 0, (MAX_SB_SIZE+1)*(MAX_SB_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_VPX_HIGHBITDEPTH
|
|
||||||
|
|
||||||
using std::tr1::make_tuple;
|
|
||||||
|
|
||||||
#if HAVE_SSSE3
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3_C_COMPARE, MaskedVarianceTest,
|
|
||||||
::testing::Values(
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_masked_variance128x128_ssse3,
|
|
||||||
&vpx_masked_variance128x128_c),
|
|
||||||
make_tuple(&vpx_masked_variance128x64_ssse3,
|
|
||||||
&vpx_masked_variance128x64_c),
|
|
||||||
make_tuple(&vpx_masked_variance64x128_ssse3,
|
|
||||||
&vpx_masked_variance64x128_c),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_masked_variance64x64_ssse3,
|
|
||||||
&vpx_masked_variance64x64_c),
|
|
||||||
make_tuple(&vpx_masked_variance64x32_ssse3,
|
|
||||||
&vpx_masked_variance64x32_c),
|
|
||||||
make_tuple(&vpx_masked_variance32x64_ssse3,
|
|
||||||
&vpx_masked_variance32x64_c),
|
|
||||||
make_tuple(&vpx_masked_variance32x32_ssse3,
|
|
||||||
&vpx_masked_variance32x32_c),
|
|
||||||
make_tuple(&vpx_masked_variance32x16_ssse3,
|
|
||||||
&vpx_masked_variance32x16_c),
|
|
||||||
make_tuple(&vpx_masked_variance16x32_ssse3,
|
|
||||||
&vpx_masked_variance16x32_c),
|
|
||||||
make_tuple(&vpx_masked_variance16x16_ssse3,
|
|
||||||
&vpx_masked_variance16x16_c),
|
|
||||||
make_tuple(&vpx_masked_variance16x8_ssse3,
|
|
||||||
&vpx_masked_variance16x8_c),
|
|
||||||
make_tuple(&vpx_masked_variance8x16_ssse3,
|
|
||||||
&vpx_masked_variance8x16_c),
|
|
||||||
make_tuple(&vpx_masked_variance8x8_ssse3,
|
|
||||||
&vpx_masked_variance8x8_c),
|
|
||||||
make_tuple(&vpx_masked_variance8x4_ssse3,
|
|
||||||
&vpx_masked_variance8x4_c),
|
|
||||||
make_tuple(&vpx_masked_variance4x8_ssse3,
|
|
||||||
&vpx_masked_variance4x8_c),
|
|
||||||
make_tuple(&vpx_masked_variance4x4_ssse3,
|
|
||||||
&vpx_masked_variance4x4_c)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3_C_COMPARE, MaskedSubPixelVarianceTest,
|
|
||||||
::testing::Values(
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance128x128_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance128x128_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance128x64_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance128x64_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance64x128_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance64x128_c),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance64x64_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance64x64_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance64x32_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance64x32_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance32x64_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance32x64_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance32x32_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance32x32_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance32x16_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance32x16_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance16x32_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance16x32_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance16x16_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance16x16_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance16x8_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance16x8_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance8x16_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance8x16_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance8x8_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance8x8_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance8x4_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance8x4_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance4x8_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance4x8_c),
|
|
||||||
make_tuple(&vpx_masked_sub_pixel_variance4x4_ssse3,
|
|
||||||
&vpx_masked_sub_pixel_variance4x4_c)));
|
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3_C_COMPARE, HighbdMaskedVarianceTest,
|
|
||||||
::testing::Values(
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_masked_variance128x128_ssse3,
|
|
||||||
&vpx_highbd_masked_variance128x128_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance128x64_ssse3,
|
|
||||||
&vpx_highbd_masked_variance128x64_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance64x128_ssse3,
|
|
||||||
&vpx_highbd_masked_variance64x128_c, VPX_BITS_8),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_masked_variance64x64_ssse3,
|
|
||||||
&vpx_highbd_masked_variance64x64_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance64x32_ssse3,
|
|
||||||
&vpx_highbd_masked_variance64x32_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance32x64_ssse3,
|
|
||||||
&vpx_highbd_masked_variance32x64_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance32x32_ssse3,
|
|
||||||
&vpx_highbd_masked_variance32x32_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance32x16_ssse3,
|
|
||||||
&vpx_highbd_masked_variance32x16_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance16x32_ssse3,
|
|
||||||
&vpx_highbd_masked_variance16x32_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance16x16_ssse3,
|
|
||||||
&vpx_highbd_masked_variance16x16_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance16x8_ssse3,
|
|
||||||
&vpx_highbd_masked_variance16x8_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance8x16_ssse3,
|
|
||||||
&vpx_highbd_masked_variance8x16_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance8x8_ssse3,
|
|
||||||
&vpx_highbd_masked_variance8x8_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance8x4_ssse3,
|
|
||||||
&vpx_highbd_masked_variance8x4_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance4x8_ssse3,
|
|
||||||
&vpx_highbd_masked_variance4x8_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_variance4x4_ssse3,
|
|
||||||
&vpx_highbd_masked_variance4x4_c, VPX_BITS_8),
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance128x128_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance128x128_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance128x64_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance128x64_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance64x128_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance64x128_c, VPX_BITS_10),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance64x64_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance64x64_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance64x32_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance64x32_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance32x64_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance32x64_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance32x32_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance32x32_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance32x16_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance32x16_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance16x32_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance16x32_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance16x16_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance16x16_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance16x8_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance16x8_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance8x16_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance8x16_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance8x8_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance8x8_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance8x4_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance8x4_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance4x8_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance4x8_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_variance4x4_ssse3,
|
|
||||||
&vpx_highbd_10_masked_variance4x4_c, VPX_BITS_10),
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance128x128_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance128x128_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance128x64_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance128x64_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance64x128_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance64x128_c, VPX_BITS_12),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance64x64_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance64x64_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance64x32_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance64x32_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance32x64_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance32x64_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance32x32_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance32x32_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance32x16_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance32x16_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance16x32_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance16x32_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance16x16_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance16x16_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance16x8_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance16x8_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance8x16_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance8x16_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance8x8_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance8x8_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance8x4_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance8x4_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance4x8_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance4x8_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_variance4x4_ssse3,
|
|
||||||
&vpx_highbd_12_masked_variance4x4_c, VPX_BITS_12)));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
SSSE3_C_COMPARE, HighbdMaskedSubPixelVarianceTest,
|
|
||||||
::testing::Values(
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance128x128_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance128x128_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance128x64_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance128x64_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance64x128_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance64x128_c, VPX_BITS_8),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance64x64_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance64x64_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance64x32_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance64x32_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance32x64_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance32x64_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance32x32_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance32x32_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance32x16_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance32x16_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance16x32_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance16x32_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance16x16_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance16x16_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance16x8_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance16x8_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance8x16_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance8x16_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance8x8_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance8x8_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance8x4_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance8x4_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance4x8_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance4x8_c, VPX_BITS_8),
|
|
||||||
make_tuple(&vpx_highbd_masked_sub_pixel_variance4x4_ssse3,
|
|
||||||
&vpx_highbd_masked_sub_pixel_variance4x4_c, VPX_BITS_8),
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance128x128_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance128x128_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance128x64_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance128x64_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance64x128_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance64x128_c, VPX_BITS_10),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance64x64_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance64x64_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance64x32_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance64x32_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance32x64_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance32x64_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance32x32_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance32x32_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance32x16_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance32x16_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance16x32_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance16x32_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance16x16_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance16x16_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance16x8_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance16x8_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance8x16_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance8x16_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance8x8_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance8x8_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance8x4_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance8x4_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance4x8_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance4x8_c, VPX_BITS_10),
|
|
||||||
make_tuple(&vpx_highbd_10_masked_sub_pixel_variance4x4_ssse3,
|
|
||||||
&vpx_highbd_10_masked_sub_pixel_variance4x4_c, VPX_BITS_10),
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance128x128_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance128x128_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance128x64_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance128x64_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance64x128_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance64x128_c, VPX_BITS_12),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance64x64_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance64x64_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance64x32_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance64x32_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance32x64_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance32x64_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance32x32_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance32x32_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance32x16_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance32x16_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance16x32_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance16x32_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance16x16_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance16x16_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance16x8_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance16x8_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance8x16_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance8x16_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance8x8_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance8x8_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance8x4_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance8x4_c, VPX_BITS_12) ,
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance4x8_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance4x8_c, VPX_BITS_12),
|
|
||||||
make_tuple(&vpx_highbd_12_masked_sub_pixel_variance4x4_ssse3,
|
|
||||||
&vpx_highbd_12_masked_sub_pixel_variance4x4_c, VPX_BITS_12)));
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
|
|
||||||
#endif // HAVE_SSSE3
|
|
||||||
} // namespace
|
|
||||||
@@ -42,10 +42,6 @@ class MD5 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Add(const uint8_t *data, size_t size) {
|
|
||||||
MD5Update(&md5_, data, static_cast<uint32_t>(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Get(void) {
|
const char *Get(void) {
|
||||||
static const char hex[16] = {
|
static const char hex[16] = {
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
|||||||
@@ -1,132 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using ::libvpx_test::ACMRandom;
|
|
||||||
|
|
||||||
typedef void (*MinMaxFunc)(const uint8_t *a, int a_stride,
|
|
||||||
const uint8_t *b, int b_stride,
|
|
||||||
int *min, int *max);
|
|
||||||
|
|
||||||
class MinMaxTest : public ::testing::TestWithParam<MinMaxFunc> {
|
|
||||||
public:
|
|
||||||
virtual void SetUp() {
|
|
||||||
mm_func_ = GetParam();
|
|
||||||
rnd_.Reset(ACMRandom::DeterministicSeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
MinMaxFunc mm_func_;
|
|
||||||
ACMRandom rnd_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void reference_minmax(const uint8_t *a, int a_stride,
|
|
||||||
const uint8_t *b, int b_stride,
|
|
||||||
int *min_ret, int *max_ret) {
|
|
||||||
int min = 255;
|
|
||||||
int max = 0;
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
for (int j = 0; j < 8; j++) {
|
|
||||||
const int diff = abs(a[i * a_stride + j] - b[i * b_stride + j]);
|
|
||||||
if (min > diff) min = diff;
|
|
||||||
if (max < diff) max = diff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*min_ret = min;
|
|
||||||
*max_ret = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(MinMaxTest, MinValue) {
|
|
||||||
for (int i = 0; i < 64; i++) {
|
|
||||||
uint8_t a[64], b[64];
|
|
||||||
memset(a, 0, sizeof(a));
|
|
||||||
memset(b, 255, sizeof(b));
|
|
||||||
b[i] = i; // Set a minimum difference of i.
|
|
||||||
|
|
||||||
int min, max;
|
|
||||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
|
|
||||||
EXPECT_EQ(255, max);
|
|
||||||
EXPECT_EQ(i, min);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(MinMaxTest, MaxValue) {
|
|
||||||
for (int i = 0; i < 64; i++) {
|
|
||||||
uint8_t a[64], b[64];
|
|
||||||
memset(a, 0, sizeof(a));
|
|
||||||
memset(b, 0, sizeof(b));
|
|
||||||
b[i] = i; // Set a maximum difference of i.
|
|
||||||
|
|
||||||
int min, max;
|
|
||||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
|
|
||||||
EXPECT_EQ(i, max);
|
|
||||||
EXPECT_EQ(0, min);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(MinMaxTest, CompareReference) {
|
|
||||||
uint8_t a[64], b[64];
|
|
||||||
for (int j = 0; j < 64; j++) {
|
|
||||||
a[j] = rnd_.Rand8();
|
|
||||||
b[j] = rnd_.Rand8();
|
|
||||||
}
|
|
||||||
|
|
||||||
int min_ref, max_ref, min, max;
|
|
||||||
reference_minmax(a, 8, b, 8, &min_ref, &max_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, 8, b, 8, &min, &max));
|
|
||||||
EXPECT_EQ(max_ref, max);
|
|
||||||
EXPECT_EQ(min_ref, min);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(MinMaxTest, CompareReferenceAndVaryStride) {
|
|
||||||
uint8_t a[8 * 64], b[8 * 64];
|
|
||||||
for (int i = 0; i < 8 * 64; i++) {
|
|
||||||
a[i] = rnd_.Rand8();
|
|
||||||
b[i] = rnd_.Rand8();
|
|
||||||
}
|
|
||||||
for (int a_stride = 8; a_stride <= 64; a_stride += 8) {
|
|
||||||
for (int b_stride = 8; b_stride <= 64; b_stride += 8) {
|
|
||||||
int min_ref, max_ref, min, max;
|
|
||||||
reference_minmax(a, a_stride, b, b_stride, &min_ref, &max_ref);
|
|
||||||
ASM_REGISTER_STATE_CHECK(mm_func_(a, a_stride, b, b_stride, &min, &max));
|
|
||||||
EXPECT_EQ(max_ref, max) << "when a_stride = " << a_stride
|
|
||||||
<< " and b_stride = " << b_stride;;
|
|
||||||
EXPECT_EQ(min_ref, min) << "when a_stride = " << a_stride
|
|
||||||
<< " and b_stride = " << b_stride;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(C, MinMaxTest, ::testing::Values(&vpx_minmax_8x8_c));
|
|
||||||
|
|
||||||
#if HAVE_SSE2
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE2, MinMaxTest,
|
|
||||||
::testing::Values(&vpx_minmax_8x8_sse2));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_NEON
|
|
||||||
INSTANTIATE_TEST_CASE_P(NEON, MinMaxTest,
|
|
||||||
::testing::Values(&vpx_minmax_8x8_neon));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@@ -1,192 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
#include "test/function_equivalence_test.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
|
|
||||||
#define MAX_SB_SQUARE (MAX_SB_SIZE * MAX_SB_SIZE)
|
|
||||||
|
|
||||||
using libvpx_test::FunctionEquivalenceTest;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
static const int kIterations = 1000;
|
|
||||||
static const int kMaskMax = 64;
|
|
||||||
|
|
||||||
typedef unsigned int (*ObmcSadF)(const uint8_t *pre, int pre_stride,
|
|
||||||
const int32_t *wsrc, const int32_t *mask);
|
|
||||||
typedef libvpx_test::FuncParam<ObmcSadF> TestFuncs;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 8 bit
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class ObmcSadTest : public FunctionEquivalenceTest<ObmcSadF> {};
|
|
||||||
|
|
||||||
TEST_P(ObmcSadTest, RandomValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint8_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = rng_(MAX_SB_SIZE + 1);
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = rng_.Rand8();
|
|
||||||
wsrc[i] = rng_.Rand8() * rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
mask[i] = rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int ref_res = params_.ref_func(pre, pre_stride, wsrc, mask);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(tst_res =
|
|
||||||
params_.tst_func(pre, pre_stride, wsrc, mask));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ObmcSadTest, ExtremeValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint8_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < MAX_SB_SIZE && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = iter;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = UINT8_MAX;
|
|
||||||
wsrc[i] = UINT8_MAX * kMaskMax * kMaskMax;
|
|
||||||
mask[i] = kMaskMax * kMaskMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int ref_res = params_.ref_func(pre, pre_stride, wsrc, mask);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(tst_res =
|
|
||||||
params_.tst_func(pre, pre_stride, wsrc, mask));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
const ObmcSadTest::ParamType sse4_functions[] = {
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_obmc_sad128x128_c, vpx_obmc_sad128x128_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad128x64_c, vpx_obmc_sad128x64_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad64x128_c, vpx_obmc_sad64x128_sse4_1),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_obmc_sad64x64_c, vpx_obmc_sad64x64_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad64x32_c, vpx_obmc_sad64x32_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad32x64_c, vpx_obmc_sad32x64_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad32x32_c, vpx_obmc_sad32x32_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad32x16_c, vpx_obmc_sad32x16_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad16x32_c, vpx_obmc_sad16x32_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad16x16_c, vpx_obmc_sad16x16_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad16x8_c, vpx_obmc_sad16x8_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad8x16_c, vpx_obmc_sad8x16_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad8x8_c, vpx_obmc_sad8x8_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad8x4_c, vpx_obmc_sad8x4_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad4x8_c, vpx_obmc_sad4x8_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_sad4x4_c, vpx_obmc_sad4x4_sse4_1)
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE4_1_C_COMPARE, ObmcSadTest,
|
|
||||||
::testing::ValuesIn(sse4_functions));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// High bit-depth
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
class ObmcSadHBDTest : public FunctionEquivalenceTest<ObmcSadF> {};
|
|
||||||
|
|
||||||
TEST_P(ObmcSadHBDTest, RandomValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint16_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = rng_(MAX_SB_SIZE + 1);
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = rng_(1<<12);
|
|
||||||
wsrc[i] = rng_(1<<12) * rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
mask[i] = rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int ref_res =
|
|
||||||
params_.ref_func(CONVERT_TO_BYTEPTR(pre), pre_stride, wsrc, mask);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(tst_res =
|
|
||||||
params_.tst_func(CONVERT_TO_BYTEPTR(pre), pre_stride, wsrc, mask));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ObmcSadHBDTest, ExtremeValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint16_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < MAX_SB_SIZE && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = iter;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = (1 << 12) - 1;
|
|
||||||
wsrc[i] = ((1 << 12) - 1) * kMaskMax * kMaskMax;
|
|
||||||
mask[i] = kMaskMax * kMaskMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int ref_res =
|
|
||||||
params_.ref_func(CONVERT_TO_BYTEPTR(pre), pre_stride, wsrc, mask);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(tst_res =
|
|
||||||
params_.tst_func(CONVERT_TO_BYTEPTR(pre), pre_stride, wsrc, mask));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
ObmcSadHBDTest::ParamType sse4_functions_hbd[] = {
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad128x128_c, vpx_highbd_obmc_sad128x128_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad128x64_c, vpx_highbd_obmc_sad128x64_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad64x128_c, vpx_highbd_obmc_sad64x128_sse4_1),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad64x64_c, vpx_highbd_obmc_sad64x64_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad64x32_c, vpx_highbd_obmc_sad64x32_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad32x64_c, vpx_highbd_obmc_sad32x64_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad32x32_c, vpx_highbd_obmc_sad32x32_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad32x16_c, vpx_highbd_obmc_sad32x16_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad16x32_c, vpx_highbd_obmc_sad16x32_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad16x16_c, vpx_highbd_obmc_sad16x16_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad16x8_c, vpx_highbd_obmc_sad16x8_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad8x16_c, vpx_highbd_obmc_sad8x16_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad8x8_c, vpx_highbd_obmc_sad8x8_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad8x4_c, vpx_highbd_obmc_sad8x4_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad4x8_c, vpx_highbd_obmc_sad4x8_sse4_1),
|
|
||||||
TestFuncs(vpx_highbd_obmc_sad4x4_c, vpx_highbd_obmc_sad4x4_sse4_1)
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE4_1_C_COMPARE, ObmcSadHBDTest,
|
|
||||||
::testing::ValuesIn(sse4_functions_hbd));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
} // namespace
|
|
||||||
@@ -1,294 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
#include "test/acm_random.h"
|
|
||||||
|
|
||||||
#include "test/function_equivalence_test.h"
|
|
||||||
#include "test/register_state_check.h"
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "vpx/vpx_integer.h"
|
|
||||||
|
|
||||||
#define MAX_SB_SQUARE (MAX_SB_SIZE * MAX_SB_SIZE)
|
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
|
||||||
using libvpx_test::FunctionEquivalenceTest;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
static const int kIterations = 1000;
|
|
||||||
static const int kMaskMax = 64;
|
|
||||||
|
|
||||||
typedef unsigned int (*ObmcVarF)(const uint8_t *pre, int pre_stride,
|
|
||||||
const int32_t *wsrc, const int32_t *mask,
|
|
||||||
unsigned int *sse);
|
|
||||||
typedef libvpx_test::FuncParam<ObmcVarF> TestFuncs;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 8 bit
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class ObmcVarianceTest : public FunctionEquivalenceTest<ObmcVarF> {};
|
|
||||||
|
|
||||||
TEST_P(ObmcVarianceTest, RandomValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint8_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = this->rng_(MAX_SB_SIZE + 1);
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = this->rng_.Rand8();
|
|
||||||
wsrc[i] = this->rng_.Rand8() * this->rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
mask[i] = this->rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ref_sse, tst_sse;
|
|
||||||
const unsigned int ref_res = params_.ref_func(pre, pre_stride, wsrc, mask,
|
|
||||||
&ref_sse);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
tst_res = params_.tst_func(pre, pre_stride, wsrc, mask, &tst_sse));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
ASSERT_EQ(ref_sse, tst_sse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ObmcVarianceTest, ExtremeValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint8_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < MAX_SB_SIZE && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = iter;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = UINT8_MAX;
|
|
||||||
wsrc[i] = UINT8_MAX * kMaskMax * kMaskMax;
|
|
||||||
mask[i] = kMaskMax * kMaskMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ref_sse, tst_sse;
|
|
||||||
const unsigned int ref_res = params_.ref_func(pre, pre_stride, wsrc, mask,
|
|
||||||
&ref_sse);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
tst_res = params_.tst_func(pre, pre_stride, wsrc, mask, &tst_sse));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
ASSERT_EQ(ref_sse, tst_sse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
const ObmcVarianceTest::ParamType sse4_functions[] = {
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_obmc_variance128x128_c, vpx_obmc_variance128x128_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance128x64_c, vpx_obmc_variance128x64_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance64x128_c, vpx_obmc_variance64x128_sse4_1),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_obmc_variance64x64_c, vpx_obmc_variance64x64_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance64x32_c, vpx_obmc_variance64x32_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance32x64_c, vpx_obmc_variance32x64_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance32x32_c, vpx_obmc_variance32x32_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance32x16_c, vpx_obmc_variance32x16_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance16x32_c, vpx_obmc_variance16x32_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance16x16_c, vpx_obmc_variance16x16_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance16x8_c, vpx_obmc_variance16x8_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance8x16_c, vpx_obmc_variance8x16_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance8x8_c, vpx_obmc_variance8x8_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance8x4_c, vpx_obmc_variance8x4_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance4x8_c, vpx_obmc_variance4x8_sse4_1),
|
|
||||||
TestFuncs(vpx_obmc_variance4x4_c, vpx_obmc_variance4x4_sse4_1)
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE4_1_C_COMPARE, ObmcVarianceTest,
|
|
||||||
::testing::ValuesIn(sse4_functions));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// High bit-depth
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
class ObmcVarianceHBDTest : public FunctionEquivalenceTest<ObmcVarF> {};
|
|
||||||
|
|
||||||
TEST_P(ObmcVarianceHBDTest, RandomValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint16_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < kIterations && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = this->rng_(MAX_SB_SIZE + 1);
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = this->rng_(1 << params_.bit_depth);
|
|
||||||
wsrc[i] = this->rng_(1 << params_.bit_depth) *
|
|
||||||
this->rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
mask[i] = this->rng_(kMaskMax * kMaskMax + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ref_sse, tst_sse;
|
|
||||||
const unsigned int ref_res = params_.ref_func(CONVERT_TO_BYTEPTR(pre),
|
|
||||||
pre_stride,
|
|
||||||
wsrc, mask, &ref_sse);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
tst_res = params_.tst_func(CONVERT_TO_BYTEPTR(pre),
|
|
||||||
pre_stride, wsrc, mask, &tst_sse));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
ASSERT_EQ(ref_sse, tst_sse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ObmcVarianceHBDTest, ExtremeValues) {
|
|
||||||
DECLARE_ALIGNED(32, uint16_t, pre[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, wsrc[MAX_SB_SQUARE]);
|
|
||||||
DECLARE_ALIGNED(32, int32_t, mask[MAX_SB_SQUARE]);
|
|
||||||
|
|
||||||
for (int iter = 0 ; iter < MAX_SB_SIZE && !HasFatalFailure() ; ++iter) {
|
|
||||||
const int pre_stride = iter;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < MAX_SB_SQUARE ; ++i) {
|
|
||||||
pre[i] = (1 << params_.bit_depth) - 1;
|
|
||||||
wsrc[i] = ((1 << params_.bit_depth) - 1) * kMaskMax * kMaskMax;
|
|
||||||
mask[i] = kMaskMax * kMaskMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int ref_sse, tst_sse;
|
|
||||||
const unsigned int ref_res = params_.ref_func(CONVERT_TO_BYTEPTR(pre),
|
|
||||||
pre_stride,
|
|
||||||
wsrc, mask, &ref_sse);
|
|
||||||
unsigned int tst_res;
|
|
||||||
ASM_REGISTER_STATE_CHECK(
|
|
||||||
tst_res = params_.tst_func(CONVERT_TO_BYTEPTR(pre), pre_stride,
|
|
||||||
wsrc, mask, &tst_sse));
|
|
||||||
|
|
||||||
ASSERT_EQ(ref_res, tst_res);
|
|
||||||
ASSERT_EQ(ref_sse, tst_sse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SSE4_1
|
|
||||||
ObmcVarianceHBDTest::ParamType sse4_functions_hbd[] = {
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance128x128_c,
|
|
||||||
vpx_highbd_obmc_variance128x128_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance128x64_c,
|
|
||||||
vpx_highbd_obmc_variance128x64_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance64x128_c,
|
|
||||||
vpx_highbd_obmc_variance64x128_sse4_1, 8),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance64x64_c,
|
|
||||||
vpx_highbd_obmc_variance64x64_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance64x32_c,
|
|
||||||
vpx_highbd_obmc_variance64x32_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance32x64_c,
|
|
||||||
vpx_highbd_obmc_variance32x64_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance32x32_c,
|
|
||||||
vpx_highbd_obmc_variance32x32_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance32x16_c,
|
|
||||||
vpx_highbd_obmc_variance32x16_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance16x32_c,
|
|
||||||
vpx_highbd_obmc_variance16x32_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance16x16_c,
|
|
||||||
vpx_highbd_obmc_variance16x16_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance16x8_c,
|
|
||||||
vpx_highbd_obmc_variance16x8_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance8x16_c,
|
|
||||||
vpx_highbd_obmc_variance8x16_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance8x8_c,
|
|
||||||
vpx_highbd_obmc_variance8x8_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance8x4_c,
|
|
||||||
vpx_highbd_obmc_variance8x4_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance4x8_c,
|
|
||||||
vpx_highbd_obmc_variance4x8_sse4_1, 8),
|
|
||||||
TestFuncs(vpx_highbd_obmc_variance4x4_c,
|
|
||||||
vpx_highbd_obmc_variance4x4_sse4_1, 8),
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance128x128_c,
|
|
||||||
vpx_highbd_10_obmc_variance128x128_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance128x64_c,
|
|
||||||
vpx_highbd_10_obmc_variance128x64_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance64x128_c,
|
|
||||||
vpx_highbd_10_obmc_variance64x128_sse4_1, 10),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance64x64_c,
|
|
||||||
vpx_highbd_10_obmc_variance64x64_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance64x32_c,
|
|
||||||
vpx_highbd_10_obmc_variance64x32_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance32x64_c,
|
|
||||||
vpx_highbd_10_obmc_variance32x64_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance32x32_c,
|
|
||||||
vpx_highbd_10_obmc_variance32x32_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance32x16_c,
|
|
||||||
vpx_highbd_10_obmc_variance32x16_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance16x32_c,
|
|
||||||
vpx_highbd_10_obmc_variance16x32_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance16x16_c,
|
|
||||||
vpx_highbd_10_obmc_variance16x16_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance16x8_c,
|
|
||||||
vpx_highbd_10_obmc_variance16x8_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance8x16_c,
|
|
||||||
vpx_highbd_10_obmc_variance8x16_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance8x8_c,
|
|
||||||
vpx_highbd_10_obmc_variance8x8_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance8x4_c,
|
|
||||||
vpx_highbd_10_obmc_variance8x4_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance4x8_c,
|
|
||||||
vpx_highbd_10_obmc_variance4x8_sse4_1, 10),
|
|
||||||
TestFuncs(vpx_highbd_10_obmc_variance4x4_c,
|
|
||||||
vpx_highbd_10_obmc_variance4x4_sse4_1, 10),
|
|
||||||
#if CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance128x128_c,
|
|
||||||
vpx_highbd_12_obmc_variance128x128_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance128x64_c,
|
|
||||||
vpx_highbd_12_obmc_variance128x64_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance64x128_c,
|
|
||||||
vpx_highbd_12_obmc_variance64x128_sse4_1, 12),
|
|
||||||
#endif // CONFIG_EXT_PARTITION
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance64x64_c,
|
|
||||||
vpx_highbd_12_obmc_variance64x64_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance64x32_c,
|
|
||||||
vpx_highbd_12_obmc_variance64x32_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance32x64_c,
|
|
||||||
vpx_highbd_12_obmc_variance32x64_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance32x32_c,
|
|
||||||
vpx_highbd_12_obmc_variance32x32_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance32x16_c,
|
|
||||||
vpx_highbd_12_obmc_variance32x16_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance16x32_c,
|
|
||||||
vpx_highbd_12_obmc_variance16x32_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance16x16_c,
|
|
||||||
vpx_highbd_12_obmc_variance16x16_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance16x8_c,
|
|
||||||
vpx_highbd_12_obmc_variance16x8_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance8x16_c,
|
|
||||||
vpx_highbd_12_obmc_variance8x16_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance8x8_c,
|
|
||||||
vpx_highbd_12_obmc_variance8x8_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance8x4_c,
|
|
||||||
vpx_highbd_12_obmc_variance8x4_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance4x8_c,
|
|
||||||
vpx_highbd_12_obmc_variance4x8_sse4_1, 12),
|
|
||||||
TestFuncs(vpx_highbd_12_obmc_variance4x4_c,
|
|
||||||
vpx_highbd_12_obmc_variance4x4_sse4_1, 12)
|
|
||||||
};
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(SSE4_1_C_COMPARE, ObmcVarianceHBDTest,
|
|
||||||
::testing::ValuesIn(sse4_functions_hbd));
|
|
||||||
#endif // HAVE_SSE4_1
|
|
||||||
#endif // CONFIG_VPX_HIGHBITDEPTH
|
|
||||||
} // namespace
|
|
||||||
@@ -13,15 +13,14 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vp10_rtcd.h"
|
|
||||||
#include "./vpx_dsp_rtcd.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
#include "vp10/common/blockd.h"
|
|
||||||
#include "vp10/common/scan.h"
|
#include "./vp9_rtcd.h"
|
||||||
|
#include "vp9/common/vp9_blockd.h"
|
||||||
|
#include "vp9/common/vp9_scan.h"
|
||||||
#include "vpx/vpx_integer.h"
|
#include "vpx/vpx_integer.h"
|
||||||
|
|
||||||
using libvpx_test::ACMRandom;
|
using libvpx_test::ACMRandom;
|
||||||
@@ -75,16 +74,16 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
|
|||||||
FAIL() << "Wrong Size!";
|
FAIL() << "Wrong Size!";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block1, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block2, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
|
||||||
|
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
const int block_size = size * size;
|
const int block_size = size * size;
|
||||||
|
|
||||||
DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kMaxNumCoeffs);
|
||||||
|
|
||||||
int max_error = 0;
|
int max_error = 0;
|
||||||
for (int i = 0; i < count_test_block; ++i) {
|
for (int i = 0; i < count_test_block; ++i) {
|
||||||
@@ -115,7 +114,7 @@ TEST_P(PartialIDctTest, RunQuantCheck) {
|
|||||||
// quantization with maximum allowed step sizes
|
// quantization with maximum allowed step sizes
|
||||||
test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
|
test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
|
||||||
for (int j = 1; j < last_nonzero_; ++j)
|
for (int j = 1; j < last_nonzero_; ++j)
|
||||||
test_coef_block1[vp10_default_scan_orders[tx_size_].scan[j]]
|
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]]
|
||||||
= (output_ref_block[j] / 1828) * 1828;
|
= (output_ref_block[j] / 1828) * 1828;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,10 +153,10 @@ TEST_P(PartialIDctTest, ResultsMatch) {
|
|||||||
FAIL() << "Wrong Size!";
|
FAIL() << "Wrong Size!";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block1, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_coef_block2, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
|
||||||
DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
|
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
|
||||||
const int count_test_block = 1000;
|
const int count_test_block = 1000;
|
||||||
const int max_coeff = 32766 / 4;
|
const int max_coeff = 32766 / 4;
|
||||||
const int block_size = size * size;
|
const int block_size = size * size;
|
||||||
@@ -177,7 +176,7 @@ TEST_P(PartialIDctTest, ResultsMatch) {
|
|||||||
max_energy_leftover = 0;
|
max_energy_leftover = 0;
|
||||||
coef = 0;
|
coef = 0;
|
||||||
}
|
}
|
||||||
test_coef_block1[vp10_default_scan_orders[tx_size_].scan[j]] = coef;
|
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]] = coef;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(test_coef_block2, test_coef_block1,
|
memcpy(test_coef_block2, test_coef_block1,
|
||||||
@@ -202,142 +201,117 @@ using std::tr1::make_tuple;
|
|||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
C, PartialIDctTest,
|
C, PartialIDctTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vp9_idct32x32_1024_add_c,
|
||||||
&vpx_idct32x32_34_add_c,
|
&vp9_idct32x32_34_add_c,
|
||||||
TX_32X32, 34),
|
TX_32X32, 34),
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vp9_idct32x32_1024_add_c,
|
||||||
&vpx_idct32x32_1_add_c,
|
&vp9_idct32x32_1_add_c,
|
||||||
TX_32X32, 1),
|
TX_32X32, 1),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct16x16_10_add_c,
|
&vp9_idct16x16_10_add_c,
|
||||||
TX_16X16, 10),
|
TX_16X16, 10),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct16x16_1_add_c,
|
&vp9_idct16x16_1_add_c,
|
||||||
TX_16X16, 1),
|
TX_16X16, 1),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_12_add_c,
|
&vp9_idct8x8_12_add_c,
|
||||||
TX_8X8, 12),
|
TX_8X8, 12),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_1_add_c,
|
&vp9_idct8x8_1_add_c,
|
||||||
TX_8X8, 1),
|
TX_8X8, 1),
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
make_tuple(&vp9_fdct4x4_c,
|
||||||
&vpx_idct4x4_16_add_c,
|
&vp9_idct4x4_16_add_c,
|
||||||
&vpx_idct4x4_1_add_c,
|
&vp9_idct4x4_1_add_c,
|
||||||
TX_4X4, 1)));
|
TX_4X4, 1)));
|
||||||
|
|
||||||
#if HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_NEON
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
NEON, PartialIDctTest,
|
NEON, PartialIDctTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vp9_idct32x32_1024_add_c,
|
||||||
&vpx_idct32x32_1_add_neon,
|
&vp9_idct32x32_1_add_neon,
|
||||||
TX_32X32, 1),
|
TX_32X32, 1),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct16x16_10_add_neon,
|
&vp9_idct16x16_10_add_neon,
|
||||||
TX_16X16, 10),
|
TX_16X16, 10),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct16x16_1_add_neon,
|
&vp9_idct16x16_1_add_neon,
|
||||||
TX_16X16, 1),
|
TX_16X16, 1),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_12_add_neon,
|
&vp9_idct8x8_12_add_neon,
|
||||||
TX_8X8, 12),
|
TX_8X8, 12),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_1_add_neon,
|
&vp9_idct8x8_1_add_neon,
|
||||||
TX_8X8, 1),
|
TX_8X8, 1),
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
make_tuple(&vp9_fdct4x4_c,
|
||||||
&vpx_idct4x4_16_add_c,
|
&vp9_idct4x4_16_add_c,
|
||||||
&vpx_idct4x4_1_add_neon,
|
&vp9_idct4x4_1_add_neon,
|
||||||
TX_4X4, 1)));
|
TX_4X4, 1)));
|
||||||
#endif // HAVE_NEON && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
#if HAVE_SSE2 && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSE2, PartialIDctTest,
|
SSE2, PartialIDctTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vp9_idct32x32_1024_add_c,
|
||||||
&vpx_idct32x32_34_add_sse2,
|
&vp9_idct32x32_34_add_sse2,
|
||||||
TX_32X32, 34),
|
TX_32X32, 34),
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct32x32_c,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vp9_idct32x32_1024_add_c,
|
||||||
&vpx_idct32x32_1_add_sse2,
|
&vp9_idct32x32_1_add_sse2,
|
||||||
TX_32X32, 1),
|
TX_32X32, 1),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct16x16_10_add_sse2,
|
&vp9_idct16x16_10_add_sse2,
|
||||||
TX_16X16, 10),
|
TX_16X16, 10),
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct16x16_256_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct16x16_1_add_sse2,
|
&vp9_idct16x16_1_add_sse2,
|
||||||
TX_16X16, 1),
|
TX_16X16, 1),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_12_add_sse2,
|
&vp9_idct8x8_12_add_sse2,
|
||||||
TX_8X8, 12),
|
TX_8X8, 12),
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_1_add_sse2,
|
&vp9_idct8x8_1_add_sse2,
|
||||||
TX_8X8, 1),
|
TX_8X8, 1),
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
make_tuple(&vp9_fdct4x4_c,
|
||||||
&vpx_idct4x4_16_add_c,
|
&vp9_idct4x4_16_add_c,
|
||||||
&vpx_idct4x4_1_add_sse2,
|
&vp9_idct4x4_1_add_sse2,
|
||||||
TX_4X4, 1)));
|
TX_4X4, 1)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SSSE3 && ARCH_X86_64 && \
|
#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \
|
||||||
!CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
!CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
SSSE3_64, PartialIDctTest,
|
SSSE3_64, PartialIDctTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
make_tuple(&vp9_fdct8x8_c,
|
||||||
&vpx_idct8x8_64_add_c,
|
&vp9_idct8x8_64_add_c,
|
||||||
&vpx_idct8x8_12_add_ssse3,
|
&vp9_idct8x8_12_add_ssse3,
|
||||||
TX_8X8, 12)));
|
TX_8X8, 12)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
#if HAVE_SSSE3 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
MSA, PartialIDctTest,
|
SSSE3, PartialIDctTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
make_tuple(&vp9_fdct16x16_c,
|
||||||
&vpx_idct32x32_1024_add_c,
|
&vp9_idct16x16_256_add_c,
|
||||||
&vpx_idct32x32_34_add_msa,
|
&vp9_idct16x16_10_add_ssse3,
|
||||||
TX_32X32, 34),
|
TX_16X16, 10)));
|
||||||
make_tuple(&vpx_fdct32x32_c,
|
#endif
|
||||||
&vpx_idct32x32_1024_add_c,
|
|
||||||
&vpx_idct32x32_1_add_msa,
|
|
||||||
TX_32X32, 1),
|
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
|
||||||
&vpx_idct16x16_256_add_c,
|
|
||||||
&vpx_idct16x16_10_add_msa,
|
|
||||||
TX_16X16, 10),
|
|
||||||
make_tuple(&vpx_fdct16x16_c,
|
|
||||||
&vpx_idct16x16_256_add_c,
|
|
||||||
&vpx_idct16x16_1_add_msa,
|
|
||||||
TX_16X16, 1),
|
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
|
||||||
&vpx_idct8x8_64_add_c,
|
|
||||||
&vpx_idct8x8_12_add_msa,
|
|
||||||
TX_8X8, 10),
|
|
||||||
make_tuple(&vpx_fdct8x8_c,
|
|
||||||
&vpx_idct8x8_64_add_c,
|
|
||||||
&vpx_idct8x8_1_add_msa,
|
|
||||||
TX_8X8, 1),
|
|
||||||
make_tuple(&vpx_fdct4x4_c,
|
|
||||||
&vpx_idct4x4_16_add_c,
|
|
||||||
&vpx_idct4x4_1_add_msa,
|
|
||||||
TX_4X4, 1)));
|
|
||||||
#endif // HAVE_MSA && !CONFIG_VPX_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
63
test/postproc.sh
Executable file
63
test/postproc.sh
Executable file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/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 postproc example code. To add new tests to this
|
||||||
|
## file, do the following:
|
||||||
|
## 1. Write a shell function (this is your test).
|
||||||
|
## 2. Add the function to postproc_tests (on a new line).
|
||||||
|
##
|
||||||
|
. $(dirname $0)/tools_common.sh
|
||||||
|
|
||||||
|
# Environment check: Make sure input is available:
|
||||||
|
# $VP8_IVF_FILE and $VP9_IVF_FILE are required.
|
||||||
|
postproc_verify_environment() {
|
||||||
|
if [ ! -e "${VP8_IVF_FILE}" ] || [ ! -e "${VP9_IVF_FILE}" ]; then
|
||||||
|
echo "Libvpx test data must exist in LIBVPX_TEST_DATA_PATH."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Runs postproc using $1 as input file. $2 is the codec name, and is used
|
||||||
|
# solely to name the output file.
|
||||||
|
postproc() {
|
||||||
|
local decoder="${LIBVPX_BIN_PATH}/postproc${VPX_TEST_EXE_SUFFIX}"
|
||||||
|
local input_file="$1"
|
||||||
|
local codec="$2"
|
||||||
|
local output_file="${VPX_TEST_OUTPUT_DIR}/postproc_${codec}.raw"
|
||||||
|
|
||||||
|
if [ ! -x "${decoder}" ]; then
|
||||||
|
elog "${decoder} does not exist or is not executable."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval "${VPX_TEST_PREFIX}" "${decoder}" "${input_file}" "${output_file}" \
|
||||||
|
${devnull}
|
||||||
|
|
||||||
|
[ -e "${output_file}" ] || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
postproc_vp8() {
|
||||||
|
if [ "$(vp8_decode_available)" = "yes" ]; then
|
||||||
|
postproc "${VP8_IVF_FILE}" vp8 || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
postproc_vp9() {
|
||||||
|
if [ "$(vpx_config_option_enabled CONFIG_VP9_POSTPROC)" = "yes" ]; then
|
||||||
|
if [ "$(vp9_decode_available)" = "yes" ]; then
|
||||||
|
postproc "${VP9_IVF_FILE}" vp9 || return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
postproc_tests="postproc_vp8
|
||||||
|
postproc_vp9"
|
||||||
|
|
||||||
|
run_tests postproc_verify_environment "${postproc_tests}"
|
||||||
113
test/pp_filter_test.cc
Normal file
113
test/pp_filter_test.cc
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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 "test/clear_system_state.h"
|
||||||
|
#include "test/register_state_check.h"
|
||||||
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vp8_rtcd.h"
|
||||||
|
#include "vpx/vpx_integer.h"
|
||||||
|
#include "vpx_mem/vpx_mem.h"
|
||||||
|
|
||||||
|
typedef void (*PostProcFunc)(unsigned char *src_ptr,
|
||||||
|
unsigned char *dst_ptr,
|
||||||
|
int src_pixels_per_line,
|
||||||
|
int dst_pixels_per_line,
|
||||||
|
int cols,
|
||||||
|
unsigned char *flimit,
|
||||||
|
int size);
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class VP8PostProcessingFilterTest
|
||||||
|
: public ::testing::TestWithParam<PostProcFunc> {
|
||||||
|
public:
|
||||||
|
virtual void TearDown() {
|
||||||
|
libvpx_test::ClearSystemState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test routine for the VP8 post-processing function
|
||||||
|
// vp8_post_proc_down_and_across_mb_row_c.
|
||||||
|
|
||||||
|
TEST_P(VP8PostProcessingFilterTest, FilterOutputCheck) {
|
||||||
|
// Size of the underlying data block that will be filtered.
|
||||||
|
const int block_width = 16;
|
||||||
|
const int block_height = 16;
|
||||||
|
|
||||||
|
// 5-tap filter needs 2 padding rows above and below the block in the input.
|
||||||
|
const int input_width = block_width;
|
||||||
|
const int input_height = block_height + 4;
|
||||||
|
const int input_stride = input_width;
|
||||||
|
const int input_size = input_width * input_height;
|
||||||
|
|
||||||
|
// Filter extends output block by 8 samples at left and right edges.
|
||||||
|
const int output_width = block_width + 16;
|
||||||
|
const int output_height = block_height;
|
||||||
|
const int output_stride = output_width;
|
||||||
|
const int output_size = output_width * output_height;
|
||||||
|
|
||||||
|
uint8_t *const src_image =
|
||||||
|
reinterpret_cast<uint8_t*>(vpx_calloc(input_size, 1));
|
||||||
|
uint8_t *const dst_image =
|
||||||
|
reinterpret_cast<uint8_t*>(vpx_calloc(output_size, 1));
|
||||||
|
|
||||||
|
// Pointers to top-left pixel of block in the input and output images.
|
||||||
|
uint8_t *const src_image_ptr = src_image + (input_stride << 1);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Initialize pixels in the input:
|
||||||
|
// block pixels to value 1,
|
||||||
|
// border pixels to value 10.
|
||||||
|
(void)vpx_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) {
|
||||||
|
pixel_ptr[j] = 1;
|
||||||
|
}
|
||||||
|
pixel_ptr += input_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize pixels in the output to 99.
|
||||||
|
(void)vpx_memset(dst_image, 99, output_size);
|
||||||
|
|
||||||
|
ASM_REGISTER_STATE_CHECK(
|
||||||
|
GetParam()(src_image_ptr, dst_image_ptr, input_stride,
|
||||||
|
output_stride, block_width, flimits, 16));
|
||||||
|
|
||||||
|
static const uint8_t expected_data[block_height] = {
|
||||||
|
4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
pixel_ptr = dst_image_ptr;
|
||||||
|
for (int i = 0; i < block_height; ++i) {
|
||||||
|
for (int j = 0; j < block_width; ++j) {
|
||||||
|
EXPECT_EQ(expected_data[i], pixel_ptr[j])
|
||||||
|
<< "VP8PostProcessingFilterTest failed with invalid filter output";
|
||||||
|
}
|
||||||
|
pixel_ptr += output_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
vpx_free(src_image);
|
||||||
|
vpx_free(dst_image);
|
||||||
|
vpx_free(flimits);
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(C, VP8PostProcessingFilterTest,
|
||||||
|
::testing::Values(vp8_post_proc_down_and_across_mb_row_c));
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
INSTANTIATE_TEST_CASE_P(SSE2, VP8PostProcessingFilterTest,
|
||||||
|
::testing::Values(vp8_post_proc_down_and_across_mb_row_sse2));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace
|
||||||
@@ -11,12 +11,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "test/acm_random.h"
|
#include "test/acm_random.h"
|
||||||
#include "test/clear_system_state.h"
|
#include "test/clear_system_state.h"
|
||||||
#include "test/register_state_check.h"
|
#include "test/register_state_check.h"
|
||||||
#include "test/util.h"
|
#include "test/util.h"
|
||||||
|
|
||||||
|
#include "./vpx_config.h"
|
||||||
|
#include "./vp8_rtcd.h"
|
||||||
#include "vp8/common/blockd.h"
|
#include "vp8/common/blockd.h"
|
||||||
#include "vp8/common/onyx.h"
|
#include "vp8/common/onyx.h"
|
||||||
#include "vp8/encoder/block.h"
|
#include "vp8/encoder/block.h"
|
||||||
@@ -55,7 +56,7 @@ class QuantizeTestBase {
|
|||||||
|
|
||||||
// The full configuration is necessary to generate the quantization tables.
|
// The full configuration is necessary to generate the quantization tables.
|
||||||
VP8_CONFIG vp8_config;
|
VP8_CONFIG vp8_config;
|
||||||
memset(&vp8_config, 0, sizeof(vp8_config));
|
vpx_memset(&vp8_config, 0, sizeof(vp8_config));
|
||||||
|
|
||||||
vp8_comp_ = vp8_create_compressor(&vp8_config);
|
vp8_comp_ = vp8_create_compressor(&vp8_config);
|
||||||
|
|
||||||
@@ -68,7 +69,8 @@ class QuantizeTestBase {
|
|||||||
// Copy macroblockd from the reference to get pre-set-up dequant values.
|
// Copy macroblockd from the reference to get pre-set-up dequant values.
|
||||||
macroblockd_dst_ = reinterpret_cast<MACROBLOCKD *>(
|
macroblockd_dst_ = reinterpret_cast<MACROBLOCKD *>(
|
||||||
vpx_memalign(32, sizeof(*macroblockd_dst_)));
|
vpx_memalign(32, sizeof(*macroblockd_dst_)));
|
||||||
memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_));
|
vpx_memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd,
|
||||||
|
sizeof(*macroblockd_dst_));
|
||||||
// Fix block pointers - currently they point to the blocks in the reference
|
// Fix block pointers - currently they point to the blocks in the reference
|
||||||
// structure.
|
// structure.
|
||||||
vp8_setup_block_dptrs(macroblockd_dst_);
|
vp8_setup_block_dptrs(macroblockd_dst_);
|
||||||
@@ -77,7 +79,8 @@ class QuantizeTestBase {
|
|||||||
void UpdateQuantizer(int q) {
|
void UpdateQuantizer(int q) {
|
||||||
vp8_set_quantizer(vp8_comp_, q);
|
vp8_set_quantizer(vp8_comp_, q);
|
||||||
|
|
||||||
memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd, sizeof(*macroblockd_dst_));
|
vpx_memcpy(macroblockd_dst_, &vp8_comp_->mb.e_mbd,
|
||||||
|
sizeof(*macroblockd_dst_));
|
||||||
vp8_setup_block_dptrs(macroblockd_dst_);
|
vp8_setup_block_dptrs(macroblockd_dst_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,12 +194,4 @@ INSTANTIATE_TEST_CASE_P(NEON, QuantizeTest,
|
|||||||
::testing::Values(make_tuple(&vp8_fast_quantize_b_neon,
|
::testing::Values(make_tuple(&vp8_fast_quantize_b_neon,
|
||||||
&vp8_fast_quantize_b_c)));
|
&vp8_fast_quantize_b_c)));
|
||||||
#endif // HAVE_NEON
|
#endif // HAVE_NEON
|
||||||
|
|
||||||
#if HAVE_MSA
|
|
||||||
INSTANTIATE_TEST_CASE_P(
|
|
||||||
MSA, QuantizeTest,
|
|
||||||
::testing::Values(
|
|
||||||
make_tuple(&vp8_fast_quantize_b_msa, &vp8_fast_quantize_b_c),
|
|
||||||
make_tuple(&vp8_regular_quantize_b_msa, &vp8_regular_quantize_b_c)));
|
|
||||||
#endif // HAVE_MSA
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -1,64 +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.
|
|
||||||
*/
|
|
||||||
#include "test/codec_factory.h"
|
|
||||||
#include "test/encode_test_driver.h"
|
|
||||||
#include "test/util.h"
|
|
||||||
#include "test/video_source.h"
|
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const int kVideoSourceWidth = 320;
|
|
||||||
const int kVideoSourceHeight = 240;
|
|
||||||
const int kFramesToEncode = 2;
|
|
||||||
|
|
||||||
class RealtimeTest
|
|
||||||
: public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
|
||||||
protected:
|
|
||||||
RealtimeTest()
|
|
||||||
: EncoderTest(GET_PARAM(0)), frame_packets_(0) {}
|
|
||||||
virtual ~RealtimeTest() {}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
SetMode(::libvpx_test::kRealTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
|
||||||
// TODO(tomfinegan): We're changing the pass value here to make sure
|
|
||||||
// we get frames when real time mode is combined with |g_pass| set to
|
|
||||||
// VPX_RC_FIRST_PASS. This is necessary because EncoderTest::RunLoop() sets
|
|
||||||
// the pass value based on the mode passed into EncoderTest::SetMode(),
|
|
||||||
// which overrides the one specified in SetUp() above.
|
|
||||||
cfg_.g_pass = VPX_RC_FIRST_PASS;
|
|
||||||
}
|
|
||||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t * /*pkt*/) {
|
|
||||||
frame_packets_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
int frame_packets_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(RealtimeTest, RealtimeFirstPassProducesFrames) {
|
|
||||||
::libvpx_test::RandomVideoSource video;
|
|
||||||
video.SetSize(kVideoSourceWidth, kVideoSourceHeight);
|
|
||||||
video.set_limit(kFramesToEncode);
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
EXPECT_EQ(kFramesToEncode, frame_packets_);
|
|
||||||
}
|
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(RealtimeTest,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime));
|
|
||||||
VP9_INSTANTIATE_TEST_CASE(RealtimeTest,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime));
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@@ -30,16 +30,20 @@
|
|||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
|
|
||||||
#undef NOMINMAX
|
#define _WIN32_LEAN_AND_MEAN
|
||||||
#define NOMINMAX
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
|
namespace testing {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
inline bool operator==(const M128A& lhs, const M128A& rhs) {
|
inline bool operator==(const M128A& lhs, const M128A& rhs) {
|
||||||
return (lhs.Low == rhs.Low && lhs.High == rhs.High);
|
return (lhs.Low == rhs.Low && lhs.High == rhs.High);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
|
|
||||||
// Compares the state of xmm[6-15] at construction with their state at
|
// Compares the state of xmm[6-15] at construction with their state at
|
||||||
@@ -87,12 +91,12 @@ class RegisterStateCheck {
|
|||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
|
||||||
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP10) \
|
#elif defined(CONFIG_SHARED) && defined(HAVE_NEON_ASM) && defined(CONFIG_VP9) \
|
||||||
&& !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP10
|
&& !CONFIG_SHARED && HAVE_NEON_ASM && CONFIG_VP9
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Save the d8-d15 registers into store.
|
// Save the d8-d15 registers into store.
|
||||||
void vpx_push_neon(int64_t *store);
|
void vp9_push_neon(int64_t *store);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace libvpx_test {
|
namespace libvpx_test {
|
||||||
@@ -107,7 +111,7 @@ class RegisterStateCheck {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool StoreRegisters(int64_t store[8]) {
|
static bool StoreRegisters(int64_t store[8]) {
|
||||||
vpx_push_neon(store);
|
vp9_push_neon(store);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +119,7 @@ class RegisterStateCheck {
|
|||||||
bool Check() const {
|
bool Check() const {
|
||||||
if (!initialized_) return false;
|
if (!initialized_) return false;
|
||||||
int64_t post_store[8];
|
int64_t post_store[8];
|
||||||
vpx_push_neon(post_store);
|
vp9_push_neon(post_store);
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
EXPECT_EQ(pre_store_[i], post_store[i]) << "d"
|
EXPECT_EQ(pre_store_[i], post_store[i]) << "d"
|
||||||
<< i + 8 << " has been modified";
|
<< i + 8 << " has been modified";
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
@@ -83,187 +81,34 @@ static void write_ivf_frame_header(const vpx_codec_cx_pkt_t *const pkt,
|
|||||||
const unsigned int kInitialWidth = 320;
|
const unsigned int kInitialWidth = 320;
|
||||||
const unsigned int kInitialHeight = 240;
|
const unsigned int kInitialHeight = 240;
|
||||||
|
|
||||||
struct FrameInfo {
|
unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) {
|
||||||
FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
|
if (frame < 10)
|
||||||
: pts(_pts), w(_w), h(_h) {}
|
return val;
|
||||||
|
if (frame < 20)
|
||||||
vpx_codec_pts_t pts;
|
return val / 2;
|
||||||
unsigned int w;
|
if (frame < 30)
|
||||||
unsigned int h;
|
return val * 2 / 3;
|
||||||
};
|
if (frame < 40)
|
||||||
|
return val / 4;
|
||||||
void ScaleForFrameNumber(unsigned int frame,
|
if (frame < 50)
|
||||||
unsigned int initial_w,
|
return val * 7 / 8;
|
||||||
unsigned int initial_h,
|
return val;
|
||||||
unsigned int *w,
|
|
||||||
unsigned int *h,
|
|
||||||
int flag_codec) {
|
|
||||||
if (frame < 10) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 20) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 30) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 40) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 50) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 60) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 70) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 80) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 90) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 100) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 110) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 120) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 130) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 140) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 150) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 160) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 170) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 180) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 190) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 200) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 210) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 220) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 230) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 240) {
|
|
||||||
*w = initial_w * 3 / 4;
|
|
||||||
*h = initial_h * 3 / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 250) {
|
|
||||||
*w = initial_w / 2;
|
|
||||||
*h = initial_h / 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (frame < 260) {
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Go down very low.
|
|
||||||
if (frame < 270) {
|
|
||||||
*w = initial_w / 4;
|
|
||||||
*h = initial_h / 4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (flag_codec == 1) {
|
|
||||||
// Cases that only works for VP9.
|
|
||||||
// For VP9: Swap width and height of original.
|
|
||||||
if (frame < 320) {
|
|
||||||
*w = initial_h;
|
|
||||||
*h = initial_w;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*w = initial_w;
|
|
||||||
*h = initial_h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
|
class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
|
||||||
public:
|
public:
|
||||||
ResizingVideoSource() {
|
ResizingVideoSource() {
|
||||||
SetSize(kInitialWidth, kInitialHeight);
|
SetSize(kInitialWidth, kInitialHeight);
|
||||||
limit_ = 350;
|
limit_ = 60;
|
||||||
}
|
}
|
||||||
int flag_codec_;
|
|
||||||
virtual ~ResizingVideoSource() {}
|
virtual ~ResizingVideoSource() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Next() {
|
virtual void Next() {
|
||||||
++frame_;
|
++frame_;
|
||||||
unsigned int width;
|
SetSize(ScaleForFrameNumber(frame_, kInitialWidth),
|
||||||
unsigned int height;
|
ScaleForFrameNumber(frame_, kInitialHeight));
|
||||||
ScaleForFrameNumber(frame_, kInitialWidth, kInitialHeight, &width, &height,
|
|
||||||
flag_codec_);
|
|
||||||
SetSize(width, height);
|
|
||||||
FillFrame();
|
FillFrame();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -275,6 +120,15 @@ class ResizeTest : public ::libvpx_test::EncoderTest,
|
|||||||
|
|
||||||
virtual ~ResizeTest() {}
|
virtual ~ResizeTest() {}
|
||||||
|
|
||||||
|
struct FrameInfo {
|
||||||
|
FrameInfo(vpx_codec_pts_t _pts, unsigned int _w, unsigned int _h)
|
||||||
|
: pts(_pts), w(_w), h(_h) {}
|
||||||
|
|
||||||
|
vpx_codec_pts_t pts;
|
||||||
|
unsigned int w;
|
||||||
|
unsigned int h;
|
||||||
|
};
|
||||||
|
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
InitializeConfig();
|
InitializeConfig();
|
||||||
SetMode(GET_PARAM(1));
|
SetMode(GET_PARAM(1));
|
||||||
@@ -290,17 +144,15 @@ class ResizeTest : public ::libvpx_test::EncoderTest,
|
|||||||
|
|
||||||
TEST_P(ResizeTest, TestExternalResizeWorks) {
|
TEST_P(ResizeTest, TestExternalResizeWorks) {
|
||||||
ResizingVideoSource video;
|
ResizingVideoSource video;
|
||||||
video.flag_codec_ = 0;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
cfg_.g_lag_in_frames = 0;
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
|
|
||||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
||||||
info != frame_info_list_.end(); ++info) {
|
info != frame_info_list_.end(); ++info) {
|
||||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
const unsigned int frame = static_cast<unsigned>(info->pts);
|
||||||
unsigned int expected_w;
|
const unsigned int expected_w = ScaleForFrameNumber(frame, kInitialWidth);
|
||||||
unsigned int expected_h;
|
const unsigned int expected_h = ScaleForFrameNumber(frame, kInitialHeight);
|
||||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight,
|
|
||||||
&expected_w, &expected_h, 0);
|
|
||||||
EXPECT_EQ(expected_w, info->w)
|
EXPECT_EQ(expected_w, info->w)
|
||||||
<< "Frame " << frame << " had unexpected width";
|
<< "Frame " << frame << " had unexpected width";
|
||||||
EXPECT_EQ(expected_h, info->h)
|
EXPECT_EQ(expected_h, info->h)
|
||||||
@@ -344,19 +196,6 @@ class ResizeInternalTest : public ResizeTest {
|
|||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
||||||
libvpx_test::Encoder *encoder) {
|
libvpx_test::Encoder *encoder) {
|
||||||
if (change_config_) {
|
|
||||||
int new_q = 60;
|
|
||||||
if (video->frame() == 0) {
|
|
||||||
struct vpx_scaling_mode mode = {VP8E_ONETWO, VP8E_ONETWO};
|
|
||||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
|
||||||
}
|
|
||||||
if (video->frame() == 1) {
|
|
||||||
struct vpx_scaling_mode mode = {VP8E_NORMAL, VP8E_NORMAL};
|
|
||||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
|
||||||
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = new_q;
|
|
||||||
encoder->Config(&cfg_);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (video->frame() == kStepDownFrame) {
|
if (video->frame() == kStepDownFrame) {
|
||||||
struct vpx_scaling_mode mode = {VP8E_FOURFIVE, VP8E_THREEFIVE};
|
struct vpx_scaling_mode mode = {VP8E_FOURFIVE, VP8E_THREEFIVE};
|
||||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
||||||
@@ -366,10 +205,9 @@ class ResizeInternalTest : public ResizeTest {
|
|||||||
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
encoder->Control(VP8E_SET_SCALEMODE, &mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (frame0_psnr_ == 0.)
|
if (!frame0_psnr_)
|
||||||
frame0_psnr_ = pkt->data.psnr.psnr[0];
|
frame0_psnr_ = pkt->data.psnr.psnr[0];
|
||||||
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
||||||
}
|
}
|
||||||
@@ -389,7 +227,6 @@ class ResizeInternalTest : public ResizeTest {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
double frame0_psnr_;
|
double frame0_psnr_;
|
||||||
bool change_config_;
|
|
||||||
#if WRITE_COMPRESSED_STREAM
|
#if WRITE_COMPRESSED_STREAM
|
||||||
FILE *outfile_;
|
FILE *outfile_;
|
||||||
unsigned int out_frames_;
|
unsigned int out_frames_;
|
||||||
@@ -400,7 +237,6 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
|
|||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||||
30, 1, 0, 10);
|
30, 1, 0, 10);
|
||||||
init_flags_ = VPX_CODEC_USE_PSNR;
|
init_flags_ = VPX_CODEC_USE_PSNR;
|
||||||
change_config_ = false;
|
|
||||||
|
|
||||||
// q picked such that initial keyframe on this clip is ~30dB PSNR
|
// q picked such that initial keyframe on this clip is ~30dB PSNR
|
||||||
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
|
cfg_.rc_min_quantizer = cfg_.rc_max_quantizer = 48;
|
||||||
@@ -425,198 +261,6 @@ TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResizeInternalTest, TestInternalResizeChangeConfig) {
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 10);
|
|
||||||
cfg_.g_w = 352;
|
|
||||||
cfg_.g_h = 288;
|
|
||||||
change_config_ = true;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
}
|
|
||||||
|
|
||||||
class ResizeRealtimeTest : public ::libvpx_test::EncoderTest,
|
|
||||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
|
||||||
protected:
|
|
||||||
ResizeRealtimeTest() : EncoderTest(GET_PARAM(0)) {}
|
|
||||||
virtual ~ResizeRealtimeTest() {}
|
|
||||||
|
|
||||||
virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
|
|
||||||
libvpx_test::Encoder *encoder) {
|
|
||||||
if (video->frame() == 0) {
|
|
||||||
encoder->Control(VP9E_SET_AQ_MODE, 3);
|
|
||||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (change_bitrate_ && video->frame() == 120) {
|
|
||||||
change_bitrate_ = false;
|
|
||||||
cfg_.rc_target_bitrate = 500;
|
|
||||||
encoder->Config(&cfg_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void SetUp() {
|
|
||||||
InitializeConfig();
|
|
||||||
SetMode(GET_PARAM(1));
|
|
||||||
set_cpu_used_ = GET_PARAM(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void DecompressedFrameHook(const vpx_image_t &img,
|
|
||||||
vpx_codec_pts_t pts) {
|
|
||||||
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void MismatchHook(const vpx_image_t *img1,
|
|
||||||
const vpx_image_t *img2) {
|
|
||||||
double mismatch_psnr = compute_psnr(img1, img2);
|
|
||||||
mismatch_psnr_ += mismatch_psnr;
|
|
||||||
++mismatch_nframes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int GetMismatchFrames() {
|
|
||||||
return mismatch_nframes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultConfig() {
|
|
||||||
cfg_.rc_buf_initial_sz = 500;
|
|
||||||
cfg_.rc_buf_optimal_sz = 600;
|
|
||||||
cfg_.rc_buf_sz = 1000;
|
|
||||||
cfg_.rc_min_quantizer = 2;
|
|
||||||
cfg_.rc_max_quantizer = 56;
|
|
||||||
cfg_.rc_undershoot_pct = 50;
|
|
||||||
cfg_.rc_overshoot_pct = 50;
|
|
||||||
cfg_.rc_end_usage = VPX_CBR;
|
|
||||||
cfg_.kf_mode = VPX_KF_AUTO;
|
|
||||||
cfg_.g_lag_in_frames = 0;
|
|
||||||
cfg_.kf_min_dist = cfg_.kf_max_dist = 3000;
|
|
||||||
// Enable dropped frames.
|
|
||||||
cfg_.rc_dropframe_thresh = 1;
|
|
||||||
// Enable error_resilience mode.
|
|
||||||
cfg_.g_error_resilient = 1;
|
|
||||||
// Enable dynamic resizing.
|
|
||||||
cfg_.rc_resize_allowed = 1;
|
|
||||||
// Run at low bitrate.
|
|
||||||
cfg_.rc_target_bitrate = 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector< FrameInfo > frame_info_list_;
|
|
||||||
int set_cpu_used_;
|
|
||||||
bool change_bitrate_;
|
|
||||||
double mismatch_psnr_;
|
|
||||||
int mismatch_nframes_;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
|
|
||||||
ResizingVideoSource video;
|
|
||||||
video.flag_codec_ = 1;
|
|
||||||
DefaultConfig();
|
|
||||||
// Disable internal resize for this test.
|
|
||||||
cfg_.rc_resize_allowed = 0;
|
|
||||||
change_bitrate_ = false;
|
|
||||||
mismatch_psnr_ = 0.0;
|
|
||||||
mismatch_nframes_ = 0;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
|
|
||||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
|
||||||
info != frame_info_list_.end(); ++info) {
|
|
||||||
const unsigned int frame = static_cast<unsigned>(info->pts);
|
|
||||||
unsigned int expected_w;
|
|
||||||
unsigned int expected_h;
|
|
||||||
ScaleForFrameNumber(frame, kInitialWidth, kInitialHeight,
|
|
||||||
&expected_w, &expected_h, 1);
|
|
||||||
EXPECT_EQ(expected_w, info->w)
|
|
||||||
<< "Frame " << frame << " had unexpected width";
|
|
||||||
EXPECT_EQ(expected_h, info->h)
|
|
||||||
<< "Frame " << frame << " had unexpected height";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
|
|
||||||
// Run at low bitrate, with resize_allowed = 1, and verify that we get
|
|
||||||
// one resize down event.
|
|
||||||
TEST_P(ResizeRealtimeTest, TestInternalResizeDown) {
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 299);
|
|
||||||
DefaultConfig();
|
|
||||||
cfg_.g_w = 352;
|
|
||||||
cfg_.g_h = 288;
|
|
||||||
change_bitrate_ = false;
|
|
||||||
mismatch_psnr_ = 0.0;
|
|
||||||
mismatch_nframes_ = 0;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
|
|
||||||
unsigned int last_w = cfg_.g_w;
|
|
||||||
unsigned int last_h = cfg_.g_h;
|
|
||||||
int resize_count = 0;
|
|
||||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
|
||||||
info != frame_info_list_.end(); ++info) {
|
|
||||||
if (info->w != last_w || info->h != last_h) {
|
|
||||||
// Verify that resize down occurs.
|
|
||||||
ASSERT_LT(info->w, last_w);
|
|
||||||
ASSERT_LT(info->h, last_h);
|
|
||||||
last_w = info->w;
|
|
||||||
last_h = info->h;
|
|
||||||
resize_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
// Verify that we get 1 resize down event in this test.
|
|
||||||
ASSERT_EQ(1, resize_count) << "Resizing should occur.";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
#else
|
|
||||||
printf("Warning: VP9 decoder unavailable, unable to check resize count!\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the dynamic resizer behavior for real time, 1 pass CBR mode.
|
|
||||||
// Start at low target bitrate, raise the bitrate in the middle of the clip,
|
|
||||||
// scaling-up should occur after bitrate changed.
|
|
||||||
TEST_P(ResizeRealtimeTest, TestInternalResizeDownUpChangeBitRate) {
|
|
||||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
|
||||||
30, 1, 0, 359);
|
|
||||||
DefaultConfig();
|
|
||||||
cfg_.g_w = 352;
|
|
||||||
cfg_.g_h = 288;
|
|
||||||
change_bitrate_ = true;
|
|
||||||
mismatch_psnr_ = 0.0;
|
|
||||||
mismatch_nframes_ = 0;
|
|
||||||
// Disable dropped frames.
|
|
||||||
cfg_.rc_dropframe_thresh = 0;
|
|
||||||
// Starting bitrate low.
|
|
||||||
cfg_.rc_target_bitrate = 80;
|
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
|
||||||
|
|
||||||
unsigned int last_w = cfg_.g_w;
|
|
||||||
unsigned int last_h = cfg_.g_h;
|
|
||||||
int resize_count = 0;
|
|
||||||
for (std::vector<FrameInfo>::const_iterator info = frame_info_list_.begin();
|
|
||||||
info != frame_info_list_.end(); ++info) {
|
|
||||||
if (info->w != last_w || info->h != last_h) {
|
|
||||||
resize_count++;
|
|
||||||
if (resize_count == 1) {
|
|
||||||
// Verify that resize down occurs.
|
|
||||||
ASSERT_LT(info->w, last_w);
|
|
||||||
ASSERT_LT(info->h, last_h);
|
|
||||||
} else if (resize_count == 2) {
|
|
||||||
// Verify that resize up occurs.
|
|
||||||
ASSERT_GT(info->w, last_w);
|
|
||||||
ASSERT_GT(info->h, last_h);
|
|
||||||
}
|
|
||||||
last_w = info->w;
|
|
||||||
last_h = info->h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CONFIG_VP9_DECODER
|
|
||||||
// Verify that we get 2 resize events in this test.
|
|
||||||
ASSERT_EQ(resize_count, 2) << "Resizing should occur twice.";
|
|
||||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
|
||||||
#else
|
|
||||||
printf("Warning: VP9 decoder unavailable, unable to check resize count!\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
vpx_img_fmt_t CspForFrameNumber(int frame) {
|
vpx_img_fmt_t CspForFrameNumber(int frame) {
|
||||||
if (frame < 10)
|
if (frame < 10)
|
||||||
return VPX_IMG_FMT_I420;
|
return VPX_IMG_FMT_I420;
|
||||||
@@ -671,7 +315,7 @@ class ResizeCspTest : public ResizeTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||||
if (frame0_psnr_ == 0.)
|
if (!frame0_psnr_)
|
||||||
frame0_psnr_ = pkt->data.psnr.psnr[0];
|
frame0_psnr_ = pkt->data.psnr.psnr[0];
|
||||||
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
EXPECT_NEAR(pkt->data.psnr.psnr[0], frame0_psnr_, 2.0);
|
||||||
}
|
}
|
||||||
@@ -722,13 +366,11 @@ TEST_P(ResizeCspTest, TestResizeCspWorks) {
|
|||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||||
}
|
}
|
||||||
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(ResizeTest,
|
VP8_INSTANTIATE_TEST_CASE(ResizeTest, ONE_PASS_TEST_MODES);
|
||||||
|
VP9_INSTANTIATE_TEST_CASE(ResizeTest,
|
||||||
::testing::Values(::libvpx_test::kRealTime));
|
::testing::Values(::libvpx_test::kRealTime));
|
||||||
VP10_INSTANTIATE_TEST_CASE(ResizeInternalTest,
|
VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest,
|
||||||
::testing::Values(::libvpx_test::kOnePassBest));
|
::testing::Values(::libvpx_test::kOnePassBest));
|
||||||
VP10_INSTANTIATE_TEST_CASE(ResizeRealtimeTest,
|
VP9_INSTANTIATE_TEST_CASE(ResizeCspTest,
|
||||||
::testing::Values(::libvpx_test::kRealTime),
|
|
||||||
::testing::Range(5, 9));
|
|
||||||
VP10_INSTANTIATE_TEST_CASE(ResizeCspTest,
|
|
||||||
::testing::Values(::libvpx_test::kRealTime));
|
::testing::Values(::libvpx_test::kRealTime));
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user