Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/filters/parser/DiracSplitter/libdirac')
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/AUTHORS48
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/COPYING1332
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/INSTALL182
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/NEWS271
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/README496
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac.vcproj809
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.cpp192
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.h182
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.cpp299
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.h397
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.cpp134
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.h135
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.cpp98
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.h125
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.cpp84
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.h120
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.cpp264
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.h158
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.cpp502
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.h200
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.cpp78
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.h104
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.cpp332
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.h269
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.cpp97
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.h126
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.cpp227
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.h117
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.cpp289
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.h247
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.cpp279
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.h208
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.cpp137
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.h115
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.cpp169
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.h146
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.cpp169
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.h469
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/arrays.h595
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.cpp119
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.h248
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec_template.h557
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.cpp101
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.h140
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.cpp454
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.h524
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.cpp78
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.h92
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.cpp1143
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.h1613
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/common_types.h209
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.cpp66
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.h80
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.cpp100
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.h215
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_inttypes.h48
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_types.h198
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.cpp1239
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.h301
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.cpp470
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.h64
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.cpp722
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.h448
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.cpp641
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.h301
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.cpp672
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.h528
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.cpp337
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.h149
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.cpp265
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.h198
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.cpp200
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.h98
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert_mmx.cpp39
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.cpp534
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.h102
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.cpp1570
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.h731
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils_mmx.cpp1625
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.cpp163
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.h129
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/decoder_types.h61
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.cpp287
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.h190
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.cpp409
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.h183
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.cpp372
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.h156
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.cpp170
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.h190
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.cpp156
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.h114
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.cpp1179
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.h481
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.cpp383
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.h163
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.cpp292
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.h222
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.cpp710
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.h201
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.cpp588
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.h68
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.cpp184
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.h124
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.cpp363
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.h130
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp530
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.h221
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.cpp892
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.h387
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.cpp469
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.h207
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.cpp204
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.h94
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert_mmx.cpp246
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.cpp573
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.h167
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.cpp176
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.h115
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.cpp1785
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.h557
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.cpp1134
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.h81
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.cpp247
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.h105
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.cpp380
-rw-r--r--src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.h157
127 files changed, 43815 insertions, 0 deletions
diff --git a/src/filters/parser/DiracSplitter/libdirac/AUTHORS b/src/filters/parser/DiracSplitter/libdirac/AUTHORS
new file mode 100644
index 000000000..9bb2340f7
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/AUTHORS
@@ -0,0 +1,48 @@
+ORIGINAL AUTHORS
+~~~~~~~~~~~~~~~~
+
+Thomas Davies, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+CONTRIBUTORS
+~~~~~~~~~~~~
+(in no particular order)
+
+Richard Felton, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Scott Robert Ladd, Coyote Gulch Productions
+coyote@coyotegulch.com
+
+Stuart Cunningham, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Anuradha Suraparaju, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Chris Bowley, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Tim Borer, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Peter Meerwald
+pmeerw@users.sourceforge.net
+
+Steve Bearcroft
+bearcrsw@users.sourceforge.net
+
+Zen
+ogg@illiminable.com
+
+Mike Ferenduros
+mike_ferenduros@users.sourceforge.net
+
+Andrew Kennedy, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Peter Bleackley, BBC Research and Development
+dirac@rd.bbc.co.uk
+
+Myo Tun, Brunel University
+myo.tun@brunel.ac.uk
diff --git a/src/filters/parser/DiracSplitter/libdirac/COPYING b/src/filters/parser/DiracSplitter/libdirac/COPYING
new file mode 100644
index 000000000..a05cad15d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/COPYING
@@ -0,0 +1,1332 @@
+The Dirac software source code is licensed under the Mozilla Public License
+Version 1.1, which is included below. The provisions of this license allow
+for relicensing under other licenses, which are specified in the license
+preamble at the beginning of each source-code file. For the purposes of this
+distribution, the licenses under which relicensing is possible are uniformly
+specified to be the GNU Public License Version 2.0 and the GNU Lesser Public
+License Version 2.1. These may be downloaded from www.gnu.org/licenses; however
+copies are also provided in Annex A and Annex B to this document.
+
+
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
+ANNEX A: The GNU GENERAL PUBLIC LICENSE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+ANNEX B : THE GNU LESSER GENERAL PUBLIC LICENSE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/INSTALL b/src/filters/parser/DiracSplitter/libdirac/INSTALL
new file mode 100644
index 000000000..fc3fba48a
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/INSTALL
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.ac' is used to create `configure' by a program
+called `autoconf'. You only need `configure.ac' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CXX=c89 CXXFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/src/filters/parser/DiracSplitter/libdirac/NEWS b/src/filters/parser/DiracSplitter/libdirac/NEWS
new file mode 100644
index 000000000..b4df9db28
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/NEWS
@@ -0,0 +1,271 @@
+dirac_0.8,0
+===========
+Major release complying with the latest Dirac Bytestream Specification.
+
+- Support for interlaced coding
+- Fixed bug with DC weight being set incorrectly
+- Improved constant bit-rate coding mode so that quality crashes and
+ rate explosions are reduced.
+- Improved motion estimation
+- Added support for full-seach block matching.
+- Fixed bugs reported by valgrind.
+- API changes to conform with spec revision 1.0.0.pre9_02. Application using
+ Dirac libraries will need to be recompiled.
+- Added support for larger wavelet-depths in non-MMX mode.
+- Released patches to MPlayer, FFmpeg to comply with this release. Earlier
+ patch to transcode can be used with release.
+- DirectShow Filter released to be able to play back Dirac v0.8.x files in
+ Windows Media Player.
+
+dirac_0.7.0
+===========
+Major release complying with Dirac ByteStream Specification 1.0.0_pre4. The
+specification is available on the Dirac Homepage on Sourceforge.
+
+- Added support for Constant Bit Rate Coding.
+- Improved quality of encoded pictures at low bit-rates and for difficult
+ sequences.
+- Improved motion vector data partitioning to allow for parallel encoding
+ and decoding of this data especially in hardware.
+- Added support for integral motion vector precision.
+- Improved Arithmetic coding. Arithmetic coding is lots faster now.
+- Minor bug-fixes to ensure compliance with spec.
+- Solution and Project files for Visual C++ 2005 Express edition.
+- Encoder and Decoder API header files have changed so applications
+ using the old API will have to be recompiled.
+- Released patches to MPlayer, FFmpeg to comply with this release. Earlier
+ patch to transcode can be used with release.
+- DirecShow Filter released to be able to play back Dirac v0.7.0 files in
+ Windows Media Player.
+- The Dirac programming guide has been updated to reflect changes to the
+ Encoder API headers.
+- The Algorithm API is OUT OF DATE. Please refer to the Specification
+ document (link http://dirac.sourceforge.net/specification.html) for
+ latest algorithmic changes related to the decoder side. The Algorithm
+ document will be updated shortly.
+- Bugs fixed: 1362673, 1508532, 1588191
+- Patches applied: 1537623
+
+dirac_0.6.0
+===========
+- Major release complying with Dirac ByteStream Specification. The
+ specification is available on the Dirac Homepage on Sourceforge.
+- Encoder and Decoder API have changed in this release so applications
+ using the older API will have to be recompiled.
+- Released patches to MPlayer, FFmpeg to comply with this release. Earlier
+ patch to transcode can be used with release.
+- DirecShow Filter released to be able to play back Dirac v0.6.0 files in
+ Windows Media Player.
+- Bugs fixed: 1501636, 1383890
+
+dirac_0.5.4
+===========
+- Added support for lossless encoding.
+- Improved Decoder performance by upto 20%.
+- Improved encoder performance by modifications to motion estimation
+- Modified encoder CLI so that diagnostics data and locally decoded output
+ is not generated by default. This improved the encoding efficiency.
+- Patches : 1303281, 1309571
+- Bugs: 1291478, 1291481, 1291789, 1328565
+
+dirac_0.5.3
+===========
+- Fixed encoder CLI. Added rigorous command line input checks .
+ The encoder exits with error message when command line argument is not
+ valid.
+- Fixed HD block size to improve motion compensation and prediction
+- Fixed bug with computing MV costs.
+- MMX opts to wavelet transform, motion compensation and upconversion which
+ improved decoder speed by 25-30%.
+- Improved chroma fidelity by increasing bits allocated to chroma
+- Wavelet filter type is part of bitstream.
+- Fixed bug with the way median is calculated in motion prediction.
+- Replaced constant quality encoding control mechanism with a mechanism
+ that used constant constant Lagrangian paramemters.
+- MMX optimisations are automatically used if underlying architecture
+ supports it.
+- Improved motion estimation.
+- Modified arithmetic coding to use a look-up table for division.
+
+- Patches: 1211899, 1216297
+- Bugs: 1209017, 1209053, 1212581, 1245129, 1240709
+
+dirac_0.5.2
+===========
+ - Changed encoder command line interface to accept all encoding parameters.
+ E.g. frame dimensions, chroma format, frame rate, etc. Header files
+ are no longer required. Refer to section 4.3 of README for details.
+ - Applied patch supplied by Mike Ferenduros to make the TwoDArray class
+ more efficient
+ - An overall increase in decoding speed by 20% by speeding up Motion
+ compensation, frame clip, and wavelet transform.
+ - Arithmetic coding speedup
+ - Added support for multiple wavelet filter types
+ - Added support for variable motion vector precision.
+ - Updated bitstream version. Encoder/Decoder apps in this release will not
+ be able to decode bitstreams generated by earlier versions.
+ - Released a source code patch for MPlayer-1.0pre7 to enable Dirac play
+ back support.
+ - Released a source code patch for ffmpeg-0.4.9-pre1 to enable Dirac encode
+ and decode.
+ - Released a source code patch for transcode-0.6.14 to enable Dirac encode
+ and decode using the patched ffmpeg-0.4.9-pre1.
+ - Patches Applied: 1151976 (partial), 1156674
+ - Bugs fixed : 1159031
+
+dirac_0.5.1
+===========
+ - Significant speedup in the Arithmetic coding and decoding engines
+ - Modified wavelet coefficient coding to code blocks of coeffients with
+ skip flags if all coefficients are zero. This improves compression
+ performance and decoding speed.
+ - Modified block prediction mode coding to improve compression performance.
+ - Fixed bug in assigning costs to lists of vectors in block matching.
+ - MMX optimisation for calculating block differences in Motion Estimation.
+ This resulted in 20-30% improvement in encoding speed. The configure
+ flag --enable-mmx enables compile time MMX optimisation detection.
+ Currently works only on GNU/Linux.
+ - New script create_dirac_testfile.pl to generate input formats
+ compatible with Dirac from rgb files. Step 3, Section 4.2 in README
+ describes how to use the script.
+ - Released a source code patch for MPlayer-1.0pre6a to enable Dirac play
+ back support.
+ - Released DirectShow filter for Dirac to enable playback of Dirac bitstreams
+ using Windows Media Player
+ - Reinstituted bi-directional prediction
+ - Added support for multiple quantisers.
+ - Code restructure and tidying.
+ - Updated bitstream version. Encoder/Decoder apps in this release will not
+ be able to decode bitstreams generated by earlier versions.
+ - Patches applied: 1081736,1081743
+
+dirac_0.5.0
+===========
+ - Added C interface for the encoder application. Refer to the api
+ documentation in dirac_encoder.h or in the Programmer's Guide at
+ http://dirac.sourceforge.net/documentation/code/programmers_guide/index.htm
+ - Updated bitstream version. Encoder/Decoder apps in this release will not
+ be able to decode bitstreams generated by earlier versions.
+ - Improvements to Constant Quality encoding engine to improve stability.
+ - Speed-ups to motion compensation and wavelet transform for faster decoding
+ - Removed rounding errors from motion compensation.
+ - Fixed bugs with clipping and encoding black or white areas.
+ - Fixed bug with overflow in context modelling for arithmetic coding of
+ HD pictures.
+ - Added unit tests for motion compensation classes and wavelet classes.
+ - The number of frames parameter is no longer required. All existing picture
+ header files must be recreated using make_header for this parameter to be
+ omitted. Otherwise, incorrect bit rates will be reported by the encoder
+ application.
+ - Updated algortihm documentation.
+ - Restructured libraries so that only two libraries are generated - an encoder
+ library and a decoder library. 'make install' will now install only the
+ public API libraries and header files, the encoder and decoder apps and the
+ conversion and instrumentation utilities.
+ - Added support for building shared and/or static libraries using libtool
+ under UNIX, GNU/Linux. Shared and static libraries are built by default.
+ - Added support for building shared or static libraries under MS Windows
+ using MSYS and the no cost MSVC++ 2003 toolkit. Shared libraries are built
+ by default.
+ - Added support for building the codec using MS Visual C++ .NET 2003 under
+ MS Windows. Options are available to build Dlls and static libraries.
+ The _declspec mechanism is used to export the Encoder and Decoder public
+ "C" API.
+ - New target 'valgrind-check' added to make under Linux.
+ - Build under MS Windows using nmake no longer supported.
+ - Bug fixes: 1050816, 1055692, 1050757, 1044503, 1044501, 1044499
+ - Patches Applied: 1055714, 1055707, 1061923, 1071429, 1059342
+
+dirac-0.4.3
+===========
+ - Quality metric has changed from PSNR to one based on 4th powers of errors.
+ This results in pictures with more stable quality and fewer artefacts.
+ - Fixed bug with scaling motion vectors for non 4:4:4 formats.
+ - Fixed bug in encoder in downconverting a picture with odd valued dimensions
+ - Fixed bug in encoder in handling input with 4:1:1 chroma format.
+ - Fixed bug in diagnostics tool in handling input with 4:1:1 chroma format.
+ - Updated algorithm documentation
+
+dirac-0.4.2
+===========
+ - Fixed bugs in writing instrumentation data while encoding which
+ caused the diagnostics tool to go into an infinite loop
+ - Fixed bug in diagnostic tool when handling reference 2 and only
+ one reference frame is available
+ - Number of frames in encoded output header is now set correctly to
+ the number of frames encoded.
+ - Fixed bug with bit-rate being miscalculated when only a section of the
+ sequence is encoded.
+ - Fixed bug with setting DC band perceptual weight.
+
+dirac-0.4.1
+===========
+ - Added support for build under Microsoft Windows using gnu autotools,
+ MSYS and no-cost MS VC++ 2003 compiler
+
+ - Fixed bug in building unit tests when older versions of cppunit are
+ installed
+
+ - Fixed bugs in measurement of PSNR and motion estimation process
+
+dirac-0.4.0
+===========
+ - Added constant quality encoding interface using PSNR
+ as the quality measure, and using multi-pass frame
+ coding
+ - Added Intra-frame insertion and cut detection
+ - Added C interface for the decoder application to allow
+ interfacing to player software. Refer to the api documentation
+ in dirac_parser.h.
+ - Implemented unique frame headers to facilitate bit-stream
+ parsing
+ - Added instrumentation output from encoder and an
+ instrumentation display tool for visualising encoder
+ decisions to help with algorithmic development
+ - Cleansed and refactored numerous code files to add comments,
+ improve readability and modularity
+ - Added a unit testing framework based on cppunit for testing
+ classes
+ - Fixed bug with vertical block separation always being set
+ to 8 pixels
+ - Added feature to encode only a section of input video rather
+ than the whole sequence
+ - Tweaked motion estimation parameters to improve performance,
+ mostly for higher-res pictures
+ - Included document describing the syntax of Dirac bitstream v0.1
+ in the doc directory.
+ - Fixed bug 1008694 (Out-of-tree building fails)
+ - Fixed header and pkconfig installation
+ - Updated algorithm documentation
+
+Dirac-0.3.1
+===========
+ - Fixed compiling under Windows
+ - Video conversion utilites now build under Windows
+ - Colour conversion matrix coefficients corrected in conversion utilites
+
+Dirac-0.3.0
+===========
+ - Added conversion utilities for going to and from RGB and
+ various YUV formats, plus bitmaps
+ - Fixed serious artifacts when frame dimensions are not multiples of 32
+ - Performance speed up writing output to disk
+ - Changed .hdr format from binary to text for cross-platform interoperability
+ - Added autotest framework with simple colour-bars test
+ - Added format conversion, MPlayer and ImageMagick examples to README
+ - Added decoder support for arbitrary temporal prediction structures
+ - Added support for I-frame only coding
+ - Added support for coding with a single initial I-frame
+ - Extended code documentation to all major classes
+
+Dirac-0.2.0
+===========
+ - Fixed crash when frame dimensions are not multiples of 32
+ - Removed dependency on XParam library
+ - Removed libtool for faster compiles and ease of debugging
+ - Included doxygen documentation of major classes
+ - Initial "programmer's guide" documentation - doc/dirac_algor.tex
+
+Dirac-0.1.0
+===========
+ - Initial Sourceforge release.
diff --git a/src/filters/parser/DiracSplitter/libdirac/README b/src/filters/parser/DiracSplitter/libdirac/README
new file mode 100644
index 000000000..c2374f9cb
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/README
@@ -0,0 +1,496 @@
+README for the Dirac video codec
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+by the BBC R&D Dirac team (dirac@rd.bbc.co.uk)
+
+
+1. Executive Summary
+~~~~~~~~~~~~~~~~~~~~
+
+Dirac is an open source video codec. It uses a traditional hybrid video codec
+architecture, but with the wavelet transform instead of the usual block
+transforms. Motion compensation uses overlapped blocks to reduce block
+artefacts that would upset the transform coding stage.
+
+Dirac can code just about any size of video, from streaming up to HD and
+beyond, although certain presets are defined for different applications and
+standards. These cover the parameters that need to be set for the encoder to
+work, such as block sizes and temporal prediction structures, which must
+otherwise be set by hand.
+
+Dirac is intended to develop into real coding and decoding software, capable
+of plugging into video processing applications and media players that need
+compression. It is intended to develop into a simple set of reliable but
+effective coding tools that work over a wide variety of content and formats,
+using well-understood compression techniques, in a clear and accessible
+software structure. It is not intended as a demonstration or reference coder.
+
+
+2. Documentation
+~~~~~~~~~~~~~~~~
+
+A user guide and a guide to the software is in progress. More details on
+running the codec can be found at http://dirac.sourceforge.net/
+
+
+3. Building and installing
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ GNU/Linux, Unix, MacOS X, Cygwin, Mingw
+ ---------------------------------------
+ ./configure --enable-debug
+ (to enable extra debug compile options)
+ OR
+ ./configure --enable-profile
+ (to enable the g++ profiling flag -pg)
+ OR
+ ./configure --disable-mmx
+ (to disable MMX optimisation which is enabled by default)
+ OR
+ ./configure --enable-debug --enable-profile
+ (to enable extra debug compile options and profiling options)
+ OR
+ ./configure
+
+ By default, both shared and static libraries are built. To build all-static
+ libraries use
+ ./configure --disable-shared
+
+ To build shared libraries only use
+ ./configure --disable-static
+
+ make
+ make install
+
+ The INSTALL file documents arguments to ./configure such as
+ --prefix=/usr/local (specify the installation location prefix).
+
+
+ MSYS and Microsoft Visual C++
+ -----------------------------
+ Download and install the no-cost Microsoft Visual C++ 2005 Express
+ Edition from
+ http://msdn.microsoft.com/vstudio/express/visualc/
+
+ Download and install MSYS (the MinGW Minimal SYStem), MSYS-1.0.10.exe,
+ from http://www.mingw.org/download.shtml. An MSYS icon will be available
+ on the desktop.
+
+ Click on the MSYS icon on the desktop to open a MSYS shell window.
+
+ Create a .profile file to set up the environment variables required.
+ vi .profile
+
+ Include the following three lines in the .profile file.
+
+ PATH=/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/Common7/IDE:/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/VC/BIN:/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/Common7/Tools:/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/SDK/v2.0/bin:/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/VC/VCPackages:$PATH
+
+ INCLUDE=/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/VC/include
+
+ LIB=/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/VC/LIB:/c/Program\ Files/Microsoft\ Visual\ Studio\ 8/SDK/v2.0/lib:$LIB
+
+ (Replace /c/Program\ Files/Microsoft\ Visual\ Studio\ 8/ with
+ the location where VC++ 2005 is installed if necessary)
+
+
+ Exit from the MSYS shell and click on the MSYS icon on the desktop to open
+ a new MSYS shell window for the .profile to take effect.
+
+ Change directory to the directory where Dirac was unpacked. By default
+ only the dynamic libraries are built.
+
+ ./configure CXX=cl LD=cl --enable-debug
+ (to enable extra debug compile options)
+ OR
+ ./configure CXX=cl LD=cl --disable-shared
+ (to build static libraries)
+ OR
+ ./configure CXX=cl LD=cl
+ make
+ make install
+
+ The INSTALL file documents arguments to ./configure such as
+ --prefix=/usr/local (specify the installation location prefix).
+
+ Microsoft Visual C++ .NET 2005
+ ------------------------------
+ Download and install the no-cost Microsoft Visual C++ 2005 Express
+ Edition from
+ http://msdn.microsoft.com/vstudio/express/visualc/
+
+ The MS VC++ 2005 solution and project files are in win32/VisualStudio
+ directory. Double-click on the solution file, dirac.sln, in the
+ win32/VisualStudio directory. The target 'Everything' builds the codec
+ libraries and utilities. Four build-types are supported
+
+ Debug - builds unoptimised encoder and decoder dlls with debug symbols
+ Release - builds optimised encoder and decoder dlls
+ Debug-mmx - builds unoptimised encoder and decoder dlls with debug symbols
+ and mmx optimisations enabled.
+ Release-mmx - builds optimised encoder and decoder dlls with mmx
+ optimisations enabled.
+ Static-Debug - builds unoptimised encoder and decoder static libraries
+ with debug symbols
+ Static-Release - builds optimised encoder and decoder static libraries
+ Static-Debug-mmx - builds unoptimised encoder and decoder static libraries
+ with debug symbols and mmx optmisations enabled.
+ Static-Release-mmx - builds optimised encoder and decoder static libraries
+ with mmx optmisations enabled.
+
+ Static libraries are created in the win32/VS2003/lib/<build-type> directory.
+
+ Encoder and Decoder dlls and import libraries, encoder and decoder apps are
+ created in the win32/VisualStudio/bin/<build-type> directory. The "C" public
+ API is exported using the _declspec(dllexport) mechanism.
+
+ Conversion utilites are created in the
+ win32/VS2003/utils/conversion/<build-type> directory. Only static versions are built.
+ Instrumentation utility is created in the
+ win32/VisualStudio/utils/instrumentation/<build-type> directory. Only static
+ versions are built.
+
+
+ Microsoft Visual C++ .NET 2003
+ ------------------------------
+
+ NOTE: Since Visual C++ 2005 Express edition is freely available to
+ download, and the project and solution files for VC++ 2003 and VC++
+ 2005 are different, VC++ 2003 project and solution files will not
+ be maintained in future releases. So it is suggested that the users
+ upgrade their VC++ environment to VC++ 2005.
+
+ The MS VC++ .NET 2003 solution and project files are in win32/VS2003
+ directory. Double-click on the solution file, dirac.sln, in the
+ win32/VS2003 directory. The target 'Everything' builds the codec
+ libraries and utilities. Four build-types are supported
+
+ Debug - builds unoptimised encoder and decoder dlls with debug symbols
+ Release - builds optimised encoder and decoder dlls
+ Debug-mmx - builds unoptimised encoder and decoder dlls with debug symbols
+ and mmx optimisations enabled.
+ Release-mmx - builds optimised encoder and decoder dlls with mmx
+ optimisations enabled.
+ Static-Debug - builds unoptimised encoder and decoder static libraries
+ with debug symbols
+ Static-Release - builds optimised encoder and decoder static libraries
+ Static-Debug-mmx - builds unoptimised encoder and decoder static libraries
+ with debug symbols and mmx optmisations enabled.
+ Static-Release-mmx - builds optimised encoder and decoder static libraries
+ with mmx optmisations enabled.
+
+ Static libraries are created in the win32/VS2003/lib/<build-type> directory.
+
+ Encoder and Decoder dlls and import libraries, encoder and decoder apps are
+ created in the win32/VS2003/bin/<build-type> directory. The "C" public API
+ is exported using the _declspec(dllexport) mechanism.
+
+ Conversion utilites are created in the
+ win32/VS2003/utils/conversion/<build-type> directory. Only static versions
+ are built.
+
+ Instrumentation utility is created in the
+ win32/VS2003/utils/instrumentation/<build-type> directory. Only static
+ versions are built.
+
+
+4. Running the example programs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+4.1 Command-line parameters
+
+At the moment there is a simple command-line parser class which is
+used in all the executables. The general procedure for running a program
+is to type:
+
+ prog_name -<flag_name> flag_val ... param1 param2 ...
+
+In other words, options are prefixed by a dash; some options take values,
+while others are boolean options that enable specific features. For example:
+When running the encoder, the -qf options requires a numeric argument
+specifying the "quality factor" for encoding. The -verbose option enables
+detailed output and does not require an argument.
+
+Running any program without arguments will display a list of parameters and
+options.
+
+4.2 File formats
+
+The example coder and decoder use raw 8-bit planar YUV data. This means that
+data is stored bytewise, with a frame of Y followed by a frame of U followed
+by a frame of V, all scanned in the usual raster order. The video dimensions
+, frame rate and chroma are passed to the encoder via command line arguments.
+
+Other file formats are supported by means of conversion utilities that
+may be found in the subdirectory util/conversion. These will convert to
+and from raw RGB format, and support all the standard raw YUV formats as
+well as bitmaps. Raw RGB can be obtained as an output from standard conversion
+utilities such as ImageMagick.
+
+Example.
+ Compress an image sequence of 100 frames of 352x288 video in tiff format.
+
+ Step 1.
+
+ Use your favourite conversion routine to produce a single raw RGB file of
+ all the data. If your routine converts frame-by-frame then you will
+ need to concatenate the output.
+
+ Step 2.
+
+ Convert from RGB to the YUV format of your choice. For example, to do
+ 420, type
+
+ RGBtoYUV420 <file.rgb >file.yuv 352 288 100
+
+ Note that this uses stdin and stdout to read and write the data.
+
+ We have provided a script create_test_data.pl to help convert rgb format
+ files into all the input formats supported by Dirac. The command line
+ arguments it supports can be listed using
+
+ create_test_data.pl -use
+
+ Sample usage is
+
+ create_test_data.pl -width=352 -height=288 -num_frames=100 file.rgb
+
+ (This assumes that the RGBtoYUV utilities are in a directory specified in
+ PATH variable. If not in the path, then use options -convutildir and to set
+ the directories where the script can find the conversion utilities.)
+
+ The scripts then outputs files in all chroma formats (420, 422,
+ 444) supported by Dirac to the current directory.
+
+
+ Step 4.
+
+ Run the encoder. This will produce a locally decoded output in the
+ same format if the locally decoded output is enabled using the -local flag.
+
+ Step 5.
+
+ Convert back to RGB.
+
+ YUV420toRGB <file.yuv >file.rgb 352 288 100
+
+ Step 6.
+
+ Use your favourite conversion utility to convert to the format of your
+ choice.
+
+You can also use the transcode utility to convert data to and from Dirac's
+native formats (see http://zebra.fh-weingarten.de/~transcode/):
+
+ This example uses a 720x576x50 DV source, and transcodes to 720x576 YUV in
+ 4:2:0 chroma format. Cascading codecs (DV + Dirac) is generally a bad idea
+ - use this only if you don't have any other source of uncompressed video.
+
+ transcode -i source.dv -x auto,null --dv_yuy2_mode -k -V -y raw,null -o file.avi
+ tcextract -i test.avi -x rgb > file.yuv
+
+Viewing and playback utilities for uncompressed video include MPlayer and
+ImageMagick's display command.
+
+ Continuing the 352x288 4:2:0 example above, to display a single frame
+ of raw YUV with ImageMagick use the following (use <spacebar> to see
+ subsequent frames):
+
+ display -size 352x288 test.yuv
+
+ Raw YUV 420 data can also be played back in MPlayer - use the following
+ MPlayer command:
+
+ mplayer -fps 15 -rawvideo on:size=152064:w=352:h=288 test.yuv
+
+ (at the time of writing MPlayer could not playback 4:2:2 or 4:4:4 YUV data)
+
+
+4.3 Encoding
+
+The basic encoding syntax is to type
+
+dirac_encoder [options] file_in file_out
+
+This will compress file_in and produce an output file_out of compressed data.
+
+A locally decoded output file_out.local-dec.yuv and instrumentation data
+file_out.imt (for debugging the encoder and of interest to developers only)
+are also produced if the -local flag is enabled on the command line.
+
+There are a large number of optional parameters that can be used to run the
+encoder, all of which are listed below. To encode video you need three types of
+parameter need to be set:
+
+a) quality factor or target bit rate
+b) source parameters (width, height, frame rate, chroma format)
+c) encoding parameters (motion compensation block sizes, preferred viewing
+ distance)
+
+In practice you don't have to set all these directly because presets can be used
+to use appropriate default values.
+
+a) The most important parameters are the quality factor or target bit rate.
+
+The quality factor is specified by using the option
+
+qf : Overall quality factor (>0)
+
+This value is greater than 0, the higher the number, the better
+the quality. Typical high quality is 8-10, but it will vary from sequence to
+sequence, sometimes higher and sometimes lower.
+
+The target bit rate is set using the option
+
+targetrate : Target bit rate in Kb/s
+
+This will attempt to maintain constant bit rate over the sequence. It works
+reasonably well, but actual bit rate, especially over short sequences, may be
+slightly different from the target.
+
+Setting -targetrate overrides -qf, in that CBR will still be applied, although
+the initial quality will be set by the given qf value. This might help the CBR
+algorithm to adapt faster.
+
+Setting -lossless overrides both -qf and -targetrate, and enforces lossless
+coding.
+
+b) Source parameters need to be set as the imput is just a raw YUV file and
+the encoder doesn't have any information about it.
+
+The best way to set source parameters is to use a preset for
+different video formats.
+
+The available preset options are:
+QSIF : width=176; height=120; 4:2:0 format; 14.98 frames/sec
+QCIF : width=176; height=144; 4:2:0 format; 12.5 frames/sec
+SIF : width=352; height=240; 4:2:0 format; 14.98 frames/sec
+CIF : width=352; height=288; 4:2:0 format; 12.5 frames/sec
+4SIF : width=704; height=480; 4:2:0 format; 14.98 frames/sec
+4CIF : width=704; height=576; 4:2:0 format; 12.5 frames/sec
+SD480 : width=720; height=480; 4:2:2 format; 29.97 frames/sec
+SD576 : width=720; height=576; 4:2:2 format; 25 frames/sec
+HD720P60 : width=1280; height=720; 4:2:2 format; 60 frames/sec
+HD720P50 : width=1280; height=720; 4:2:2 format; 50 frames/sec
+HD1080I60 : width=1920; height=1080; 4:2:2 format; 29,97 frames/sec
+HD1080I50 : width=1920; height=1080; 4:2:2 format; 25 frames/sec
+HD1080P60 : width=1920; height=1080; 4:2:2 format; 59.94 frames/sec
+HD1080P50 : width=1920; height=1080; 4:2:2 format; 50 frames/sec
+
+The default format used is CUSTOM format which has the following preset values
+width=640; height=480; 4:2:0 format; 23.97 frames/sec.
+
+If your video is not one of these formats, you should pick the nearest preset
+and override the parameters that are different.
+
+Example 1 Simple coding example. Code a 720x576 sequence in 420 format to
+high quality.
+
+Solution.
+
+ dirac_encoder -cformat 2 -SD576 -qf 9 test.yuv test_out.drc
+
+Example 2. Code a 720x486 sequence at 29.97 frames/sec in 422 format to
+medium quality
+
+Solution
+
+ dirac_encoder -SD576 -width 720 -height 486 -fr 29.97 -cformat 1 -qf 7 test.yuv test_out.drc
+
+Source parameters that affect coding are:
+
+width : Width of video frame
+height : Height of video frame
+cformat : Chroma format. It accepts a number between 0 and 4.
+ 0 - 4:4:4, 1 - 4:2:2, 2 - 4:2:0
+fr : Frame rate. Can be a decimal number or a fraction. Examples
+ of acceptable values are 25, 29.97, 12.5, 30000/1001.
+source_type : Source material type - progressive or interlaced
+field_dominance : If source is interlaced, field dominance type - topfieldfirst
+ (default) or bottomfieldfirst
+
+Fora complete list of source parameters, refer to Annex C of the Dirac
+Specification.
+
+WARNING!! If you use a preset but don't override source parameters that
+are different, then Dirac will still compress, but the bit rate will be
+much, much higher and there may well be serious artefacts. The encoder prints
+out the parameters it's actually using before starting encoding (in verbose
+mode only), so that you can abort at this point.
+
+c) The presets ALSO set encoding parameters. That's why it's a very good idea
+to use presets, as the encoding parameters are a bit obscure. They're still
+supported for those who want to experiment, but use with care.
+
+Encoding parameters are:
+
+L1_sep : the separation between L1 frames (frames that are predicted but
+ also used as reference frames, like P frames in MPEG-2)
+num_L1 : the number of L1 frames before the next intra frame
+xblen : the width of blocks used for motion compensation
+yblen : the height of blocks used for motion compensation
+xbsep : the horizontal separation between blocks. Always <xblen
+ybsep : the vertical separation between blocks. Always <yblen
+cpd : normalised viewing distance parameter, in cycles per degree.
+iwlt_filter : transform filter to use when encoding INTRA frames, Valid
+ values are DD9_7, LEGALL5_3, DD13_7, HAAR0, HAAR1, FIDELITY,
+ DAUB97. Default value is DD9_5.
+rwlt_filter : transform filter to use when encoding INTER frames, Valid
+ values are DD9_7, LEGALL5_3, DD13_7, HAAR0, HAAR1, FIDELITY,
+ DAUB97. Default value is LEGALL5_3.
+wlt_depth : transform depth, i.e number of times the component is split
+ while applying the wavelet transform
+no_spartition : Do not split a subband into coefficient blocks before
+ entropy coding
+multi_quants : If subbands are split into multiple coefficient blocks before
+ entropy coding, assign different quantisers to each block
+ within the subband.
+denoise : Apply a denoising filter to the input video before encoding
+ (note PSNR statistics will be computed relative to the denoised
+ video if -local is enabled)
+lossless : Lossless coding.(overrides -qf and -targetrate)
+mv_prec : Motion vector precision. Valid values are 1 (Pixel precision),
+ 1/2 (half-pixel precision), 1/4 (quarter pixel precision which
+ is the default), 1/8 ( Eighth pixel precision).
+full_search : Use full search motion estimation
+interlaced : Set coding type to interlaced for interlaced for interlaced
+ material. Default coding type is progressive.
+
+Modifying L1_sep and num_L1 allows for new GOP structures to be used, and
+should be entirely safe. There are two non-GOP modes that can also be used for
+encoding: setting num_L1=0 gives I-frame only coding, and setting num_L1<0
+will produce a sequence with infinitely many L1 frames i.e. with a single I
+frame at the beginning of the sequence.
+
+Modifying the block parameters is strongly deprecated: it's likely to break
+the encoder as there are many constraints. Modifying cpd will not break
+anything, but will change the way noise is distributed which may be more (or
+less) suitable for your application. Setting cpd equal zero turns off
+perceptual weighting altogether.
+
+For more information, see the algorithm documentation on the website:
+http://dirac.sourceforge.net
+
+Other options. The encoder also supports some other options, which are
+
+verbose : turn on verbosity (if you don't, you won't see the final bitrate!)
+start : code from this frame number
+stop : code up until this frame number
+local : Generate diagnostics and locally decoded output (to avoid running a
+ decoder to see your video)
+
+Using -start and -stop allows a small section to be coded, rather than the
+whole thing.
+
+If the -local flag is present in the command line, the encoder produces
+diagnostic information about motion vectors that can be used to debug the
+encoder algorithm. It also produces a locally decoded picture so that you
+don't have to run the decoder to see what the pictures are like.
+
+4.4 Decoding
+
+Decoding is much simpler. Just point the decoder input at the bitstream and the
+output to a file:
+
+ dirac_decoder -verbose test_enc test_dec
+
+will decode test_enc into test_dec with running commentary.
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac.vcproj b/src/filters/parser/DiracSplitter/libdirac/libdirac.vcproj
new file mode 100644
index 000000000..548585fbd
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac.vcproj
@@ -0,0 +1,809 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="libdirac"
+ ProjectGUID="{12BE3440-A1F3-4C48-A229-30CB619EA276}"
+ RootNamespace="libdirac"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\..\common.vsprops;..\..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/MP"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ UsePrecompiledHeader="0"
+ WarningLevel="0"
+ DisableSpecificWarnings="4800;"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\lib\libdiracD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\..\common.vsprops;..\..\..\..\debug.vsprops"
+ UseOfMFC="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="_WIN64;_DEBUG;_LIB"
+ UsePrecompiledHeader="0"
+ WarningLevel="0"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\lib64\libdiracD.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\..\common.vsprops;..\..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB;HAVE_MMX"
+ BufferSecurityCheck="true"
+ EnableEnhancedInstructionSet="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="0"
+ DisableSpecificWarnings="4244;4800;4355"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\lib\libdiracR.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ InheritedPropertySheets="..\..\..\..\common.vsprops;..\..\..\..\release.vsprops"
+ UseOfMFC="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="."
+ PreprocessorDefinitions="_WIN64;NDEBUG;_LIB;HAVE_MMX"
+ BufferSecurityCheck="true"
+ EnableEnhancedInstructionSet="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\lib64\libdiracR.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\libdirac_byteio\accessunit_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\arith_codec.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\band_codec.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\band_vlc.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\bit_manager.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\block_match.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\cmd_line.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\codingparams_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\common.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\comp_compress.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\comp_decompress.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\component_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\dirac_assertions.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\dirac_byte_stats.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\dirac_byte_stream.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\dirac_cppparser.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\dirac_encoder.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\dirac_exception.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\dirac_parser.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\displayparams_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\downconvert.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\downconvert_mmx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\enc_picture.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\enc_queue.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\endofsequence_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_mode_decn.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_subpel.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_utils.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_utils_mmx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\mot_comp.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\mot_comp_mmx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\motion.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\motion_estimate.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\mv_codec.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\mvdata_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\mvdataelement_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\parseparams_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\parseunit_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\pic_io.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\picture.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\picture_buffer.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\picture_compress.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\picture_decompress.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\pixel_match.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\prefilter.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\quality_monitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\quant_chooser.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\rate_control.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\seq_compress.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\seq_decompress.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\subband_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\transform_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\upconvert.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\upconvert_mmx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\video_format_defaults.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\wavelet_utils.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ GeneratePreprocessedFile="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ GeneratePreprocessedFile="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\libdirac_common\wavelet_utils_mmx.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ GeneratePreprocessedFile="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ GeneratePreprocessedFile="0"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\libdirac_byteio\accessunit_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\arith_codec.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\arrays.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\band_codec.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\band_codec_template.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\band_vlc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\bit_manager.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\block_match.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\cmd_line.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\codingparams_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\common.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\common_types.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\comp_compress.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\comp_decompress.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\component_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\decoder_types.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\dirac_assertions.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\dirac_byte_stats.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\dirac_byte_stream.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\dirac_cppparser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\dirac_encoder.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\dirac_exception.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\dirac_inttypes.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\dirac_parser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\dirac_types.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\displayparams_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\downconvert.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\enc_picture.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\enc_queue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\endofsequence_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_mode_decn.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_subpel.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_utils.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\me_utils_mmx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\mot_comp.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\mot_comp_mmx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\motion.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\motion_estimate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\mv_codec.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\mvdata_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\mvdataelement_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\parseparams_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\parseunit_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\pic_io.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\picture.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\picture_buffer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\picture_byteio.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\picture_compress.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\picture_decompress.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_motionest\pixel_match.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\prefilter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\quality_monitor.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\quant_chooser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\rate_control.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_encoder\seq_compress.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_decoder\seq_decompress.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\subband_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_byteio\transform_byteio.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\upconvert.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\video_format_defaults.h"
+ >
+ </File>
+ <File
+ RelativePath=".\libdirac_common\wavelet_utils.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ <Global
+ Name="DevPartner_IsInstrumented"
+ Value="0"
+ />
+ </Globals>
+</VisualStudioProject>
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.cpp
new file mode 100644
index 000000000..33bb8ff9f
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.cpp
@@ -0,0 +1,192 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: accessunit_byteio.cpp,v 1.7 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/dirac_exception.h>
+#include <libdirac_byteio/accessunit_byteio.h>
+
+using namespace dirac;
+
+// Constructor for encoding
+SequenceHeaderByteIO::SequenceHeaderByteIO( SourceParams& src_params,
+ EncoderParams& enc_params):
+ParseUnitByteIO(),
+m_parseparams_byteio(*this, m_parse_params, enc_params),
+// create default source parameters for comparisions
+m_default_src_params(src_params.GetVideoFormat()),
+m_src_params(src_params),
+m_sourceparams_byteio( m_src_params,
+ m_default_src_params,
+ *this),
+m_codec_params(enc_params),
+m_codingparams_byteio(m_src_params,
+ m_codec_params,
+ m_default_src_params,
+ *this)
+{
+}
+
+// Constructor for decoding
+SequenceHeaderByteIO::SequenceHeaderByteIO(const ParseUnitByteIO& parseunit_byteio,
+ ParseParams& parse_params,
+ SourceParams& src_params,
+ CodecParams& codec_params) :
+ParseUnitByteIO(parseunit_byteio),
+m_parseparams_byteio( parseunit_byteio, parse_params),
+m_src_params(src_params),
+m_sourceparams_byteio( m_src_params,
+ m_default_src_params,
+ parseunit_byteio),
+m_codec_params(codec_params),
+m_codingparams_byteio( m_src_params,
+ m_codec_params,
+ m_default_src_params,
+ parseunit_byteio)
+{
+}
+
+SequenceHeaderByteIO::~SequenceHeaderByteIO()
+{
+}
+
+//-----public------------------------------------------------------
+bool SequenceHeaderByteIO::Input()
+{
+ //int o=mp_stream->tellg();
+ InputParseParams();
+
+ // Inout Video format
+ SetByteParams(m_parseparams_byteio);
+ VideoFormat vf = IntToVideoFormat(ReadUint());
+ if(vf==VIDEO_FORMAT_UNDEFINED)
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_VIDEO_FORMAT,
+ "Dirac does not recognise the specified video-format",
+ SEVERITY_ACCESSUNIT_ERROR);
+
+ SourceParams src_params(vf, true);
+ m_src_params = src_params;
+
+ InputSourceParams();
+
+ CodecParams codec_params(vf);
+ m_codec_params = codec_params;
+
+ InputCodingParams();
+
+ return true;
+}
+
+void SequenceHeaderByteIO::Output()
+{
+ OutputParseParams();
+
+ // Output the video format
+ SetByteParams(m_parseparams_byteio);
+ WriteUint(static_cast<int>(m_src_params.GetVideoFormat()));
+
+ OutputSourceParams();
+
+ OutputCodingParams();
+
+}
+
+int SequenceHeaderByteIO::GetSize() const
+{
+ return ParseUnitByteIO::GetSize()+
+ m_parseparams_byteio.GetSize()+
+ ByteIO::GetSize() +
+ m_sourceparams_byteio.GetSize()+
+ m_codingparams_byteio.GetSize();
+}
+
+
+
+//-------private-------------------------------------------------------
+
+unsigned char SequenceHeaderByteIO::CalcParseCode() const
+{
+ unsigned char code = 0;
+
+ // no further mods required
+
+ return code;
+}
+
+
+void SequenceHeaderByteIO::InputSourceParams()
+{
+ // copy current input params
+ m_sourceparams_byteio.SetByteParams(*this);
+
+ m_sourceparams_byteio.Input();
+}
+
+void SequenceHeaderByteIO::InputParseParams()
+{
+ m_parseparams_byteio.Input();
+}
+
+void SequenceHeaderByteIO::InputCodingParams()
+{
+ // copy current input params
+ m_codingparams_byteio.SetByteParams(m_sourceparams_byteio);
+
+ m_codingparams_byteio.Input();
+}
+
+void SequenceHeaderByteIO::OutputSourceParams()
+{
+ // copy current output params
+ m_sourceparams_byteio.SetByteParams(*this);
+
+ m_sourceparams_byteio.Output();
+}
+
+void SequenceHeaderByteIO::OutputParseParams()
+{
+ m_parseparams_byteio.Output();
+}
+
+void SequenceHeaderByteIO::OutputCodingParams()
+{
+ // copy current output params
+ m_codingparams_byteio.SetByteParams(m_sourceparams_byteio);
+
+ m_codingparams_byteio.Output();
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.h
new file mode 100644
index 000000000..2c2966ed8
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/accessunit_byteio.h
@@ -0,0 +1,182 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: accessunit_byteio.h,v 1.7 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy(Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class SequenceHeaderByteIO
+*/
+#ifndef accessunit_byteio_h
+#define accessunit_byteio_h
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/parseunit_byteio.h> // Parent class
+#include <libdirac_byteio/parseparams_byteio.h> // ParseParamsByteIO class
+#include <libdirac_byteio/displayparams_byteio.h> // SourceParamsByteIO class
+#include <libdirac_byteio/codingparams_byteio.h> // CodingParamsByteIO class
+
+namespace dirac
+{
+ /**
+ * A random access point within a Dirac bytestream
+ */
+ class SequenceHeaderByteIO : public ParseUnitByteIO
+ {
+ public:
+
+ /**
+ * Constructor (encoding)
+ *@param src_params Source parameters for current AccessUnit
+ *@param enc_params Encoder parameters for current AccessUnit
+ */
+ SequenceHeaderByteIO( SourceParams& src_params,
+ EncoderParams& enc_params);
+
+ /**
+ * Constructor (decoding)
+ *@param parseunit_byteio Source of data
+ *@param parse_params Destination of parse paramters data
+ *@param src_params Destination of source paramters data
+ *@param codec_params Destination of coding paramters data
+ */
+ SequenceHeaderByteIO(const ParseUnitByteIO& parseunit_byteio,
+ ParseParams& parse_params,
+ SourceParams& src_params,
+ CodecParams& codec_params);
+
+ /**
+ * Destructor
+ */
+ ~SequenceHeaderByteIO();
+
+ /**
+ * Parses data in Dirac-stream format (decoding)
+ */
+ bool Input();
+
+ /**
+ * Writes access-unit info to Dirac stream-format (encoding)
+ */
+ void Output();
+
+ /*
+ * Gets size of access-unit (in bytes)
+ */
+ int GetSize() const;
+
+ /**
+ * Gets parse-unit type
+ */
+ ParseUnitType GetType() const { return PU_SEQ_HEADER;}
+
+ private:
+
+ /**
+ * Calculates parse-code based on access-unit parameters (encoding)
+ *@return Char bit-set
+ */
+ unsigned char CalcParseCode() const;
+
+ /**
+ * Parse source attributes from bytestream-compatible input (decoding)
+ */
+ void InputSourceParams();
+
+ /**
+ * Parse parse attributes from bytestream-compatible input (decoding)
+ */
+ void InputParseParams();
+
+ /**
+ * Parse Coding attributes from bytestream-compatible input (decoding)
+ */
+ void InputCodingParams();
+
+ /**
+ * Output source attributes for bytestream-compatible output (encoding)
+ */
+ void OutputSourceParams();
+
+ /**
+ * Output parse attributes for bytestream-compatible output (encoding)
+ */
+ void OutputParseParams();
+
+ /**
+ * Output coding attributes for bytestream-compatible output (encoding)
+ */
+ void OutputCodingParams();
+
+ /**
+ * Current parse parameters
+ */
+ ParseParams m_parse_params;
+
+
+ /**
+ * Parse-params byte input/output
+ */
+ ParseParamsByteIO m_parseparams_byteio;
+
+ /**
+ * Default source parameters
+ */
+ SourceParams m_default_src_params;
+
+ /**
+ * Current source parameters
+ */
+ SourceParams& m_src_params;
+
+ /**
+ * Source-params byte input/output
+ */
+ SourceParamsByteIO m_sourceparams_byteio;
+
+ /**
+ * Current codec parameters
+ */
+ CodecParams& m_codec_params;
+
+ /**
+ * Coding-params byte input/output
+ */
+ CodingParamsByteIO m_codingparams_byteio;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.cpp
new file mode 100644
index 000000000..12b129953
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.cpp
@@ -0,0 +1,299 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: byteio.cpp,v 1.4 2008/03/14 08:17:36 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author),
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <cmath>
+#include <libdirac_byteio/byteio.h>
+using namespace dirac;
+using namespace std;
+
+ByteIO::ByteIO(bool new_stream):
+m_current_byte(0),
+m_current_pos(0),
+m_num_bytes(0),
+m_new_stream(true),
+m_bits_left(0)
+{
+ if(new_stream)
+ mp_stream = new stringstream(stringstream::in | stringstream::out |
+ stringstream::binary);
+
+
+}
+
+ByteIO::ByteIO(const ByteIO& stream_data):
+m_current_byte(0),
+m_current_pos(0),
+m_num_bytes(0),
+m_new_stream(false),
+m_bits_left(0)
+{
+ mp_stream=stream_data.mp_stream;
+}
+
+
+ByteIO::~ByteIO()
+{
+ if (m_new_stream)
+ delete mp_stream;
+}
+
+const string ByteIO::GetBytes()
+{
+ return mp_stream->str();
+}
+
+int ByteIO::GetSize() const
+{
+ return m_num_bytes;
+}
+
+void ByteIO::SetByteParams(const ByteIO& byte_io)
+{
+ mp_stream=byte_io.mp_stream;
+ m_current_byte=byte_io.m_current_byte;
+ m_current_pos=byte_io.m_current_pos;
+}
+
+//----------protected---------------------------------------------------------------
+
+void ByteIO::ByteAlignInput()
+{
+ m_current_pos=0;
+ m_current_byte=0;
+}
+
+void ByteIO::ByteAlignOutput()
+{
+ if(m_current_pos!=0)
+ OutputCurrentByte();
+}
+
+int ByteIO::ReadBit()
+{
+ if(m_current_pos == CHAR_BIT)
+ m_current_pos=0;
+
+ if (m_current_pos == 0)
+ m_current_byte = InputUnByte();
+#if 1
+ // MSB to LSB
+ return GetBit(m_current_byte, (CHAR_BIT-1-m_current_pos++));
+#else
+ // LSB to MSB
+ return GetBit(m_current_byte, m_current_pos++);
+#endif
+}
+
+int ByteIO::ReadBitB()
+{
+ if (m_bits_left)
+ {
+ --m_bits_left;
+ return ReadBit();
+ }
+ else
+ return 1;
+}
+
+bool ByteIO::ReadBool()
+{
+ return ReadBit();
+}
+
+bool ByteIO::ReadBoolB()
+{
+ return ReadBitB();
+}
+
+unsigned int ByteIO::ReadNBits(int count)
+{
+ unsigned int val = 0;
+ for (int i = 0; i < count; ++i)
+ {
+ val <<= 1;
+ val += ReadBit();
+ }
+ return val;
+}
+
+void ByteIO::FlushInputB()
+{
+ while(m_bits_left)
+ {
+ ReadBit();
+ --m_bits_left;
+ }
+}
+
+int ByteIO::ReadSint()
+{
+
+ int val = ReadUint();
+ bool bit;
+
+ //get the sign
+ if (val != 0)
+ {
+ bit = ReadBit();
+ if (bit )
+ val = -val;
+ }
+ return val;
+}
+
+int ByteIO::ReadSintB()
+{
+
+ int val = ReadUintB();
+ bool bit;
+
+ //get the sign
+ if (val != 0)
+ {
+ bit = ReadBitB();
+ if (bit )
+ val = -val;
+ }
+ return val;
+}
+
+unsigned int ByteIO::ReadUint()
+{
+ unsigned int value = 1;
+ while (!ReadBit())
+ {
+ value <<= 1;
+ if (ReadBit())
+ value +=1;
+ }
+ --value;
+ return value;
+}
+
+unsigned int ByteIO::ReadUintB()
+{
+ unsigned int value = 1;
+ while (!ReadBitB())
+ {
+ value <<= 1;
+ if (ReadBitB())
+ value +=1;
+ }
+ --value;
+ return value;
+}
+
+void ByteIO::WriteBit(const bool& bit)
+{
+ if(bit)
+#if 1
+ // MSB to LSB
+ SetBit(m_current_byte, CHAR_BIT-1-m_current_pos);
+#else
+ // LSB to MSB
+ SetBit(m_current_byte, m_current_pos);
+#endif
+
+ if ( m_current_pos == CHAR_BIT-1)
+ {
+ // If a whole byte has been written, output to stream
+ OutputCurrentByte();
+ m_current_byte = 0;
+ m_current_pos = 0;
+ }
+ else
+ // Shift mask to next bit in the output byte
+ ++m_current_pos;
+}
+
+void ByteIO::WriteNBits(unsigned int val, int count)
+{
+ do
+ {
+ WriteBit(val & ( 1 << (count-1)));
+ count--;
+ }
+ while(count > 0);
+}
+
+int ByteIO::WriteNBits(unsigned int val)
+{
+ int nbits = static_cast<int>(log(static_cast<double>(val))/log(2.0)) + 1;
+ WriteNBits(val, nbits);
+ return nbits;
+}
+
+void ByteIO::WriteSint(int val)
+{
+ unsigned int value = (val >= 0 ? val : -val);
+ //output magnitude
+ WriteUint(value);
+
+ //do sign
+ if (val<0) WriteBit(1);
+ else if (val>0) WriteBit(0);
+}
+
+void ByteIO::WriteUint(unsigned int value)
+{
+ unsigned int val = value+1;
+
+ int num_follow_zeroes = 0;
+
+ while (val >= (1U <<num_follow_zeroes))
+ ++num_follow_zeroes;
+ --num_follow_zeroes;
+
+ for (int i=num_follow_zeroes-1; i>=0; --i)
+ {
+ WriteBit(BIT_ZERO);
+ WriteBit(val&(1<<i));
+ }
+ WriteBit(BIT_ONE);
+}
+
+void ByteIO::RemoveRedundantBytes(const int size)
+{
+ int prev_pos = mp_stream->tellg();
+ string data=mp_stream->str();
+ data.erase(0, size);
+ mp_stream->str(data);
+ m_num_bytes=data.size();
+ if(data.size())
+ SeekGet(max(prev_pos-size, 0), ios_base::beg);
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.h
new file mode 100644
index 000000000..db885d658
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/byteio.h
@@ -0,0 +1,397 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: byteio.h,v 1.11 2009/01/21 05:18:09 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author),
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class ByteIO.
+*/
+#ifndef byteio_h
+#define byteio_h
+
+// SYSTEM INCLUDES
+#include <iostream> // IO classes
+#include <sstream> // IO classes
+#include <iomanip> // setw
+#include <climits> // CHAR_BIT
+
+//LOCAL INCLUDEs
+#include <libdirac_byteio/dirac_byte_stats.h> // stores stats
+
+namespace dirac
+{
+
+ // BIT DEFS
+ #define BIT_ZERO 0
+ #define BIT_ONE 1
+
+ // most significant bit in a character
+ #define MS_BIT (1 << (CHAR_BIT - 1))
+
+ /* array index for character containing bit */
+ //#define BIT_IN_CHAR(bit) (1 << (CHAR_BIT-1-bit))
+ #define BIT_IN_CHAR(bit) (1 << bit)
+
+
+ /**
+ * Class ByteIO - top-level class for reading/writing bytes to a stream
+ */
+ class ByteIO
+ {
+ public:
+
+ /**
+ * Default constructor
+ *@param new_stream <B>Has Creates & owns data buffer </B>
+ */
+ ByteIO(bool new_stream=true);
+
+ /**
+ * Constructor
+ *@param stream_data Copies data buffer details
+ */
+ ByteIO(const ByteIO& stream_data);
+
+ /**
+ * Destructor
+ */
+ virtual ~ByteIO();
+
+ /**
+ * Gathers byte-stream statistics
+ *@param dirac_byte_stats Collates byte information
+ */
+ virtual void CollateByteStats(DiracByteStats& dirac_byte_stats)
+ { dirac_byte_stats.Clear(); }
+
+ /**
+ * Get bytes in Dirac-bytestream format
+ */
+ virtual const std::string GetBytes();
+
+ /**
+ * Get position of read stream pointer
+ */
+ int GetReadBytePosition() const { return mp_stream->tellg();};
+
+
+ /**
+ *Gets size (in bytes)
+ */
+ virtual int GetSize() const;
+
+ /**
+ * Copies stream source/destination info
+ *@param byte_io Byte source/destination
+ */
+ void SetByteParams(const ByteIO& byte_io);
+
+ /**
+ * Sync input for byte-alignment
+ */
+ void ByteAlignOutput();
+
+ /**
+ * Ouputs an unsigned integer in interleaved exp Golomb format
+ *@param value Integer to be output
+ */
+ //void OutputVarLengthUint(const unsigned int& value);
+ void WriteUint(unsigned int value);
+
+ /**
+ * Sets input size in bits. Read is limited by this
+ */
+ void SetBitsLeft(int left_bits) { m_bits_left = left_bits; }
+
+ /**
+ * Sets input size in bits. Read is limited by this
+ */
+ int BitsLeft(void) { return m_bits_left; }
+
+ protected:
+
+ inline bool CanRead() const { return(!mp_stream->eof()); }
+
+ inline bool GetBit(unsigned char& c, int pos) const { return (c & BIT_IN_CHAR(pos)); }
+
+ inline void SetBit(unsigned char& c, int pos) const { c |= BIT_IN_CHAR(pos); }
+
+ inline void SetBits(unsigned char& c, unsigned char bits) const { c |= bits; }
+
+ /**
+ * Sync input for byte-alignment
+ */
+ void ByteAlignInput();
+
+
+ /**
+ * Reads boolean value
+ */
+ bool ReadBool();
+
+ /**
+ * Reads boolean value - bounded i/o
+ */
+ bool ReadBoolB();
+
+ /**
+ * Reads next bit
+ */
+ int ReadBit();
+
+ /**
+ * Reads next bit - bounded i/o
+ */
+ int ReadBitB();
+
+ /**
+ * Reads next 'count' bits
+ *@param count number of bits to be read
+ *@return unsigned interger read
+ */
+ unsigned int ReadNBits(int count);
+
+ /**
+ * Reads from stream
+ *@param data Start of char buffer
+ *@param count Number of bytes to read
+ */
+ void InputBytes(char* data, int count)
+ {
+ //int j=mp_stream->tellg();
+ mp_stream->read(data, count);
+
+ //int h=mp_stream->tellg();
+ }
+
+ /**
+ * Flushes the bounde input
+ */
+ void FlushInputB();
+
+ /**
+ * Reads a signed integer in interleaved exp-Golomb format
+ *return Signed integer read
+ */
+ //int InputVarLengthInt();
+ int ReadSint();
+
+ /**
+ * Reads a signed integer in interleaved exp-Golomb format from bounded input
+ *return Signed integer read
+ */
+ int ReadSintB();
+
+ /**
+ * Reads an unsigned integer in interleaved exp Golomb format
+ *@return Unsigned Integer read
+ */
+ //unsigned int InputVarLengthUint();
+ unsigned int ReadUint();
+
+ /**
+ * Reads an unsigned integer in interleaved exp Golomb format from bounded input
+ *@return Unsigned Integer read
+ */
+ //unsigned int InputVarLengthUint();
+ unsigned int ReadUintB();
+
+ /**
+ * Reads a fixed length unsigned integer from the stream in big endian
+ *@param byte_size Number of bytes in fixed length integer
+ *@return Unsigned Integer read
+ */
+ //inline unsigned int InputFixedLengthUint(const int byte_size) {
+ inline unsigned int ReadUintLit(const int byte_size) {
+ unsigned int val=0;
+ for(int i=0; i < byte_size; ++i)
+ {
+ val <<= 8;
+ val += (unsigned char)mp_stream->get();
+ }
+ m_num_bytes+=byte_size;
+ return val;
+ }
+
+ /**
+ * Reads a byte from the stream
+ */
+ inline unsigned char InputUnByte() {m_num_bytes++ ; return mp_stream->get(); }
+
+ /**
+ * Reads a series of bytes from a stream
+ */
+ inline std::string InputUnString(const int count)
+ {
+ std::string str;
+ for(int index=0; index < count; ++index)
+ str.push_back(InputUnByte());
+ return str;
+ }
+
+ /**
+ * Outputs a bit
+ *@param bit 1/0 Output
+ */
+ void WriteBit(const bool& bit);
+
+ /**
+ * Outputs an unsigned integer
+ *@param val Integer to be output
+ *@return number of bits written
+ */
+ int WriteNBits(unsigned int val);
+
+ /**
+ * Outputs an n bit integer
+ *@param val Unsigned Integer to be output
+ *@param count number of bits to be written
+ */
+ void WriteNBits(unsigned int val, int count);
+
+
+
+ /**
+ * Outputs a series of bytes
+ */
+ void OutputBytes(const std::string& bytes) {
+ int cur_pos = mp_stream->tellg();
+ mp_stream->str(mp_stream->str()+bytes);
+ m_num_bytes+=bytes.size();
+ // *mp_stream << bytes;
+ mp_stream->seekg(std::max(cur_pos,0), std::ios_base::beg);
+ }
+
+ /**
+ * Outputs current byte contents
+ */
+ inline void OutputCurrentByte()
+ {
+ if (m_current_pos)
+ {
+ *mp_stream << (m_current_byte);
+ ++m_num_bytes;
+ m_current_pos = 0;
+ m_current_byte = 0;
+ }
+ };
+
+ /**
+ * Outputs an integer in Golomb signed integer format
+ *@param val Integer to be output
+ */
+ //void OutputVarLengthInt(const int val);
+ void WriteSint(int val);
+
+ /**
+ * Output unsigned int value in big endian format
+ * @param value Integer to be output
+ * @param length number of bytes in val to output
+ */
+ //inline void OutputFixedLengthUint(const unsigned int& value, const int& length)
+ inline void WriteUintLit(const unsigned int& value, const int& length)
+ {
+ for(int i=length-1; i >=0 ; --i)
+ {
+ unsigned char cp = (value>>(i*8))&0xff;
+ *mp_stream << cp;
+ }
+ m_num_bytes+=length;
+ }
+
+ /**
+ * Removes portion of byte-stream no longer required
+ *@param count Number of bytes to be removed from beginning of stream
+ */
+ void RemoveRedundantBytes(const int count);
+
+ inline void SeekGet(const int offset, std::ios_base::seekdir dir)
+ {
+ mp_stream->seekg(offset, dir);
+ }
+
+ /**
+ * Input/output steam
+ */
+ std::stringstream* mp_stream;
+
+
+ private:
+
+ /**
+ * ArithCodec can see internals for getting/setting bits
+ */
+ friend class ArithCodecBase;
+
+ /**
+ * VLC entropy coder can see internals for getting/setting bits
+ */
+ friend class ArithCodecToVLCAdapter;
+
+ /**
+ * Char used for temporary storage of op data bits
+ */
+ unsigned char m_current_byte;
+
+ /**
+ * Used to set individual bit within the current header byte
+ */
+ int m_current_pos;
+
+ /**
+ * Number of bytes processed
+ */
+ int m_num_bytes;
+
+ /**
+ * stream alloc flag
+ */
+ bool m_new_stream;
+
+ /**
+ * num bits left to read
+ */
+ int m_bits_left;
+ protected:
+
+
+ };
+
+
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.cpp
new file mode 100644
index 000000000..7326b4562
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.cpp
@@ -0,0 +1,134 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: codingparams_byteio.cpp,v 1.9 2008/04/29 08:51:52 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/codingparams_byteio.h>
+#include <libdirac_common/common.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+
+CodingParamsByteIO::CodingParamsByteIO(const SourceParams& src_params,
+ CodecParams& codec_params,
+ const SourceParams& default_source_params,
+ const ByteIO& stream_data):
+ByteIO(stream_data),
+m_src_params(src_params),
+m_codec_params(codec_params),
+m_default_source_params(default_source_params)
+{
+
+}
+
+CodingParamsByteIO::~CodingParamsByteIO()
+{
+}
+
+//---------public---------------------------------------------------
+
+void CodingParamsByteIO::Input()
+{
+ // input picture coding mode
+ InputPictureCodingMode();
+
+ m_codec_params.SetTopFieldFirst(m_src_params.TopFieldFirst());
+
+ // Set the dimensions to frame dimensions
+ m_codec_params.SetXl(m_src_params.Xl());
+ m_codec_params.SetYl(m_src_params.Yl());
+
+ m_codec_params.SetChromaXl(m_src_params.ChromaWidth());
+ m_codec_params.SetChromaYl(m_src_params.ChromaHeight());
+
+ // If source was coded as fields, halve the vertical dimensions
+ // to set them to field dimensions
+ if (m_codec_params.FieldCoding())
+ {
+ m_codec_params.SetYl(m_codec_params.Yl()>>1);
+ m_codec_params.SetChromaYl(m_codec_params.ChromaYl()>>1);
+ }
+
+ unsigned int luma_depth = static_cast<unsigned int>
+ (
+ std::log((double)m_src_params.LumaExcursion())/std::log(2.0) + 1
+ );
+ m_codec_params.SetLumaDepth(luma_depth);
+
+ unsigned int chroma_depth = static_cast<unsigned int>
+ (
+ std::log((double)m_src_params.ChromaExcursion())/std::log(2.0) + 1
+ );
+ m_codec_params.SetChromaDepth(chroma_depth);
+
+ // byte align
+ ByteAlignInput();
+}
+
+
+void CodingParamsByteIO::Output()
+{
+ // output picture coding mode flag
+ OutputPictureCodingMode();
+
+ // byte align
+ ByteAlignOutput();
+}
+
+//-------------private---------------------------------------------------------------
+
+void CodingParamsByteIO::InputPictureCodingMode()
+{
+ unsigned int coding_mode = ReadUint();
+ if (coding_mode > 1)
+ {
+ std::ostringstream errstr;
+ errstr << "Picture coding mode " << coding_mode
+ << " out of range [0-1]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_ACCESSUNIT_ERROR);
+ }
+ m_codec_params.SetPictureCodingMode(coding_mode);
+}
+
+
+void CodingParamsByteIO::OutputPictureCodingMode()
+{
+ WriteUint(m_codec_params.FieldCoding() ? 1 : 0);
+}
+
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.h
new file mode 100644
index 000000000..b96b037a0
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/codingparams_byteio.h
@@ -0,0 +1,135 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: codingparams_byteio.h,v 1.3 2007/12/05 01:42:40 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class CodingParamsByteIO
+*/
+#ifndef codingparams_byteio_h
+#define codingparams_byteio_h
+
+
+// DIRAC INCLUDES
+#include <libdirac_common/common.h> // CodecParams, SourceParams
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+
+
+namespace dirac
+{
+
+ /**
+ * Represents compressed sequence-parameter data used in an AccessUnit
+ */
+ class CodingParamsByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param src_params Source parameters
+ *@param codec_params Coding parameters
+ *@param default_source_params Default source parameters
+ *@param stream_data Source/Destination of data
+ */
+ CodingParamsByteIO(const SourceParams& src_params,
+ CodecParams& codec_params,
+ const SourceParams& default_source_params,
+ const ByteIO& stream_data);
+
+
+ /**
+ * Destructor
+ */
+ ~CodingParamsByteIO();
+
+ /**
+ * Reads sequence information from Dirac byte-format
+ */
+ void Input();
+
+ /**
+ * Outputs sequence information to Dirac byte-format
+ */
+ void Output();
+
+ protected:
+
+
+ private:
+
+ /**
+ * Reads number of bits used to compress input signal
+ */
+ void InputVideoDepth();
+
+ /**
+ * Reads picture coding mode - 0 - frames, 1 - fields
+ */
+ void InputPictureCodingMode();
+
+ /**
+ * Outputs number of bits used to compress input signal
+ */
+ void OutputVideoDepth();
+
+ /**
+ * Outputs how input was coded - i.e. frames or fields
+ */
+ void OutputPictureCodingMode();
+
+ /**
+ * Source paramters for intput/output
+ */
+ const SourceParams& m_src_params;
+
+ /**
+ * Coding paramters for intput/output
+ */
+ CodecParams& m_codec_params;
+
+ /**
+ * Default source parameters
+ */
+ const SourceParams& m_default_source_params;
+
+ };
+
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.cpp
new file mode 100644
index 000000000..07f5433d1
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.cpp
@@ -0,0 +1,98 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: component_byteio.cpp,v 1.2 2008/04/29 08:51:52 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/component_byteio.h>
+
+using namespace dirac;
+using namespace std;
+
+ComponentByteIO::ComponentByteIO(CompSort cs,
+ const ByteIO& byteio):
+ByteIO(byteio),
+m_compsort(cs)
+{}
+
+ComponentByteIO::ComponentByteIO(CompSort cs):
+ByteIO(),
+m_compsort(cs)
+{}
+
+ComponentByteIO::~ComponentByteIO()
+{}
+
+//--------------public----------------------------------------------
+
+void ComponentByteIO::AddSubband(SubbandByteIO* p_subband_byteio)
+{
+ OutputBytes(p_subband_byteio->GetBytes());
+}
+
+void ComponentByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ // set number of component bytes
+ switch(m_compsort)
+ {
+ case Y_COMP:
+ dirac_byte_stats.SetByteCount(STAT_YCOMP_BYTE_COUNT,
+ GetSize());
+ break;
+ case U_COMP:
+ dirac_byte_stats.SetByteCount(STAT_UCOMP_BYTE_COUNT,
+ GetSize());
+ break;
+ case V_COMP:
+ dirac_byte_stats.SetByteCount(STAT_VCOMP_BYTE_COUNT,
+ GetSize());
+ break;
+ }
+}
+
+bool ComponentByteIO::Input()
+{
+
+ return true;
+}
+
+void ComponentByteIO::Output()
+{
+
+
+}
+
+
+//-------------private-------------------------------------------------------
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.h
new file mode 100644
index 000000000..e80b0877a
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/component_byteio.h
@@ -0,0 +1,125 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class ComponentByteIO
+*/
+#ifndef component_byteio_h
+#define component_byteio_h
+
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+#include <libdirac_byteio/subband_byteio.h> // child-type
+
+// DIRAC includes
+
+// SYSTEM INCLUDES
+#include <vector>
+
+namespace dirac
+{
+ /**
+ * Picture component in Dirac bytestream format
+ */
+ class ComponentByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param cs Picture-component type
+ *@param byteIO Input/output Byte stream
+ */
+ ComponentByteIO(CompSort cs,
+ const ByteIO& byteIO);
+
+ /**
+ * Constructor
+ *@param cs Picture-component type
+ */
+ ComponentByteIO(CompSort cs);
+
+ /**
+ * Destructor
+ */
+ ~ComponentByteIO();
+
+ /**
+ * Gathers byte stats on the component data
+ *@param dirac_byte_stats Stat container
+ */
+ void CollateByteStats(DiracByteStats& dirac_byte_stats);
+
+ /**
+ * Add a subband byte-stream to this component
+ *@param p_subband_byteio Subband to be added
+ */
+ void AddSubband(SubbandByteIO *p_subband_byteio);
+
+ /**
+ * Inputs data from Dirac stream-format
+ */
+ bool Input();
+
+ /**
+ * Outputs picture values to Dirac stream-format
+ */
+ void Output();
+
+
+
+ protected:
+
+
+ private:
+
+ /**
+ * Picture component type
+ */
+ CompSort m_compsort;
+
+ /**
+ * List of subbands in output/input order
+ */
+ std::vector<ByteIO*> m_subband_list;
+
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.cpp
new file mode 100644
index 000000000..9c697bc3d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.cpp
@@ -0,0 +1,84 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_byte_stats.cpp,v 1.3 2008/04/29 12:27:49 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/dirac_byte_stats.h>
+
+using namespace dirac;
+using namespace std;
+
+
+DiracByteStats::DiracByteStats()
+{
+}
+
+DiracByteStats::DiracByteStats(const DiracByteStats& dirac_byte_stats):
+m_byte_count(dirac_byte_stats.m_byte_count)
+{
+}
+
+DiracByteStats::~DiracByteStats()
+{
+}
+
+
+void DiracByteStats::Clear()
+{
+ m_byte_count.clear();
+}
+
+int64_t DiracByteStats::GetBitCount(const StatType& stat_type) const
+{
+ return GetByteCount(stat_type) * CHAR_BIT;
+}
+
+int64_t DiracByteStats::GetByteCount(const StatType& stat_type) const
+{
+ std::map<StatType, int64_t>::const_iterator it;
+ it = m_byte_count.find(stat_type);
+ if(it==m_byte_count.end())
+ return 0;
+
+ return it->second;
+}
+
+void DiracByteStats::SetByteCount(const StatType& stat_type, int64_t count)
+{
+ if(m_byte_count.find(stat_type)==m_byte_count.end())
+ m_byte_count[stat_type]=0;
+
+ m_byte_count[stat_type]+=count;
+ }
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.h
new file mode 100644
index 000000000..0da273f0a
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stats.h
@@ -0,0 +1,120 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_byte_stats.h,v 1.5 2008/05/06 09:35:51 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class DiracByteStats
+*/
+#ifndef dirac_byte_stats_h
+#define dirac_byte_stats_h
+
+// SYSTEM INCLUDES
+#include <map> // for byte-counts
+#include <climits>
+
+#include <libdirac_common/dirac_inttypes.h>
+
+namespace dirac
+{
+
+ #ifdef _MSC_VER
+ // char length
+ #define CHAR_BIT 8
+#endif
+
+ typedef enum {
+ STAT_TOTAL_BYTE_COUNT=0,
+ STAT_MV_BYTE_COUNT,
+ STAT_YCOMP_BYTE_COUNT,
+ STAT_UCOMP_BYTE_COUNT,
+ STAT_VCOMP_BYTE_COUNT
+ } StatType;
+
+
+ /**
+ * Class DiracByteStats - for collecting statistics on aspects of the Dirac byte-stream
+ */
+ class DiracByteStats
+ {
+ public:
+ /**
+ * Constructor
+ */
+ DiracByteStats();
+
+ /**
+ * Copy constructor
+ */
+ DiracByteStats(const DiracByteStats& dirac_byte_stats);
+
+ /**
+ * Destructor
+ */
+ ~DiracByteStats();
+
+ /**
+ * Clears data
+ */
+ void Clear();
+
+ /**
+ * Gets number of bits for a particular stat-type
+ */
+ int64_t GetBitCount(const StatType& stat_type) const;
+
+ /**
+ * Gets number of bytes for a particular stat-type
+ */
+ int64_t GetByteCount(const StatType& stat_type) const;
+
+ /**
+ * Sets number of bytes for a particular stat-type
+ */
+ void SetByteCount(const StatType& stat_type, int64_t count);
+
+
+ private:
+
+ /**
+ * Map of byte-counts
+ */
+ std::map<StatType, int64_t> m_byte_count;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.cpp
new file mode 100644
index 000000000..a45e54706
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.cpp
@@ -0,0 +1,264 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_byte_stream.cpp,v 1.8 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/dirac_byte_stream.h>
+#include <libdirac_byteio/endofsequence_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+using namespace std;
+
+DiracByteStream::DiracByteStream():
+ByteIO(),
+mp_prev_parse_unit(NULL)
+{
+}
+
+DiracByteStream::~DiracByteStream()
+{
+ delete mp_prev_parse_unit;
+}
+
+//---------------decoding----------------------------------------------------
+
+void DiracByteStream::AddBytes(char* start,
+ int count)
+{
+ // add to input stream
+ string str(start, count);
+ ByteIO::OutputBytes(str);
+
+}
+
+DiracByteStats DiracByteStream::GetLastUnitStats()
+{
+ DiracByteStats dirac_byte_stats;
+
+ if(m_parse_unit_list.empty())
+ return dirac_byte_stats;
+
+ ParseUnitByteIO* p_parse_unit = m_parse_unit_list.back().second;
+ p_parse_unit->CollateByteStats(dirac_byte_stats);
+
+ return dirac_byte_stats;
+}
+
+void DiracByteStream::Reset(ParseUnitByteIO* p_curr_unit, int pos)
+{
+ delete p_curr_unit;
+ SeekGet(pos, ios_base::beg);
+}
+
+ParseUnitByteIO* DiracByteStream::GetNextParseUnit()
+{
+ if(GetSize()==0)
+ return NULL;
+
+ int pos=0;
+ if(mp_prev_parse_unit)
+ {
+ // remove the unwanted bytes associated with the previous parse-unit
+ int prev_offset = mp_prev_parse_unit->GetNextParseOffset();
+ RemoveRedundantBytes(prev_offset ? prev_offset : mp_prev_parse_unit->GetSize());
+ delete mp_prev_parse_unit;
+ mp_prev_parse_unit=NULL;
+ if(!GetSize())
+ return NULL;
+ }
+
+ ParseUnitByteIO* p_curr_unit=NULL;
+
+ while(true)
+ {
+ pos = GetReadBytePosition();
+
+ p_curr_unit = new ParseUnitByteIO(*this);
+ if (!p_curr_unit->Input())
+ {
+ Reset(p_curr_unit, pos);
+ return NULL;
+ }
+
+ // skip past current unit
+ if(!p_curr_unit->CanSkip())
+ {
+ Reset(p_curr_unit, pos);
+ return NULL;
+ }
+
+ if (p_curr_unit->IsEndOfSequence())
+ {
+ break;
+ }
+
+ // look to see if next unit validates the current one
+ if(!p_curr_unit->IsValid())
+ {
+ // delete the unit - it's invalid
+ delete p_curr_unit;
+ // remove unwanted portion of bytes
+ RemoveRedundantBytes(pos);
+ // look for next potential parse-unit
+ continue;
+ }
+ break;
+ } // while
+
+ // Remove all redundant bytes that are not part of a parse unit
+ int remove_size = std::max (0, GetReadBytePosition()-p_curr_unit->GetSize());
+ if (remove_size)
+ {
+ //std::cerr << "Size="<<GetSize() << " Un-useful bytes=" << remove_size << std::endl;
+ RemoveRedundantBytes(remove_size);
+ }
+
+ mp_prev_parse_unit=p_curr_unit;
+ return p_curr_unit;
+}
+
+DiracByteStats DiracByteStream::GetSequenceStats() const
+{
+ return m_sequence_stats;
+}
+
+//---------------encoding-----------------------------------------------------
+
+void DiracByteStream::AddSequenceHeader(SequenceHeaderByteIO *p_seqheader_byteio)
+{
+ // set previous parse-unit details
+ ParseUnitByteIO *mp_previous_parse_unit=mp_prev_parse_unit;
+
+ if(!m_parse_unit_list.empty())
+ mp_previous_parse_unit = m_parse_unit_list.back().second;
+
+ // set adjacent parse-unit
+ p_seqheader_byteio->SetAdjacentParseUnits(mp_previous_parse_unit);
+
+ // push onto to pending list
+ m_parse_unit_list.push(std::make_pair (PU_SEQ_HEADER, p_seqheader_byteio) );
+
+ // set previous parse-unit
+ mp_previous_parse_unit = p_seqheader_byteio;
+
+ // save stats
+ p_seqheader_byteio->CollateByteStats(m_sequence_stats);
+}
+
+void DiracByteStream::AddPicture(PictureByteIO *p_frame_byteio)
+{
+ // set previous parse-unit details
+ ParseUnitByteIO *mp_previous_parse_unit=mp_prev_parse_unit;
+
+ if(!m_parse_unit_list.empty())
+ mp_previous_parse_unit = m_parse_unit_list.back().second;
+
+ // set adjacent parse-unit
+ p_frame_byteio->SetAdjacentParseUnits(mp_previous_parse_unit);
+
+ // push onto to pending list
+ m_parse_unit_list.push(std::make_pair(PU_PICTURE, p_frame_byteio ) );
+
+ // set previous parse-unit
+ mp_previous_parse_unit = p_frame_byteio;
+
+ // save stats
+ p_frame_byteio->CollateByteStats(m_sequence_stats);
+}
+
+void DiracByteStream::Clear()
+{
+ while(!m_parse_unit_list.empty())
+ {
+ ParseUnitByteIO* p_parse_unit=m_parse_unit_list.front().second;
+ m_parse_unit_list.pop();
+ if(m_parse_unit_list.empty())
+ {
+ delete mp_prev_parse_unit;
+ mp_prev_parse_unit=p_parse_unit;
+ }
+ else
+ delete p_parse_unit;
+ }
+}
+
+DiracByteStats DiracByteStream::EndSequence()
+{
+ // create
+ EndOfSequenceByteIO *p_endofsequence_byteio = new EndOfSequenceByteIO(*this);
+
+ // set previous parse-unit details
+ ParseUnitByteIO *mp_previous_parse_unit=mp_prev_parse_unit;
+
+ if(!m_parse_unit_list.empty())
+ mp_previous_parse_unit = m_parse_unit_list.back().second;
+
+ // set adjacent parse-unit
+ p_endofsequence_byteio->SetAdjacentParseUnits(mp_previous_parse_unit);
+
+ // push onto to pending list
+ m_parse_unit_list.push(std::make_pair(PU_END_OF_SEQUENCE, p_endofsequence_byteio) );
+
+ p_endofsequence_byteio->CollateByteStats(m_sequence_stats);
+
+ // clear stats
+ DiracByteStats seq_stats(m_sequence_stats);
+ m_sequence_stats.Clear();
+
+ // return seq stats
+ return seq_stats;
+}
+
+const string DiracByteStream::GetBytes()
+{
+ // take copy
+ ParseUnitList parse_list = m_parse_unit_list;
+ mp_stream->str("");
+
+ while(!parse_list.empty())
+ {
+ *mp_stream << parse_list.front().second->GetBytes();
+ parse_list.pop();
+ }
+
+ return mp_stream->str();
+}
+
+bool DiracByteStream::IsUnitAvailable() const
+{
+ return !m_parse_unit_list.empty();
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.h
new file mode 100644
index 000000000..d448b5fca
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/dirac_byte_stream.h
@@ -0,0 +1,158 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_byte_stream.h,v 1.4 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class DiracByteStream
+*/
+#ifndef dirac_byte_stream_h
+#define dirac_byte_stream_h
+
+//SYSTEM INCLUDES
+#include <queue>
+
+//LOCAL INCLUDES
+#include "byteio.h" // Parent class
+#include "accessunit_byteio.h" // manages parse-unit types
+#include "picture_byteio.h" // manages parse-unit types
+
+namespace dirac
+{
+
+ /**
+ * Represents a series of bytes in the Dirac bytestream specfication format.
+ * These bytes are grouped into more managable parse units by this class.
+ */
+ class DiracByteStream : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ */
+ DiracByteStream();
+
+ /**
+ * Destructor
+ */
+ ~DiracByteStream();
+
+ /**
+ * Adds Dirac-formatted bytes to internal-byte-stream for processing
+ *@param start Start of char list
+ *@param count Number of chars
+ */
+ void AddBytes(char* start, int count);
+
+ /**
+ * Gets the statistics of the most recent parse-unit to be processed
+ *@return Byte-statistics
+ */
+ DiracByteStats GetLastUnitStats();
+
+ /**
+ * Gets the next parse-unit in the current byte-stream
+ */
+ ParseUnitByteIO* GetNextParseUnit();
+
+
+ /**
+ * Gets stats for current sequence
+ */
+ DiracByteStats GetSequenceStats() const;
+
+ /**
+ * Adds a random access point to the current Dirac byte stream
+ *@param p_seqheader_byteio Sequence header data.
+ */
+ void AddSequenceHeader(SequenceHeaderByteIO *p_seqheader_byteio);
+
+ /**
+ * Adds a picture to the current Dirac byte stream
+ *@param p_frame_byteio Picture stream. This class is now responsible for deleting.
+ */
+ void AddPicture(PictureByteIO *p_frame_byteio);
+
+ /**
+ * Clear parse-units
+ */
+ void Clear();
+
+ /**
+ * Insert end-of-sequence data
+ *@return Sequence stats
+ */
+ DiracByteStats EndSequence();
+
+ /**
+ * Gets a pointer to all current output bytes
+ */
+ const std::string GetBytes();
+
+ /**
+ * Any info pending?
+ */
+ bool IsUnitAvailable() const;
+
+ private:
+
+ void Reset(ParseUnitByteIO* p_curr_unit, int pos);
+
+ private:
+
+ /**
+ * Parse-units in Dirac stream
+ */
+ typedef std::queue< std::pair <ParseUnitType, ParseUnitByteIO*> > ParseUnitList;
+ ParseUnitList m_parse_unit_list;
+
+ /**
+ * Last unit to be processed
+ * Required for specifying the previous parse-unit
+ */
+ ParseUnitByteIO* mp_prev_parse_unit;
+
+ /**
+ * Stats for current sequence
+ */
+ DiracByteStats m_sequence_stats;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.cpp
new file mode 100644
index 000000000..e74a4f278
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.cpp
@@ -0,0 +1,502 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: displayparams_byteio.cpp,v 1.10 2008/01/31 11:25:15 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/displayparams_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+
+SourceParamsByteIO::SourceParamsByteIO( SourceParams& src_params,
+ const SourceParams& default_src_params,
+ const ByteIO& stream_data):
+ByteIO(stream_data),
+m_src_params(src_params),
+m_default_src_params(default_src_params)
+{
+
+
+}
+
+SourceParamsByteIO::~SourceParamsByteIO()
+{
+}
+
+//-----------------public----------------------------------------------------
+
+void SourceParamsByteIO::Input()
+{
+ // input frame dimensions
+ InputFrameSize();
+
+ // input chroma sampling format
+ InputChromaSamplingFormat();
+
+ // input scan format
+ InputScanFormat();
+
+ // input frame rate
+ InputFrameRate();
+
+ // input pixel aspect ratio
+ InputPixelAspectRatio();
+
+ // input clean area
+ InputCleanArea();
+
+ // input signal range
+ InputSignalRange();
+
+ // input colour spec
+ InputColourSpecification();
+}
+
+void SourceParamsByteIO::Output()
+{
+ // output frame dimensions
+ OutputFrameSize();
+
+ // output chroma sampling format
+ OutputChromaSamplingFormat();
+
+ // output scan format
+ OutputScanFormat();
+
+ // output frame rate
+ OutputFrameRate();
+
+ // output pixel aspect ratio
+ OutputPixelAspectRatio();
+
+ // output clean area
+ OutputCleanArea();
+
+ // output signal range
+ OutputSignalRange();
+
+ // output colour spec
+ OutputColourSpecification();
+}
+
+//-------------------private-----------------------------------------------
+void SourceParamsByteIO::InputFrameSize()
+{
+ bool custom_flag = ReadBool();
+
+ if(!custom_flag)
+ return;
+
+ // set custom width
+ m_src_params.SetXl(ReadUint());
+
+ // set custom height
+ m_src_params.SetYl(ReadUint());
+}
+
+void SourceParamsByteIO::InputChromaSamplingFormat()
+{
+ bool chroma_flag = ReadBool();
+
+ if(!chroma_flag)
+ return;
+
+ // set chroma
+ ChromaFormat chroma_format = IntToChromaFormat(ReadUint());
+ if(chroma_format==formatNK)
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_CHROMA_FORMAT,
+ "Dirac does not recognise the specified chroma-format",
+ SEVERITY_ACCESSUNIT_ERROR)
+ m_src_params.SetCFormat(chroma_format);
+}
+
+void SourceParamsByteIO::InputPixelAspectRatio()
+{
+ bool pixel_aspect_ratio_flag = ReadBool();
+ if(!pixel_aspect_ratio_flag)
+ return;
+
+ // read index value
+ int pixel_aspect_ratio_index = ReadUint();
+ PixelAspectRatioType pixel_aspect_ratio=IntToPixelAspectRatioType(pixel_aspect_ratio_index);
+ if(pixel_aspect_ratio==PIXEL_ASPECT_RATIO_UNDEFINED)
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_PIXEL_ASPECT_RATIO,
+ "Dirac does not recognise the specified pixel_aspect_ratio",
+ SEVERITY_ACCESSUNIT_ERROR)
+
+ if(pixel_aspect_ratio_index!=PIXEL_ASPECT_RATIO_CUSTOM)
+ {
+ m_src_params.SetPixelAspectRatio(pixel_aspect_ratio);
+ }
+ else
+ {
+ // read num/denom
+ int numerator = ReadUint();
+ int denominator = ReadUint();
+ m_src_params.SetPixelAspectRatio(numerator, denominator);
+ }
+
+}
+
+void SourceParamsByteIO::InputCleanArea()
+{
+ bool clean_area_flag = ReadBool();
+ if(!clean_area_flag)
+ return;
+
+ m_src_params.SetCleanWidth( ReadUint() );
+ m_src_params.SetCleanHeight( ReadUint() );
+ m_src_params.SetLeftOffset( ReadUint() );
+ m_src_params.SetTopOffset( ReadUint() );
+}
+
+void SourceParamsByteIO::InputColourMatrix()
+{
+ bool colour_matrix_flag = ReadBool();
+ if(!colour_matrix_flag)
+ return;
+
+ // read index value
+ int colour_matrix_index = ReadUint();
+ m_src_params.SetColourMatrixIndex(colour_matrix_index);
+}
+
+void SourceParamsByteIO::InputColourPrimaries()
+{
+ bool colour_primaries_flag = ReadBool();
+ if(!colour_primaries_flag)
+ return;
+
+ // read index value
+ int colour_primaries_index = ReadUint();
+ m_src_params.SetColourPrimariesIndex(colour_primaries_index);
+}
+
+void SourceParamsByteIO::InputColourSpecification()
+{
+ bool colour_spec_flag = ReadBool();
+ if(!colour_spec_flag)
+ return;
+
+ // read index value
+ int colour_spec_index = ReadUint();
+ m_src_params.SetColourSpecification( colour_spec_index );
+ if(colour_spec_index==0)
+ {
+ InputColourPrimaries();
+ InputColourMatrix();
+ InputTransferFunction();
+ }
+}
+
+void SourceParamsByteIO::InputFrameRate()
+{
+ bool fr_flag = ReadBool();
+ if(!fr_flag)
+ return;
+
+ int frame_rate_index = ReadUint();
+ FrameRateType frame_rate=IntToFrameRateType(frame_rate_index);
+ if(frame_rate==FRAMERATE_UNDEFINED)
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_PICTURE_RATE,
+ "Dirac does not recognise the specified frame-rate",
+ SEVERITY_ACCESSUNIT_ERROR)
+
+ if(frame_rate_index!=FRAMERATE_CUSTOM)
+ {
+ m_src_params.SetFrameRate(frame_rate);
+ }
+ else
+ {
+ // read num/denom
+ int numerator = ReadUint();
+ int denominator = ReadUint();
+ m_src_params.SetFrameRate(numerator, denominator);
+ }
+}
+
+void SourceParamsByteIO::InputScanFormat()
+{
+ bool scan_flag = ReadBool();
+ if(!scan_flag)
+ return;
+
+ unsigned int source_sampling = ReadUint();
+ if (source_sampling > 1)
+ {
+ std::ostringstream errstr;
+ errstr << "Source Sampling " << source_sampling
+ << " out of range [0-1]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_ACCESSUNIT_ERROR);
+ }
+ m_src_params.SetSourceSampling(source_sampling);
+}
+
+void SourceParamsByteIO::InputSignalRange()
+{
+ bool signal_range_flag = ReadBool();
+ if(!signal_range_flag)
+ return;
+
+ // read index value
+ int signal_range_index = ReadUint();
+ SignalRangeType signal_range = IntToSignalRangeType(signal_range_index);
+ if(signal_range==SIGNAL_RANGE_UNDEFINED)
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_SIGNAL_RANGE,
+ "Dirac does not recognise the specified signal-range",
+ SEVERITY_ACCESSUNIT_ERROR)
+
+ if(signal_range_index!=SIGNAL_RANGE_CUSTOM)
+ {
+ m_src_params.SetSignalRange(signal_range);
+ }
+ else
+ {
+ // read luma values
+ m_src_params.SetLumaOffset( ReadUint() );
+ m_src_params.SetLumaExcursion( ReadUint() );
+ // read chroma values
+ m_src_params.SetChromaOffset( ReadUint() );
+ m_src_params.SetChromaExcursion( ReadUint() );
+ }
+}
+
+void SourceParamsByteIO::InputTransferFunction()
+{
+ bool trans_fun_flag = ReadBool();
+ if(!trans_fun_flag)
+ return;
+
+ // read index value
+ int trans_fun_index = ReadUint();
+ m_src_params.SetTransferFunctionIndex(trans_fun_index);
+}
+
+void SourceParamsByteIO::OutputFrameSize()
+{
+
+ // output 'is custom' dimensions flag
+ bool is_custom = (m_src_params.Xl()!=m_default_src_params.Xl() ||
+ m_src_params.Yl()!=m_default_src_params.Yl());
+
+ WriteBit(is_custom);
+
+ if(!is_custom)
+ return;
+
+ // set custom X and Y
+ WriteUint(m_src_params.Xl());
+ WriteUint(m_src_params.Yl());
+
+}
+
+void SourceParamsByteIO::OutputChromaSamplingFormat()
+{
+ // output 'is default' flag
+ bool not_default = m_src_params.CFormat()!=m_default_src_params.CFormat();
+
+ WriteBit(not_default);
+
+ if(!not_default)
+ return;
+
+ // output chroma index
+ WriteUint(static_cast<int>(m_src_params.CFormat()));
+}
+
+
+void SourceParamsByteIO::OutputPixelAspectRatio()
+{
+ if (m_src_params.PixelAspectRatioIndex()!= PIXEL_ASPECT_RATIO_CUSTOM
+ && m_src_params.PixelAspectRatioIndex() == m_default_src_params.PixelAspectRatioIndex())
+ {
+ // default frame rate index
+ WriteBit(0);
+ return;
+ }
+ // Non-defaults
+ WriteBit(1);
+
+ // Picture rate index
+ WriteUint(m_src_params.PixelAspectRatioIndex());
+
+ if (!m_src_params.PixelAspectRatioIndex()) // i,e. custom value
+ {
+ WriteUint(m_src_params.PixelAspectRatio().m_num);
+ WriteUint(m_src_params.PixelAspectRatio().m_denom);
+ }
+}
+
+
+void SourceParamsByteIO::OutputCleanArea()
+{
+ if (m_src_params.CleanWidth() != m_default_src_params.CleanWidth() ||
+ m_src_params.CleanHeight() != m_default_src_params.CleanHeight() ||
+ m_src_params.LeftOffset() != m_default_src_params.LeftOffset() ||
+ m_src_params.TopOffset() != m_default_src_params.TopOffset())
+ {
+ WriteBit(1); // non-default value
+ WriteUint(m_src_params.CleanWidth());
+ WriteUint(m_src_params.CleanHeight());
+ WriteUint(m_src_params.LeftOffset());
+ WriteUint(m_src_params.TopOffset());
+ }
+ else
+ WriteBit(0); // default value
+}
+
+void SourceParamsByteIO::OutputColourSpecification()
+{
+ if (m_src_params.ColourSpecificationIndex() &&
+ m_src_params.ColourSpecificationIndex() ==
+ m_default_src_params.ColourSpecificationIndex())
+ {
+ // default colour specification
+ WriteBit(0);
+ return;
+ }
+
+ // Non-defaults
+ WriteBit(1);
+ // Output Colour specification index
+ WriteUint(m_src_params.ColourSpecificationIndex());
+
+ if (!m_src_params.ColourSpecificationIndex()) // i,e, custom values
+ {
+ // Output Colour Primaries
+ if (m_src_params.ColourPrimariesIndex() == m_default_src_params.ColourPrimariesIndex())
+ {
+ // default value
+ WriteBit(0);
+ }
+ else
+ {
+ WriteBit(1);
+ WriteUint(m_src_params.ColourPrimariesIndex());
+ }
+
+ // Output Colour Matrix
+ if (m_src_params.ColourMatrixIndex() == m_default_src_params.ColourMatrixIndex())
+ {
+ // default value
+ WriteBit(0);
+ }
+ else
+ {
+ WriteBit(1);
+ WriteUint(m_src_params.ColourMatrixIndex());
+ }
+
+ // Output TransferFunction
+ if (m_src_params.TransferFunctionIndex() == m_default_src_params.TransferFunctionIndex())
+ {
+ // default value
+ WriteBit(0);
+ }
+ else
+ {
+ WriteBit(1);
+ WriteUint(m_src_params.TransferFunctionIndex());
+ }
+ }
+}
+
+void SourceParamsByteIO::OutputFrameRate()
+{
+ if (m_src_params.FrameRateIndex()!=FRAMERATE_CUSTOM
+ && m_src_params.FrameRateIndex() == m_default_src_params.FrameRateIndex())
+ {
+ // default frame rate index
+ WriteBit(0);
+ return;
+ }
+ // Non-defaults
+ WriteBit(1);
+
+ // Picture rate index
+ WriteUint(m_src_params.FrameRateIndex());
+
+ if (!m_src_params.FrameRateIndex()) // i,e. custom value
+ {
+ WriteUint(m_src_params.FrameRate().m_num);
+ WriteUint(m_src_params.FrameRate().m_denom);
+ }
+}
+
+void SourceParamsByteIO::OutputScanFormat()
+{
+ // output 'is default' flag
+ bool not_interlace_default = m_src_params.SourceSampling()!=m_default_src_params.SourceSampling();
+
+ WriteBit(not_interlace_default);
+
+ if(!not_interlace_default)
+ return;
+
+ // output interlace value
+ WriteUint(m_src_params.SourceSampling());
+}
+
+
+void SourceParamsByteIO::OutputSignalRange()
+{
+ if (m_src_params.SignalRangeIndex()!=SIGNAL_RANGE_CUSTOM &&
+ m_src_params.SignalRangeIndex() == m_default_src_params.SignalRangeIndex())
+ {
+ // defaults
+ WriteBit(0);
+ return;
+ }
+
+ // Non-defaults
+ WriteBit(1);
+ // Output Signal Range Index
+ WriteUint(m_src_params.SignalRangeIndex());
+
+ if (!m_src_params.SignalRangeIndex()) // i.e. custom values
+ {
+ WriteUint(m_src_params.LumaOffset());
+ WriteUint(m_src_params.LumaExcursion());
+ WriteUint(m_src_params.ChromaOffset());
+ WriteUint(m_src_params.ChromaExcursion());
+ }
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.h
new file mode 100644
index 000000000..bc5fe823d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/displayparams_byteio.h
@@ -0,0 +1,200 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: displayparams_byteio.h,v 1.4 2008/01/15 04:36:23 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class SourceParamsByteIO
+*/
+#ifndef displayparams_byteio_h
+#define displayparams_byteio_h
+
+
+// DIRAC INCLUDES
+#include <libdirac_common/common.h> // SeqParams
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+
+
+namespace dirac
+{
+
+ /**
+ * Represents compressed source-parameter data contained in a sequence header
+ */
+ class SourceParamsByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor for Input/Output
+ *@param src_params Source parameters
+ *@param default_src_params Default Source parameters
+ *@param stream_data Source/Destination of data
+ */
+ SourceParamsByteIO( SourceParams& src_params,
+ const SourceParams& default_src_params,
+ const ByteIO& stream_data);
+ /**
+ * Destructor
+ */
+ ~SourceParamsByteIO();
+
+ /**
+ * Reads source params information from Dirac byte-format
+ */
+ void Input();
+
+ /**
+ * Outputs source params information to Dirac byte-format
+ */
+ void Output();
+
+ protected:
+
+
+ private:
+
+ /**
+ * Reads frame dimensions
+ */
+ void InputFrameSize();
+
+ /**
+ * Reads Chroma Sampling Format
+ */
+ void InputChromaSamplingFormat();
+
+ /**
+ * Reads pixel aspect ratio info
+ */
+ void InputPixelAspectRatio();
+
+ /**
+ * Reads clean-area info
+ */
+ void InputCleanArea();
+
+ /**
+ * Reads colour-matrix info
+ */
+ void InputColourMatrix();
+
+ /**
+ * Reads primary-colour info
+ */
+ void InputColourPrimaries();
+
+ /**
+ * Reads colour spec info
+ */
+ void InputColourSpecification();
+
+ /**
+ * Reads frame-rate info
+ */
+ void InputFrameRate();
+
+ /**
+ * Reads Scan info
+ */
+ void InputScanFormat();
+
+ /**
+ * Reads signal range info
+ */
+ void InputSignalRange();
+
+ /**
+ * Reads transfer-function info
+ */
+ void InputTransferFunction();
+
+ /**
+ * Outputs frame dimensions
+ */
+ void OutputFrameSize();
+
+ /**
+ * Outputs Chroma Sampling Format
+ */
+ void OutputChromaSamplingFormat();
+
+ /**
+ * Outputs pixel aspect ratio info
+ */
+ void OutputPixelAspectRatio();
+
+ /**
+ * Outputs clean-area info
+ */
+ void OutputCleanArea();
+
+ /**
+ * Outputs colour spec info
+ */
+ void OutputColourSpecification();
+
+ /**
+ * Outputs frame-rate info
+ */
+ void OutputFrameRate();
+
+ /**
+ * Outputs Scan info
+ */
+ void OutputScanFormat();
+
+ /**
+ * Outputs signal range info
+ */
+ void OutputSignalRange();
+
+ /**
+ * Source parameters for input/ouput
+ */
+ SourceParams& m_src_params;
+
+ /**
+ * Default source parameters
+ */
+ const SourceParams& m_default_src_params;
+ };
+
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.cpp
new file mode 100644
index 000000000..ca0144e8e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.cpp
@@ -0,0 +1,78 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: endofsequence_byteio.cpp,v 1.2 2007/03/29 16:43:38 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include "endofsequence_byteio.h"
+
+using namespace dirac;
+using namespace std;
+
+
+// start & end of end-of-sequence bits
+#define PARSE_CODE_END_OF_SEQUENCE (0x10)
+
+
+EndOfSequenceByteIO::EndOfSequenceByteIO(const ByteIO& byte_io):
+ParseUnitByteIO(byte_io)
+{
+
+}
+
+
+EndOfSequenceByteIO::~EndOfSequenceByteIO()
+{
+
+}
+
+void EndOfSequenceByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ dirac_byte_stats.SetByteCount(STAT_TOTAL_BYTE_COUNT, GetSize());
+}
+
+
+
+//-------------private-------------------------------------------------------
+
+unsigned char EndOfSequenceByteIO::CalcParseCode() const
+{
+ unsigned char code = 0;
+
+ // set end-of-sequence parse-code
+ SetBits(code, PARSE_CODE_END_OF_SEQUENCE);
+
+ return code;
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.h
new file mode 100644
index 000000000..0bce3997f
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/endofsequence_byteio.h
@@ -0,0 +1,104 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: endofsequence_byteio.h,v 1.3 2008/01/31 11:25:15 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class EndOfSequenceByteIO
+*/
+#ifndef endofsequence_byteio_h
+#define endofsequence_byteio_h
+
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/parseunit_byteio.h> // Parent class
+
+// DIRAC includes
+#include <libdirac_common/common.h> // PictureType etc
+
+namespace dirac
+{
+ /**
+ * Signals the end of a sequence in a Dirac-formatted bitstream. Current Accessunit parameters
+ * are no longer valid for subsequent frames
+ */
+ class EndOfSequenceByteIO : public ParseUnitByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param stream_data Stream parameters
+ */
+ EndOfSequenceByteIO(const ByteIO& stream_data);
+
+ /**
+ * Destructor
+ */
+ ~EndOfSequenceByteIO();
+
+
+ /**
+ * Gets parse-unit type
+ */
+ ParseUnitType GetType() const { return PU_END_OF_SEQUENCE;}
+
+ /**
+ * Gathers byte stats on the end of sequence data
+ *@param dirac_byte_stats Stat container
+ */
+ void CollateByteStats(DiracByteStats& dirac_byte_stats);
+ protected:
+
+ /**
+ * Calculates number of bytes to start of next unit
+ *@return Zero(0) End of sequence does not specify a 'next'unit
+ */
+ int CalcNextUnitOffset() { return 0;}
+
+ private:
+
+ /**
+ * Calculates parse-code based on picture parameters
+ *@return Char bit-set
+ */
+ unsigned char CalcParseCode() const;
+
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.cpp
new file mode 100644
index 000000000..2ed0357aa
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.cpp
@@ -0,0 +1,332 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mvdata_byteio.cpp,v 1.13 2008/08/27 00:17:10 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/mvdata_byteio.h>
+#include <libdirac_common/video_format_defaults.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+
+MvDataByteIO::MvDataByteIO(PictureParams& pparams,
+ PicturePredParams& picpredparams):
+ByteIO(),
+m_pparams(pparams),
+m_picpredparams(picpredparams),
+m_splitmode_data(),
+m_predmode_data(),
+m_mv1hblock_data(),
+m_mv1vblock_data(),
+m_mv2hblock_data(),
+m_mv2vblock_data(),
+m_ydcblock_data(),
+m_udcblock_data(),
+m_vdcblock_data()
+{}
+
+MvDataByteIO::MvDataByteIO(ByteIO &byte_io, PictureParams& pparams,
+ PicturePredParams& picpredparams):
+ByteIO(byte_io),
+m_pparams(pparams),
+m_picpredparams(picpredparams),
+m_splitmode_data(byte_io),
+m_predmode_data(byte_io),
+m_mv1hblock_data(byte_io),
+m_mv1vblock_data(byte_io),
+m_mv2hblock_data(byte_io),
+m_mv2vblock_data(byte_io),
+m_ydcblock_data(byte_io),
+m_udcblock_data(byte_io),
+m_vdcblock_data(byte_io)
+{}
+
+MvDataByteIO::~MvDataByteIO()
+{}
+
+void MvDataByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ // set number of MV bytes
+ dirac_byte_stats.SetByteCount(STAT_MV_BYTE_COUNT,
+ GetSize());
+}
+
+int MvDataByteIO::GetSize() const
+{
+ if (m_pparams.NumRefs()==2)
+ return ByteIO::GetSize() +
+ m_splitmode_data.GetSize()+
+ m_predmode_data.GetSize()+
+ m_mv1hblock_data.GetSize()+
+ m_mv1vblock_data.GetSize()+
+ m_mv2hblock_data.GetSize()+
+ m_mv2vblock_data.GetSize()+
+ m_ydcblock_data.GetSize()+
+ m_udcblock_data.GetSize()+
+ m_vdcblock_data.GetSize();
+ else
+ return ByteIO::GetSize() +
+ m_splitmode_data.GetSize()+
+ m_predmode_data.GetSize()+
+ m_mv1hblock_data.GetSize()+
+ m_mv1vblock_data.GetSize()+
+ m_ydcblock_data.GetSize()+
+ m_udcblock_data.GetSize()+
+ m_vdcblock_data.GetSize();
+}
+
+const std::string MvDataByteIO::GetBytes()
+{
+ //Output header and block data
+ if (m_pparams.NumRefs()==2 )
+ return ByteIO::GetBytes() +
+ m_splitmode_data.GetBytes()+
+ m_predmode_data.GetBytes()+
+ m_mv1hblock_data.GetBytes()+
+ m_mv1vblock_data.GetBytes()+
+ m_mv2hblock_data.GetBytes()+
+ m_mv2vblock_data.GetBytes()+
+ m_ydcblock_data.GetBytes()+
+ m_udcblock_data.GetBytes()+
+ m_vdcblock_data.GetBytes();
+ else
+ return ByteIO::GetBytes() +
+ m_splitmode_data.GetBytes()+
+ m_predmode_data.GetBytes()+
+ m_mv1hblock_data.GetBytes()+
+ m_mv1vblock_data.GetBytes()+
+ m_ydcblock_data.GetBytes()+
+ m_udcblock_data.GetBytes()+
+ m_vdcblock_data.GetBytes();
+}
+
+void MvDataByteIO::Input()
+{
+ // Byte Alignment
+ ByteAlignInput();
+
+ // Input Block Params
+ InputBlockParams();
+
+ // Input Motion Vector Precision
+ InputMVPrecision();
+
+ // Input chroma
+ InputGlobalMotionParams();
+
+ // Input Picture Prediction mode
+ InputFramePredictionMode();
+
+ // Input picture weights
+ InputPictureWeights();
+
+ // Byte Alignment
+ ByteAlignInput();
+}
+
+void MvDataByteIO::Output()
+{
+ // Output Block Params
+ OutputBlockParams();
+
+ // Output Motion Vector Precision
+ OutputMVPrecision();
+
+ // output global motion
+ OutputGlobalMotionParams();
+
+ // output picture prediction mode
+ OutputFramePredictionMode();
+
+ // output picture weights
+ OutputPictureWeights();
+
+ // Byte Align
+ ByteAlignOutput();
+}
+
+//-------------private---------------------------------------------------------------
+
+void MvDataByteIO::OutputBlockParams()
+{
+ const OLBParams& olb_params = m_picpredparams.LumaBParams(2);
+
+ // output custom block params flag
+ unsigned int pidx = BlockParametersIndex(olb_params);
+ WriteUint(pidx);
+ if (pidx == 0) // custom block params
+ {
+ // output Xblen
+ WriteUint(olb_params.Xblen());
+ // output Yblen
+ WriteUint(olb_params.Yblen());
+ // output Xbsep
+ WriteUint(olb_params.Xbsep());
+ // output Ybsep
+ WriteUint(olb_params.Ybsep());
+ }
+}
+
+void MvDataByteIO::InputBlockParams()
+{
+ OLBParams olb_params;
+
+ unsigned int p_idx = ReadUint();
+ if (p_idx == 0)
+ {
+ // Input Xblen
+ olb_params.SetXblen(ReadUint());
+ // Input Yblen
+ olb_params.SetYblen(ReadUint());
+ // Input Xbsep
+ olb_params.SetXbsep(ReadUint());
+ // Input Ybsep
+ olb_params.SetYbsep(ReadUint());
+ }
+ else
+ SetDefaultBlockParameters (olb_params, p_idx);
+
+ m_picpredparams.SetLumaBlockParams(olb_params);
+}
+
+void MvDataByteIO::OutputMVPrecision()
+{
+ // Output Motion vector precision
+ WriteUint(m_picpredparams.MVPrecision());
+}
+
+void MvDataByteIO::InputMVPrecision()
+{
+ // Input Motion vector precision
+ MVPrecisionType mv_prec = IntToMVPrecisionType(ReadUint());
+ if(mv_prec==MV_PRECISION_UNDEFINED)
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_MOTION_VECTOR_PRECISION,
+ "Dirac does not recognise the specified MV precision",
+ SEVERITY_PICTURE_ERROR)
+
+ m_picpredparams.SetMVPrecision(mv_prec);
+}
+
+void MvDataByteIO::OutputGlobalMotionParams()
+{
+ // Always setting global motion to false
+ // NOTE: FIXME - output actual global motion params in future
+ // Using Global motion flag
+ WriteBit(false);
+}
+
+void MvDataByteIO::InputGlobalMotionParams()
+{
+ // Always setting global motion to false
+ // Using Global motion flag
+ if (ReadBool())
+ {
+ m_picpredparams.SetUsingGlobalMotion(true);
+
+ // NOTE: FIXME - input actual global motion params in future
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ "Cannot handle global motion parameters",
+ SEVERITY_PICTURE_ERROR)
+ }
+ else
+ m_picpredparams.SetUsingGlobalMotion(false);
+}
+
+void MvDataByteIO::OutputFramePredictionMode()
+{
+ // TODO: Output default picture prediction mode index until other
+ // modes are supported.
+ WriteUint(0);
+}
+
+void MvDataByteIO::InputFramePredictionMode()
+{
+ // TODO - need to process this field when alternative prediction modes
+ // become available.
+ unsigned int frame_pred_mode = ReadUint();
+ if (frame_pred_mode != 0)
+ {
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ "Non-default Picture Prediction Mode not supported",
+ SEVERITY_PICTURE_ERROR);
+ }
+}
+
+
+void MvDataByteIO::OutputPictureWeights()
+{
+ // Output default weights flags
+ if (m_picpredparams.PictureWeightsBits() != 1 ||
+ m_picpredparams.Ref1Weight() != 1 ||
+ (m_pparams.Refs().size() > 1 && m_picpredparams.Ref2Weight() != 1) )
+ {
+ WriteBit(true);
+ // Output weight precision bits
+ WriteUint(m_picpredparams.PictureWeightsBits());
+ // Output Ref1 weight
+ WriteSint(m_picpredparams.Ref1Weight());
+ if (m_pparams.Refs().size() > 1)
+ {
+ // Output Ref1 weight
+ WriteSint(m_picpredparams.Ref2Weight());
+ }
+ }
+ else
+ {
+ WriteBit(false);
+ }
+}
+
+void MvDataByteIO::InputPictureWeights()
+{
+ if (ReadBool())
+ {
+ m_picpredparams.SetPictureWeightsPrecision(ReadUint());
+ m_picpredparams.SetRef1Weight(ReadSint());
+ if (m_pparams.Refs().size() > 1)
+ m_picpredparams.SetRef2Weight(ReadSint());
+ else
+ m_picpredparams.SetRef2Weight(0);
+ }
+ else
+ {
+ m_picpredparams.SetPictureWeightsPrecision(1);
+ m_picpredparams.SetRef1Weight(1);
+ m_picpredparams.SetRef2Weight(1);
+ }
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.h
new file mode 100644
index 000000000..578a3594e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdata_byteio.h
@@ -0,0 +1,269 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mvdata_byteio.h,v 1.5 2008/09/10 12:28:46 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class MvDataByteIO
+*/
+#ifndef MV_DATA_BYTEIO_H
+#define MV_DATA_BYTEIO_H
+
+
+// DIRAC INCLUDES
+#include <libdirac_common/common.h> // EncParams
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+#include <libdirac_byteio/mvdataelement_byteio.h>// Member byteio class
+
+
+namespace dirac
+{
+ /**
+ * Represents compressed sequence-parameter data used in an AccessUnit
+ */
+ class MvDataByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param pparams Picture Params
+ *@param picpredparams Picture prediction parameters
+ */
+ MvDataByteIO(PictureParams& pparams,
+ PicturePredParams& picpredparams);
+
+ /**
+ * Constructor
+ *@param byte_io Input/Output Byte stream
+ *@param pparams Picture Params
+ *@param picpredparams Picture prediction parameters
+ */
+ MvDataByteIO(ByteIO &byte_io, PictureParams& pparams,
+ PicturePredParams& picpredparams);
+
+ /**
+ * Destructor
+ */
+ virtual ~MvDataByteIO();
+
+ /**
+ * Gathers byte stats on the motion vector data
+ *@param dirac_byte_stats Stat container
+ */
+ void CollateByteStats(DiracByteStats& dirac_byte_stats);
+
+ /**
+ * Outputs motion vector data Dirac byte-format
+ */
+ void Output();
+
+ /**
+ * Inputs motion vector information
+ */
+ void Input();
+
+
+ /**
+ * Get string containing coded bytes
+ */
+ virtual const std::string GetBytes();
+
+ /**
+ * Return pointer to the superblock splitting modes ByteIO stream
+ */
+ MvDataElementByteIO* SplitModeData() { return &m_splitmode_data; };
+
+ /**
+ * Return pointer to the superblock splitting modes ByteIO stream
+ */
+ MvDataElementByteIO* PredModeData() { return &m_predmode_data; };
+
+ /**
+ * Return pointer to the block MVs reference 1 ByteIO stream
+ */
+ MvDataElementByteIO* MV1HorizData() { return &m_mv1hblock_data; };
+
+ /**
+ * Return pointer to the block MVs reference 1 ByteIO stream
+ */
+ MvDataElementByteIO* MV1VertData() { return &m_mv1vblock_data; };
+
+ /**
+ * Return pointer to the block MV reference 2 ByteIO stream
+ */
+ MvDataElementByteIO* MV2HorizData() { return &m_mv2hblock_data; };
+
+ /**
+ * Return pointer to the block MV reference 2 ByteIO stream
+ */
+ MvDataElementByteIO* MV2VertData() { return &m_mv2vblock_data; };
+
+ /**
+ * Return pointer to the block Y DC values ByteIO stream
+ */
+ MvDataElementByteIO* YDCData() { return &m_ydcblock_data; };
+
+ /**
+ * Return pointer to the block U DC values ByteIO stream
+ */
+ MvDataElementByteIO* UDCData() { return &m_udcblock_data; };
+
+ /**
+ * Return pointer to the block V DC values ByteIO stream
+ */
+ MvDataElementByteIO* VDCData() { return &m_vdcblock_data; };
+
+ /**
+ * Return the size
+ */
+ int GetSize() const;
+
+ protected:
+
+
+ private:
+ /**
+ * Inputs block parameters
+ */
+ void InputBlockParams();
+
+ /**
+ * Inputs Motion vector precision data
+ */
+ void InputMVPrecision();
+
+ /**
+ * Inputs global motion parameters
+ */
+ void InputGlobalMotionParams();
+
+ /**
+ * Inputs picture prediction mode
+ */
+ void InputFramePredictionMode();
+
+ /**
+ * Inputs Picture Weights
+ */
+ void InputPictureWeights();
+
+ /**
+ * Outputs block parameters
+ */
+ void OutputBlockParams();
+
+ /**
+ * Outputs Motion vector precision data
+ */
+ void OutputMVPrecision();
+
+ /**
+ * Outputs global motion parameters
+ */
+ void OutputGlobalMotionParams();
+
+ /**
+ * Outputs picture prediction mode
+ */
+ void OutputFramePredictionMode();
+
+ /**
+ * Outputs Picture Weights
+ */
+ void OutputPictureWeights();
+
+ /**
+ * Sequence paramters for intput/output
+ */
+ PictureParams& m_pparams;
+
+ /**
+ * Codec params - EncParams for Output and DecParams for input
+ */
+ PicturePredParams& m_picpredparams;
+
+ /**
+ * block data containing split modes
+ */
+ MvDataElementByteIO m_splitmode_data;
+
+ /**
+ * block data containing prediction modes
+ */
+ MvDataElementByteIO m_predmode_data;
+
+ /**
+ * block data containing horizontal MV components for reference 1
+ */
+ MvDataElementByteIO m_mv1hblock_data;
+
+ /**
+ * block data containing vertical MV components for reference 1
+ */
+ MvDataElementByteIO m_mv1vblock_data;
+
+ /**
+ * block data containing horizontal MV components for reference 2
+ */
+ MvDataElementByteIO m_mv2hblock_data;
+
+ /**
+ * block data containing vertical MV components for reference 2
+ */
+ MvDataElementByteIO m_mv2vblock_data;
+
+ /**
+ * block data containing Y DC data
+ */
+ MvDataElementByteIO m_ydcblock_data;
+
+ /**
+ * block data containing U DC data
+ */
+ MvDataElementByteIO m_udcblock_data;
+
+ /**
+ * block data containing V DC data
+ */
+ MvDataElementByteIO m_vdcblock_data;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.cpp
new file mode 100644
index 000000000..f8785616d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.cpp
@@ -0,0 +1,97 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mvdataelement_byteio.cpp,v 1.2 2007/11/16 04:48:44 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+* Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/mvdataelement_byteio.h>
+#include <libdirac_common/video_format_defaults.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+
+MvDataElementByteIO::MvDataElementByteIO():
+ByteIO(),
+m_block_data()
+{
+}
+
+MvDataElementByteIO::MvDataElementByteIO(ByteIO &byte_io):
+ByteIO(byte_io),
+m_block_data(byte_io)
+{
+}
+
+MvDataElementByteIO::~MvDataElementByteIO()
+{
+}
+
+/*
+void MvDataElementByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ // set number of MV bytes
+ dirac_byte_stats.SetByteCount(STAT_MV_BYTE_COUNT,
+ GetSize());
+}
+*/
+int MvDataElementByteIO::GetSize() const
+{
+ return ByteIO::GetSize() + m_block_data.GetSize();
+}
+
+const std::string MvDataElementByteIO::GetBytes()
+{
+ //Output header and block data
+ return ByteIO::GetBytes() + m_block_data.GetBytes();
+}
+
+void MvDataElementByteIO::Input()
+{
+ // Input block data size
+ m_block_size = ReadUint();
+
+ // Byte Alignment
+ ByteAlignInput();
+}
+
+void MvDataElementByteIO::Output()
+{
+ //Output size of block data
+ WriteUint(m_block_data.GetSize());
+
+ // Byte Align
+ ByteAlignOutput();
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.h
new file mode 100644
index 000000000..2e0aa4211
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/mvdataelement_byteio.h
@@ -0,0 +1,126 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mvdataelement_byteio.h,v 1.2 2008/12/16 01:19:30 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+* Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class MvDataElementByteIO
+*/
+#ifndef MV_DATAELEMENT_BYTEIO_H
+#define MV_DATAELEMENT_BYTEIO_H
+
+
+// DIRAC INCLUDES
+#include <libdirac_common/common.h> // EncParams
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+
+
+namespace dirac
+{
+
+ /**
+ * Represents compressed sequence-parameter data used in an AccessUnit
+ */
+ class MvDataElementByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ */
+ MvDataElementByteIO();
+
+ /**
+ * Constructor
+ *@param byte_io Input/Output Byte stream
+ */
+ MvDataElementByteIO(ByteIO &byte_io);
+
+ /**
+ * Destructor
+ */
+ virtual ~MvDataElementByteIO();
+
+ /**
+ * Outputs motion vector data Dirac byte-format
+ */
+ void Output();
+
+ /**
+ * Inputs motion vector information
+ */
+ void Input();
+
+
+ /**
+ * Get string containing coded bytes
+ */
+ virtual const std::string GetBytes();
+
+ /**
+ * Return pointer to the block data ByteIO stream
+ */
+ ByteIO* DataBlock() { return &m_block_data; };
+
+ /**
+ * Return the input block data size
+ */
+ unsigned int DataBlockSize() { return m_block_size; }
+
+ /**
+ * Return the size
+ */
+ int GetSize() const;
+
+ protected:
+
+ /**
+ * block data
+ */
+ ByteIO m_block_data;
+
+ /**
+ * In block data size
+ */
+ unsigned int m_block_size;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.cpp
new file mode 100644
index 000000000..5034933bc
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.cpp
@@ -0,0 +1,227 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: parseparams_byteio.cpp,v 1.9 2008/10/21 00:04:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <sstream> //For std::ostringstream
+#include <libdirac_byteio/parseparams_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+
+const unsigned int PP_AU_PICTURE_NUM_SIZE = 4;
+
+using namespace dirac;
+
+ParseParamsByteIO::ParseParamsByteIO( const ByteIO& stream_data,
+ ParseParams &parse_params,
+ EncoderParams &enc_params):
+ByteIO(stream_data),
+m_parse_params(parse_params)
+{
+ if (enc_params.NumL1() == 0)
+ {
+ if (!enc_params.UsingAC())
+ {
+ // Simple Profile
+ m_parse_params.SetProfile(1);
+ }
+ else
+ {
+ // Main (Intra) profile
+ m_parse_params.SetProfile(2);
+ }
+ }
+ else
+ {
+ // Main (Long GOP) profile
+ m_parse_params.SetProfile(8);
+ }
+ // FIXME - no support for Low Delay Profile
+}
+
+ParseParamsByteIO::ParseParamsByteIO( const ByteIO& stream_data,
+ ParseParams &parse_params):
+ByteIO(stream_data),
+m_parse_params(parse_params)
+{
+
+
+}
+
+ParseParamsByteIO::~ParseParamsByteIO()
+{
+}
+
+void ParseParamsByteIO::CheckVersion()
+{
+ std::ostringstream errstr;
+ ParseParams def_parse_params;
+
+ if (m_parse_params.MajorVersion() > def_parse_params.MajorVersion() ||
+ m_parse_params.MajorVersion() == 0 ||
+ (m_parse_params.MajorVersion() == def_parse_params.MajorVersion() &&
+ m_parse_params.MinorVersion() > def_parse_params.MinorVersion()))
+ {
+ errstr << "WARNING: Bitstream version is ";
+ errstr << m_parse_params.MajorVersion() << ".";
+ errstr << m_parse_params.MinorVersion() << ".";
+ errstr << " Supported version is ";
+ errstr << def_parse_params.MajorVersion() << ".";
+ errstr << def_parse_params.MinorVersion();
+ errstr << ". May not be able to decode bitstream correctly" << std::endl;
+ }
+
+ if (errstr.str().size())
+ {
+ DiracException err(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ DIRAC_LOG_EXCEPTION(err);
+ }
+}
+
+void ParseParamsByteIO::CheckProfile()
+{
+ std::ostringstream errstr;
+ ParseParams def_parse_params;
+
+ // No profiles were specified in versions 1.0, 1.1, and 2.0 and 2.1.
+ // So for these versions profile should be 0 in the bitstream
+ if (m_parse_params.MajorVersion() <= 2 &&
+ m_parse_params.MinorVersion() < 2 &&
+ m_parse_params.Profile() != 0)
+ {
+ errstr << "Cannot handle profile " << m_parse_params.Profile()
+ << " for bitstream version " << m_parse_params.MajorVersion()
+ << "." << m_parse_params.MinorVersion();
+ errstr << ". May not be able to decode bitstream correctly" << std::endl;
+ }
+ else if (m_parse_params.MajorVersion() == def_parse_params.MajorVersion() &&
+ m_parse_params.MinorVersion() == def_parse_params.MinorVersion() &&
+ m_parse_params.Profile() != 1 /* Simple */ &&
+ m_parse_params.Profile() != 2 /* Main (Intra) */ &&
+ m_parse_params.Profile() != 8 /* Main (Long GOP) */
+ )
+ {
+ errstr << "Cannot handle profile " << m_parse_params.Profile()
+ << " for bitstream version " << m_parse_params.MajorVersion()
+ << ". " << m_parse_params.MinorVersion()
+ << ". Supported profiles are 1 (Simple) "
+ << " 2 (Main Intra) and 8 (Long GOP)";
+ errstr << ". May not be able to decode bitstream correctly" << std::endl;
+ }
+
+ if (errstr.str().size())
+ {
+ DiracException err(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ DIRAC_LOG_EXCEPTION(err);
+ }
+}
+
+void ParseParamsByteIO::CheckLevel()
+{
+ std::ostringstream errstr;
+ ParseParams def_parse_params;
+
+ // No resources constraints for decoder
+ if (def_parse_params.Level() == 0)
+ return;
+
+ // Constraints on Decoder. Can Handles level 1 for Simple and Main (Intra)
+ // profiles, and level 128 for Main (Long GOP) Profile.
+ if (def_parse_params.Level() != 0)
+ {
+ if ((m_parse_params.Profile() <= 2 && m_parse_params.Level() != 1) ||
+ (m_parse_params.Profile() ==8 && m_parse_params.Level() != 128))
+ {
+ errstr << "Cannot handle Level " << m_parse_params.Level()
+ << " for bitstream version " << m_parse_params.MajorVersion()
+ << ". " << m_parse_params.MinorVersion()
+ << " Profile " << m_parse_params.Profile()
+ << ". Supported levels are 1 for Profiles 0, 1, 2 "
+ << " and 128 for Profile 8";
+ errstr << ". May not be able to decode bitstream correctly" << std::endl;
+ }
+ }
+
+ if (errstr.str().size())
+ {
+ DiracException err(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ DIRAC_LOG_EXCEPTION(err);
+ }
+ return;
+}
+
+//-------------public---------------------------------------------------------------
+
+void ParseParamsByteIO::Input()
+{
+
+ //input version
+ m_parse_params.SetMajorVersion(ReadUint());
+ m_parse_params.SetMinorVersion(ReadUint());
+
+ // input profile
+ m_parse_params.SetProfile(ReadUint());
+
+ // input level
+ m_parse_params.SetLevel(ReadUint());
+
+ CheckVersion();
+
+ CheckProfile();
+
+ CheckLevel();
+}
+
+void ParseParamsByteIO::Output()
+{
+ // output version
+ WriteUint(m_parse_params.MajorVersion());
+ WriteUint(m_parse_params.MinorVersion());
+
+ // output profile
+ WriteUint(m_parse_params.Profile());
+
+ // output level - does not conform to any defined level
+ WriteUint(m_parse_params.Level());
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.h
new file mode 100644
index 000000000..1e5423f31
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseparams_byteio.h
@@ -0,0 +1,117 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: parseparams_byteio.h,v 1.4 2008/05/07 05:47:00 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Scott R Ladd (Original Author), Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class ParseParamsByteIO
+*/
+#ifndef parseparams_byteio_h
+#define parseparams_byteio_h
+
+
+// DIRAC INCLUDES
+#include <libdirac_common/common.h> // DiracEncoder
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+
+
+namespace dirac
+{
+
+ /**
+ * Represents compressed parse-parameter data used in an AccessUnit
+ */
+ class ParseParamsByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param stream_data Destination of data
+ *@param parse_params Parse parameters
+ *@param enc_params Encoder parameters
+ */
+ ParseParamsByteIO(const ByteIO& stream_data,
+ ParseParams &parse_params,
+ EncoderParams &enc_params);
+
+ /**
+ * Constructor
+ *@param stream_data Source of data
+ *@param parse_params Destination of parse params
+ */
+ ParseParamsByteIO(const ByteIO& stream_data,
+ ParseParams &parse_params);
+
+ /**
+ * Destructor
+ */
+ ~ParseParamsByteIO();
+
+ /**
+ * Reads parse information from Dirac byte-format
+ */
+ void Input();
+
+ /**
+ * Outputs parse information to Dirac byte-format
+ */
+ void Output();
+
+ /**
+ * Get access-unit number
+ */
+ int GetIdNumber() const;
+
+ protected:
+
+ private:
+ void CheckVersion();
+ void CheckProfile();
+ void CheckLevel();
+
+ private:
+ /**
+ * Reference to parse parameters
+ */
+ ParseParams& m_parse_params;
+ };
+
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.cpp
new file mode 100644
index 000000000..56c0ebb8b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.cpp
@@ -0,0 +1,289 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: parseunit_byteio.cpp,v 1.10 2008/05/02 05:57:19 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/parseunit_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+
+#include <iomanip>
+
+using namespace dirac;
+using namespace std;
+
+// Fixed parse-prefix
+const string PU_PREFIX = "BBCD";
+
+// Parse-unit byte sizes
+const int PU_NEXT_PARSE_OFFSET_SIZE = 4;
+const int PU_PREVIOUS_PARSE_OFFSET_SIZE = 4;
+const int PU_PREFIX_SIZE = 4;
+const int PU_PARSE_CODE_SIZE = 1;
+const int PU_PARSEUNIT_SIZE = PU_NEXT_PARSE_OFFSET_SIZE + PU_PREVIOUS_PARSE_OFFSET_SIZE+
+ PU_PREFIX_SIZE + PU_PARSE_CODE_SIZE;
+
+ParseUnitByteIO::ParseUnitByteIO():
+ByteIO(),
+m_previous_parse_offset(0),
+m_next_parse_offset(0)
+{
+
+}
+
+ParseUnitByteIO::ParseUnitByteIO(const ByteIO& byte_io):
+ByteIO(byte_io),
+m_previous_parse_offset(0),
+m_next_parse_offset(0)
+{
+
+}
+
+ParseUnitByteIO::ParseUnitByteIO(const ParseUnitByteIO& parseunit_byteio):
+ByteIO(parseunit_byteio),
+m_previous_parse_offset(parseunit_byteio.m_previous_parse_offset),
+m_next_parse_offset(parseunit_byteio.m_next_parse_offset),
+m_parse_code(parseunit_byteio.m_parse_code)
+{
+}
+
+ParseUnitByteIO::~ParseUnitByteIO()
+{
+
+}
+
+
+//--------------public---------------------------------------------------------
+
+void ParseUnitByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ dirac_byte_stats.SetByteCount(STAT_TOTAL_BYTE_COUNT,
+ m_next_parse_offset);
+}
+
+bool ParseUnitByteIO::Input()
+{
+
+ // input prefix
+ if(!SyncToUnitStart())
+ return false;
+
+ // input parse code
+ m_parse_code = InputUnByte();
+
+ // input parse-offsets
+ m_next_parse_offset = ReadUintLit(PU_NEXT_PARSE_OFFSET_SIZE);
+
+ m_previous_parse_offset = ReadUintLit(PU_PREVIOUS_PARSE_OFFSET_SIZE);
+
+ return true;
+}
+
+bool ParseUnitByteIO::IsValid()
+{
+ if (IsEndOfSequence())
+ return true;
+
+ // Skip past the end of current parse unit
+ SeekGet(m_next_parse_offset-GetSize(), ios_base::cur);
+
+ // check the next series of bytes are the parse-info prefix
+ string prefix = InputUnString(PU_PREFIX_SIZE);
+
+ if(prefix==PU_PREFIX)
+ {
+ unsigned char next_parse_code;
+
+ next_parse_code = InputUnByte();
+ // input next unit parse-offsets
+ int next_unit_next_parse_offset;
+ next_unit_next_parse_offset = ReadUintLit(PU_NEXT_PARSE_OFFSET_SIZE);
+
+ int next_unit_previous_parse_offset;
+ next_unit_previous_parse_offset = ReadUintLit(PU_PREVIOUS_PARSE_OFFSET_SIZE);
+ if (next_unit_previous_parse_offset == m_next_parse_offset)
+ {
+ SeekGet(-(m_next_parse_offset-GetSize()+PU_PARSEUNIT_SIZE), ios_base::cur);
+ return true;
+ }
+ }
+ SeekGet(-(m_next_parse_offset-GetSize()), ios_base::cur);
+ return false;
+}
+
+bool ParseUnitByteIO::CanSkip()
+{
+ if(m_next_parse_offset==0 || m_next_parse_offset == GetSize())
+ return true;
+
+ // Skip past the end of current parse unit and past the header of the
+ // next unit
+ SeekGet(m_next_parse_offset-GetSize() + GetSize(), ios_base::cur);
+ if(GetReadBytePosition() >= 0)
+ {
+ SeekGet(-(m_next_parse_offset-GetSize() + GetSize()), ios_base::cur);
+ return true; // success
+ }
+
+ // end of stream reached
+ mp_stream->clear();
+
+ return false;
+}
+
+const string ParseUnitByteIO::GetBytes()
+{
+ stringstream parse_string;
+ parse_string << PU_PREFIX;
+ parse_string << CalcParseCode();
+
+ //FIXME : Need to do this properly.
+ // Write the parse offsets in Big Endian format
+ for(int i=PU_NEXT_PARSE_OFFSET_SIZE-1; i >= 0; --i)
+ {
+ unsigned char cp = (m_next_parse_offset>>(i*8)) & 0xff;
+ parse_string << cp;
+ }
+
+ for(int i=PU_PREVIOUS_PARSE_OFFSET_SIZE-1; i >= 0; --i)
+ {
+ unsigned char cp = (m_previous_parse_offset>>(i*8)) & 0xff;
+ parse_string << cp;
+ }
+
+ return parse_string.str() + ByteIO::GetBytes();
+}
+
+
+int ParseUnitByteIO::GetSize() const
+{
+ return PU_PARSEUNIT_SIZE;
+}
+
+int ParseUnitByteIO::GetNextParseOffset() const
+{
+ return m_next_parse_offset;
+}
+
+int ParseUnitByteIO::GetPreviousParseOffset() const
+{
+ return m_previous_parse_offset;
+}
+
+void ParseUnitByteIO::SetAdjacentParseUnits(ParseUnitByteIO *p_prev_parseunit)
+{
+ // set next offset
+ m_next_parse_offset = CalcNextUnitOffset();
+
+ if(!p_prev_parseunit)
+ return;
+
+ // set previous parse offset
+ m_previous_parse_offset = p_prev_parseunit->m_next_parse_offset;
+}
+
+
+ParseUnitType ParseUnitByteIO::GetType() const
+{
+ if(IsSeqHeader())
+ return PU_SEQ_HEADER;
+
+ if(IsCoreSyntax())
+ return PU_CORE_PICTURE;
+
+ if(IsLowDelay())
+ return PU_LOW_DELAY_PICTURE;
+
+ if(IsPicture())
+ return PU_PICTURE;
+
+ if(IsEndOfSequence())
+ return PU_END_OF_SEQUENCE;
+
+ if(IsAuxiliaryData())
+ return PU_AUXILIARY_DATA;
+
+ if(IsPaddingData())
+ return PU_PADDING_DATA;
+
+ return PU_UNDEFINED;
+}
+
+//------------protected-------------------------------------------------------
+
+int ParseUnitByteIO::CalcNextUnitOffset()
+{
+ // typically size of current unit
+ return GetSize();
+}
+
+bool ParseUnitByteIO::SyncToUnitStart()
+{
+ // locate parse-unit prefix
+ string byte_buffer;
+
+ while(CanRead()==true && mp_stream->tellg() >= 0)
+ {
+ // ensure current buffer length
+ if((int)byte_buffer.size() == PU_PREFIX_SIZE)
+ {
+ byte_buffer.assign(byte_buffer.substr(1,PU_PREFIX_SIZE-1));
+ }
+ // read next byte
+ byte_buffer.push_back(InputUnByte());
+
+ //look to see if we have prefix
+ if(byte_buffer==PU_PREFIX)
+ {
+ // check we can read a parse-unit
+ //int prev_pos = mp_stream->tellg();
+ mp_stream->seekg (PU_PARSEUNIT_SIZE-PU_PREFIX_SIZE, ios_base::cur);
+ int cur_pos = mp_stream->tellg();
+ if (cur_pos < 0) // past end of stream
+ {
+ mp_stream->clear();
+ return false;
+ }
+ mp_stream->seekg(-(PU_PARSEUNIT_SIZE-PU_PREFIX_SIZE), ios_base::cur);
+ return true;
+ }
+
+ }
+
+ // Clear the eof flag and throw an error.
+ mp_stream->clear();
+ return false;
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.h
new file mode 100644
index 000000000..8d7742afa
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/parseunit_byteio.h
@@ -0,0 +1,247 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: parseunit_byteio.h,v 1.11 2008/05/02 05:57:19 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class ParseUnitByteIO
+*/
+#ifndef parseunit_byteio_h
+#define parseunit_byteio_h
+
+//SYSTEM INLUDES
+#include <map> // Byte-map
+#include <string> // stores values
+
+//LOCAL INCLUDES
+#include "byteio.h" // Parent class
+
+
+namespace dirac
+{
+
+ /* Types of parse-unit */
+ typedef enum {
+ PU_SEQ_HEADER=0,
+ PU_PICTURE,
+ PU_END_OF_SEQUENCE,
+ PU_AUXILIARY_DATA,
+ PU_PADDING_DATA,
+ PU_CORE_PICTURE,
+ PU_LOW_DELAY_PICTURE,
+ PU_UNDEFINED
+ } ParseUnitType;
+
+ /**
+ * Represents a collection of data in a Dirac bytestream that can be parsed as a
+ * self-contained unit
+ */
+ class ParseUnitByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ */
+ ParseUnitByteIO();
+
+ /**
+ * Constructor
+ *@param byte_io Stream parameters
+ */
+ ParseUnitByteIO(const ByteIO& byte_io);
+
+ /**
+ * Constructor
+ *@param parseunit_byteio Parse-unit parameters
+ */
+ ParseUnitByteIO(const ParseUnitByteIO& parseunit_byteio);
+
+ /**
+ * Destructor
+ */
+ ~ParseUnitByteIO();
+
+ /**
+ * Gathers byte stats on the parse-unit data
+ *@param dirac_byte_stats Stat container
+ */
+ virtual void CollateByteStats(DiracByteStats& dirac_byte_stats);
+
+ /**
+ * Reads from byte-stream to find parse data
+ *@return <B>false</B> if not enough data in stream
+ */
+ bool Input(); // decoding
+
+ /**
+ * Accesses validity of a unit by comparing it with an adjacent unit
+ */
+ bool IsValid();
+
+ /**
+ * Can Skip past the entire parse-unit
+ *@return <B>false</B> Nothing to skip to
+ */
+ bool CanSkip();
+
+ /**
+ * Gets string containing coded bytes
+ */
+ virtual const std::string GetBytes(); // encoding
+
+ /**
+ * Set next/previous parse-unit values
+ *@param p_prev_parseunit Previous parse-unit
+ */
+ void SetAdjacentParseUnits(ParseUnitByteIO *p_prev_parseunit); // encoding
+
+ /*
+ * Gets number of bytes input/output within unit
+ */
+ virtual int GetSize() const;
+
+ /**
+ * Gets expected number of bytes to start of next parse-unit
+ */
+ int GetNextParseOffset() const;
+
+ /**
+ * Gets number of bytes to start of previous parse-unit
+ */
+ int GetPreviousParseOffset() const;
+
+ /**
+ * Gets parse-unit type
+ */
+ virtual ParseUnitType GetType() const;
+
+ /**
+ * Returns true is parse unit is a Sequence Header
+ */
+ bool IsSeqHeader() const
+ { return m_parse_code==0x00; }
+
+ /**
+ * Returns true is parse unit is an End of Sequence unit
+ */
+ bool IsEndOfSequence() const
+ { return m_parse_code==0x10; }
+
+ /**
+ * Returns true is parse unit is Auxiliary Data
+ */
+ bool IsAuxiliaryData() const
+ { return (m_parse_code&0xF8)==0x20; }
+
+ /**
+ * Returns true is parse unit is Padding data
+ */
+ bool IsPaddingData() const
+ { return m_parse_code==0x30; }
+
+ /**
+ * Returns true is parse unit is Picture data
+ */
+ bool IsPicture() const
+ { return ((m_parse_code&0x08)==0x08); }
+
+ /**
+ * Returns true is parse unit is Low Delay Sybtax unit
+ */
+ bool IsLowDelay() const
+ { return ((m_parse_code&0x88)==0x88); }
+
+ /**
+ * Returns true is parse unit is Core syntax unit
+ */
+ bool IsCoreSyntax() const
+ { return ((m_parse_code&0x88)==0x08); }
+
+ /**
+ * Returns true is parse unit uses Arithmetic coding
+ */
+ bool IsUsingAC() const
+ { return ((m_parse_code&0x48)==0x08); }
+
+ protected:
+
+ /**
+ * Calculates number of bytes to start of next unit
+ *@return Number of bytes to next unit
+ */
+ virtual int CalcNextUnitOffset();
+
+ /**
+ * Pure virtual method for calculating parse-code
+ *@return Char containing bit-set for parse-unit parameters
+ */
+ virtual unsigned char CalcParseCode() const { return 0;} // encoding
+
+ /**
+ * Locates start of parse-unit
+ *@return <B>false</B> if not enough data
+ */
+ bool SyncToUnitStart(); // decoding
+
+ /**
+ * Get parse code
+ */
+ unsigned char GetParseCode() const { return m_parse_code;}
+
+ private:
+
+ /**
+ * Number of bytes to next parse-unit
+ */
+ int m_previous_parse_offset;
+
+ /**
+ * Number of bytes to previous parse-unit
+ */
+ int m_next_parse_offset;
+
+ /**
+ * Parse-type-identifier
+ */
+ unsigned char m_parse_code;
+
+ };
+
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.cpp
new file mode 100644
index 000000000..23231bea7
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.cpp
@@ -0,0 +1,279 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_byteio.cpp,v 1.3 2008/08/14 01:58:39 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author),
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include "picture_byteio.h"
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+using namespace std;
+
+const unsigned int PP_PICTURE_NUM_SIZE = 4;
+
+const int CODE_ONE_REF_BIT = 0;
+const int CODE_TWO_REF_BIT = 1;
+const int CODE_REF_PICTURE_BIT = 2;
+const int CODE_PUTYPE_1_BIT = 3;
+const int CODE_VLC_ENTROPY_CODING_BIT = 6;
+
+// maximum number of refs allowed
+const unsigned int MAX_NUM_REFS = 2;
+
+PictureByteIO::PictureByteIO(PictureParams& frame_params,
+ int frame_num) :
+ParseUnitByteIO(),
+m_frame_params(frame_params),
+m_frame_num(frame_num),
+m_mv_data(0),
+m_transform_data(0)
+{
+
+}
+
+PictureByteIO::PictureByteIO(PictureParams& frame_params,
+ const ParseUnitByteIO& parseunit_byteio ):
+ParseUnitByteIO(parseunit_byteio),
+m_frame_params(frame_params),
+m_frame_num(0),
+m_mv_data(0),
+m_transform_data(0)
+{
+
+}
+
+
+PictureByteIO::~PictureByteIO()
+{
+ //delete block data
+ if (m_mv_data)
+ {
+ delete m_mv_data;
+ m_mv_data = 0;
+ }
+ if (m_transform_data)
+ {
+ delete m_transform_data;
+ m_transform_data = 0;
+ }
+}
+
+void PictureByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ if(m_mv_data)
+ m_mv_data->CollateByteStats(dirac_byte_stats);
+ if(m_transform_data)
+ m_transform_data->CollateByteStats(dirac_byte_stats);
+
+ ParseUnitByteIO::CollateByteStats(dirac_byte_stats);
+}
+
+bool PictureByteIO::Input()
+{
+ // set picture type
+ SetPictureType();
+ SetReferenceType();
+ SetEntropyCodingFlag();
+
+ // Use of VLC for entropy coding is supported for
+ // intra frames only
+ if (m_frame_params.GetPictureType() == INTER_PICTURE &&
+ m_frame_params.UsingAC() == false)
+ {
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ "VLC codes for entropy coding of coefficient data supported for Intra frames only",
+ SEVERITY_PICTURE_ERROR);
+ }
+
+ // input picture number
+ m_frame_num = ReadUintLit(PP_PICTURE_NUM_SIZE);
+ m_frame_params.SetPictureNum(m_frame_num);
+
+ // input reference Picture numbers
+ InputReferencePictures();
+
+ // input retired Picture numbers list
+ m_frame_params.SetRetiredPictureNum(-1);
+ if (IsRef())
+ InputRetiredPicture();
+
+ // byte align
+ ByteAlignInput();
+
+ return true;
+}
+
+const string PictureByteIO::GetBytes()
+{
+ // Write mv data
+ if(m_frame_params.PicSort().IsInter() && m_mv_data)
+ {
+ OutputBytes(m_mv_data->GetBytes());
+ }
+
+ // Write transform header
+ if (m_transform_data)
+ {
+ OutputBytes(m_transform_data->GetBytes());
+ }
+ return ParseUnitByteIO::GetBytes();
+}
+
+int PictureByteIO::GetSize() const
+{
+ int size = 0;
+ if (m_mv_data)
+ size += m_mv_data->GetSize();
+ if (m_transform_data)
+ size += m_transform_data->GetSize();
+
+ //std::cerr << "Picture Header Size=" << ByteIO::GetSize();
+ //std::cerr << "Data Size=" << size << std::endl;
+
+ return size+ParseUnitByteIO::GetSize()+ByteIO::GetSize();
+}
+
+void PictureByteIO::Output()
+{
+ // output picture number
+ WriteUintLit(m_frame_num, PP_PICTURE_NUM_SIZE);
+
+ if(m_frame_params.GetPictureType()==INTER_PICTURE)
+ {
+ // output reference picture numbers
+ const std::vector<int>& refs = m_frame_params.Refs();
+ for(size_t i=0; i < refs.size() && i < MAX_NUM_REFS; ++i)
+ WriteSint(refs[i] - m_frame_num);
+ }
+
+ // output retired picture
+ ASSERTM (m_frame_params.GetReferenceType() == REFERENCE_PICTURE || m_frame_params.RetiredPictureNum() == -1, "Only Reference frames can retire frames");
+ if(m_frame_params.GetReferenceType() == REFERENCE_PICTURE)
+ {
+ if (m_frame_params.RetiredPictureNum() == -1)
+ WriteSint(0);
+ else
+ {
+ WriteSint (m_frame_params.RetiredPictureNum() - m_frame_num);
+ }
+ }
+ // byte align output
+ ByteAlignOutput();
+
+}
+
+
+//-------------private-------------------------------------------------------
+
+unsigned char PictureByteIO::CalcParseCode() const
+{
+ unsigned char code = 0;
+
+ int num_refs = m_frame_params.Refs().size();
+
+ if(m_frame_params.GetPictureType()==INTER_PICTURE)
+ {
+ // set number of refs
+ if(num_refs == 1)
+ SetBit(code, CODE_ONE_REF_BIT);
+ if(num_refs > 1)
+ SetBit(code, CODE_TWO_REF_BIT);
+ }
+ // set ref type
+ if(m_frame_params.GetReferenceType()==REFERENCE_PICTURE)
+ SetBit(code, CODE_REF_PICTURE_BIT);
+
+ // Set parse unit type
+ SetBit(code, CODE_PUTYPE_1_BIT);
+
+ // Set Entropy Coding type
+ if (!m_frame_params.UsingAC())
+ {
+ SetBit(code, CODE_VLC_ENTROPY_CODING_BIT);
+ }
+ return code;
+
+
+}
+
+void PictureByteIO::InputReferencePictures()
+{
+ // get number of frames referred to
+ int ref_count = NumRefs();
+
+ // get the number of these frames
+ vector<int>& refs = m_frame_params.Refs();
+ refs.resize(ref_count);
+ for(int i=0; i < ref_count; ++i)
+ refs[i]=m_frame_num+ReadSint();
+}
+
+void PictureByteIO::InputRetiredPicture()
+{
+ TESTM(IsRef(), "Retired Picture offset only set for Reference Frames");
+
+ // input retired picture offset
+ int offset = ReadSint();
+ // input retired frames
+ if (offset)
+ {
+ m_frame_params.SetRetiredPictureNum(m_frame_num + offset);
+ }
+}
+
+void PictureByteIO::SetPictureType()
+{
+ if(IsIntra())
+ m_frame_params.SetPictureType(INTRA_PICTURE);
+ else if(IsInter())
+ m_frame_params.SetPictureType(INTER_PICTURE);
+
+}
+
+void PictureByteIO::SetReferenceType()
+{
+ if(IsRef())
+ m_frame_params.SetReferenceType(REFERENCE_PICTURE);
+ else if(IsNonRef())
+ m_frame_params.SetReferenceType(NON_REFERENCE_PICTURE);
+
+}
+
+void PictureByteIO::SetEntropyCodingFlag()
+{
+ m_frame_params.SetUsingAC(IsUsingAC());
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.h
new file mode 100644
index 000000000..bdca76f40
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/picture_byteio.h
@@ -0,0 +1,208 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_byteio.h,v 1.1 2008/01/31 11:25:15 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class PictureByteIO
+*/
+#ifndef picture_byteio_h
+#define picture_byteio_h
+
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/parseunit_byteio.h> // Parent class
+#include <libdirac_byteio/mvdata_byteio.h> // Contains mvdata streams
+#include <libdirac_byteio/transform_byteio.h> // Transform header
+
+// DIRAC includes
+#include <libdirac_common/common.h> // PictureType etc
+
+
+namespace dirac
+{
+ /**
+ * A compressed picture in Dirac bytestream format
+ */
+ class PictureByteIO : public ParseUnitByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param frame_params Picture parameters
+ *@param frame_num Picture number
+ */
+ PictureByteIO(PictureParams& frame_params,
+ int frame_num);
+
+
+ /**
+ * Constructor
+ *@param frame_params Destination of data
+ *@param parseunit_byteio Source of data
+ */
+ PictureByteIO(PictureParams& frame_params,
+ const ParseUnitByteIO& parseunit_byteio);
+
+ /**
+ * Destructor
+ */
+ virtual ~PictureByteIO();
+
+ /**
+ * Gathers byte stats on the picture data
+ *@param dirac_byte_stats Stat container
+ */
+ void CollateByteStats(DiracByteStats& dirac_byte_stats);
+
+ /**
+ * Inputs data from Dirac stream-format
+ */
+ bool Input();
+
+ /**
+ * Outputs picture values to Dirac stream-format
+ */
+ void Output();
+
+
+
+ const std::string GetBytes();
+
+ int GetSize() const;
+
+ /**
+ * Gets parse-unit type
+ */
+ ParseUnitType GetType() const { return PU_PICTURE;}
+
+ /**
+ * Returns true is picture in Reference picture
+ */
+ int IsRef() const { return (GetParseCode()&0x0C)==0x0C;}
+
+ /**
+ * Returns true is picture in Non-Reference picture
+ */
+ int IsNonRef() const { return (GetParseCode()&0x0C)==0x08;}
+
+ /**
+ * Gets parse-unit type
+ */
+ int NumRefs() const { return (GetParseCode()&0x03);}
+
+ /**
+ * Returns true is picture is Intra picture
+ */
+ bool IsIntra() const { return IsPicture() && (NumRefs()==0) ; }
+
+ /**
+ * Returns true is picture is Inter picture
+ */
+ bool IsInter() const { return IsPicture() && (NumRefs()>0) ; }
+
+ /***
+ * Sets the MVDataIO
+ */
+ void SetMvData(MvDataByteIO *mv_data) {m_mv_data = mv_data; }
+
+ /***
+ * Sets the TransformByteIo
+ */
+ void SetTransformData(TransformByteIO *transform_data) {m_transform_data = transform_data; }
+
+ protected:
+
+
+ private:
+
+ /**
+ * Calculates parse-code based on picture parameters
+ *@return Char bit-set
+ */
+ unsigned char CalcParseCode() const;
+
+ /**
+ * Reads reference-picture data
+ */
+ void InputReferencePictures();
+
+ /**
+ * Reads retired picture number
+ */
+ void InputRetiredPicture();
+
+ /**
+ * Calculates picture-type (eg INTRA/INTER) of picture
+ */
+ void SetPictureType();
+
+ /**
+ * Calculates reference-type of picture
+ */
+ void SetReferenceType();
+
+ /**
+ * Sets the entropy coding flag in the picture parameters
+ */
+ void SetEntropyCodingFlag();
+
+ /**
+ * Picture parameters
+ */
+ PictureParams& m_frame_params;
+
+ /**
+ * Picture number
+ */
+ int m_frame_num;
+
+ /**
+ * MV data
+ */
+ MvDataByteIO * m_mv_data;
+
+ /**
+ * Transform data
+ */
+ TransformByteIO * m_transform_data;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.cpp
new file mode 100644
index 000000000..63d0607b9
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.cpp
@@ -0,0 +1,137 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: subband_byteio.cpp,v 1.4 2008/04/29 08:51:52 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/subband_byteio.h>
+
+using namespace dirac;
+using namespace std;
+
+SubbandByteIO::SubbandByteIO(Subband& sub_band,
+ const ByteIO& byteio):
+ByteIO(byteio),
+m_subband(sub_band),
+m_band_data_length(0)
+{
+
+}
+
+SubbandByteIO::SubbandByteIO(Subband& sub_band):
+ByteIO(),
+m_subband(sub_band),
+m_band_data_length(0)
+{
+
+}
+
+SubbandByteIO::~SubbandByteIO()
+{
+
+}
+
+//--------------public----------------------------------------------
+
+bool SubbandByteIO::Input()
+{
+ // read length of Arith-coded data block
+ m_band_data_length = ReadUint();
+
+ // set skip flag if no data
+ m_subband.SetSkip(m_band_data_length==0 ? true : false);
+
+ // check for zero-length sub-band
+ if(m_subband.Skipped())
+ {
+ ByteAlignInput();
+ return true;
+ }
+
+ // If we're not skipped, we need a quantisation index for the subband
+ m_subband.SetQuantIndex(ReadUint() );
+
+ if ( !m_subband.UsingMultiQuants() )
+ {
+ // Propogate the quantiser index to all the code blocks if we
+ // don't have multiquants
+ for ( int j=0 ; j<m_subband.GetCodeBlocks().LengthY() ; ++j )
+ for ( int i=0 ; i<m_subband.GetCodeBlocks().LengthX() ; ++i )
+ m_subband.GetCodeBlocks()[j][i].SetQuantIndex( m_subband.QuantIndex() );
+ }
+
+ // byte align
+ ByteAlignInput();
+ //int f=mp_stream->tellg();
+
+ return true;
+}
+
+int SubbandByteIO::GetBandDataLength() const
+{
+ return m_band_data_length;
+}
+
+const string SubbandByteIO::GetBytes()
+{
+ ByteIO byte_io;
+
+ ByteAlignOutput();
+
+ // output size
+ byte_io.WriteUint(GetSize());
+
+ // check for zero-length sub-band
+ if(GetSize()==0)
+ {
+ byte_io.ByteAlignOutput();
+ return byte_io.GetBytes();
+ }
+
+ // output quantisation
+ byte_io.WriteUint(m_subband.QuantIndex());
+
+ // byte align
+ byte_io.ByteAlignOutput();
+
+ //std::cerr << "Subband hdr size=" << byte_io.GetSize();
+ //std::cerr << " Arithdata size=" << this->GetSize()<< std::endl;
+
+ return byte_io.GetBytes()+ByteIO::GetBytes();
+}
+
+
+
+//-------------private-------------------------------------------------------
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.h
new file mode 100644
index 000000000..88d03cf87
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/subband_byteio.h
@@ -0,0 +1,115 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: subband_byteio.h,v 1.1 2006/04/20 10:41:56 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class SubbandByteIO
+*/
+#ifndef subband_byteio_h
+#define subband_byteio_h
+
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+
+// DIRAC includes
+#include <libdirac_common/wavelet_utils.h> // Subband class
+
+namespace dirac
+{
+ /**
+ * Subband Dirac-bytestream input/output
+ */
+ class SubbandByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Constructor
+ *@param sub_band Corresponding Subband
+ *@param byteio Source/Destination of data
+ */
+ SubbandByteIO(Subband& sub_band,
+ const ByteIO& byteio);
+
+
+ /* Constructor
+ *@param sub_band Corresponding Subband
+ *@param byteio Source/Destination of data
+ */
+ SubbandByteIO(Subband& sub_band);
+
+ /**
+ * Destructor
+ */
+ ~SubbandByteIO();
+
+ /**
+ * Inputs data from Dirac stream-format
+ */
+ bool Input();
+
+
+ /**
+ * Gets number of bytes in Arith-coded data block
+ */
+ int GetBandDataLength() const;
+
+ /**
+ * Gets subband bytes in Dirac-bytestream format
+ */
+ const std::string GetBytes();
+
+
+ protected:
+
+
+ private:
+
+ /**
+ * Sub-band that is inputed/outputed
+ */
+ Subband& m_subband;
+
+ /**
+ * Number of bytes in arith-coded data block
+ */
+ int m_band_data_length;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.cpp
new file mode 100644
index 000000000..6eba5a31d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.cpp
@@ -0,0 +1,169 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: transform_byteio.cpp,v 1.10 2008/01/31 11:25:15 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_byteio/transform_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+
+TransformByteIO::TransformByteIO(PictureParams& fparams,
+ CodecParams& cparams):
+ByteIO(),
+m_fparams(fparams),
+m_cparams(cparams),
+m_default_cparams(cparams.GetVideoFormat(), fparams.GetPictureType(), fparams.Refs().size(), true)
+{
+}
+
+TransformByteIO::TransformByteIO(ByteIO &byte_io,
+ PictureParams& fparams,
+ CodecParams& cparams):
+ByteIO(byte_io),
+m_fparams(fparams),
+m_cparams(cparams),
+m_default_cparams(cparams.GetVideoFormat(), fparams.GetPictureType(), fparams.Refs().size(), true)
+{
+}
+
+TransformByteIO::~TransformByteIO()
+{
+ for(size_t index=0; index < m_component_list.size(); ++index)
+ delete m_component_list[index];
+}
+
+void TransformByteIO::CollateByteStats(DiracByteStats& dirac_byte_stats)
+{
+ // set number of component bytes
+ for(size_t index=0; index < m_component_list.size(); ++index)
+ m_component_list[index]->CollateByteStats(dirac_byte_stats);
+}
+
+int TransformByteIO::GetSize() const
+{
+ //std::cerr << "Transform Size=" << ByteIO::GetSize() << std::endl;
+ int size=0;
+ for(size_t index=0; index < m_component_list.size(); ++index)
+ size += m_component_list[index]->GetSize();
+ return ByteIO::GetSize()+size;
+}
+
+const std::string TransformByteIO::GetBytes()
+{
+ std::string bytes;
+ for(size_t index=0; index < m_component_list.size(); ++index)
+ bytes += m_component_list[index]->GetBytes();
+ return ByteIO::GetBytes()+bytes;
+}
+
+void TransformByteIO::Output()
+{
+ // Zero Transform flag - applies only to inter frames
+ if (m_fparams.PicSort().IsInter())
+ WriteBit(false);
+ // Wavelet index
+ WriteUint(m_cparams.TransformFilter());
+
+ // Wavelet Depth
+ WriteUint(m_cparams.TransformDepth());
+
+ // Spatial Partition flag
+ WriteBit(m_cparams.SpatialPartition());
+ if (m_cparams.SpatialPartition())
+ {
+ for (unsigned int i = 0; i <= m_cparams.TransformDepth(); ++i)
+ {
+ const CodeBlocks &cb = m_cparams.GetCodeBlocks(i);
+ // Number of Horizontal code blocks for level i
+ WriteUint(cb.HorizontalCodeBlocks());
+ // Number of Vertical code block for level i
+ WriteUint(cb.VerticalCodeBlocks());
+ }
+ // Code block mode index
+ WriteUint(m_cparams.GetCodeBlockMode());
+ }
+ // Flush output for bend alignment
+ ByteAlignOutput();
+}
+
+void TransformByteIO::Input()
+{
+ // Byte Alignment
+ ByteAlignInput();
+
+ m_cparams.SetZeroTransform(false);
+ // Zero transform flag - applies only for inter frames
+ if (m_fparams.PicSort().IsInter())
+ m_cparams.SetZeroTransform(ReadBool());
+
+ if (m_cparams.ZeroTransform())
+ return;
+
+ // Transform filter
+ m_cparams.SetTransformFilter(ReadUint());
+
+ // transform depth
+ m_cparams.SetTransformDepth(ReadUint());
+
+ // Spatial partition flag
+ m_cparams.SetSpatialPartition(ReadBool());
+
+ if (m_cparams.SpatialPartition())
+ {
+ // Input number of code blocks for each level
+ for (unsigned int i = 0; i <= m_cparams.TransformDepth(); ++i)
+ {
+ // number of horizontal code blocks for level i
+ unsigned int hblocks = ReadUint();
+ // number of vertical code blocks for level i
+ unsigned int vblocks = ReadUint();
+ m_cparams.SetCodeBlocks(i, hblocks, vblocks);
+ }
+ // Code block mode index
+ m_cparams.SetCodeBlockMode(ReadUint());
+ }
+ // Byte Alignment
+ ByteAlignInput();
+}
+
+void TransformByteIO::AddComponent(ComponentByteIO* component_byteio)
+{
+ m_component_list.push_back(component_byteio);
+}
+
+
+//-------------private---------------------------------------------------------------
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.h
new file mode 100644
index 000000000..6fa1c0c5f
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_byteio/transform_byteio.h
@@ -0,0 +1,146 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: transform_byteio.h,v 1.2 2008/01/31 11:25:15 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Definition of class TransformByteIO
+*/
+#ifndef TRANSFORM_BYTEIO_H
+#define TRANSFORM_BYTEIO_H
+
+// DIRAC INCLUDES
+#include <libdirac_common/common.h> // EncParams
+
+//LOCAL INCLUDES
+#include <libdirac_byteio/byteio.h> // Parent class
+#include <libdirac_byteio/component_byteio.h> // Contains tranform-component
+
+
+namespace dirac
+{
+
+ /**
+ * Represents compressed sequence-parameter data used in an AccessUnit
+ */
+ class TransformByteIO : public ByteIO
+ {
+ public:
+
+ /**
+ * Output Constructor
+ *@param fparams Picture parameters
+ *@param c_params Codec params
+ */
+ TransformByteIO(PictureParams& fparams,
+ CodecParams& c_params);
+
+ /**
+ * Input Constructor
+ *@param byte_io ByteIO object for copy constructor
+ *@param fparams Picture parameters
+ *@param c_params Codec params
+ */
+ TransformByteIO(ByteIO &byte_io, PictureParams& fparams,
+ CodecParams& c_params);
+
+ /**
+ * Destructor
+ */
+ virtual ~TransformByteIO();
+
+ /**
+ * Gathers byte stats on the transform data
+ *@param dirac_byte_stats Stats container
+ */
+ void CollateByteStats(DiracByteStats& dirac_byte_stats);
+
+ /**
+ * Outputs sequence information to Dirac byte-format
+ */
+ void Output();
+
+ /**
+ * Outputs sequence information to Dirac byte-format
+ */
+ void Input();
+
+
+ /**
+ * Get string containing coded bytes
+ */
+ virtual const std::string GetBytes();
+
+ /**
+ * Return the size
+ */
+ int GetSize() const;
+
+ /**
+ * Adds a Picture-component in Dirac-bytestream format
+ *@param component_byteio Picture-component bytestream
+ */
+ void AddComponent(ComponentByteIO *component_byteio);
+
+ protected:
+
+
+ private:
+
+ /**
+ * Sequence paramters for intput/output
+ */
+ PictureParams& m_fparams;
+
+ /**
+ * Codec params - EncParams for Output and DecParams for input
+ */
+ CodecParams& m_cparams;
+
+ /**
+ * Default Codec params - EncParams for Output and DecParams for input
+ */
+ CodecParams m_default_cparams;
+
+ /***
+ * Transform Component data
+ */
+ std::vector<ComponentByteIO *> m_component_list;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.cpp
new file mode 100644
index 000000000..756ac19b5
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.cpp
@@ -0,0 +1,169 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: arith_codec.cpp,v 1.17 2007/11/16 04:48:44 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* Contributor(s): Tim Borer (Author),
+ Thomas Davies,
+ Scott R Ladd,
+ Peter Bleackley,
+ Steve Bearcroft,
+ Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/arith_codec.h>
+
+namespace dirac{
+
+ const unsigned int Context::lut[256] = {
+ //LUT corresponds to window = 16 @ p0=0.5 & 8 @ p=1.0
+ 0, 2, 5, 8, 11, 15, 20, 24,
+ 29, 35, 41, 47, 53, 60, 67, 74,
+ 82, 89, 97, 106, 114, 123, 132, 141,
+ 150, 160, 170, 180, 190, 201, 211, 222,
+ 233, 244, 256, 267, 279, 291, 303, 315,
+ 327, 340, 353, 366, 379, 392, 405, 419,
+ 433, 447, 461, 475, 489, 504, 518, 533,
+ 548, 563, 578, 593, 609, 624, 640, 656,
+ 672, 688, 705, 721, 738, 754, 771, 788,
+ 805, 822, 840, 857, 875, 892, 910, 928,
+ 946, 964, 983, 1001, 1020, 1038, 1057, 1076,
+ 1095, 1114, 1133, 1153, 1172, 1192, 1211, 1231,
+ 1251, 1271, 1291, 1311, 1332, 1352, 1373, 1393,
+ 1414, 1435, 1456, 1477, 1498, 1520, 1541, 1562,
+ 1584, 1606, 1628, 1649, 1671, 1694, 1716, 1738,
+ 1760, 1783, 1806, 1828, 1851, 1874, 1897, 1920,
+ 1935, 1942, 1949, 1955, 1961, 1968, 1974, 1980,
+ 1985, 1991, 1996, 2001, 2006, 2011, 2016, 2021,
+ 2025, 2029, 2033, 2037, 2040, 2044, 2047, 2050,
+ 2053, 2056, 2058, 2061, 2063, 2065, 2066, 2068,
+ 2069, 2070, 2071, 2072, 2072, 2072, 2072, 2072,
+ 2072, 2071, 2070, 2069, 2068, 2066, 2065, 2063,
+ 2060, 2058, 2055, 2052, 2049, 2045, 2042, 2038,
+ 2033, 2029, 2024, 2019, 2013, 2008, 2002, 1996,
+ 1989, 1982, 1975, 1968, 1960, 1952, 1943, 1934,
+ 1925, 1916, 1906, 1896, 1885, 1874, 1863, 1851,
+ 1839, 1827, 1814, 1800, 1786, 1772, 1757, 1742,
+ 1727, 1710, 1694, 1676, 1659, 1640, 1622, 1602,
+ 1582, 1561, 1540, 1518, 1495, 1471, 1447, 1422,
+ 1396, 1369, 1341, 1312, 1282, 1251, 1219, 1186,
+ 1151, 1114, 1077, 1037, 995, 952, 906, 857,
+ 805, 750, 690, 625, 553, 471, 376, 255
+ };
+
+ ArithCodecBase::ArithCodecBase(ByteIO* p_byteio, size_t number_of_contexts):
+ m_context_list( number_of_contexts ),
+ m_scount( 0 ),
+ m_byteio(p_byteio ),
+ m_decode_data_ptr( 0 )
+ {
+ // nothing needed here
+ }
+
+ ArithCodecBase::~ArithCodecBase() {
+ delete[] m_decode_data_ptr; }
+
+
+ void ArithCodecBase::InitEncoder()
+ {
+ // Set the m_code word stuff
+ m_low_code = 0;
+ m_range = 0xFFFF;
+ m_underflow = 0;
+ }
+
+ void ArithCodecBase::FlushEncoder()
+ {
+
+ // Do final renormalisation and output
+ while (((m_low_code+m_range-1)^m_low_code)<0x8000 )
+ {
+ m_byteio->WriteBit( m_low_code & 0x8000);
+ for (; m_underflow > 0; m_underflow-- )
+ m_byteio->WriteBit(~m_low_code & 0x8000);
+
+ m_low_code <<= 1;
+ m_low_code &= 0xFFFF;
+ m_range <<= 1;
+ }
+
+ while ( (m_low_code & 0x4000) && !((m_low_code+m_range-1) & 0x4000) )
+ {
+ m_underflow += 1;
+ m_low_code ^= 0x4000;
+ m_low_code <<= 1;
+ m_low_code &= 0xFFFF;
+ m_range <<= 1;
+ }
+
+ m_byteio->WriteBit(m_low_code & 0x4000);
+ while ( m_underflow >= 0 ) {
+ m_byteio->WriteBit(~m_low_code & 0x4000);
+ m_underflow -= 1; }
+
+ // byte align
+ m_byteio->ByteAlignOutput();
+ }
+
+ void ArithCodecBase::InitDecoder(int num_bytes)
+ {
+ ReadAllData(num_bytes);
+ m_input_bits_left = 8;
+
+ m_code = 0;
+ m_low_code = 0;
+
+ m_range = 0xFFFF;
+
+ m_code = 0;
+ for (int i=0; i<16; ++i)
+ {
+ m_code <<= 1;
+ m_code += InputBit();
+ }
+
+ }
+
+ int ArithCodecBase::ByteCount() const
+ {
+ return m_byteio->GetSize();
+ }
+
+ void ArithCodecBase::ReadAllData(int num_bytes)
+ {
+ if ( m_decode_data_ptr )
+ delete[] m_decode_data_ptr;
+
+ m_decode_data_ptr = new char[num_bytes+2];
+ m_byteio->InputBytes( m_decode_data_ptr , num_bytes );
+ m_decode_data_ptr[num_bytes] = (char)255;
+ m_decode_data_ptr[num_bytes+1] = (char)255;
+
+ m_data_ptr = m_decode_data_ptr;
+ }
+
+}// namespace dirac
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.h
new file mode 100644
index 000000000..72da756a4
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arith_codec.h
@@ -0,0 +1,469 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: arith_codec.h,v 1.40 2007/11/16 04:48:44 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author),
+ Thomas Davies,
+ Scott R Ladd,
+ Peter Bleackley,
+ Steve Bearcroft,
+ Anuradha Suraparaju,
+ Tim Borer (major refactor February 2006)
+ Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _ARITH_CODEC_H_
+#define _ARITH_CODEC_H_
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+//// ////
+////-----------Abstract binary arithmetic coding class---------------////
+////subclass this for coding motion vectors, subband residues etc ...////
+//// ////
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+#include <libdirac_common/common.h>
+#include <libdirac_byteio/byteio.h>
+#include <vector>
+
+namespace dirac
+{
+
+ class Context {
+ public:
+
+ //! Default Constructor.
+ /*!
+ Default constructor initialises counts to 1 each of 0 and 1.
+ */
+ inline Context();
+
+ //Class is POD
+ //Use built in copy constructor, assignment and destructor.
+
+ //! Returns estimate of probability of 0 (false) scaled to 2**16
+
+ inline unsigned int GetScaledProb0( ) const{ return m_prob0;}
+
+ //! Updates context counts
+ inline void Update( bool symbol ) {
+ if (symbol) m_prob0 -= lut[m_prob0>>8];
+ else m_prob0 += lut[255-(m_prob0>>8)];
+ }
+
+ private:
+
+ int m_prob0;
+ static const unsigned int lut[256]; //Probability update table
+ };
+
+ Context::Context(): m_prob0( 0x8000 ) {}
+
+ class ArithCodecBase {
+
+ public:
+
+ //! Constructor
+ /*!
+ Creates an ArithCodec object to decode input based on a set of
+ parameters.
+ \param p_byteio input/output for encoded bits
+ \param number_of_contexts the number of contexts used
+ */
+ ArithCodecBase(ByteIO* p_byteio, size_t number_of_contexts);
+
+ //! Destructor
+ /*!
+ Destructor is virtual as this class is abstract.
+ */
+ virtual ~ArithCodecBase();
+
+ protected:
+
+ //core encode functions
+ ////////////////////////////
+
+ //! Initialises the Encoder
+ void InitEncoder();
+
+ //! encodes a symbol and writes to output
+ void EncodeSymbol(const bool symbol, const int context_num);
+
+ void EncodeUInt(const unsigned int value, const int bin1, const int max_bin);
+
+ void EncodeSInt(const int value, const int bin1, const int max_bin);
+
+ //! flushes the output of the encoder.
+ void FlushEncoder();
+
+ int ByteCount() const;
+
+ // core decode functions
+ ////////////////////////////
+
+ //! Initialise the Decoder
+ void InitDecoder(int num_bytes);
+
+ //! Decodes a symbol given a context number
+ bool DecodeSymbol( int context_num );
+
+ unsigned int DecodeUInt(const int bin1, const int max_bin);
+
+ int DecodeSInt(const int bin1, const int max_bin);
+
+ //! List of contexts
+ std::vector<Context> m_context_list;
+
+ private:
+
+ //! private, bodyless copy constructor: class should not be copied
+ ArithCodecBase(const ArithCodecBase & cpy);
+
+ //! private, bodyless copy operator=: class should not be assigned
+ ArithCodecBase & operator = (const ArithCodecBase & rhs);
+
+
+ // Decode functions
+ ////////////////////////////
+
+ //! Read all the data in
+ void ReadAllData(int num_bytes);
+
+ //! Read in a bit of data
+ inline bool InputBit();
+
+ // Codec data
+ ////////////////////////////
+
+ unsigned int m_scount;
+
+ //! Start of the current code range
+ unsigned int m_low_code;
+
+ //! Length of the current code range
+ unsigned int m_range;
+
+ //! Input/output stream of Dirac-format bytes
+ ByteIO *m_byteio;
+
+ // For encoder only
+
+ //! Number of underflow bits
+ int m_underflow;
+
+ //! A pointer to the data for reading in
+ char* m_decode_data_ptr;
+
+ //! A point to the byte currently being read
+ char* m_data_ptr;
+
+ //! The index of the bit of the byte being read
+ int m_input_bits_left;
+
+ //! The present input code
+ unsigned int m_code;
+
+ };
+
+
+ inline bool ArithCodecBase::DecodeSymbol( int context_num )
+ {
+
+ // Determine the next symbol value by placing code within
+ // the [low,high] interval.
+
+ // Fetch the statistical context to be used
+ Context& ctx = m_context_list[context_num];
+
+ // Decode as per updated specification
+ const unsigned int count = m_code - m_low_code ;
+ const unsigned int range_x_prob = ( m_range* ctx.GetScaledProb0())>>16;
+ const bool symbol = ( count >= range_x_prob );
+
+ // Rescale the interval
+ if( symbol ) //symbol is 1
+ {
+ m_low_code += range_x_prob;
+ m_range -= range_x_prob;
+ }
+ else //symbol is 0, so m_low_code unchanged
+ {
+ m_range = range_x_prob;
+ }
+
+ // Update the statistical context
+ ctx.Update( symbol );
+
+ while ( m_range<=0x4000 )
+ {
+ if( ( (m_low_code+m_range-1)^m_low_code)>=0x8000 )
+ {
+ // Straddle condition
+ // We must have an underflow situation with
+ // low = 0x01... and high = 0x10...
+ // Flip 2nd bit prior to rescaling
+ m_code ^= 0x4000;
+ m_low_code ^= 0x4000;
+ }
+
+ // Double low and range, throw away top bit of low
+ m_low_code <<= 1;
+ m_range <<= 1;
+ m_low_code &= 0xFFFF;
+
+ // Shift in another bit of code
+ m_code <<= 1;
+ m_code += InputBit();
+ m_code &= 0xFFFF;
+
+ }
+
+ return symbol;
+ }
+
+ inline unsigned int ArithCodecBase::DecodeUInt(const int bin1, const int max_bin) {
+ const int info_ctx = (max_bin+1);
+ int bin = bin1;
+ unsigned int value = 1;
+ while (!DecodeSymbol(bin)) {
+ value <<= 1;
+ if (DecodeSymbol(info_ctx)) value+=1;
+ if (bin<max_bin) bin+=1;
+ }
+ value -= 1;
+ return value;
+ }
+
+ inline int ArithCodecBase::DecodeSInt(const int bin1, const int max_bin) {
+ int value = 0;
+ const int magnitude = DecodeUInt(bin1, max_bin);
+ if (magnitude!=0) {
+ if (DecodeSymbol(max_bin+2)) value=-magnitude;
+ else value=magnitude;
+ }
+ return value;
+ }
+
+ inline void ArithCodecBase::EncodeSymbol(const bool symbol, const int context_num)
+ {
+
+ // Adjust high and low (rescale interval) based on the symbol we are encoding
+
+ Context& ctx = m_context_list[context_num];
+
+ const unsigned int range_x_prob = ( m_range* ctx.GetScaledProb0())>>16;
+
+ if ( symbol ) //symbol is 1
+ {
+ m_low_code += range_x_prob;
+ m_range -= range_x_prob;
+ }
+ else // symbol is 0, so m_low_code unchanged
+ {
+ m_range = range_x_prob;
+ }
+
+ // Update the statistical context
+ ctx.Update( symbol );
+
+ while ( m_range <= 0x4000 )
+ {
+ if ( ( (m_low_code+m_range-1)^m_low_code)>=0x8000 )
+ {
+ // Straddle condition
+ // We must have an underflow situation with
+ // low = 0x01... and high = 0x10...
+
+ m_low_code ^= 0x4000;
+ m_underflow++;
+
+ }
+ else
+ {
+ // Bits agree - output them
+ m_byteio->WriteBit( m_low_code & 0x8000);
+ for (; m_underflow > 0; m_underflow-- )
+ m_byteio->WriteBit(~m_low_code & 0x8000);
+ }
+
+ // Double low value and range
+ m_low_code <<= 1;
+ m_range <<= 1;
+
+ // keep low to 16 bits - throw out top bit
+ m_low_code &= 0xFFFF;
+
+ }
+ }
+
+ inline void ArithCodecBase::EncodeUInt(const unsigned int the_int,
+ const int bin1, const int max_bin) {
+ const int value = (the_int+1);
+ const int info_ctx = (max_bin+1);
+ int bin = bin1;
+ int top_bit = 1;
+ {
+ int max_value = 1;
+ while (value>max_value) {
+ top_bit <<= 1;
+ max_value <<= 1;
+ max_value += 1;
+ }
+ }
+ bool stop = (top_bit==1);
+ EncodeSymbol(stop, bin);
+ while (!stop) {
+ top_bit >>= 1;
+ EncodeSymbol( (value&top_bit), info_ctx);
+ if ( bin < max_bin) bin+=1;
+ stop = (top_bit==1);
+ EncodeSymbol(stop, bin);
+ }
+ }
+
+ inline void ArithCodecBase::EncodeSInt(const int value,
+ const int bin1, const int max_bin) {
+ EncodeUInt(std::abs(value), bin1, max_bin);
+ if (value != 0) {
+ EncodeSymbol( (value < 0), max_bin+2 );
+ }
+ }
+
+
+ //! Abstract binary arithmetic coding class
+ /*!
+ This is an abtract binary arithmetic encoding class, used as the base
+ for concrete classes that encode motion vectors and subband residues.
+ \param T a container (most probably, or array) type
+ */
+
+ template<class T> //T is container/array type
+ class ArithCodec
+ : public ArithCodecBase
+ {
+ public:
+
+ //! Constructor for encoding
+ /*!
+ Creates an ArithCodec object to decode input based on a set of
+ parameters.
+ \param p_byteio input/output for encoded bits
+ \param number_of_contexts the number of contexts used
+ */
+ ArithCodec(ByteIO* p_byteio, size_t number_of_contexts);
+
+
+ //! Destructor
+ /*!
+ Destructor is virtual as this class is abstract.
+ */
+ virtual ~ArithCodec() {}
+
+ //! Compresses the input and returns the number of bits written.
+ /*!
+ Compress takes a type T object (a container or array) and
+ compresses it using the abstract function DoWorkCode() which
+ is overridden in subclasses. It returns the number of
+ bits written.
+ \param in_data the input to be compressed. Non-const,
+ since the compression may be lossy.
+ */
+ int Compress(T & in_data);
+
+ //! Decompresses the bitstream and writes into the output.
+ /*!
+ Decompresses the bitstream, up to the number of bytes
+ specified and writes into the output subclasses.
+ \param out_data the output into which the decompressed data
+ is written.
+ \param num_bytes the number of bytes to be read from the
+ bitstream.
+ */
+ void Decompress(T & out_data, const int num_bytes);
+
+ protected:
+
+ //virtual encode-only functions
+ ///////////////////////////////
+
+ //! Does the work of actually coding the data
+ virtual void DoWorkCode(T & in_data) = 0;
+
+ //! virtual decode-only functions
+ ///////////////////////////////
+ virtual void DoWorkDecode(T & out_data)=0;
+ };
+
+ //Implementation - core functions
+ /////////////////////////////////
+
+ template<class T>
+ ArithCodec<T>::ArithCodec(ByteIO* p_byteio, size_t number_of_contexts):
+ ArithCodecBase(p_byteio, number_of_contexts) {}
+
+
+
+ template<class T>
+ int ArithCodec<T>::Compress(T &in_data)
+ {
+ InitEncoder();
+ DoWorkCode(in_data);
+ FlushEncoder();
+ return ByteCount();
+ }
+
+ template<class T>
+ void ArithCodec<T>::Decompress( T &out_data, const int num_bytes )
+ {
+ InitDecoder(num_bytes);
+ DoWorkDecode( out_data );
+ }
+
+ inline bool ArithCodecBase::InputBit()
+ {
+ if (m_input_bits_left == 0)
+ {
+ m_data_ptr++;
+ m_input_bits_left = 8;
+ }
+ m_input_bits_left--;
+ // MSB to LSB
+ return bool( ( (*m_data_ptr) >> m_input_bits_left ) & 1 );
+ }
+
+}// namespace dirac
+#endif
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arrays.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arrays.h
new file mode 100644
index 000000000..276ba5ef2
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/arrays.h
@@ -0,0 +1,595 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: arrays.h,v 1.21 2008/03/14 08:17:36 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Peter Meerwald (pmeerw@users.sourceforge.net)
+* Mike Ferenduros (mike_ferenzduros@users.sourceforge.net)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ARRAYS_H_
+#define _ARRAYS_H_
+
+//basic array types used for pictures etc
+
+#include <memory>
+#include <cstddef>
+#include <stdexcept>
+#include <iostream>
+#include <algorithm>
+#include <cstring>
+
+namespace dirac
+{
+ //! Range type.
+ /*!
+ Range type encapsulating a closed range of values [first,last].
+ Used to initialies OneDArrays.
+ */
+ class Range
+ {
+ public:
+ //! Constructor
+ /*!
+ Constructor taking a start and an end point for the range.
+ */
+ Range(int s, int e): m_fst(s), m_lst(e){}
+
+ //! Returns the start of the range.
+ int First() const {return m_fst;}
+
+ //! Returns the end point of the range.
+ int Last() const {return m_lst;}
+
+ private:
+ int m_fst ,m_lst;
+ };
+
+ //////////////////////////////
+ //One-Dimensional Array type//
+ //////////////////////////////
+
+ //! A template class for one-dimensional arrays.
+ /*!
+ A template class for one-D arrays. Can be used wherever built-in
+ arrays are used, and eliminates the need for explicit memory
+ (de-)allocation. Also supports arrays not based at zero.
+ */
+ template <class T> class OneDArray
+ {
+ public:
+ //! Default constructor.
+ /*!
+ Default constructor produces an empty array.
+ */
+ OneDArray();
+
+ //! 'Length' constructor.
+ /*!
+ Length constructor produces a zero-based array.
+ */
+ OneDArray(const int len);
+
+ //! Range constructor
+ /*!
+ Range constructor produces an array with values indexed within the
+ range parameters.
+ \param r a range of indexing values.
+ */
+ OneDArray(const Range& r);
+
+ //! Destructor.
+ /*!
+ Destructor frees the data allocated in the constructors.
+ */
+ ~OneDArray()
+ {
+ FreePtr();
+ }
+
+ //! Copy constructor.
+ /*!
+ Copy constructor copies both data and metadata.
+ */
+ OneDArray(const OneDArray<T>& cpy);
+
+ //! Assignment=
+ /*!
+ Assignment= assigns both data and metadata.
+ */
+ OneDArray<T>& operator=(const OneDArray<T>& rhs);
+
+ //! Resize the array, throwing away the current data.
+ void Resize(int l);
+
+ //! Element access.
+ T& operator[](const int pos){return m_ptr[pos-m_first];}
+
+ //! Element access.
+ const T& operator[](const int pos) const {return m_ptr[pos-m_first];}
+
+ //! Returns the length of the array.
+ int Length() const {return m_length;}
+
+ //! Returns the index of the first element.
+ int First() const {return m_first;}
+
+ //! Returns the index of the last element.
+ int Last() const {return m_last;}
+
+ private:
+ void Init(const int len);
+
+ void Init(const Range& r);
+
+ void FreePtr();
+
+ int m_first, m_last;
+ int m_length;
+ T* m_ptr;
+ };
+
+ //public member functions//
+ ///////////////////////////
+
+ template <class T>
+ OneDArray<T>::OneDArray()
+ {
+ Init(0);
+ }
+
+ template <class T>
+ OneDArray<T>::OneDArray(const int len)
+ {
+ Init(len);
+ }
+
+ template <class T>
+ OneDArray<T>::OneDArray(const Range& r)
+ {
+ Init(r);
+ }
+
+ template <class T>
+ OneDArray<T>::OneDArray(const OneDArray<T>& cpy)
+ {
+ m_first = cpy.m_first;
+ m_last = cpy.m_last;
+ m_length = m_last - m_first + 1;
+
+ if (m_first==0)
+ Init(m_length);
+ else
+ Init(Range(m_first , m_last));
+
+ memcpy( m_ptr , cpy.m_ptr , m_length * sizeof( T ) );
+ }
+
+ template <class T>
+ OneDArray<T>& OneDArray<T>::operator=(const OneDArray<T>& rhs)
+ {
+ if (&rhs != this)
+ {
+ FreePtr();
+ m_first = rhs.m_first;
+ m_last = rhs.m_last;
+ m_length = rhs.m_length;
+
+ if (m_first == 0)
+ Init(m_length);
+ else
+ Init(Range(m_first , m_last));
+
+ memcpy( m_ptr , rhs.m_ptr , m_length * sizeof( T ) );
+
+ }
+ return *this;
+ }
+
+ template <class T>
+ void OneDArray<T>::Resize(int l)
+ {
+ if (l != m_length)
+ {
+ FreePtr();
+ Init(l);
+ }
+ }
+
+ //private member functions//
+ ////////////////////////////
+
+ template <class T>
+ void OneDArray<T>::Init(const int len)
+ {
+ Range r(0 , len-1);
+
+ Init(r);
+
+ }
+
+ template <class T>
+ void OneDArray<T>::Init(const Range& r)
+ {
+
+ m_first = r.First();
+ m_last = r.Last();
+ m_length = m_last - m_first + 1;
+
+ if ( m_length>0 )
+ {
+ m_ptr = new T[ m_length ];
+ }
+ else
+ {
+ m_length = 0;
+ m_first = 0;
+ m_last = -1;
+ m_ptr = NULL;
+ }
+ }
+
+ template <class T>
+ void OneDArray<T>::FreePtr()
+ {
+ if ( m_length>0 )
+ delete[] m_ptr;
+ }
+
+
+ //////////////////////////////
+ //Two-Dimensional Array type//
+ //////////////////////////////
+
+ //! A template class for two-dimensional arrays.
+ /*!
+ A template class to do two-d arrays, so that explicit memory
+ (de-)allocation is not required. Only zero-based arrays are
+ currently supported so that access is fast. Accessing elements along
+ a row is therefore much faster than accessing them along a column.
+ Rows are contiguous in memory, so array[y][x] is equivalent to
+ array[0][x+y*LengthX()].
+ */
+ template <class T> class TwoDArray
+ {
+ typedef T* element_type;
+
+ public:
+
+ //! Default constructor.
+ /*!
+ Default constructor creates an empty array.
+ */
+ TwoDArray(){ Init(0,0); }
+
+ //! Constructor.
+ /*!
+ The constructor creates an array of given width height.
+ */
+ TwoDArray( const int height , const int width ){Init(height , width);}
+
+ //! Constructor.
+ /*!
+ The constructor creates an array of given width and length height
+ and initialises it to a value
+ */
+ TwoDArray( const int height , const int width , T val);
+
+ //! Destructor
+ /*!
+ Destructor frees the data allocated in the constructor.
+ */
+ virtual ~TwoDArray(){
+ FreeData();
+ }
+
+ //! Copy constructor.
+ /*!
+ Copy constructor copies data and metadata.
+ */
+ TwoDArray(const TwoDArray<T>& Cpy);
+
+ //! Assignment =
+ /*!
+ Assignement = assigns both data and metadata.
+ */
+ TwoDArray<T>& operator=(const TwoDArray<T>& rhs);
+
+ //! Copy Contents
+ /*!
+ Copy contents of array into output array retaining the dimensions
+ of the output array. If output array is larger that array then
+ pad with last true value.
+ Return true is copy was successful
+ */
+ bool CopyContents(TwoDArray<T>& out) const;
+
+ //! Fill contents
+ /*!
+ Initialise the array with the val provided.
+ */
+ void Fill(T val);
+
+ //! Resizes the array, deleting the current data.
+ void Resize(const int height, const int width);
+
+ //! Element access.
+ /*!
+ Accesses the rows of the arrays, which are returned in the form
+ of pointers to the row data NOT OneDArray objects.
+ */
+ inline element_type& operator[](const int pos){return m_array_of_rows[pos];}
+
+ //! Element access.
+ /*!
+ Accesses the rows of the arrays, which are returned in the form of
+ pointers to the row data NOT OneDArray objects.
+ */
+ inline const element_type& operator[](const int pos) const {return m_array_of_rows[pos];}
+
+ //! Returns the width
+ int LengthX() const { return m_length_x; }
+
+ //! Returns the height
+ int LengthY() const { return m_length_y; }
+
+ //! Returns the index of the first element of a row
+ int FirstX() const { return m_first_x; }
+
+ //! Returns the index of the first element of a column
+ int FirstY() const { return m_first_y; }
+
+ //! Returns the index of the last element of a row
+ int LastX() const { return m_last_x; }
+
+ //! Returns the index of the first element of a column
+ int LastY() const { return m_last_y; }
+
+ private:
+ //! Initialise the array
+ void Init(const int height,const int width);
+
+ //! Free all the allocated data
+ void FreeData();
+
+ int m_first_x;
+ int m_first_y;
+
+ int m_last_x;
+ int m_last_y;
+
+ int m_length_x;
+ int m_length_y;
+
+ element_type* m_array_of_rows;
+ };
+
+ //public member functions//
+ ///////////////////////////
+
+ template <class T>
+ TwoDArray<T>::TwoDArray( const int height , const int width , const T val)
+ {
+ Init( height , width );
+ std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val);
+ }
+
+ template <class T>
+ TwoDArray<T>::TwoDArray(const TwoDArray<T>& Cpy)
+ {
+ m_first_x = Cpy.m_first_x;
+ m_first_y = Cpy.m_first_y;
+ m_last_x = Cpy.m_last_x;
+ m_last_y = Cpy.m_last_y;
+
+ m_length_x = m_last_x - m_first_x + 1;
+ m_length_y = m_last_y - m_first_y + 1;
+
+ if (m_first_x == 0 && m_first_y == 0)
+ Init(m_length_y , m_length_x);
+ else{
+ //based 2D arrays not yet supported
+ }
+
+ memcpy( m_array_of_rows[0] , (Cpy.m_array_of_rows)[0] , m_length_x * m_length_y * sizeof( T ) );
+
+ }
+
+ template <class T>
+ TwoDArray<T>& TwoDArray<T>::operator=(const TwoDArray<T>& rhs)
+ {
+ if (&rhs != this)
+ {
+ FreeData();
+
+ m_first_x = rhs.m_first_x;
+ m_first_y = rhs.m_first_y;
+
+ m_last_x = rhs.m_last_x;
+ m_last_y = rhs.m_last_y;
+
+ m_length_x = m_last_x - m_first_x + 1;
+ m_length_y = m_last_y - m_first_y + 1;
+
+ if (m_first_x == 0 && m_first_y == 0)
+ Init(m_length_y , m_length_x);
+ else
+ {
+ //based 2D arrays not yet supported
+ }
+
+ memcpy( m_array_of_rows[0], (rhs.m_array_of_rows)[0], m_length_x * m_length_y * sizeof( T ) );
+
+ }
+
+ return *this;
+
+ }
+
+ template <class T>
+ bool TwoDArray<T>::CopyContents(TwoDArray<T>& out) const
+ {
+ if (&out != this)
+ {
+ int rows = std::min (m_length_y, out.m_length_y);
+ int cols = std::min (m_length_x, out.m_length_x);
+ for (int j = 0; j < rows; ++j)
+ {
+ memcpy( out.m_array_of_rows[j], m_array_of_rows[j], cols * sizeof( T )) ;
+ for (int i = cols; i <out.m_length_x; ++i)
+ out.m_array_of_rows[j][i] = out.m_array_of_rows[j][cols-1];
+ }
+ for (int j = rows; j < out.m_length_y; ++j)
+ {
+ memcpy( out.m_array_of_rows[j], out.m_array_of_rows[rows-1], out.m_length_x * sizeof( T )) ;
+ }
+ }
+ return true;
+ }
+
+ template <class T>
+ void TwoDArray<T>::Fill( T val)
+ {
+ if (m_length_x && m_length_y)
+ std::fill_n( m_array_of_rows[0], m_length_x*m_length_y, val);
+ }
+
+ template <class T>
+ void TwoDArray<T>::Resize(const int height, const int width)
+ {
+ if (height != m_length_y || width != m_length_x)
+ {
+ FreeData();
+ Init(height , width);
+ }
+ }
+
+ //private member functions//
+ ////////////////////////////
+
+ template <class T>
+ void TwoDArray<T>::Init(const int height , const int width)
+ {
+ m_length_x = width;
+ m_length_y = height;
+ m_first_x = 0;
+ m_first_y = 0;
+
+ m_last_x = m_length_x-1;
+ m_last_y = m_length_y-1;
+
+ if (m_length_y>0)
+ {
+ // allocate the array containing ptrs to all the rows
+ m_array_of_rows = new element_type[ m_length_y ];
+
+ if ( m_length_x>0 )
+ {
+ // Allocate the whole thing as a single big block
+ m_array_of_rows[0] = new T[ m_length_x * m_length_y ];
+
+ // Point the pointers
+ for (int j=1 ; j<m_length_y ; ++j)
+ m_array_of_rows[j] = m_array_of_rows[0] + j * m_length_x;
+ }
+ else
+ {
+ m_length_x = 0;
+ m_first_x = 0;
+ m_last_x = -1;
+ }
+ }
+ else
+ {
+ m_length_x = 0;
+ m_length_y = 0;
+ m_first_x = 0;
+ m_first_y = 0;
+ m_last_x = -1;
+ m_last_y = -1;
+ m_array_of_rows = NULL;
+ }
+ }
+
+ template <class T>
+ void TwoDArray<T>::FreeData()
+ {
+ if (m_length_y>0)
+ {
+ if (m_length_x>0)
+ {
+ delete[] m_array_of_rows[0];
+ }
+
+ m_length_y = m_length_x = 0;
+ // deallocate the array of rows
+ delete[] m_array_of_rows;
+ }
+ }
+
+ // Related functions
+
+ //! A function for extracting array data
+ template <class T >
+ std::ostream & operator<< (std::ostream & stream, TwoDArray<T> & array)
+ {
+ for (int j=0 ; j<array.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<array.LengthX() ; ++i)
+ {
+ stream << array[j][i] << " ";
+ }// i
+ stream << std::endl;
+ }// j
+
+ return stream;
+ }
+
+ //! A function for inserting array data
+ template <class T >
+ std::istream & operator>> (std::istream & stream, TwoDArray<T> & array)
+ {
+ for (int j=0 ; j<array.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<array.LengthX() ; ++i)
+ {
+ stream >> array[j][i];
+ }// i
+ }// j
+
+ return stream;
+ }
+
+} //namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.cpp
new file mode 100644
index 000000000..fc0e42312
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.cpp
@@ -0,0 +1,119 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: band_codec.cpp,v 1.53 2009/02/10 01:46:23 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (c) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Steve Bearcroft
+* Andrew Kennedy
+* Anuradha Suraparaju
+* David Schleef
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+// System includes
+#include <sstream>
+
+// Dirac includes
+#include <libdirac_common/band_codec.h>
+#include <libdirac_byteio/subband_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+#include <libdirac_common/band_codec_template.h>
+
+using namespace dirac;
+
+template
+GenericBandCodec<ArithCodec<CoeffArray> >::GenericBandCodec(
+ SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList & band_list,
+ int band_num,
+ const bool is_intra);
+
+
+template
+GenericIntraDCBandCodec<ArithCodec<CoeffArray> >::GenericIntraDCBandCodec(
+ SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList & band_list);
+//////////////////////////////////////////////////////////////////////////////////
+//Finally,special class incorporating prediction for the DC band of intra frames//
+//////////////////////////////////////////////////////////////////////////////////
+
+void IntraDCBandCodec::DoWorkCode(CoeffArray& in_data)
+{
+ // Residues after prediction, quantisation and inverse quantisation
+ m_dc_pred_res.Resize( m_node.Yl() , m_node.Xl() );
+ m_dc_pred_res.Fill( 0 );
+
+ BandCodec::DoWorkCode(in_data);
+}
+
+void IntraDCBandCodec::CodeCoeff( CoeffArray& in_data, const int xpos, const int ypos)
+{
+ m_nhood_nonzero = false;
+ if (ypos > m_node.Yp())
+ m_nhood_nonzero |= bool(m_dc_pred_res[ypos-1][xpos]);
+ if (xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(m_dc_pred_res[ypos][xpos-1]);
+ if (ypos > m_node.Yp() && xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(m_dc_pred_res[ypos-1][xpos-1]);
+
+ ValueType prediction = GetPrediction( in_data , xpos , ypos );
+ ValueType val = in_data[ypos][xpos] - prediction;
+ CodeVal( in_data , xpos , ypos , val );
+ m_dc_pred_res[ypos][xpos] = in_data[ypos][xpos];
+ in_data[ypos][xpos] += prediction;
+}
+
+void IntraDCBandCodec::DoWorkDecode(CoeffArray& out_data)
+{
+ // Residues after prediction, quantisation and inverse quantisation
+ m_dc_pred_res.Resize( m_node.Yl() , m_node.Xl() );
+ m_dc_pred_res.Fill( 0 );
+
+ BandCodec::DoWorkDecode(out_data);
+}
+
+void IntraDCBandCodec::DecodeCoeff( CoeffArray& out_data, const int xpos, const int ypos)
+{
+ m_nhood_nonzero = false;
+ if (ypos > m_node.Yp())
+ m_nhood_nonzero |= bool(m_dc_pred_res[ypos-1][xpos]);
+ if (xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(m_dc_pred_res[ypos][xpos-1]);
+ if (ypos > m_node.Yp() && xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(m_dc_pred_res[ypos-1][xpos-1]);
+
+ DecodeVal( out_data , xpos , ypos );
+ m_dc_pred_res[ypos][xpos] = out_data[ypos][xpos];
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.h
new file mode 100644
index 000000000..dfebb2e7f
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec.h
@@ -0,0 +1,248 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: band_codec.h,v 1.36 2009/01/21 05:18:09 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Steve Bearcroft
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _BAND_CODEC_H_
+#define _BAND_CODEC_H_
+
+#include <libdirac_common/arith_codec.h>
+#include <libdirac_common/wavelet_utils.h>
+
+
+namespace dirac
+{
+
+ class SubbandByteIO;
+
+ //Subclasses the arithmetic codec to produce a coding/decoding tool for subbands
+
+
+ //! A template class for coding and decoding wavelet subband data.
+ template<typename EntropyCodec>
+ class GenericBandCodec: public EntropyCodec
+ {
+ public:
+
+ //! Constructor
+ /*!
+ Creates a BandCodec object to encode subband data
+ \param subband_byteio input/output for the encoded bits
+ \param number_of_contexts the number of contexts used in the encoding process
+ \param band_list the set of all the subbands
+ \param band_num the number of the subband being coded
+ \param is_intra Flag indicating whether the band comes from an intra picture
+ */
+ GenericBandCodec(SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList& band_list,
+ int band_num,
+ const bool is_intra);
+
+ protected:
+ //! Code an individual quantised value and perform inverse-quantisation
+ inline void CodeVal( CoeffArray& in_data , const int xpos , const int ypos , const CoeffType val);
+
+ //! Decode an individual quantised value and perform inverse-quantisation
+ inline void DecodeVal(CoeffArray& out_data , const int xpos , const int ypos );
+
+ //! Encode the offset for a code block quantiser
+ void CodeQuantIndexOffset( const int offset );
+
+ //! Decode the offset for a code block quantiser
+ int DecodeQuantIndexOffset();
+
+ //! Set a code block area to a given value
+ inline void SetToVal( const CodeBlock& code_block , CoeffArray& coeff_data , const CoeffType val);
+
+ //! Set all block values to 0
+ virtual void ClearBlock( const CodeBlock& code_block , CoeffArray& coeff_data);
+
+ protected:
+ //functions
+ // Overridden from the base class
+ virtual void DoWorkCode(CoeffArray& in_data);
+ // Ditto
+ virtual void DoWorkDecode(CoeffArray& out_data);
+
+ virtual void CodeCoeffBlock(const CodeBlock& code_block , CoeffArray& in_data);
+ virtual void DecodeCoeffBlock(const CodeBlock& code_block , CoeffArray& out_data);
+
+ virtual void CodeCoeff(CoeffArray& in_data, const int xpos, const int ypos);
+
+ virtual void DecodeCoeff(CoeffArray& in_data, const int xpos, const int ypos);
+ //! A function for choosing the context for "follow bits"
+ inline int ChooseFollowContext( const int bin_number ) const;
+
+ //! A function for choosing the context for "information bits"
+ inline int ChooseInfoContext() const;
+
+ //! A function for choosing the context for sign bits
+ inline int ChooseSignContext(const CoeffArray& data , const int xpos , const int ypos ) const;
+
+ private:
+ //! Private, bodyless copy constructor: class should not be copied
+ GenericBandCodec(const GenericBandCodec& cpy);
+ //! Private, bodyless copy operator=: class should not be assigned
+ GenericBandCodec& operator=(const GenericBandCodec& rhs);
+
+ protected:
+
+ //! Flag indicating whether the band comes from an intra picture
+ bool m_is_intra;
+
+ //! variables
+ int m_bnum;
+
+ //! the subband being coded
+ const Subband m_node;
+
+ //! the quantisation index of the last codeblock
+ int m_last_qf_idx;
+
+ //! quantisation value
+ int m_qf;
+
+ //! reconstruction point
+ CoeffType m_offset;
+
+ //! True if neighbours non-zero
+ bool m_nhood_nonzero;
+
+ //! the parent subband
+ Subband m_pnode;
+
+ //! position of the parent coefficient
+ int m_pxpos, m_pypos;
+
+ //! True if the parent of a coeff is not zero
+ bool m_parent_notzero;
+
+ };
+
+ //! A general class for coding and decoding wavelet subband data.
+ /*!
+ A general class for coding and decoding wavelet subband data, deriving from the abstract ArithCodec class.
+ */
+ typedef GenericBandCodec<ArithCodec<CoeffArray> > BandCodec;
+ typedef BandCodec LFBandCodec;
+
+ //////////////////////////////////////////////////////////////////////////////////
+ //Finally,special class incorporating prediction for the DC band of intra frames//
+ //////////////////////////////////////////////////////////////////////////////////
+
+ //! A template class specially for coding the DC subband of Intra frames
+ template<typename EntropyCodec>
+ class GenericIntraDCBandCodec : public GenericBandCodec<EntropyCodec>
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a IntraDCBandCodec object to encode subband data
+ \param subband_byteio input/output for the encoded bits
+ \param number_of_contexts the number of contexts used in the encoding process
+ \param band_list the set of all the subbands
+ */
+ GenericIntraDCBandCodec(SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList& band_list)
+ : GenericBandCodec<EntropyCodec>(subband_byteio,number_of_contexts,
+ band_list, band_list.Length(),
+ true){}
+
+ protected:
+ //! When coding a skipped block, propegate the predicted values for future non skipped blocks
+ void ClearBlock( const CodeBlock& code_block , CoeffArray& coeff_data);
+
+ //! Prediction of a DC value from its previously coded neighbours
+ CoeffType GetPrediction(const CoeffArray& data , const int xpos , const int ypos ) const;
+
+ //! Decode codeblock of coefficients and perform DC prediction
+ void DecodeCoeffBlock(const CodeBlock& code_block , CoeffArray& out_data);
+ };
+
+
+ //! A class specially for coding the DC subband of Intra frames
+ /*!
+ A class specially for coding the DC subband of Intra frames, using
+ intra-band prediction of coefficients. It uses the abstract ArithCodec
+ class
+ */
+ class IntraDCBandCodec: public GenericIntraDCBandCodec<ArithCodec<CoeffArray> >
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a IntraDCBandCodec object to encode subband data, based on parameters
+ \param subband_byteio input/output for the encoded bits
+ \param number_of_contexts the number of contexts used in the encoding process
+ \param band_list the set of all the subbands
+ */
+ IntraDCBandCodec(SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList& band_list)
+ : GenericIntraDCBandCodec<ArithCodec<CoeffArray> >(subband_byteio,
+ number_of_contexts,
+ band_list){}
+
+
+ private:
+ //! Initialize extra data required for error-feedback DC quantization
+ void DoWorkCode(CoeffArray& in_data); //overridden from the base class
+
+ //! Ditto
+ void DoWorkDecode(CoeffArray& out_data);
+
+ //! Encode a single coefficient using error-feedback DC quantization
+ void CodeCoeff(CoeffArray& in_data, const int xpos, const int ypos);
+
+ //! Decode a single coefficient using error-feedback DC quantization
+ void DecodeCoeff(CoeffArray& out_data, const int xpos, const int ypos);
+
+ //! Private, bodyless copy constructor: class should not be copied
+ IntraDCBandCodec(const IntraDCBandCodec& cpy);
+
+ //! Private, bodyless copy operator=: class should not be assigned
+ IntraDCBandCodec& operator=(const IntraDCBandCodec& rhs);
+
+ private:
+ CoeffArray m_dc_pred_res;
+ };
+
+}// end namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec_template.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec_template.h
new file mode 100644
index 000000000..8ca94d089
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_codec_template.h
@@ -0,0 +1,557 @@
+
+#include <libdirac_common/band_codec.h>
+#include <libdirac_byteio/subband_byteio.h>
+
+using namespace dirac;
+
+//! Constructor for encoding.
+template<typename EntropyCodec>
+GenericBandCodec<EntropyCodec>::GenericBandCodec(SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList & band_list,
+ int band_num,
+ const bool is_intra):
+ EntropyCodec(subband_byteio,number_of_contexts),
+ m_is_intra(is_intra),
+ m_bnum(band_num),
+ m_node(band_list(band_num)),
+ m_last_qf_idx(m_node.QuantIndex())
+{
+ if (m_node.Parent()!=0)
+ m_pnode=band_list(m_node.Parent());
+}
+
+
+//encoding function
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::DoWorkCode(CoeffArray& in_data)
+{
+
+ const TwoDArray<CodeBlock>& block_list( m_node.GetCodeBlocks() );
+
+ // coeff blocks can be skipped only if SpatialPartitioning is
+ // enabled i.e. more than one code-block per subband
+ bool code_skip = (block_list.LengthX() > 1 || block_list.LengthY() > 1);
+ // Now loop over the blocks and code
+ for (int j=block_list.FirstY() ; j<=block_list.LastY() ; ++j)
+ {
+ CodeBlock *block = block_list[j];
+ for (int i=block_list.FirstX() ; i<=block_list.LastX() ; ++i)
+ {
+ if (code_skip)
+ EntropyCodec::EncodeSymbol(block[i].Skipped() , BLOCK_SKIP_CTX );
+ if ( !block[i].Skipped() )
+ CodeCoeffBlock( block[i] , in_data );
+ else
+ ClearBlock (block[i] , in_data);
+ }// i
+ }// j
+
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::CodeCoeffBlock( const CodeBlock& code_block , CoeffArray& in_data )
+{
+ //main coding function, using binarisation
+
+ const int xbeg = code_block.Xstart();
+ const int ybeg = code_block.Ystart();
+ const int xend = code_block.Xend();
+ const int yend = code_block.Yend();
+
+ const int qf_idx = code_block.QuantIndex();
+
+ bool has_parent = m_node.Parent() != 0;
+
+ if ( m_node.UsingMultiQuants() )
+ {
+ CodeQuantIndexOffset( qf_idx - m_last_qf_idx);
+ m_last_qf_idx = qf_idx;
+ }
+
+ m_qf = dirac_quantiser_lists.QuantFactor4( qf_idx );
+ if (m_is_intra)
+ m_offset = dirac_quantiser_lists.IntraQuantOffset4( qf_idx );
+ else
+ m_offset = dirac_quantiser_lists.InterQuantOffset4( qf_idx );
+
+ for ( int ypos=ybeg; ypos<yend ;++ypos)
+ {
+ m_pypos=(( ypos-m_node.Yp() )>>1)+m_pnode.Yp();
+ for ( int xpos=xbeg; xpos<xend ;++xpos)
+ {
+ m_pxpos=(( xpos-m_node.Xp() )>>1)+m_pnode.Xp();
+
+ m_nhood_nonzero = false;
+ if (ypos > m_node.Yp())
+ m_nhood_nonzero |= bool(in_data[ypos-1][xpos]);
+ if (xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(in_data[ypos][xpos-1]);
+ if (ypos > m_node.Yp() && xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(in_data[ypos-1][xpos-1]);
+
+ if (has_parent)
+ m_parent_notzero = static_cast<bool> ( in_data[m_pypos][m_pxpos] );
+ else
+ m_parent_notzero = false;
+
+ CodeCoeff( in_data , xpos , ypos );
+
+ }// xpos
+ }// ypos
+
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::CodeCoeff( CoeffArray& in_data, const int xpos, const int ypos)
+{
+ CodeVal( in_data , xpos , ypos , in_data[ypos][xpos] );
+}
+
+
+/*
+Coefficient magnitude value and differential quantiser index magnitude are
+coded using interleaved exp-Golomb coding for binarisation. In this scheme, a
+value N>=0 is coded by writing N+1 in binary form of a 1 followed by K other
+bits: 1bbbbbbb (adding 1 ensures there'll be a leading 1). These K bits ("info
+bits") are interleaved with K zeroes ("follow bits") each of which means
+"another bit coming", followed by a terminating 1:
+
+ 0b0b0b ...0b1
+
+(Conventional exp-Golomb coding has the K zeroes at the beginning, followed
+by the 1 i.e 00...01bb .. b, but interleaving allows the decoder to run a
+single loop and avoid counting the number of zeroes, sparing a register.)
+
+All bits are arithmetically coded. The follow bits have separate contexts
+based on position, and have different contexts from the info bits.
+*/
+
+template<typename EntropyCodec>
+inline void GenericBandCodec<EntropyCodec>::CodeVal( CoeffArray& in_data ,
+ const int xpos ,
+ const int ypos ,
+ const CoeffType val )
+{
+ unsigned int abs_val( std::abs(val) );
+ abs_val <<= 2;
+ abs_val /= m_qf;
+
+ const int N = abs_val+1;
+ int num_follow_zeroes=0;
+
+ while ( N >= (1<<num_follow_zeroes) )
+ ++num_follow_zeroes;
+ --num_follow_zeroes;
+
+ for ( int i=num_follow_zeroes-1, c=1; i>=0; --i, ++c )
+ {
+ EntropyCodec::EncodeSymbol( 0, ChooseFollowContext( c ) );
+ EntropyCodec::EncodeSymbol( N&(1<<i), ChooseInfoContext() );
+ }
+ EntropyCodec::EncodeSymbol( 1, ChooseFollowContext( num_follow_zeroes+1 ) );
+
+ in_data[ypos][xpos] = static_cast<CoeffType>( abs_val );
+
+ if ( abs_val )
+ {
+ // Must code sign bits and reconstruct
+ in_data[ypos][xpos] *= m_qf;
+ in_data[ypos][xpos] += m_offset+2;
+ in_data[ypos][xpos] >>= 2;
+
+ if ( val>0 )
+ {
+ EntropyCodec::EncodeSymbol( 0 , ChooseSignContext( in_data , xpos , ypos ) );
+ }
+ else
+ {
+ EntropyCodec::EncodeSymbol( 1 , ChooseSignContext( in_data , xpos , ypos ) );
+ in_data[ypos][xpos] = -in_data[ypos][xpos];
+ }
+ }
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::CodeQuantIndexOffset( const int offset )
+{
+
+ const int abs_val = std::abs( offset );
+
+ int N = abs_val+1;
+ int num_follow_zeroes=0;
+
+ while ( N>= (1<<num_follow_zeroes) )
+ ++num_follow_zeroes;
+ --num_follow_zeroes;
+
+ for ( int i=num_follow_zeroes-1, c=1; i>=0; --i, ++c )
+ {
+ EntropyCodec::EncodeSymbol( 0 , Q_OFFSET_FOLLOW_CTX );
+ EntropyCodec::EncodeSymbol( N&(1<<i), Q_OFFSET_INFO_CTX );
+ }
+ EntropyCodec::EncodeSymbol( 1 , Q_OFFSET_FOLLOW_CTX );
+
+ if ( abs_val )
+ {
+ if ( offset>0 )
+ EntropyCodec::EncodeSymbol( 0 , Q_OFFSET_SIGN_CTX );
+ else
+ EntropyCodec::EncodeSymbol( 1 , Q_OFFSET_SIGN_CTX );
+ }
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::DoWorkDecode( CoeffArray& out_data )
+{
+ const TwoDArray<CodeBlock>& block_list( m_node.GetCodeBlocks() );
+
+ // coeff blocks can be skipped only if SpatialPartitioning is
+ // enabled i.e. more than one code-block per subband
+ bool decode_skip= (block_list.LengthX() > 1 || block_list.LengthY() > 1);
+ // Now loop over the blocks and decode
+ for (int j=block_list.FirstY() ; j<=block_list.LastY() ; ++j)
+ {
+ CodeBlock *block = block_list[j];
+ for (int i=block_list.FirstX() ; i<=block_list.LastX() ; ++i)
+ {
+ if (decode_skip)
+ block[i].SetSkip( EntropyCodec::DecodeSymbol( BLOCK_SKIP_CTX ) );
+ if ( !block[i].Skipped() )
+ DecodeCoeffBlock( block[i] , out_data );
+ else
+ ClearBlock (block[i] , out_data);
+
+ }// i
+ }// j
+
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::DecodeCoeffBlock( const CodeBlock& code_block , CoeffArray& out_data )
+{
+
+
+ const int xbeg = code_block.Xstart();
+ const int ybeg = code_block.Ystart();
+ const int xend = code_block.Xend();
+ const int yend = code_block.Yend();
+
+ int qf_idx = m_node.QuantIndex();
+
+ bool has_parent = m_node.Parent() != 0;
+
+ if ( m_node.UsingMultiQuants() )
+ {
+ qf_idx = m_last_qf_idx+DecodeQuantIndexOffset();
+ m_last_qf_idx = qf_idx;
+ }
+
+ if (qf_idx > (int)dirac_quantiser_lists.MaxQuantIndex())
+ {
+ std::ostringstream errstr;
+ errstr << "Quantiser index out of range [0.."
+ << (int)dirac_quantiser_lists.MaxQuantIndex() << "]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ }
+
+ m_qf = dirac_quantiser_lists.QuantFactor4( qf_idx );
+
+ if (m_is_intra)
+ m_offset = dirac_quantiser_lists.IntraQuantOffset4( qf_idx );
+ else
+ m_offset = dirac_quantiser_lists.InterQuantOffset4( qf_idx );
+
+ //Work
+
+ for ( int ypos=ybeg; ypos<yend ;++ypos)
+ {
+ m_pypos=(( ypos-m_node.Yp() )>>1)+m_pnode.Yp();
+ CoeffType *p_out_data = NULL;
+ if (has_parent)
+ p_out_data = out_data[m_pypos];
+ CoeffType *c_out_data_1 = NULL;
+ if (ypos!=m_node.Yp())
+ c_out_data_1 = out_data[ypos-1];
+ CoeffType *c_out_data_2 = out_data[ypos];
+ for ( int xpos=xbeg; xpos<xend ;++xpos)
+ {
+ m_pxpos=(( xpos-m_node.Xp() )>>1)+m_pnode.Xp();
+
+ m_nhood_nonzero = false;
+ /* c_out_data_1 is the line above the current
+ * c_out_data_2 is the current line */
+ if (ypos > m_node.Yp())
+ m_nhood_nonzero |= bool(c_out_data_1[xpos]);
+ if (xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(c_out_data_2[xpos-1]);
+ if (ypos > m_node.Yp() && xpos > m_node.Xp())
+ m_nhood_nonzero |= bool(c_out_data_1[xpos-1]);
+
+ if (has_parent)
+ m_parent_notzero = ( p_out_data[m_pxpos] != 0 );
+ else
+ m_parent_notzero = false;
+
+ DecodeCoeff( out_data , xpos , ypos );
+
+ }// xpos
+ }// ypos
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::DecodeCoeff( CoeffArray& in_data, const int xpos, const int ypos)
+{
+ DecodeVal( in_data , xpos , ypos );
+}
+
+
+/*
+Coefficient magnitude value and differential quantiser index value is coded
+using interleaved exp-Golomb coding for binarisation. In this scheme, a value
+N>=0 is coded by writing N+1 in binary form of a 1 followed by K other bits:
+1bbbbbbb (adding 1 ensures there'll be a leading 1). These K bits ("info bits")
+are interleaved with K zeroes ("follow bits") each of which means "another bit
+coming", followed by a terminating 1:
+
+ 0b0b0b ...0b1
+
+(Conventional exp-Golomb coding has the K zeroes at the beginning, followed
+by the 1 i.e 00...01bb .. b, but interleaving allows the decoder to run a
+single loop and avoid counting the number of zeroes, sparing a register.)
+
+All bits are arithmetically coded. The follow bits have separate contexts
+based on position, and have different contexts from the info bits.
+*/
+template<typename EntropyCodec>
+inline void GenericBandCodec<EntropyCodec>::DecodeVal( CoeffArray& out_data , const int xpos , const int ypos )
+{
+
+ CoeffType& out_pixel = out_data[ypos][xpos];
+
+ out_pixel = 1;
+ int bit_count=1;
+
+ while ( !EntropyCodec::DecodeSymbol( ChooseFollowContext( bit_count ) ) )
+ {
+ out_pixel <<= 1;
+ out_pixel |= EntropyCodec::DecodeSymbol( ChooseInfoContext() );
+ bit_count++;
+ };
+ --out_pixel;
+
+ if ( out_pixel )
+ {
+ out_pixel *= m_qf;
+ out_pixel += m_offset+2;
+ out_pixel >>= 2;
+
+ if ( EntropyCodec::DecodeSymbol( ChooseSignContext(out_data, xpos, ypos)) )
+ out_pixel = -out_pixel;
+ }
+}
+
+template<typename EntropyCodec>
+inline int GenericBandCodec<EntropyCodec>::ChooseFollowContext( const int bin_number ) const
+{
+ //condition on neighbouring values and parent values
+
+ if (!m_parent_notzero)
+ {
+ switch ( bin_number )
+ {
+ case 1 :
+ if(m_nhood_nonzero == false)
+ return Z_FBIN1z_CTX;
+
+ return Z_FBIN1nz_CTX;
+
+ case 2 :
+ return Z_FBIN2_CTX;
+ case 3 :
+ return Z_FBIN3_CTX;
+ case 4 :
+ return Z_FBIN4_CTX;
+ case 5 :
+ return Z_FBIN5_CTX;
+ default :
+ return Z_FBIN6plus_CTX;
+ }
+ }
+ else
+ {
+ switch ( bin_number )
+ {
+ case 1 :
+ if(m_nhood_nonzero == false)
+ return NZ_FBIN1z_CTX;
+
+ return NZ_FBIN1nz_CTX;
+
+ case 2 :
+ return NZ_FBIN2_CTX;
+ case 3 :
+ return NZ_FBIN3_CTX;
+ case 4 :
+ return NZ_FBIN4_CTX;
+ case 5 :
+ return NZ_FBIN5_CTX;
+ default :
+ return NZ_FBIN6plus_CTX;
+ }
+
+ }
+
+ /* not reachable, but dumb compilers can't spot that */
+ return 0;
+}
+
+template<typename EntropyCodec>
+inline int GenericBandCodec<EntropyCodec>::ChooseInfoContext() const
+{
+ return INFO_CTX;
+}
+
+template<typename EntropyCodec>
+inline int GenericBandCodec<EntropyCodec>::ChooseSignContext( const CoeffArray& data , const int xpos , const int ypos ) const
+{
+ if ( m_node.Yp()==0 && m_node.Xp()!=0 )
+ {
+ //we're in a vertically oriented subband
+ if (ypos == 0)
+ return SIGN0_CTX;
+ else
+ {
+ if (data[ypos-1][xpos]>0)
+ return SIGN_POS_CTX;
+ else if (data[ypos-1][xpos]<0)
+ return SIGN_NEG_CTX;
+ else
+ return SIGN0_CTX;
+ }
+ }
+ else if ( m_node.Xp()==0 && m_node.Yp()!=0 )
+ {
+ //we're in a horizontally oriented subband
+ if (xpos == 0)
+ return SIGN0_CTX;
+ else
+ {
+ if ( data[ypos][xpos-1] > 0 )
+ return SIGN_POS_CTX;
+ else if ( data[ypos][xpos-1] < 0 )
+ return SIGN_NEG_CTX;
+ else
+ return SIGN0_CTX;
+ }
+ }
+ else
+ return SIGN0_CTX;
+}
+
+template<typename EntropyCodec>
+int GenericBandCodec<EntropyCodec>::DecodeQuantIndexOffset()
+{
+ int offset = 1;
+
+ while ( !EntropyCodec::DecodeSymbol( Q_OFFSET_FOLLOW_CTX ) )
+ {
+ offset <<= 1;
+ offset |= EntropyCodec::DecodeSymbol( Q_OFFSET_INFO_CTX );
+ }
+ --offset;
+
+ if ( offset )
+ {
+ if ( EntropyCodec::DecodeSymbol( Q_OFFSET_SIGN_CTX ) )
+ offset = -offset;
+ }
+ return offset;
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::SetToVal( const CodeBlock& code_block , CoeffArray& pic_data , const CoeffType val)
+{
+ for (int j=code_block.Ystart() ; j<code_block.Yend() ; j++)
+ {
+ for (int i=code_block.Xstart() ; i<code_block.Xend() ; i++)
+ {
+ pic_data[j][i] = val;
+ }// i
+ }// j
+}
+
+template<typename EntropyCodec>
+void GenericBandCodec<EntropyCodec>::ClearBlock( const CodeBlock& code_block , CoeffArray& coeff_data)
+{
+ for (int j=code_block.Ystart() ; j<code_block.Yend() ; j++)
+ {
+ CoeffType *pic = &coeff_data[j][code_block.Xstart()];
+ memset (pic, 0, (code_block.Xend()-code_block.Xstart())*sizeof(CoeffType));
+ }// j
+
+}
+
+/* Decode a single coefficient using error-feedback DC quantization */
+template<typename EntropyCodec>
+void GenericIntraDCBandCodec<EntropyCodec>::DecodeCoeffBlock(const CodeBlock& code_block , CoeffArray& out_data)
+{
+ GenericBandCodec<EntropyCodec>::DecodeCoeffBlock(code_block, out_data);
+ /* do prediction for this block */
+ for ( int ypos=code_block.Ystart() ; ypos<code_block.Yend() ; ++ypos)
+ {
+ for ( int xpos=code_block.Xstart() ; xpos<code_block.Xend() ; ++xpos)
+ {
+ out_data[ypos][xpos] += GetPrediction( out_data , xpos , ypos );
+ }
+ }
+}
+
+/* after coding a skipped DC codeblock, reconstruct in_data by predicting the values
+ * and not adding any error term (they were all skipped). This is required to correctly
+ * predict the values in the next codeblock */
+
+template<typename EntropyCodec>
+void GenericIntraDCBandCodec<EntropyCodec>::ClearBlock( const CodeBlock& code_block , CoeffArray& coeff_data)
+{
+ for (int ypos=code_block.Ystart() ; ypos<code_block.Yend() ; ++ypos)
+ {
+ for (int xpos=code_block.Xstart() ; xpos<code_block.Xend() ; ++xpos)
+ {
+ /* NB, it is correct to overwrite the old value */
+ coeff_data[ypos][xpos] = GetPrediction( coeff_data , xpos , ypos );
+ } // i
+ } // j
+}
+
+template<typename EntropyCodec>
+CoeffType GenericIntraDCBandCodec<EntropyCodec>::GetPrediction( const CoeffArray& data , const int xpos , const int ypos ) const
+{
+ /* NB, 4.5.3 integer division
+ * numbers are rounded down towards -ve infinity, differing from
+ * C's convention that rounds towards 0
+ */
+ if (ypos!=0)
+ {
+ if (xpos!=0)
+ {
+ int sum = data[ypos][xpos-1] + data[ypos-1][xpos-1] + data[ypos-1][xpos] + 3/2;
+ if (sum<0)
+ return (sum-2)/3;
+ else
+ return sum/3;
+ }
+ else
+ return data[ypos - 1][0];
+ }
+ else
+ {
+ if(xpos!=0)
+ return data[0][xpos - 1];
+ else
+ return 0;
+ }
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.cpp
new file mode 100644
index 000000000..b6ddf5337
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.cpp
@@ -0,0 +1,101 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: band_vlc.cpp,v 1.8 2009/02/10 01:46:23 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (c) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+// System includes
+#include <sstream>
+
+// Dirac includes
+#include <libdirac_common/band_vlc.h>
+#include <libdirac_byteio/subband_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+#include <libdirac_common/band_codec_template.h>
+
+using namespace dirac;
+
+ArithCodecToVLCAdapter::ArithCodecToVLCAdapter(
+ SubbandByteIO* subband_byteio,
+ size_t /*number_of_contexts*/):
+ m_byteio(subband_byteio)
+{}
+
+// encoding functions
+int ArithCodecToVLCAdapter::Compress(CoeffArray &in_data)
+{
+ DoWorkCode(in_data);
+ return m_byteio->GetSize();
+}
+
+// decoding functions
+void ArithCodecToVLCAdapter::Decompress(CoeffArray &out_data, int num_bytes)
+{
+ m_byteio->SetBitsLeft(num_bytes * 8);
+ DoWorkDecode(out_data);
+ m_byteio->FlushInputB();
+}
+
+template
+GenericBandCodec<ArithCodecToVLCAdapter>::GenericBandCodec(
+ SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList & band_list,
+ int band_num,
+ const bool is_intra);
+
+template
+GenericIntraDCBandCodec<ArithCodecToVLCAdapter>::GenericIntraDCBandCodec(
+ SubbandByteIO* subband_byteio,
+ size_t number_of_contexts,
+ const SubbandList & band_list);
+
+IntraDCBandVLC::IntraDCBandVLC(SubbandByteIO* subband_byteio,
+ const SubbandList& band_list):
+ GenericIntraDCBandCodec<ArithCodecToVLCAdapter>(subband_byteio, 0, band_list)
+{}
+
+void IntraDCBandVLC::CodeCoeff( CoeffArray& in_data ,
+ const int xpos ,
+ const int ypos )
+{
+ CoeffType val, prediction;
+
+ prediction = GetPrediction( in_data, xpos, ypos );
+ val = in_data[ypos][xpos] - prediction;
+ CodeVal( in_data , xpos , ypos , val );
+ in_data[ypos][xpos] += prediction;
+}
+
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.h
new file mode 100644
index 000000000..597802d26
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/band_vlc.h
@@ -0,0 +1,140 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: band_vlc.h,v 1.8 2009/02/09 09:44:56 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Steve Bearcroft
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _BAND_VLC_H
+#define _BAND_VLC_H
+
+#include <libdirac_common/wavelet_utils.h>
+#include <libdirac_common/band_codec.h>
+
+
+namespace dirac
+{
+
+ class SubbandByteIO;
+ class ByteIO;
+
+ /*! Abstract VLC entropy codec base class */
+ class ArithCodecToVLCAdapter
+ {
+ public:
+ /*! Constructor */
+ ArithCodecToVLCAdapter(SubbandByteIO* subband_byteio, size_t number_of_contexts);
+
+ /*! Virtual Destructor */
+ virtual ~ArithCodecToVLCAdapter(){}
+
+ /* Compresses the input and returns the number of bits written */
+ int Compress (CoeffArray &in_data);
+
+ /* Decompresses the bitstream */
+ void Decompress (CoeffArray& out_data, int num_bytes);
+
+ /* Encodes a symbol and writes to the output */
+ void EncodeSymbol(bool val, int /*context_num*/)
+ {
+ m_byteio->WriteBit(val);
+ }
+
+ /* Decodes a symbol */
+ bool DecodeSymbol(int /*context_num*/)
+ {
+ return m_byteio->ReadBoolB();
+ }
+
+ /*! Purely virtual function that does the actual encoding. Derived classes must define it */
+ virtual void DoWorkCode(CoeffArray &in_data) = 0;
+
+ /*! Purely virtual function that does the actual decoding. Derived classes must define it */
+ virtual void DoWorkDecode(CoeffArray &out_data) = 0;
+
+ protected:
+ /*! Input/output stream for Dirac-format bytes */
+ ByteIO *m_byteio;
+
+ private:
+ //! Private, bodyless copy constructor: class should not be copied
+ ArithCodecToVLCAdapter(const ArithCodecToVLCAdapter& cpy);
+ //! Private, bodyless copy operator=: class should not be assigned
+ ArithCodecToVLCAdapter& operator=(const ArithCodecToVLCAdapter& rhs);
+ };
+
+
+ //! A general class for coding and decoding wavelet subband data using variable length coding.
+ /*!
+ A general class for coding and decoding wavelet subband data using variable length coding,
+ */
+ typedef GenericBandCodec<ArithCodecToVLCAdapter> BandVLC;
+
+ //////////////////////////////////////////////////////////////////////////////////
+ //Finally,special class incorporating prediction for the DC band of intra frames//
+ //////////////////////////////////////////////////////////////////////////////////
+
+ //! A class specially for coding the DC subband of Intra frames
+ /*!
+ A class specially for coding the DC subband of Intra frames, using intra-band prediction
+ of coefficients.
+ */
+ class IntraDCBandVLC: public GenericIntraDCBandCodec<ArithCodecToVLCAdapter>
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a IntraDCBandVLC object to encode subband data, based on parameters
+ \param subband_byteio input/output for the encoded bits
+ \param band_list the set of all the subbands
+ */
+ IntraDCBandVLC(SubbandByteIO* subband_byteio,
+ const SubbandList& band_list);
+ private:
+ //! Encode a single coefficient using error-feedback DC quantization
+ void CodeCoeff(CoeffArray& in_data, const int xpos, const int ypos);
+
+ private:
+ //! Private, bodyless copy constructor: class should not be copied
+ IntraDCBandVLC (const IntraDCBandVLC& cpy);
+
+ //! Private, bodyless copy operator=: class should not be assigned
+ IntraDCBandVLC& operator=(const IntraDCBandVLC& rhs);
+ };
+
+
+}// end namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.cpp
new file mode 100644
index 000000000..aed3d145c
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.cpp
@@ -0,0 +1,454 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: bit_manager.cpp,v 1.10 2008/01/31 11:25:16 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (original author),
+* Robert Scott Ladd,
+* Tim Borer
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/bit_manager.h>
+#include <libdirac_common/common.h>
+using namespace dirac;
+
+using std::vector;
+
+////////////////
+//Output stuff//
+////////////////
+
+//Constructor
+BasicOutputManager::BasicOutputManager(std::ostream* out_data ):
+ m_num_out_bytes(0),
+ m_op_ptr(out_data)
+{
+ InitOutputStream();
+}
+
+void BasicOutputManager::InitOutputStream()
+{
+ // Set byte pointer to start of buffer
+ m_current_byte = 0;
+ // Set output mask to MSB of byte
+ m_output_mask = 0x80;
+ // Reset the output buffer
+ m_buffer.clear();
+}
+
+void BasicOutputManager::OutputSkipInterpretStartPrefixByte()
+{
+ size_t buf_size = m_buffer.size();
+ if (buf_size >=4 &&
+ m_buffer[buf_size-1] == (char)START_CODE_PREFIX_BYTE3 &&
+ m_buffer[buf_size-2] == (char)START_CODE_PREFIX_BYTE2 &&
+ m_buffer[buf_size-3] == (char)START_CODE_PREFIX_BYTE1 &&
+ m_buffer[buf_size-4] == (char)START_CODE_PREFIX_BYTE0)
+ {
+ m_buffer.push_back((char)NOT_START_CODE);
+ std::cerr << "Wrote ignore code " << std::endl;
+ }
+}
+
+void BasicOutputManager::OutputBit(const bool& bit )
+{
+ m_current_byte |= (bit ? (m_output_mask):0);
+
+ // Shift mask to next bit in the output byte
+ m_output_mask >>= 1;
+
+ if ( m_output_mask == 0 )
+ {
+ // If a whole byte has been written, write out
+ m_output_mask = 0x80;
+ m_buffer.push_back(m_current_byte);
+ OutputSkipInterpretStartPrefixByte();
+ m_current_byte = 0;
+ }
+}
+
+void BasicOutputManager::OutputBit(const bool& bit, int& count)
+{
+ OutputBit(bit);
+ count++;
+}
+
+void BasicOutputManager::OutputByte(const char& byte)
+{
+ FlushOutput();
+ m_buffer.push_back( byte );
+ OutputSkipInterpretStartPrefixByte();
+}
+
+void BasicOutputManager::OutputBytes( char* str_array )
+{
+ FlushOutput();
+ while ( *str_array != 0 )
+ {
+ m_buffer.push_back( *str_array );
+ str_array++;
+ }
+}
+
+void BasicOutputManager::OutputBytes(char* str_array,int num)
+{
+ FlushOutput();
+ for ( int i=0 ; i<num ; ++i )
+ m_buffer.push_back( str_array[i] );
+}
+
+
+void BasicOutputManager::WriteToFile()
+{
+ FlushOutput();
+ for ( vector<char>::iterator it=m_buffer.begin() ; it!=m_buffer.end() ; ++it )
+ {
+ m_op_ptr->write( &( *it ) , 1 );
+ }
+ m_num_out_bytes = m_buffer.size();
+ InitOutputStream();
+}
+
+void BasicOutputManager::FlushOutput()
+{
+ // Flush the current byte to output buffer and reset
+ if ( m_output_mask != 0x80 )
+ {
+ m_buffer.push_back( m_current_byte );
+ m_current_byte = 0;
+ m_output_mask = 0x80;
+ }
+}
+
+size_t BasicOutputManager::Size() const
+{
+ if ( m_output_mask==0x80 )
+ return m_buffer.size();
+ else
+ return m_buffer.size()+1;
+}
+
+// Unit output - a subband or the MV data, for example //
+
+UnitOutputManager::UnitOutputManager(std::ostream* out_data ):
+ m_header(out_data),
+ m_data(out_data),
+ m_unit_bytes(0),
+ m_unit_data_bytes(0),
+ m_unit_head_bytes(0)
+ {}
+
+void UnitOutputManager::WriteToFile()
+{
+ m_header.WriteToFile();
+ m_data.WriteToFile();
+
+ // after writing to file, get the number of unit bytes written
+ m_unit_data_bytes = m_data.GetNumBytes();
+ m_unit_head_bytes = m_header.GetNumBytes();
+ m_unit_bytes = m_unit_data_bytes + m_unit_head_bytes;
+
+}
+
+size_t UnitOutputManager::Size() const
+{
+ return m_data.Size()+m_header.Size();
+}
+
+FrameOutputManager::FrameOutputManager( std::ostream* out_data , int num_bands ) :
+ m_data_array( 3 , num_bands ),
+ m_comp_bytes( 3 ),
+ m_comp_hdr_bytes( 3 ),
+ m_out_stream( out_data )
+{
+ Init( num_bands );
+}
+
+FrameOutputManager::~FrameOutputManager()
+{
+ DeleteAll();
+}
+
+void FrameOutputManager::WriteToFile()
+{
+
+ // Write out the picture header
+ m_frame_header->WriteToFile();
+ m_total_bytes = m_frame_header->GetNumBytes();
+ m_header_bytes = m_frame_header->GetNumBytes();
+
+ // Write out the motion vector data
+ m_mv_data->WriteToFile();
+
+ // after writing to file, get the number of bytes written
+ m_mv_hdr_bytes = m_mv_data->GetUnitHeaderBytes();
+ m_mv_bytes = m_mv_data->GetUnitBytes();
+
+ m_total_bytes += m_mv_bytes;
+ m_header_bytes += m_mv_hdr_bytes;
+
+ // Write out the component data
+ for ( int c=0 ; c<3 ; ++c)
+ {
+
+ m_comp_hdr_bytes[c] = 0;
+ m_comp_bytes[c] = 0;
+
+ for ( int b=m_data_array.LastX() ; b>=0 ; --b)
+ {
+ m_data_array[c][b]->WriteToFile();
+ // after writing to file, get the number of bytes written
+ m_comp_hdr_bytes[c] += m_data_array[c][b]->GetUnitHeaderBytes();
+ m_comp_bytes[c] += m_data_array[c][b]->GetUnitBytes();
+ }// b
+
+ }// c
+
+ for ( int c=0 ; c<m_data_array.LengthY() ; ++c)
+ {
+ m_total_bytes += m_comp_bytes[c];
+ m_header_bytes += m_comp_hdr_bytes[c];
+ }
+}
+
+UnitOutputManager& FrameOutputManager::BandOutput( const int csort , const int band_num)
+{
+ return *( m_data_array[csort][band_num-1] );
+}
+
+const UnitOutputManager& FrameOutputManager::BandOutput( const int csort , const int band_num) const
+{
+ return *( m_data_array[csort][band_num-1] );
+}
+
+// Picture stuff
+
+
+void FrameOutputManager::Init( int num_bands )
+{
+ // Initialise output for the picture header
+ m_frame_header = new BasicOutputManager( m_out_stream );
+
+ // Initialise output for the MV data
+ m_mv_data = new UnitOutputManager( m_out_stream );
+
+ // Initialise subband outputs
+ for ( int c=0 ; c<3 ; ++c)
+ for ( int b=0 ; b<num_bands ; ++b)
+ m_data_array[c][b] = new UnitOutputManager( m_out_stream );
+}
+
+void FrameOutputManager::Reset()
+{
+ const int num_bands = m_data_array.LengthX();
+ DeleteAll();
+ Init( num_bands );
+}
+
+void FrameOutputManager::DeleteAll()
+{
+ // Delete subband outputs
+ for ( int c=0 ; c<3 ; ++c)
+ for ( int b=0 ; b<m_data_array.LengthX() ; ++b )
+ delete m_data_array[c][b];
+
+ // Delete MV data op
+ delete m_mv_data;
+
+ // Delete picture header op
+ delete m_frame_header;
+}
+
+size_t FrameOutputManager::Size() const
+{
+ size_t size = 0;
+
+ size += m_frame_header->Size();
+
+ for ( int c=0 ; c<3 ; ++c)
+ {
+ for ( int b=0 ; b<m_data_array.LengthX() ; ++b )
+ {
+ size += m_data_array[c][b]->Size();
+ }
+ }
+
+ size += m_mv_data->Size();
+
+ return size;
+}
+
+
+// Sequence stuff //
+
+SequenceOutputManager::SequenceOutputManager( std::ostream* out_data ):
+ m_frame_op_mgr( out_data ),
+ m_seq_header( out_data ),
+ m_seq_end( out_data ),
+ m_comp_bytes( 3 ),
+ m_comp_hdr_bytes( 3 ),
+ m_mv_hdr_bytes(0),
+ m_mv_bytes(0),
+ m_total_bytes(0),
+ m_header_bytes(0),
+ m_trailer_bytes(0)
+
+{
+ for (int c=0 ; c<3 ; ++c )
+ {
+ m_comp_hdr_bytes[c] = 0;
+ m_comp_bytes[c] = 0;
+ }
+}
+
+void SequenceOutputManager::WriteFrameData()
+{
+ m_frame_op_mgr.WriteToFile();
+
+ // Keep up with count of component bytes
+ for (int c=0 ; c<m_comp_hdr_bytes.Length(); ++c)
+ {
+ m_comp_hdr_bytes[c] += m_frame_op_mgr.ComponentHeadBytes( c );
+ m_comp_bytes[c] += m_frame_op_mgr.ComponentBytes( c );
+ }// c
+
+ // Keep up with count of MV bytes
+ m_mv_hdr_bytes += m_frame_op_mgr.MVHeadBytes();
+ m_mv_bytes += m_frame_op_mgr.MVBytes();
+
+ // Keep up with overall totals
+ m_header_bytes += m_frame_op_mgr.FrameHeadBytes();
+ m_total_bytes += m_frame_op_mgr.FrameBytes();
+
+}
+
+void SequenceOutputManager::WriteSeqHeaderToFile()
+{
+ m_seq_header.WriteToFile();
+ m_header_bytes += m_seq_header.GetNumBytes();
+ m_total_bytes += m_seq_header.GetNumBytes();
+}
+
+void SequenceOutputManager::WriteSeqTrailerToFile()
+{
+ m_seq_end.WriteToFile();
+ m_trailer_bytes += m_seq_end.GetNumBytes();
+ m_total_bytes += m_seq_end.GetNumBytes();
+}
+
+////////////////
+//Input stuff//
+////////////////
+
+//Constructor
+BitInputManager::BitInputManager(std::istream* in_data ):
+ m_ip_ptr(in_data)
+{
+ InitInputStream();
+}
+
+
+void BitInputManager::InitInputStream()
+{
+ m_shift = 0xffffffff;
+ m_input_bits_left = 0;
+}
+
+bool BitInputManager::InputBit()
+{
+ //assumes mode errors will be caught by iostream class
+
+ if (m_input_bits_left == 0)
+ {
+ m_ip_ptr->read(&m_current_byte,1);
+ m_input_bits_left = 8;
+ if (m_shift == START_CODE_PREFIX && (unsigned char)m_current_byte == NOT_START_CODE)
+ {
+ std::cerr << "Ignoring byte " << std::endl;
+ m_ip_ptr->read(&m_current_byte,1);
+ m_shift = 0xffffffff;
+ }
+ m_shift = (m_shift << 8) | m_current_byte;
+ }
+
+ m_input_bits_left--;
+
+ return bool( ( m_current_byte >> m_input_bits_left ) & 1 );
+
+}
+
+bool BitInputManager::InputBit(int& count)
+{
+ count++;
+ return InputBit();
+}
+
+bool BitInputManager::InputBit(int& count, const int max_count)
+{
+ if ( count<max_count )
+ {
+ count++;
+ return InputBit();
+ }
+ else
+ return false;
+}
+
+char BitInputManager::InputByte()
+{
+ // Forget about what's in the current byte
+ FlushInput();
+
+ char byte;
+ m_ip_ptr->read(&byte,1);
+
+ return byte;
+}
+
+void BitInputManager::InputBytes(char* cptr, int num)
+{
+ // Forget about what's in the current byte
+ FlushInput();
+
+ m_ip_ptr->read(cptr,num);
+}
+
+void BitInputManager::FlushInput()
+{
+ m_input_bits_left = 0;
+}
+
+bool BitInputManager::End() const
+{
+ return m_ip_ptr->eof();
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.h
new file mode 100644
index 000000000..6f75e8004
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/bit_manager.h
@@ -0,0 +1,524 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: bit_manager.h,v 1.16 2008/01/31 11:25:16 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Robert Scott Ladd,
+* Tim Borer
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _BIT_MANAGER_H_
+#define _BIT_MANAGER_H_
+
+#include <libdirac_common/arrays.h>
+#include <cstring>
+#include <vector>
+#include <iostream>
+
+namespace dirac
+{
+ //! Prefix for all start codes
+ const unsigned int START_CODE_PREFIX = 0x42424344; //BBCD
+ const unsigned int START_CODE_PREFIX_BYTE0 =
+ (START_CODE_PREFIX >> 24) & 0xFF;
+ const unsigned int START_CODE_PREFIX_BYTE1 =
+ (START_CODE_PREFIX >> 16) & 0xFF;
+ const unsigned int START_CODE_PREFIX_BYTE2 =
+ (START_CODE_PREFIX >> 8) & 0xFF;
+ const unsigned int START_CODE_PREFIX_BYTE3 =
+ START_CODE_PREFIX & 0xFF;
+
+ //! Random Access Point (RAP) Intra Picture start Code
+ const unsigned char RAP_START_CODE = 0xD7;
+ //! Non-RAP Intra Picture start code
+ const unsigned char IFRAME_START_CODE = 0xD6;
+ //! L1 Picture start code
+ const unsigned char L1FRAME_START_CODE = 0xD4;
+ //! L2 Picture start code
+ const unsigned char L2FRAME_START_CODE = 0xD5;
+ //! Sequence end code
+ const unsigned char SEQ_END_CODE = 0xD0;
+ //! Not a start code but part of data
+ const unsigned char NOT_START_CODE = 0xFF;
+ //! Bitstream version
+ const unsigned char BITSTREAM_VERSION = 0x05; //0.5
+
+
+ ////////////////////////////////////////////////
+ //--------------Bit output stuff--------------//
+ ////////////////////////////////////////////////
+
+ class UnitOutputManager;
+ class FrameOutputManager;
+ class SequenceOutputManager;
+
+ //! Class for managing bit- and byte-oriented output.
+ /*!
+ A class for managing bit- and byte-oriented output. Wraps around
+ an ostream object but stores data in memory until told told to
+ write out in order to support data re-ordering - for example
+ writing a header once the subsequent data has been obtained.
+ Implementation to be reviewed in future. TJD 13 April 2004.
+ */
+ class BasicOutputManager
+ {
+ // Data cannot be written to file directly, only by other o/p classes
+ friend class UnitOutputManager;
+ friend class FrameOutputManager;
+ friend class SequenceOutputManager;
+
+ public:
+ //! Constructor
+ /*!
+ Constructor requires an ostream object pointer.
+ \param out_data the output stream object pointer
+ */
+ BasicOutputManager(std::ostream* out_data );
+
+ //Copy constructor is default shallow copy
+
+ //Operator= is default shallow=
+
+ //! Destructor
+ ~BasicOutputManager(){}
+
+ //! Write a bit out.
+ /*!
+ Write a bit out to the internal data cache.
+ */
+ void OutputBit(const bool& bit);
+
+ //! Write a bit out and increment count
+ /*!
+ Write a bit out to the internal data cache and increment the
+ count of bits written.
+ */
+ void OutputBit(const bool& bit,int& count);
+
+ //! Write a byte out.
+ /*!
+ Write a byte out to the internal data cache.
+ */
+ void OutputByte(const char& byte);
+
+ //! Write a null-terminated set of bytes out.
+ /*!
+ Write a null-terminated set of bytes out to the internal data cache.
+ */
+ void OutputBytes(char* str_array);
+
+ //! Write a number of bytes out.
+ /*!
+ Write a number of bytes out to the internal data cache.
+ */
+ void OutputBytes(char* str_array,int num);
+
+ //! Return the number of bytes last output to file.
+ /*!
+ Return the number of bytes last output to file.
+ */
+ size_t GetNumBytes() const {return m_num_out_bytes;}
+
+ //! Current size of the internal data cache in bytes.
+ /*!
+ Current size of the internal data cache in bytes.
+ */
+ size_t Size() const;
+
+ private:
+ // Number of output bytes written
+ size_t m_num_out_bytes;
+ std::ostream* m_op_ptr;
+ // Buffer used to store output prior to saving to file
+ std::vector<char> m_buffer;
+ // Char used for temporary storage of op data bits
+ char m_current_byte;
+ // Used to set individual bit within the current header byte
+ int m_output_mask;
+
+ //functions
+
+ //! Write all data to file.
+ /*!
+ Dump the internal data cache to the internal ostream object.
+ */
+ void WriteToFile();
+
+ //Initialise the output stream.
+ void InitOutputStream();
+
+ //Clean out any remaining output bits to the buffer
+ void FlushOutput();
+
+ //! Write an ignore code
+ /*!
+ Write a skip interpret start prefix byte out to the internal data
+ cache.
+ */
+ void OutputSkipInterpretStartPrefixByte();
+ };
+
+ //! A class for handling data output, including headers.
+ /*!
+ A class for handling data output, including headers and reordering.
+ */
+ class UnitOutputManager
+ {
+ // Only the FrameOutputManager can make this class write data to file
+ friend class FrameOutputManager;
+
+ public:
+ //! Constructor.
+ /*!
+ Constructor wraps around a pointer to an ostream object, and
+ initialises two BasicOutputManager objects for header and data
+ */
+ UnitOutputManager(std::ostream* out_data );
+
+ //Copy constructor is default shallow copy
+
+ //Operator= is default shallow=
+
+ //! Destructor
+ ~UnitOutputManager(){}
+
+ //! Handles the header bits.
+ /*!
+ A BasicOutputManager object for handling the header bits.
+ */
+ BasicOutputManager& Header(){return m_header;}
+
+ //! Handles the data bits.
+ /*!
+ A BasicOutputManager object for handling the data bits.
+ */
+ BasicOutputManager& Data(){return m_data;}
+
+ //! Returns the total number of bytes written in the last unit coded.
+ /*!
+ Returns the total number of bytes written in the last unit coded - header + data.
+ */
+ const size_t GetUnitBytes() const {return m_unit_bytes;}
+
+ //! Returns the total number of header bytes written in the last unit coded.
+ const size_t GetUnitHeaderBytes() const {return m_unit_head_bytes;}
+
+ //! Current size of the internal data cache in bytes.
+ /*!
+ Current size of the internal data cache in bytes.
+ */
+ size_t Size() const;
+
+ private:
+ // basic output managers for the header and data
+ BasicOutputManager m_header,m_data;
+
+ // total number of bytes written in the last unit coded
+ size_t m_unit_bytes;
+
+ // number of data bytes for the last unit coded
+ size_t m_unit_data_bytes;
+
+ // number of data bytes for the last unit coded
+ size_t m_unit_head_bytes;
+
+ // functions
+
+ //! Writes the bit caches to file.
+ /*!
+ Writes the header bits to the ostream, followed by the data bits.
+ */
+ void WriteToFile();
+ };
+
+ class FrameOutputManager
+ {
+ public:
+
+ // Only the SequenceOutputManager can make this class write data to file
+ friend class SequenceOutputManager;
+
+ //! Constructor
+ /*
+ Constructs a class which manages output for an entire picture.
+ \param out_data pointer to the output stream
+ \param num_bands the number of subbands per component
+ */
+ FrameOutputManager( std::ostream* out_data , const int num_bands=13 );
+
+ //! Destructor
+ ~FrameOutputManager();
+
+ //! Set the number of bands there will be in a component
+ void SetNumBands( const int num_bands );
+
+ //! Get an output manager for a subband
+ /*!
+ Get an output manager for a subband.
+ \param csort the component (Y, U or V)
+ \param band_num the number of the subband
+ */
+ UnitOutputManager& BandOutput( const int csort , const int band_num );
+
+ //! Get an output manager for a subband
+ /*!
+ Get an output manager for a subband.
+ \param csort the component (Y, U or V)
+ \param band_num the number of the subband
+ */
+ const UnitOutputManager& BandOutput( const int csort , const int band_num ) const;
+
+ //! Get an output manager for MV data
+ /*!
+ Get an output manager for MV data
+ */
+ UnitOutputManager& MVOutput(){ return *m_mv_data; }
+
+ //! Get an output manager for MV data
+ /*!
+ Get an output manager for MV data
+ */
+ const UnitOutputManager& MVOutput() const { return *m_mv_data; }
+
+ //! Get an output manager for the picture header
+ BasicOutputManager& HeaderOutput(){ return *m_frame_header; }
+
+ //! Return the number of bytes used for each component
+ const size_t ComponentBytes( const int comp_num ) const { return m_comp_bytes[comp_num];}
+
+ //! Return the number of header bytes used for each component
+ const size_t ComponentHeadBytes( const int comp_num ) const { return m_comp_hdr_bytes[comp_num];}
+
+ //! Return the number of motion vector bytes used
+ const size_t MVBytes() const { return m_mv_bytes;}
+
+ //! Return the number of motion vector header bytes used
+ const size_t MVHeadBytes() const { return m_mv_hdr_bytes;}
+
+ //! Return the number of bytes used for the whole picture
+ const size_t FrameBytes() const { return m_total_bytes;}
+
+ //! Return the number of header bytes used throughout the picture
+ const size_t FrameHeadBytes() const { return m_header_bytes;}
+
+ //! Current size of the internal data cache in bytes.
+ /*!
+ Current size of the internal data cache in bytes.
+ */
+ size_t Size() const;
+
+ private:
+
+ // Array of subband outputs, 1 for each component and subband
+ TwoDArray< UnitOutputManager* > m_data_array;
+
+ // Motion vector output
+ UnitOutputManager* m_mv_data;
+
+ // Picture header output
+ BasicOutputManager* m_frame_header;
+
+ // The total number of picture bytes
+ size_t m_total_bytes;
+
+ // The total number of header bytes
+ size_t m_header_bytes;
+
+ // The total number of MV header bytes
+ size_t m_mv_hdr_bytes;
+
+ // The total number of MV bytes
+ size_t m_mv_bytes;
+
+ // The total number of bytes in each component
+ OneDArray< size_t > m_comp_bytes;
+
+ // The total number of header bytes in each component
+ OneDArray< size_t > m_comp_hdr_bytes;
+
+ // A copy of a pointer to the output stream
+ std::ostream* m_out_stream;
+
+ // Functions
+
+ //! Initialise the band data
+ void Init( const int num_bands );
+
+ //! Reset all the data
+ void Reset();
+
+ //! Delete all the data
+ void DeleteAll();
+
+ //! Write all the picture data to file
+ void WriteToFile();
+ };
+
+ class SequenceOutputManager
+ {
+ public:
+ //! Constructor
+ SequenceOutputManager( std::ostream* out_data );
+
+ //! Return a reference to the output for a single picture
+ FrameOutputManager& FrameOutput(){ return m_frame_op_mgr; }
+
+ //! Return a reference to the output for the sequence header
+ BasicOutputManager& HeaderOutput(){ return m_seq_header; }
+
+ //! Return a reference to the output for the sequence trailer
+ BasicOutputManager& TrailerOutput(){ return m_seq_end; }
+
+ //! Reset the picture data without outputting
+ void ResetFrame(){ m_frame_op_mgr.Reset(); }
+
+ //! Write the sequence header
+ void WriteSeqHeaderToFile();
+
+ //! Write all the picture data to file
+ void WriteFrameData();
+
+ //! Write the sequence trailer
+ void WriteSeqTrailerToFile();
+
+ //! Return the total number of bytes used for the sequence
+ const size_t SequenceBytes() { return m_total_bytes; }
+
+ //! Return the total number of header bytes used throughout the sequence
+ const size_t SequenceHeadBytes() { return m_header_bytes; }
+
+ //! Return the total number bytes used for MVs
+ const size_t MVBytes() { return m_mv_bytes; }
+
+ //! Return the total number bytes used for a component
+ const size_t ComponentBytes( const int comp_num ) { return m_comp_bytes[comp_num]; }
+
+ //! Reset the picture data
+ void ResetFrameData();
+
+
+ private:
+
+ // The picture output manager
+ FrameOutputManager m_frame_op_mgr;
+
+ // Output manager for the sequence header
+ BasicOutputManager m_seq_header;
+
+ // Output manager for the sequence end
+ BasicOutputManager m_seq_end;
+
+ // The total number of bytes in each component
+ OneDArray< size_t > m_comp_bytes;
+
+ // The total number of header bits in each component
+ OneDArray< size_t > m_comp_hdr_bytes;
+
+ // The number of MV header bytes
+ size_t m_mv_hdr_bytes;
+
+ // The total number of MV bytes
+ size_t m_mv_bytes;
+
+ // The total number of bytes written so far
+ size_t m_total_bytes;
+
+ // The total number of header bytes written so far
+ size_t m_header_bytes;
+
+ // The total number of trailer bytes written so far
+ size_t m_trailer_bytes;
+ };
+
+ ///////////////////////////////////////////////
+ //--------------Bit input stuff--------------//
+ ///////////////////////////////////////////////
+
+ //! A class for managing bit-wise and byte-wise input.
+ class BitInputManager
+ {
+
+ public:
+ //! Constructor.
+ /*!
+ Constructor. Wraps around an istream object.
+ */
+ BitInputManager(std::istream* in_data );
+
+ //Copy constructor is default shallow copy
+
+ //Operator= is default shallow=
+
+ //! Destructor
+ ~BitInputManager(){}
+
+ //input functions
+ //! Obtain the next bit.
+ bool InputBit();
+
+ //! Obtain the next bit, incrementing count.
+ bool InputBit(int& count);
+
+ //! Obtain the next bit, incrementing count, if count<max_count; else return 0 (false).
+ bool InputBit(int& count, const int max_count);
+
+ //! Obtain the next byte.
+ char InputByte();
+
+ //! Obtain a number of bytes.
+ void InputBytes(char* cptr,int num);
+
+ //! Move onto the next byte. Needed if a data unit is not an exact number of bytes.
+ void FlushInput();
+
+ //! Returns true if we're at the end of the input, false otherwise
+ bool End() const ;
+
+ private:
+
+ std::istream* m_ip_ptr;
+ // Char used for temporary storage of ip bits
+ char m_current_byte;
+ // The number of bits left withint the current input byte being decoded
+ int m_input_bits_left;
+
+ //used to check if start code is detected
+ unsigned int m_shift;
+ //functions
+ // Initialise the input stream
+ void InitInputStream();
+ };
+
+} // namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.cpp
new file mode 100644
index 000000000..82abf66b8
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.cpp
@@ -0,0 +1,78 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: cmd_line.cpp,v 1.8 2008/03/14 08:17:36 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Scott R Ladd (Original Author), Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <cstring>
+#include "cmd_line.h"
+using namespace dirac;
+
+using namespace std;
+
+CommandLine::CommandLine(int argc, char * argv[], const set<string> & bool_opts)
+ : m_options(),
+ m_inputs(),
+ m_bool_opts(bool_opts)
+{
+ bool option_active = false;
+ vector<option>::iterator active_option;
+
+ for (int i = 1; i < argc; ++i)
+ {
+ // is it an option?
+ if ((strlen(argv[i]) > 1) && (argv[i][0] == '-'))
+ {
+ // store new key
+ string opt_key = string(&argv[i][1]);
+ m_options.push_back(option(opt_key));
+
+ // active option is now last in list
+ active_option = m_options.end();
+ --active_option;
+
+ // check option list to see if we're looking for an argument
+ option_active = (m_bool_opts.find(opt_key) == m_bool_opts.end());
+ }
+ else
+ {
+ if (option_active)
+ active_option->m_value = string(argv[i]);
+ else
+ m_inputs.push_back(string(argv[i]));
+
+ option_active = false;
+ }
+ }
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.h
new file mode 100644
index 000000000..0977c8b27
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/cmd_line.h
@@ -0,0 +1,92 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: cmd_line.h,v 1.7 2004/11/22 14:05:02 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Scott R Ladd (Original Author), Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#if !defined(LIBDIRAC_CMD_LINE_H)
+#define LIBDIRAC_CMD_LINE_H
+
+// Standard C++
+#include <string>
+#include <vector>
+#include <set>
+
+namespace dirac
+{
+ // structure for defining the nature of options
+ // a very simple command-line parser
+ class CommandLine
+ {
+ public:
+ struct option
+ {
+ std::string m_name;
+ std::string m_value;
+
+ option(const std::string & a_name)
+ : m_name(a_name), m_value("")
+ {
+ // nada
+ }
+ };
+
+ //! Constructor
+ CommandLine(int argc, char * argv[], const std::set<std::string> & bool_opts);
+
+ const std::vector<option> & GetOptions() const
+ {
+ return m_options;
+ }
+
+ const std::vector<std::string> & GetInputs() const
+ {
+ return m_inputs;
+ }
+
+ // convenience property
+ size_t Count() const
+ {
+ return m_options.size();
+ }
+
+ private:
+ std::vector<option> m_options;
+ std::vector<std::string> m_inputs;
+ const std::set<std::string> & m_bool_opts;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.cpp
new file mode 100644
index 000000000..35adcc5ef
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.cpp
@@ -0,0 +1,1143 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: common.cpp,v 1.80 2009/01/21 05:21:27 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Tim Borer,
+* Anuradha Suraparaju,
+* Andrew Kennedy
+* Myo Tun (Brunel University, myo.tun@brunel.ac.uk)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <algorithm>
+#include <sstream>
+#ifndef _MSC_VER
+#include <inttypes.h>
+#endif
+#include <libdirac_common/common.h>
+#include <libdirac_common/video_format_defaults.h>
+#include <libdirac_common/dirac_exception.h>
+using namespace dirac;
+
+
+//const dirac::QuantiserLists dirac::dirac_quantiser_lists;
+
+
+//EntropyCorrector functions
+
+EntropyCorrector::EntropyCorrector(int depth):
+ m_Yfctrs( 3 , 3*depth+1 ),
+ m_Ufctrs( 3 , 3*depth+1 ),
+ m_Vfctrs( 3 , 3*depth+1 )
+{
+ Init();
+}
+
+float EntropyCorrector::Factor(const int bandnum , const PictureParams& pp ,
+ const CompSort c) const
+{
+ int idx = pp.PicSort().IsIntra() ? 0 : (pp.IsBPicture() ? 1 : 2);
+ if (c == U_COMP)
+ return m_Ufctrs[idx][bandnum-1];
+ else if (c == V_COMP)
+ return m_Vfctrs[idx][bandnum-1];
+ else
+ return m_Yfctrs[idx][bandnum-1];
+}
+
+void EntropyCorrector::Init()
+{
+
+ //do I-pictures
+ for (int i=0 ; i<m_Yfctrs.LengthX() ; ++i )
+ {
+ if ( i == m_Yfctrs.LastX() )
+ {
+ // Set factor for Intra pictures
+ m_Yfctrs[0][i] = 1.0f;
+ m_Ufctrs[0][i] = 1.0f;
+ m_Vfctrs[0][i] = 1.0f;
+ // Set factor for Inter Ref pictures
+ m_Yfctrs[1][i] = 0.85f;
+ m_Ufctrs[1][i] = 0.85f;
+ m_Vfctrs[1][i] = 0.85f;
+ // Set factor for Inter Non-Ref pictures
+ m_Yfctrs[2][i] = 0.85f;
+ m_Ufctrs[2][i] = 0.85f;
+ m_Vfctrs[2][i] = 0.85f;
+ }
+ else if ( i >= m_Yfctrs.LastX()-3 )
+ {
+ // Set factor for Intra pictures
+ m_Yfctrs[0][i] = 0.85f;
+ m_Ufctrs[0][i] = 0.85f;
+ m_Vfctrs[0][i] = 0.85f;
+ // Set factor for Inter Ref pictures
+ m_Yfctrs[1][i] = 0.75f;
+ m_Ufctrs[1][i] = 0.75f;
+ m_Vfctrs[1][i] = 0.75f;
+ // Set factor for Inter Non-Ref pictures
+ m_Yfctrs[2][i] = 0.75f;
+ m_Ufctrs[2][i] = 0.75f;
+ m_Vfctrs[2][i] = 0.75f;
+ }
+ else
+ {
+ // Set factor for Intra pictures
+ m_Yfctrs[0][i] = 0.75f;
+ m_Ufctrs[0][i] = 0.75f;
+ m_Vfctrs[0][i] = 0.75f;
+ // Set factor for Inter Ref pictures
+ m_Yfctrs[1][i] = 0.75f;
+ m_Ufctrs[1][i] = 0.75f;
+ m_Vfctrs[1][i] = 0.75f;
+ // Set factor for Inter Non-Ref pictures
+ m_Yfctrs[2][i] = 0.75f;
+ m_Ufctrs[2][i] = 0.75f;
+ m_Vfctrs[2][i] = 0.75f;
+ }
+ }//i
+
+}
+
+void EntropyCorrector::Update(int bandnum , const PictureParams& pp ,
+ CompSort c ,int est_bits , int actual_bits){
+ //updates the factors - note that the estimated bits are assumed to already include the correction factor
+
+ float multiplier;
+ if (actual_bits != 0 && est_bits != 0)
+ multiplier = float(actual_bits)/float(est_bits);
+ else
+ multiplier=1.0;
+
+ int idx = pp.PicSort().IsIntra() ? 0 : (pp.IsBPicture() ? 1 : 2);
+ if (c == U_COMP)
+ m_Ufctrs[idx][bandnum-1] *= multiplier;
+ else if (c == V_COMP)
+ m_Vfctrs[idx][bandnum-1] *= multiplier;
+ else
+ m_Yfctrs[idx][bandnum-1] *= multiplier;
+}
+
+// Overlapped block parameter functions
+
+OLBParams::OLBParams(const int xblen, int const yblen, int const xbsep, int const ybsep):
+ m_xblen(xblen),
+ m_yblen(yblen),
+ m_xbsep(xbsep),
+ m_ybsep(ybsep),
+ m_xoffset( (xblen-xbsep)/2 ),
+ m_yoffset( (yblen-ybsep)/2 )
+{}
+
+bool OLBParams::operator ==(const OLBParams bparams) const
+{
+ if (bparams.Xblen() != m_xblen ||
+ bparams.Yblen() != m_yblen ||
+ bparams.Xbsep() != m_xbsep ||
+ bparams.Ybsep() != m_ybsep)
+
+ return false;
+
+ return true;
+}
+
+namespace dirac
+{
+std::ostream & operator<< (std::ostream & stream, OLBParams & params)
+{
+ stream << params.Ybsep() << " " << params.Xbsep();
+// stream << " " <<params.Yblen() << " " << params.Xblen();
+
+ return stream;
+}
+
+std::istream & operator>> (std::istream & stream, OLBParams & params)
+{
+ int temp;
+
+ stream >> temp;
+ params.SetYbsep(temp);
+
+ stream >> temp;
+ params.SetXbsep(temp);
+
+// stream >> temp;
+// params.SetYblen(temp);
+
+// stream >> temp;
+// params.SetXblen(temp);
+
+ return stream;
+}
+
+}
+
+void PicturePredParams::SetBlockSizes(const OLBParams& olbparams , const ChromaFormat cformat)
+{
+ //given the raw overlapped block parameters, set the modified internal parameters to
+ //take account of the chroma sampling format and overlapping requirements, as well
+ //as the equivalent parameters for sub-SBs and SBs.
+ //Does NOT set the number of blocks or superblocks, as padding may be required.
+
+ OLBParams tmp_olbparams = olbparams;
+ // Factors for scaling chroma blocks
+ int xcfactor,ycfactor;
+
+ if (cformat == format420)
+ {
+ xcfactor = 2;
+ ycfactor = 2;
+ }
+ else if (cformat == format422)
+ {
+ xcfactor = 2;
+ ycfactor = 1;
+ }
+ else
+ {// assume 444
+ xcfactor = 1;
+ ycfactor = 1;
+ }
+
+
+ m_lbparams[2] = tmp_olbparams;
+
+ // Check separations are all divisible by 4
+ int remainder= m_lbparams[2].Xbsep()%4;
+ if ( remainder!=0 || m_lbparams[2].Xbsep()==0 )
+ {
+ m_lbparams[2].SetXbsep( m_lbparams[2].Xbsep()+(4-remainder));
+ m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4 );
+ }
+ remainder= m_lbparams[2].Ybsep()%4;
+ if ( remainder!=0 || m_lbparams[2].Ybsep()==0 )
+ {
+ m_lbparams[2].SetYbsep( m_lbparams[2].Ybsep()+(4-remainder));
+ m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4 );
+
+ }
+
+ // Now check lengths are divisible by 4
+ remainder= m_lbparams[2].Xblen()%4;
+ if ( remainder!=0 )
+ {
+ m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4);
+ }
+ remainder= m_lbparams[2].Yblen()%4;
+ if ( remainder!=0 )
+ {
+ m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4);
+ }
+
+ // Check there's non-negative overlap,
+ // XBLEN >= XBSEP, YBLEN >= YBSEP
+ if (m_lbparams[2].Xbsep()>m_lbparams[2].Xblen())
+ {
+ m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4);
+ }
+ if (m_lbparams[2].Ybsep()>m_lbparams[2].Yblen())
+ {
+ m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4);
+ }
+
+ // Check the lengths aren't too big (100% is max roll-off)
+ // XBLEN <= 2*XBSEP, YBLEN <= 2*YBSEP
+ if (2*m_lbparams[2].Xbsep()<m_lbparams[2].Xblen())
+ {
+ m_lbparams[2].SetXblen( m_lbparams[2].Xbsep()+4);
+ }
+ if (2*m_lbparams[2].Ybsep()<m_lbparams[2].Yblen())
+ {
+ m_lbparams[2].SetYblen( m_lbparams[2].Ybsep()+4);
+ }
+
+ // Set the chroma values
+ m_cbparams[2].SetXbsep( m_lbparams[2].Xbsep()/xcfactor );
+ m_cbparams[2].SetXblen( m_lbparams[2].Xblen()/xcfactor );
+ m_cbparams[2].SetYbsep( m_lbparams[2].Ybsep()/ycfactor );
+ m_cbparams[2].SetYblen( m_lbparams[2].Yblen()/ycfactor );
+
+
+ //Now work out the overlaps for splitting levels 1 and 0
+ m_lbparams[1].SetXbsep( m_lbparams[2].Xbsep()*2 );
+ m_lbparams[1].SetXblen( m_lbparams[2].Xblen() + m_lbparams[2].Xbsep() );
+ m_lbparams[1].SetYbsep( m_lbparams[2].Ybsep()*2 );
+ m_lbparams[1].SetYblen( m_lbparams[2].Yblen() + m_lbparams[2].Xbsep() );
+
+ m_lbparams[0].SetXbsep( m_lbparams[1].Xbsep()*2 );
+ m_lbparams[0].SetXblen( m_lbparams[1].Xblen() + m_lbparams[1].Xbsep() );
+ m_lbparams[0].SetYbsep( m_lbparams[1].Ybsep()*2 );
+ m_lbparams[0].SetYblen( m_lbparams[1].Yblen() + m_lbparams[1].Xbsep() );
+
+ m_cbparams[1].SetXbsep( m_cbparams[2].Xbsep()*2 );
+ m_cbparams[1].SetXblen( m_cbparams[2].Xblen() + m_cbparams[2].Xbsep() );
+ m_cbparams[1].SetYbsep( m_cbparams[2].Ybsep()*2 );
+ m_cbparams[1].SetYblen( m_cbparams[2].Yblen() + m_cbparams[2].Xbsep() );
+
+ m_cbparams[0].SetXbsep( m_cbparams[1].Xbsep()*2 );
+ m_cbparams[0].SetXblen( m_cbparams[1].Xblen() + m_cbparams[1].Xbsep() );
+ m_cbparams[0].SetYbsep( m_cbparams[1].Ybsep()*2 );
+ m_cbparams[0].SetYblen( m_cbparams[1].Yblen() + m_cbparams[1].Xbsep() );
+
+ if ( m_lbparams[2].Xbsep()!=olbparams.Xbsep() ||
+ m_lbparams[2].Ybsep()!=olbparams.Ybsep() ||
+ m_lbparams[2].Xblen()!=olbparams.Xblen() ||
+ m_lbparams[2].Yblen()!=olbparams.Yblen() )
+ {
+ std::cout<<std::endl<<"WARNING: block parameters are inconsistent with ";
+ std::cout<<"specification requirements, which are:";
+ std::cout<<std::endl<<"\t 1. Lengths and separations must be positive multiples of 4";
+ std::cout<<std::endl<<"\t 2. Length can't be more than twice separations";
+ std::cout<<std::endl<<"\t 3. Lengths must be greater than or equal to separations";
+ std::cout<<std::endl<<std::endl<<"Instead, using:";
+ std::cout<<" xblen="<<m_lbparams[2].Xblen();
+ std::cout<<" yblen="<<m_lbparams[2].Yblen();
+ std::cout<<" xbsep="<<m_lbparams[2].Xbsep();
+ std::cout<<" ybsep="<<m_lbparams[2].Ybsep() << std::endl;
+ }
+}
+
+
+// Codec params functions
+
+CodecParams::CodecParams(const VideoFormat &vd, PictureType ftype, unsigned int num_refs, bool set_defaults):
+ m_video_format(vd)
+{
+ if (set_defaults)
+ SetDefaultCodecParameters(*this, ftype, num_refs);
+}
+
+WltFilter CodecParams::TransformFilter (unsigned int wf_idx)
+{
+ if (wf_idx >= filterNK)
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ "Wavelet filter idx out of range [0-7]",
+ SEVERITY_PICTURE_ERROR);
+
+ if (wf_idx==FIDELITY)
+ {
+ std::ostringstream errstr;
+ errstr << "Wavelet Filter " << wf_idx << " currently not supported";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ }
+ return static_cast<WltFilter>(wf_idx);
+}
+
+void CodecParams::SetTransformFilter(unsigned int wf_idx)
+{
+ SetTransformFilter(TransformFilter(wf_idx));
+}
+
+void CodecParams::SetTransformDepth (unsigned int wd)
+{
+ m_wlt_depth = wd;
+ // Resize the code block size array.
+ m_cb.Resize(wd+1);
+}
+
+void CodecParams::SetCodeBlocks (unsigned int level,
+ unsigned int hblocks,
+ unsigned int vblocks)
+{
+ if (level > m_wlt_depth)
+ {
+ std::ostringstream errstr;
+ errstr << "level " << level << " out of range [0-" << m_wlt_depth << "]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ }
+
+ m_cb[level].SetHorizontalCodeBlocks(hblocks);
+ m_cb[level].SetVerticalCodeBlocks(vblocks);
+}
+
+const CodeBlocks &CodecParams::GetCodeBlocks (unsigned int level) const
+{
+ if (level > m_wlt_depth)
+ {
+ std::ostringstream errstr;
+ errstr << "level " << level << " out of range [0-" << m_wlt_depth << "]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ }
+
+ return m_cb[level];
+}
+
+void CodecParams::SetCodeBlockMode (unsigned int cb_mode)
+{
+ if (cb_mode >= QUANT_UNDEF)
+ {
+ std::ostringstream errstr;
+ errstr << "Code Block mode " << cb_mode << " out of supported range [0-" << QUANT_MULTIPLE << "]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ }
+
+ m_cb_mode = static_cast<CodeBlockMode>(cb_mode);
+}
+
+//EncoderParams functions
+
+//Default constructor
+EncoderParams::EncoderParams(const VideoFormat& video_format,
+ PictureType ftype,
+ unsigned int num_refs,
+ bool set_defaults):
+ CodecParams(video_format, ftype, num_refs, set_defaults),
+ m_verbose(false),
+ m_loc_decode(true),
+ m_full_search(false),
+ m_x_range_me(32),
+ m_y_range_me(32),
+ m_ufactor(1.0),
+ m_vfactor(1.0),
+ m_prefilter(NO_PF),
+ m_prefilter_strength(0),
+ m_I_lambda(0.0f),
+ m_L1_lambda(0.f),
+ m_L2_lambda(0.0f),
+ m_L1_me_lambda(0.0f),
+ m_L2_me_lambda(0.0f),
+ m_ent_correct(0),
+ m_target_rate(0)
+{
+ if(set_defaults)
+ SetDefaultEncoderParameters(*this);
+}
+
+void EncoderParams::CalcLambdas(const float qf)
+{
+ if (!m_lossless )
+ {
+ m_I_lambda = std::pow( 10.0 , (12.0-qf )/2.5 )/16.0;
+
+ m_L1_lambda = m_I_lambda*4.0;
+ m_L2_lambda = m_I_lambda*32.0;
+
+ // Set the lambdas for motion estimation
+ const double me_ratio = 2.0;
+
+ // Use the same ME lambda for L1 and L2 pictures
+ m_L1_me_lambda = std::sqrt(m_L1_lambda)*me_ratio;
+ m_L2_me_lambda = m_L1_me_lambda;
+ }
+ else
+ {
+ m_I_lambda = 0.0;
+ m_L1_lambda = 0.0;
+ m_L2_lambda = 0.0;
+
+ m_L1_me_lambda = 0.0;
+ m_L2_me_lambda = 0.0;
+ }
+}
+
+void EncoderParams::SetIntraTransformFilter(unsigned int wf_idx)
+{
+ SetIntraTransformFilter(TransformFilter(wf_idx));
+}
+
+void EncoderParams::SetInterTransformFilter(unsigned int wf_idx)
+{
+ SetInterTransformFilter(TransformFilter(wf_idx));
+}
+
+void EncoderParams::SetUsualCodeBlocks ( const PictureType &/*ftype*/)
+{
+ // No subband splitting if spatial partitioning if false
+ // Since this function is common to encoder and decoder we allow the
+ // setting of code blocks without checking if DefaultSpatialPartition is
+ // true.
+ if (SpatialPartition() == false)
+ return;
+
+ SetCodeBlocks(0, 1, 1);
+ int depth = TransformDepth();
+ if (depth == 0)
+ return;
+
+ int xl_pad = (Xl() + (1 << depth)-1) & ~((1 << depth)-1);
+ int yl_pad = (Yl() + (1 << depth)-1) & ~((1 << depth)-1);
+
+ /* NB, could have different sizes based upon ftype == INTRA_PICTURE */
+ /* aim for 12x12 codeblocks in each subband, execpt the DC with 4x4 */
+ for (int i = 1; i <= depth; i++)
+ SetCodeBlocks(depth-i+1, std::max(1,(xl_pad >> i) /12), std::max(1, (yl_pad >> i) /12));
+ SetCodeBlocks(0, std::max(1,(xl_pad >> depth) /4), std::max(1,(yl_pad >> depth) /4));
+}
+
+int EncoderParams::GOPLength() const
+{
+ if (m_num_L1>0)
+ return (m_num_L1+1)*m_L1_sep;
+
+ return ((m_num_L1==0) ? 10 : 0);
+}
+
+DecoderParams::DecoderParams(const VideoFormat& video_format,
+ PictureType ftype,
+ unsigned int num_refs,
+ bool set_defaults):
+ CodecParams(video_format, ftype, num_refs, set_defaults),
+ m_verbose(false)
+{
+}
+
+// ParseParams functions
+// constructor
+ParseParams::ParseParams():
+ m_major_ver(2),
+ m_minor_ver(2),
+ m_profile(8),
+ m_level(0)
+{}
+
+
+//Source functions
+//constructor
+SourceParams::SourceParams(const VideoFormat& video_format,
+ bool set_defaults)
+{
+ // set default parameters
+ if(set_defaults)
+ SetDefaultSourceParameters(video_format, *this);
+}
+
+int SourceParams::ChromaWidth() const
+{
+ switch (m_cformat)
+ {
+ case format420:
+ case format422:
+ return m_xl/2;
+
+ case format444:
+ default:
+ return m_xl;
+ }
+}
+
+int SourceParams::ChromaHeight() const
+{
+ switch (m_cformat)
+ {
+ case format420:
+ return m_yl/2;
+
+ case format422:
+ case format444:
+ default:
+ return m_yl;
+ }
+}
+
+
+void SourceParams::SetFrameRate (FrameRateType fr)
+{
+ m_fr_idx = fr;
+ switch (fr)
+ {
+ case FRAMERATE_23p97_FPS:
+ m_framerate.m_num = 24000;
+ m_framerate.m_denom = 1001;
+ break;
+ case FRAMERATE_24_FPS:
+ m_framerate.m_num = 24;
+ m_framerate.m_denom = 1;
+ break;
+ case FRAMERATE_25_FPS:
+ m_framerate.m_num = 25;
+ m_framerate.m_denom = 1;
+ break;
+ case FRAMERATE_29p97_FPS:
+ m_framerate.m_num = 30000;
+ m_framerate.m_denom = 1001;
+ break;
+ case FRAMERATE_30_FPS:
+ m_framerate.m_num = 30;
+ m_framerate.m_denom = 1;
+ break;
+ case FRAMERATE_50_FPS:
+ m_framerate.m_num = 50;
+ m_framerate.m_denom = 1;
+ break;
+ case FRAMERATE_59p94_FPS:
+ m_framerate.m_num = 60000;
+ m_framerate.m_denom = 1001;
+ break;
+ case FRAMERATE_60_FPS:
+ m_framerate.m_num = 60;
+ m_framerate.m_denom = 1;
+ break;
+ case FRAMERATE_14p98_FPS:
+ m_framerate.m_num = 15000;
+ m_framerate.m_denom = 1001;
+ break;
+ case FRAMERATE_12p5_FPS:
+ m_framerate.m_num = 25;
+ m_framerate.m_denom = 2;
+ break;
+ default:
+ m_fr_idx = FRAMERATE_CUSTOM;
+ m_framerate.m_num = m_framerate.m_denom = 0;
+ break;
+ }
+}
+
+void SourceParams::SetPixelAspectRatio (PixelAspectRatioType pix_asr_idx)
+{
+ m_pix_asr_idx = pix_asr_idx;
+
+ switch (pix_asr_idx)
+ {
+ case PIXEL_ASPECT_RATIO_1_1:
+ m_pixel_aspect_ratio.m_num = m_pixel_aspect_ratio.m_denom = 1;
+ break;
+ case PIXEL_ASPECT_RATIO_10_11:
+ m_pixel_aspect_ratio.m_num = 10;
+ m_pixel_aspect_ratio.m_denom = 11;
+ break;
+ case PIXEL_ASPECT_RATIO_12_11:
+ m_pixel_aspect_ratio.m_num = 12;
+ m_pixel_aspect_ratio.m_denom = 11;
+ break;
+ case PIXEL_ASPECT_RATIO_40_33:
+ m_pixel_aspect_ratio.m_num = 40;
+ m_pixel_aspect_ratio.m_denom = 33;
+ break;
+ case PIXEL_ASPECT_RATIO_16_11:
+ m_pixel_aspect_ratio.m_num = 16;
+ m_pixel_aspect_ratio.m_denom = 11;
+ break;
+ case PIXEL_ASPECT_RATIO_4_3:
+ m_pixel_aspect_ratio.m_num = 4;
+ m_pixel_aspect_ratio.m_denom = 3;
+ break;
+ default:
+ m_pix_asr_idx = PIXEL_ASPECT_RATIO_CUSTOM;
+ m_pixel_aspect_ratio.m_num = m_pixel_aspect_ratio.m_denom = 0;
+ break;
+ }
+}
+
+void SourceParams::SetSignalRange (SignalRangeType sr)
+{
+ m_sr_idx = sr;
+ switch (sr)
+ {
+ case SIGNAL_RANGE_8BIT_FULL:
+ m_luma_offset = 0;
+ m_luma_excursion = 255;
+ m_chroma_offset = 128;
+ m_chroma_excursion = 255;
+ break;
+ case SIGNAL_RANGE_8BIT_VIDEO:
+ m_luma_offset = 16;
+ m_luma_excursion = 219;
+ m_chroma_offset = 128;
+ m_chroma_excursion = 224;
+ break;
+ case SIGNAL_RANGE_10BIT_VIDEO:
+ m_luma_offset = 64;
+ m_luma_excursion = 876;
+ m_chroma_offset = 512;
+ m_chroma_excursion = 896;
+ break;
+ case SIGNAL_RANGE_12BIT_VIDEO:
+ m_luma_offset = 256;
+ m_luma_excursion = 3504;
+ m_chroma_offset = 2048;
+ m_chroma_excursion = 3584;
+ break;
+ default:
+ m_sr_idx = SIGNAL_RANGE_CUSTOM;
+ m_luma_offset = 0;
+ m_luma_excursion = 0;
+ m_chroma_offset = 0;
+ m_chroma_excursion = 0;
+ break;
+ }
+}
+
+void SourceParams::SetColourSpecification (unsigned int cs_idx)
+{
+ m_cs_idx = cs_idx;
+ switch(cs_idx)
+ {
+ case 1:
+ m_col_primary = CP_SDTV_525;
+ m_col_matrix = CM_SDTV;
+ m_transfer_func = TF_TV;
+ break;
+ case 2:
+ m_col_primary = CP_SDTV_625;
+ m_col_matrix = CM_SDTV;
+ m_transfer_func = TF_TV;
+ break;
+ case 3:
+ m_col_primary = CP_HDTV_COMP_INTERNET;
+ m_col_matrix = CM_HDTV_COMP_INTERNET;
+ m_transfer_func = TF_TV;
+ break;
+ case 4:
+ m_col_primary = CP_DCINEMA;
+ m_col_matrix = CM_HDTV_COMP_INTERNET;
+ m_transfer_func = TF_DCINEMA;
+ break;
+ default:
+ m_cs_idx = 0;
+ m_col_primary = CP_HDTV_COMP_INTERNET;
+ m_col_matrix = CM_HDTV_COMP_INTERNET;
+ m_transfer_func = TF_TV;
+ break;
+ }
+}
+
+void SourceParams::SetColourPrimariesIndex (unsigned int cp)
+{
+ m_cs_idx = 0;
+ if (cp >= CP_UNDEF)
+ {
+ //TODO: flag a warning
+ }
+ m_col_primary = static_cast<ColourPrimaries>(cp);
+}
+
+void SourceParams::SetColourMatrixIndex (unsigned int cm)
+{
+ m_cs_idx = 0;
+ if (cm >= CM_UNDEF)
+ {
+ //TODO: flag a warning
+ }
+ m_col_matrix = static_cast<ColourMatrix>(cm);
+}
+
+void SourceParams::SetTransferFunctionIndex (unsigned int tf)
+{
+ m_cs_idx = 0;
+ if (tf >= TF_UNDEF)
+ {
+ //TODO: flag a warning
+ }
+ m_transfer_func = static_cast<TransferFunction>(tf);
+}
+
+
+//PictureParams functions
+// Default constructor
+PictureParams::PictureParams():
+ m_psort(PictureSort::IntraRefPictureSort()),
+ m_picture_type( INTRA_PICTURE ),
+ m_reference_type( REFERENCE_PICTURE ),
+ m_output(false),
+ m_using_ac(true)
+{}
+
+// Constructor
+PictureParams::PictureParams(const ChromaFormat& cf,
+ int xlen, int ylen,
+ unsigned int luma_depth,
+ unsigned int chroma_depth) :
+ m_cformat(cf),
+ m_psort(PictureSort::IntraRefPictureSort()),
+ m_picture_type( INTRA_PICTURE ),
+ m_reference_type( REFERENCE_PICTURE ),
+ m_output(false),
+ m_xl(xlen),
+ m_yl(ylen),
+ m_luma_depth(luma_depth),
+ m_chroma_depth(chroma_depth),
+ m_using_ac(true)
+{
+ m_cxl = m_cyl = 0;
+ if (cf == format420)
+ {
+ m_cxl = xlen>>1;
+ m_cyl = ylen>>1;
+ }
+ else if (cf == format422)
+ {
+ m_cxl = xlen>>1;
+ m_cyl = ylen;
+ }
+ else if (cf == format444)
+ {
+ m_cxl = xlen;
+ m_cyl = ylen;
+ }
+}
+
+// Constructor
+PictureParams::PictureParams(const ChromaFormat& cf, const PictureSort& ps):
+ m_cformat(cf),
+ m_output(false),
+ m_using_ac(true)
+{
+ SetPicSort( ps );
+}
+
+PictureParams::PictureParams(const SourceParams& sparams):
+ m_cformat(sparams.CFormat()),
+ m_psort(PictureSort::IntraRefPictureSort()),
+ m_picture_type( INTRA_PICTURE ),
+ m_reference_type( REFERENCE_PICTURE ),
+ m_output(false),
+ m_xl(sparams.Xl()),
+ m_yl(sparams.Yl()),
+ m_cxl(sparams.ChromaWidth()),
+ m_cyl(sparams.ChromaHeight()),
+ m_using_ac(true)
+{
+ if (sparams.SourceSampling() == 1)
+ {
+ m_yl = (m_yl>>1);
+ m_cyl = (m_cyl>>1);
+ }
+ m_luma_depth = static_cast<unsigned int>
+ (
+ std::log((double)sparams.LumaExcursion())/std::log(2.0) + 1
+ );
+
+ m_chroma_depth = static_cast<unsigned int>
+ (
+ std::log((double)sparams.ChromaExcursion())/std::log(2.0) + 1
+ );
+}
+
+
+
+void PictureParams::SetXl(int xlen)
+{
+ m_xl = xlen;
+ m_cxl = 0;
+ if (m_cformat == format420 || m_cformat == format422)
+ {
+ m_cxl = m_xl>>1;
+ }
+ else if (m_cformat == format444)
+ {
+ m_cxl = m_xl;
+ }
+}
+
+void PictureParams::SetYl(int ylen)
+{
+ m_yl = ylen;
+ m_cyl = 0;
+ if (m_cformat == format420)
+ {
+ m_cyl = m_yl>>1;
+ }
+ else if (m_cformat == format422 || m_cformat == format444)
+ {
+ m_cyl = m_yl;
+ }
+}
+
+bool PictureParams::IsBPicture() const
+{
+ bool is_B_picture( false );
+
+ if ( m_refs.size() == 2 )
+ {
+ if ( m_refs[0] < m_fnum && m_refs[1] > m_fnum )
+ is_B_picture = true;
+
+ if ( m_refs[0] > m_fnum && m_refs[1] < m_fnum )
+ is_B_picture = true;
+ }
+
+ return is_B_picture;
+}
+
+void PictureParams::SetPicSort( const PictureSort& ps )
+{
+ m_psort=ps;
+ if ( ps.IsIntra() )
+ m_picture_type = INTRA_PICTURE;
+ else
+ m_picture_type = INTER_PICTURE;
+
+ if ( ps.IsRef() )
+ m_reference_type = REFERENCE_PICTURE;
+ else
+ m_reference_type = NON_REFERENCE_PICTURE;
+
+}
+
+void PictureParams::SetPictureType(const PictureType ftype)
+{
+ m_picture_type = ftype;
+ if (ftype == INTRA_PICTURE )
+ m_psort.SetIntra();
+ else
+ m_psort.SetInter();
+}
+
+void PictureParams::SetReferenceType(const ReferenceType rtype)
+{
+ m_reference_type = rtype;
+ if (rtype == REFERENCE_PICTURE )
+ m_psort.SetRef();
+ else
+ m_psort.SetNonRef();
+}
+
+
+QuantiserLists::QuantiserLists()
+:
+ // FIXME: hardcode m_max_qindex to 119. In future this will depend on level
+ // As per spec max qf_idx is 127. But for values of qf_idx > 120 we
+ // will need more than 32 bits. Hence qf_idx is limited to 119.
+ m_max_qindex( 119 ),
+ m_qflist4( m_max_qindex+1 ),
+ m_intra_offset4( m_max_qindex+1 ),
+ m_inter_offset4( m_max_qindex+1 )
+{
+ m_qflist4[0] = 4;
+ m_qflist4[1] = 5;
+ m_intra_offset4[0] = 1;
+ m_inter_offset4[0] = 1;
+ m_intra_offset4[1] = 2;
+ m_inter_offset4[1] = 2;
+
+#ifdef _MSC_VER
+ unsigned __int64 base, qfactor;
+#else
+ uint64_t base, qfactor;
+#endif //_MSC_VER
+
+ for (unsigned int q=2; q<=m_max_qindex; ++q)
+ {
+ base = (1<<(q/4));
+
+ switch (q%4)
+ {
+ case 0:
+ qfactor = 4*base;
+ break;
+ case 1:
+ qfactor = (503829*base+52958)/105917;
+ break;
+ case 2:
+ qfactor = (665857*base+58854)/117708;
+ break;
+ case 3:
+ qfactor = (440253*base+32722)/65444;
+ break;
+ default: //Default case never used
+ qfactor = 0;
+ }
+
+ m_qflist4[q] = int( qfactor );
+
+ m_intra_offset4[q] = (m_qflist4[q]+1)>>1;
+ m_inter_offset4[q] = (3*m_qflist4[q]+4)>>3;
+ }// q
+}
+
+namespace dirac
+{
+VideoFormat IntToVideoFormat(int video_format)
+{
+ switch(video_format)
+ {
+ case VIDEO_FORMAT_CUSTOM:
+ return VIDEO_FORMAT_CUSTOM;
+ case VIDEO_FORMAT_QSIF525:
+ return VIDEO_FORMAT_QSIF525;
+ case VIDEO_FORMAT_QCIF:
+ return VIDEO_FORMAT_QCIF;
+ case VIDEO_FORMAT_SIF525:
+ return VIDEO_FORMAT_SIF525;
+ case VIDEO_FORMAT_CIF:
+ return VIDEO_FORMAT_CIF;
+ case VIDEO_FORMAT_4CIF:
+ return VIDEO_FORMAT_4CIF;
+ case VIDEO_FORMAT_4SIF525:
+ return VIDEO_FORMAT_4SIF525;
+ case VIDEO_FORMAT_SD_480I60:
+ return VIDEO_FORMAT_SD_480I60;
+ case VIDEO_FORMAT_SD_576I50:
+ return VIDEO_FORMAT_SD_576I50;
+ case VIDEO_FORMAT_HD_720P60:
+ return VIDEO_FORMAT_HD_720P60;
+ case VIDEO_FORMAT_HD_720P50:
+ return VIDEO_FORMAT_HD_720P50;
+ case VIDEO_FORMAT_HD_1080I60:
+ return VIDEO_FORMAT_HD_1080I60;
+ case VIDEO_FORMAT_HD_1080I50:
+ return VIDEO_FORMAT_HD_1080I50;
+ case VIDEO_FORMAT_HD_1080P60:
+ return VIDEO_FORMAT_HD_1080P60;
+ case VIDEO_FORMAT_HD_1080P50:
+ return VIDEO_FORMAT_HD_1080P50;
+ case VIDEO_FORMAT_DIGI_CINEMA_2K24:
+ return VIDEO_FORMAT_DIGI_CINEMA_2K24;
+ case VIDEO_FORMAT_DIGI_CINEMA_4K24:
+ return VIDEO_FORMAT_DIGI_CINEMA_4K24;
+ case VIDEO_FORMAT_UHDTV_4K60:
+ return VIDEO_FORMAT_UHDTV_4K60;
+ case VIDEO_FORMAT_UHDTV_4K50:
+ return VIDEO_FORMAT_UHDTV_4K50;
+ case VIDEO_FORMAT_UHDTV_8K60:
+ return VIDEO_FORMAT_UHDTV_8K60;
+ case VIDEO_FORMAT_UHDTV_8K50:
+ return VIDEO_FORMAT_UHDTV_8K50;
+ default:
+ return VIDEO_FORMAT_UNDEFINED;
+ }
+}
+
+ChromaFormat IntToChromaFormat(int chroma_format)
+{
+ switch(chroma_format)
+ {
+ case format444:
+ return format444;
+ case format422:
+ return format422;
+ case format420:
+ return format420;
+ default:
+ return formatNK;
+ }
+}
+
+FrameRateType IntToFrameRateType(int frame_rate_idx)
+{
+ switch(frame_rate_idx)
+ {
+ case FRAMERATE_CUSTOM:
+ return FRAMERATE_CUSTOM;
+ case FRAMERATE_23p97_FPS:
+ return FRAMERATE_23p97_FPS;
+ case FRAMERATE_24_FPS:
+ return FRAMERATE_24_FPS;
+ case FRAMERATE_25_FPS:
+ return FRAMERATE_25_FPS;
+ case FRAMERATE_29p97_FPS:
+ return FRAMERATE_29p97_FPS;
+ case FRAMERATE_30_FPS:
+ return FRAMERATE_30_FPS;
+ case FRAMERATE_50_FPS:
+ return FRAMERATE_30_FPS;
+ case FRAMERATE_59p94_FPS:
+ return FRAMERATE_59p94_FPS;
+ case FRAMERATE_60_FPS:
+ return FRAMERATE_60_FPS;
+ case FRAMERATE_14p98_FPS:
+ return FRAMERATE_14p98_FPS;
+ case FRAMERATE_12p5_FPS:
+ return FRAMERATE_12p5_FPS;
+ default:
+ return FRAMERATE_UNDEFINED;
+ }
+}
+
+PixelAspectRatioType IntToPixelAspectRatioType(int pix_asr_idx)
+{
+ switch(pix_asr_idx)
+ {
+ case PIXEL_ASPECT_RATIO_CUSTOM:
+ return PIXEL_ASPECT_RATIO_CUSTOM;
+ case PIXEL_ASPECT_RATIO_1_1:
+ return PIXEL_ASPECT_RATIO_1_1;
+ case PIXEL_ASPECT_RATIO_10_11:
+ return PIXEL_ASPECT_RATIO_10_11;
+ case PIXEL_ASPECT_RATIO_12_11:
+ return PIXEL_ASPECT_RATIO_12_11;
+ case PIXEL_ASPECT_RATIO_40_33:
+ return PIXEL_ASPECT_RATIO_40_33;
+ case PIXEL_ASPECT_RATIO_16_11:
+ return PIXEL_ASPECT_RATIO_16_11;
+ case PIXEL_ASPECT_RATIO_4_3:
+ return PIXEL_ASPECT_RATIO_4_3;
+ default:
+ return PIXEL_ASPECT_RATIO_UNDEFINED;
+
+ }
+}
+
+SignalRangeType IntToSignalRangeType(int signal_range_idx)
+{
+ switch(signal_range_idx)
+ {
+ case SIGNAL_RANGE_CUSTOM:
+ return SIGNAL_RANGE_CUSTOM;
+ case SIGNAL_RANGE_8BIT_FULL:
+ return SIGNAL_RANGE_8BIT_FULL;
+ case SIGNAL_RANGE_8BIT_VIDEO:
+ return SIGNAL_RANGE_8BIT_VIDEO;
+ case SIGNAL_RANGE_10BIT_VIDEO:
+ return SIGNAL_RANGE_10BIT_VIDEO;
+ case SIGNAL_RANGE_12BIT_VIDEO:
+ return SIGNAL_RANGE_12BIT_VIDEO;
+ default:
+ return SIGNAL_RANGE_UNDEFINED;
+ }
+}
+
+MVPrecisionType IntToMVPrecisionType(int mv_prec)
+{
+ switch(mv_prec)
+ {
+ case MV_PRECISION_PIXEL:
+ return MV_PRECISION_PIXEL;
+ case MV_PRECISION_HALF_PIXEL:
+ return MV_PRECISION_HALF_PIXEL;
+ case MV_PRECISION_QUARTER_PIXEL:
+ return MV_PRECISION_QUARTER_PIXEL;
+ case MV_PRECISION_EIGHTH_PIXEL:
+ return MV_PRECISION_EIGHTH_PIXEL;
+ default:
+ return MV_PRECISION_UNDEFINED;
+ }
+}
+
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.h
new file mode 100644
index 000000000..0ec2653e3
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common.h
@@ -0,0 +1,1613 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: common.h,v 1.79 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Tim Borer,
+* Anuradha Suraparaju,
+* Andrew Kennedy
+* Myo Tun (Brunel University, myo.tun@brunel.ac.uk)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_DEPRECATE
+#endif // _MSC_VER
+
+#include <libdirac_common/arrays.h>
+#include <libdirac_common/common_types.h>
+#include <libdirac_common/dirac_assertions.h>
+#include <vector>
+#include <cmath>
+namespace dirac
+{
+ /*! \file
+ This file contains common classes used throughout the encoder and
+ decoder. The main classes are the encoder and decoder parameters for
+ controlling the encode and decode processes. These are passed
+ throughout the codec. There are also parameter classes for sequences
+ and Pictures.
+ */
+
+
+ //Some basic types used throughout the codec ...//
+ //////////////////////////////////////////////////////////////
+
+ //! Type of picture data (including motion compensated residuals)
+ typedef short ValueType;
+
+#if !defined(HAVE_MMX)
+ //! Type of wavelet coefficient data (should be larger than ValueType)
+ typedef int CoeffType;
+#else
+ //! Type of wavelet coefficient data (should be larger than ValueType)
+ typedef short CoeffType;
+#endif
+
+ //! Type for performing calculations on ValueType and CoeffType. Should be >ValueType, >=CoeffType
+ typedef int CalcValueType;
+
+ //! Prediction modes for blocks
+ enum PredMode{ INTRA , REF1_ONLY , REF2_ONLY , REF1AND2, UNDEFINED };
+
+ //! Types of picture component
+ enum CompSort{ Y_COMP , U_COMP , V_COMP };
+
+ //! Addition or subtraction
+ enum AddOrSub{ ADD , SUBTRACT };
+
+ //! Forward or backward
+ enum Direction { FORWARD , BACKWARD };
+
+ //! Contexts used for coefficient coding
+ enum CtxAliases
+ {//used for residual coding
+ SIGN0_CTX, // -sign, previous symbol is 0
+ SIGN_POS_CTX, // -sign, previous symbol is +ve
+ SIGN_NEG_CTX, // -sign, previous symbol is -ve
+
+ // Follow bit contexts
+ Z_FBIN1z_CTX, // -bin 1, parent is zero, neighbours zero
+ Z_FBIN1nz_CTX, // -bin 1, parent is zero, neighbours non-zero
+ Z_FBIN2_CTX, // -bin 2, parent is zero
+ Z_FBIN3_CTX, // -bin 3, parent is zero
+ Z_FBIN4_CTX, // -bin 4, parent is zero
+ Z_FBIN5_CTX, // -bin 5, parent is zero
+ Z_FBIN6plus_CTX, // -bins 6 plus, parent is zero
+
+ NZ_FBIN1z_CTX, // -bin 1, parent is non-zero, neighbours zero
+ NZ_FBIN1nz_CTX, // -bin 1, parent is non-zero, neighbours non-zero
+ NZ_FBIN2_CTX, // -bin 2, parent is non-zero
+ NZ_FBIN3_CTX, // -bin 3, parent is non-zero
+ NZ_FBIN4_CTX, // -bin 4, parent is non-zero
+ NZ_FBIN5_CTX, // -bin 5, parent is non-zero
+ NZ_FBIN6plus_CTX, // -bins 6 plus, parent is non-zero
+
+ // Information bit contexts
+ INFO_CTX,
+
+ BLOCK_SKIP_CTX, // - blocks are skipped
+ Q_OFFSET_FOLLOW_CTX, // - code block quantiser offset magnitude
+ Q_OFFSET_INFO_CTX, // - code block quantiser offset info context
+ Q_OFFSET_SIGN_CTX, // - code block quantiser offset sign
+ TOTAL_COEFF_CTXS // The total number of coefficient contexts
+ };
+
+ //! Contexts used for MV data coding
+ enum MvCtxAliases
+ {
+ // DC value contexts //
+ ///////////////////////
+
+ DC_FBIN1_CTX,
+ DC_FBIN2plus_CTX,
+ DC_INFO_CTX,
+ DC_SIGN_CTX,
+
+ // Motion vector contexts //
+ ////////////////////////////
+
+
+ MV_FBIN1_CTX,
+ MV_FBIN2_CTX,
+ MV_FBIN3_CTX,
+ MV_FBIN4_CTX,
+ MV_FBIN5plus_CTX,
+
+ MV_INFO_CTX,
+
+ MV_SIGN_CTX,
+
+
+ // Prediction mode contexts
+
+ PMODE_BIT0_CTX, // -bit 0, prediction mode value
+ PMODE_BIT1_CTX, // -bin 1, prediction mode value
+
+
+ // Macroblock contexts
+
+ SB_SPLIT_BIN1_CTX, // bin 1, SB split mode vals
+ SB_SPLIT_BIN2_CTX, // bin 2, SB split mode vals. Bin 3 not required
+
+ SB_SPLIT_INFO_CTX, // info context for SB split mode
+
+ TOTAL_MV_CTXS // The total number of motion vector contexts
+ };
+
+
+ /**
+ * Function to convert an integer to a valid VideoFormat
+ *@param video_format Integer corresponding to a format
+ *@return Valid video-format (returns VIDEO_FORMAT_UNDEFINED if no valid format found)
+ */
+ VideoFormat IntToVideoFormat(int video_format);
+
+ /**
+ * Function to convert an integer to a valid VideoFormat
+ *@param chroma_format Integer corresponding to a format
+ *@return Valid chroma-format (returns formatNK if no valid format found)
+ */
+ ChromaFormat IntToChromaFormat(int chroma_format);
+
+ /**
+ * Function to convert an integer to a valid FrameRate type
+ *@param frame_rate_idx Integer corresponding to a frame-rate in the spec table
+ *@return Valid FrameRateType (returns FRAMERATE_UNDEFINED if no valid frame-rate found)
+ */
+ FrameRateType IntToFrameRateType(int frame_rate_idx);
+
+ /**
+ * Function to convert an integer to a valid PixelAspectRatio type
+ *@param pix_asr_idx Integer corresponding to a pixel aspect ratio in the spec table
+ *@return Valid PixelAspectRatioType (returns PIXEL_ASPECT_RATIO_UNDEFINED if no valid pixel aspect ratio found)
+ */
+ PixelAspectRatioType IntToPixelAspectRatioType(int pix_asr_idx);
+
+ /**
+ * Function to convert an integer to a valid SignalRange type
+ *@param signal_range_idx Integer corresponding to a signal-range in the spec table
+ *@return Valid SignalRangeType (returns SIGNAL_RANGE_UNDEFINED if no valid signal-ratio found)
+ */
+ SignalRangeType IntToSignalRangeType(int signal_range_idx);
+
+ /**
+ * Function to convert an integer to a valid motion-vector precision type
+ *@param mv_prec Integer corresponding to a valid motion-vector precision
+ *@return Valid MVPrecisionType (returns SIGNAL_RANGE_UNDEFINED if no valid precision found)
+ */
+ MVPrecisionType IntToMVPrecisionType(int mv_prec);
+
+ //Classes used throughout the codec//
+ /////////////////////////////////////
+
+ //! Class defining a rational number
+ class Rational
+ {
+ public:
+ //! Numerator
+ unsigned int m_num;
+ //! Denominator
+ unsigned int m_denom;
+ };
+
+ //! Picture type Class
+ class PictureSort
+ {
+ public:
+ PictureSort() { fs = 0x00; } // default intra non-ref
+
+ void SetIntra() { fs &= 0xfe; }
+ void SetInter() { fs |= 0x01; }
+ void SetNonRef() { fs &= 0xfd; }
+ void SetRef() { fs |= 0x02; }
+
+ bool IsInter () const { return fs & 0x01; }
+ bool IsIntra () const { return !IsInter(); }
+ bool IsRef() const { return fs & 0x02; };
+ bool IsNonRef() const { return !IsRef(); }
+
+ void SetIntraNonRef() { SetIntra(); SetNonRef(); }
+ void SetIntraRef() { SetIntra(); SetRef(); }
+ void SetInterNonRef() { SetInter(); SetNonRef(); }
+ void SetInterRef() { SetInter(); SetRef(); }
+
+ bool IsIntraNonRef() const { return (fs & 0x03) == 0x00; }
+ bool IsIntraRef() const { return (fs & 0x03) == 0x02; }
+ bool IsInterNonRef() const { return (fs & 0x03) == 0x01; }
+ bool IsInterRef() const { return (fs & 0x03) == 0x03; }
+
+ void Clear() { fs=0x00; }
+
+ static PictureSort IntraRefPictureSort()
+ {
+ PictureSort fs;
+ fs.SetIntraRef();
+ return fs;
+ }
+
+ static PictureSort InterRefPictureSort()
+ {
+ PictureSort fs;
+ fs.SetInterRef();
+ return fs;
+ }
+
+ static PictureSort IntraNonRefPictureSort()
+ {
+ PictureSort fs;
+ fs.SetIntraNonRef();
+ return fs;
+ }
+
+ static PictureSort InterNonRefPictureSort()
+ {
+ PictureSort fs;
+ fs.SetInterNonRef();
+ return fs;
+ }
+
+ private:
+ unsigned char fs;
+ };
+
+ //! Parameters relating to the source material being encoded/decoded
+ class SourceParams
+ {
+ public:
+ //! default constructor
+ SourceParams (const VideoFormat &vf = VIDEO_FORMAT_CUSTOM,
+ bool set_defaults=true);
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ ////////////////////////////////////////////////////////////////////
+
+ // Gets
+ //! Returns video-format
+ VideoFormat GetVideoFormat() const { return m_video_format;}
+
+ //! Returns the picture width
+ unsigned int Xl() const {return m_xl;}
+
+ //! Returns the picture height
+ unsigned int Yl() const {return m_yl;}
+
+ //! Returns the chroma format of the sequence (420, 422, 444)
+ ChromaFormat CFormat() const {return m_cformat;}
+
+ //! Returns the chroma width
+ int ChromaWidth() const;
+
+ //! Returns the chroma height
+ int ChromaHeight() const;
+
+ //! Returns the source sampling field of the source scan format
+ unsigned int SourceSampling() const { return m_source_sampling; }
+
+ //! Returns true if top field comes first in time
+ bool TopFieldFirst() const { return m_topfieldfirst; }
+
+ //! Return the number for frames per second
+ Rational FrameRate() const { return m_framerate; }
+
+ //! Return the type from the frame rate table
+ FrameRateType FrameRateIndex() const { return m_fr_idx; }
+
+ //! Return the pixel aspect ratio
+ Rational PixelAspectRatio() const { return m_pixel_aspect_ratio; }
+
+ //! Return the type from the pixel aspect ratio table
+ PixelAspectRatioType PixelAspectRatioIndex() const { return m_pix_asr_idx; }
+
+ // Clean area parameters
+ //! Return the Clean area width
+ unsigned int CleanWidth() const { return m_clean_width; }
+ //! Return the Clean area height
+ unsigned int CleanHeight() const { return m_clean_height; }
+ //! Return the Clean area left offset
+ unsigned int LeftOffset() const { return m_left_offset; }
+ //! Return the Clean area top offset
+ unsigned int TopOffset() const { return m_top_offset; }
+
+ // Signal Range parameters
+
+ //! Return the type from the signal range table
+ SignalRangeType SignalRangeIndex() const { return m_sr_idx; }
+
+ //! Return the luma offset
+ unsigned int LumaOffset() const { return m_luma_offset; }
+ //! Return the luma excursion
+ unsigned int LumaExcursion() const { return m_luma_excursion; }
+ //! Return the chroma offset
+ unsigned int ChromaOffset() const { return m_chroma_offset; }
+ //! Return the chroma excursion
+ unsigned int ChromaExcursion() const { return m_chroma_excursion; }
+
+ //! Return the index into the colour specification table
+ unsigned int ColourSpecificationIndex() const { return m_cs_idx; }
+
+ //! Return the colour primaries index
+ ColourPrimaries ColourPrimariesIndex() const { return m_col_primary; }
+ //! Return the colour matrix index
+ ColourMatrix ColourMatrixIndex() const { return m_col_matrix; }
+ //! Return the transfer function index
+ TransferFunction TransferFunctionIndex() const { return m_transfer_func; }
+
+ // Sets
+
+ //! Sets the picture width
+ void SetXl(unsigned int xlen) {m_xl = xlen;}
+
+ //! Sets the picture height
+ void SetYl(unsigned int ylen) {m_yl = ylen;}
+
+ //! Sets the chroma format (Y only, 420, 422 etc)
+ void SetCFormat(ChromaFormat cf) {m_cformat=cf;}
+
+ //! Set if the source sampling field of the scan format
+ void SetSourceSampling(unsigned int source_sampling)
+ { m_source_sampling = source_sampling; }
+
+ //! Set Topfield first. True if top field comes first in time
+ void SetTopFieldFirst(bool tff) { m_topfieldfirst = tff; }
+
+ //! Sets the video format
+ void SetVideoFormat(VideoFormat vf){ m_video_format=vf;}
+
+ //! Set the frame rate
+ void SetFrameRate(const Rational &frate )
+ {
+ m_fr_idx = FRAMERATE_CUSTOM; m_framerate = frate;
+ }
+
+ //! Set the frame rate
+ void SetFrameRate(unsigned int fr_num, unsigned int fr_denom )
+ {
+ m_fr_idx = FRAMERATE_CUSTOM;
+ m_framerate.m_num = fr_num;
+ m_framerate.m_denom = fr_denom;
+ }
+
+ //! Set the frame rate
+ void SetFrameRate(FrameRateType fr);
+
+ //! Set the pixel aspect ratio
+ void SetPixelAspectRatio(const Rational &pix_asr)
+ {
+ m_pix_asr_idx = PIXEL_ASPECT_RATIO_CUSTOM;
+ m_pixel_aspect_ratio = pix_asr;
+ }
+
+ //! Set the pixel aspect ratio
+ void SetPixelAspectRatio(unsigned int pix_as_num, unsigned int pix_as_denom )
+ {
+ m_pix_asr_idx = PIXEL_ASPECT_RATIO_CUSTOM;
+ m_pixel_aspect_ratio.m_num = pix_as_num;
+ m_pixel_aspect_ratio.m_denom = pix_as_denom;
+ }
+
+ //! Set the Pixel Aspect Ratio
+ void SetPixelAspectRatio(PixelAspectRatioType pixel_aspect_ratio);
+
+ // Clean area parameters
+ //! Set the Clean area width
+ void SetCleanWidth(unsigned int clean_width) { m_clean_width = clean_width; }
+ //! Set the Clean area height
+ void SetCleanHeight(unsigned int clean_height) { m_clean_height = clean_height; }
+ //! Set the Clean area left offset
+ void SetLeftOffset(unsigned int left_offset) { m_left_offset = left_offset; }
+ //! Set the Clean area top offset
+ void SetTopOffset(unsigned int top_offset) { m_top_offset = top_offset; }
+
+ // Signal Range parameters
+ //! Set the Signal Range parameters
+ void SetSignalRange(SignalRangeType sr);
+
+ //! Set the luma offset
+ void SetLumaOffset(unsigned int luma_offset) { m_sr_idx = SIGNAL_RANGE_CUSTOM; m_luma_offset = luma_offset; }
+ //! Set the luma excursion
+ void SetLumaExcursion(unsigned int luma_exc) { m_sr_idx = SIGNAL_RANGE_CUSTOM; m_luma_excursion = luma_exc; }
+ //! Set the chroma offset
+ void SetChromaOffset(unsigned int chroma_off) { m_sr_idx = SIGNAL_RANGE_CUSTOM; m_chroma_offset = chroma_off; }
+ //! Set the chroma excursion
+ void SetChromaExcursion(unsigned int chroma_exc) { m_sr_idx = SIGNAL_RANGE_CUSTOM; m_chroma_excursion = chroma_exc; }
+
+ //! Set the Colour specification
+ void SetColourSpecification(unsigned int cs_idx);
+ //! Set the colour primaries index
+ void SetColourPrimariesIndex(unsigned int cp);
+ //! Set the colour matrix index
+ void SetColourMatrixIndex(unsigned int cm);
+ //! Set the transfer function index
+ void SetTransferFunctionIndex(unsigned int tf);
+
+ private:
+ //!Video-format
+ VideoFormat m_video_format;
+
+ //! Width of video
+ unsigned int m_xl;
+
+ //! Height of video
+ unsigned int m_yl;
+
+ //! Presence of chroma and/or chroma sampling structure
+ ChromaFormat m_cformat;
+
+ //! Source sampling field : 0 - progressive, 1 - interlaced
+ unsigned int m_source_sampling;
+
+ //! If m_source_sampling=1, true if the top field is first in temporal order
+ bool m_topfieldfirst;
+
+ //! Index into frame rate table
+ FrameRateType m_fr_idx;
+
+ //! Frame Rate i.e number of frames per second
+ Rational m_framerate;
+
+ //! Index into pixel aspect ratio table
+ PixelAspectRatioType m_pix_asr_idx;
+
+ //! Pixel Aspect Ratio
+ Rational m_pixel_aspect_ratio;
+
+ // Clean area parameters
+
+ //! Clean area width
+ unsigned int m_clean_width;
+
+ //! Clean area height
+ unsigned int m_clean_height;
+
+ //! Clean area left offset
+ unsigned int m_left_offset;
+
+ //! Clean area top offset
+ unsigned int m_top_offset;
+
+ // signal range parameters
+
+ //! Index into signal range table
+ SignalRangeType m_sr_idx;
+
+ //! Luma offset
+ unsigned int m_luma_offset;
+ //! Luma excursion
+ unsigned int m_luma_excursion;
+ //! Chroma offset
+ unsigned int m_chroma_offset;
+ //! Chroma excursion
+ unsigned int m_chroma_excursion;
+
+ //! Index into colour spec table
+ unsigned int m_cs_idx;
+
+ //! Colour Primaries Index
+ ColourPrimaries m_col_primary;
+
+ // Colour Matrix index
+ ColourMatrix m_col_matrix;
+
+ // Transfer function index
+ TransferFunction m_transfer_func;
+ };
+
+
+ //! Parameters for initialising picture class objects
+ class PictureParams
+ {
+
+ public:
+ //! Default constructor
+ PictureParams();
+
+ //! Constructor
+ /*!
+ Picture chroma format is set Picture sort defaults to I picture.
+ */
+ PictureParams(const ChromaFormat& cf, int xlen, int ylen,
+ unsigned int luma_depth, unsigned int chroma_depth);
+
+ //! Constructor
+ /*!
+ Picture chroma format and picture sort are set.
+ */
+ PictureParams(const ChromaFormat& cf, const PictureSort& fs);
+
+ //! Constructor
+ /*!
+ Constructor. Parameters are derived from the source parameters
+ */
+ PictureParams(const SourceParams& sparams);
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ ////////////////////////////////////////////////////////////////////
+
+ // Gets ...
+
+ //! Returns the chroma format of the picture
+ const ChromaFormat& CFormat() const{return m_cformat;}
+
+ //! Returns the picture width
+ int Xl() const {return m_xl;}
+
+ //! Returns the picture height
+ int Yl() const {return m_yl;}
+
+ //! Returns the chroma width of the picture
+ int ChromaXl() const{return m_cxl;}
+
+ //! Returns the chroma height of the picture
+ int ChromaYl() const{return m_cyl;}
+
+ //! Returns the luma depth
+ unsigned int LumaDepth() const { return m_luma_depth; }
+
+ //! Returns the chroma depth
+ unsigned int ChromaDepth() const { return m_chroma_depth; }
+
+ //! Returns the type of the picture
+ const PictureSort& PicSort() const {return m_psort;}
+
+ //! Returns the number of the picture (in time order)
+ int PictureNum() const {return m_fnum;}
+
+ //! Returns the retired reference picture number
+ int RetiredPictureNum() const {return m_retd_fnum;}
+
+ //! Returns whether the picture is bi-directionally predicted by checking references
+ bool IsBPicture() const;
+
+ //! Returns the number of pictures after the current picture number after which the picture can be discarded
+ int ExpiryTime() const {return m_expiry_time;}
+
+ //! Returns an indication of whether the picture has been output yet
+ bool Output() const {return m_output;}
+
+ //! Returns a const C++ reference to the set of reference picture numbers (will be empty if the picture is an I picture)
+ const std::vector<int>& Refs() const {return m_refs;}
+
+ //! Returns non-const C++ referece to the vector of reference pictures, to allow them to be set
+ std::vector<int>& Refs(){return m_refs;}
+
+ //! Return the number of reference pictures
+ unsigned int NumRefs()const {return m_refs.size();}
+
+ //! Returns type of picture (see enum)
+ PictureType GetPictureType () const { return m_picture_type; }
+
+ //! Returns reference picture type (see enum)
+ ReferenceType GetReferenceType() const { return m_reference_type;}
+
+ //! Returns true is entropy coding using Arithmetic coding
+ bool UsingAC() const { return m_using_ac; }
+
+ // ... Sets
+
+ //! Sets the type of picture
+ void SetPicSort( const PictureSort& ps );
+
+ //! Sets the picture to be Intra/Inter
+ void SetPictureType(const PictureType ftype);
+
+ //! Sets the picture to be a reference or not
+ void SetReferenceType(const ReferenceType rtype);
+
+ //! Sets the picture number
+ void SetPictureNum( const int fn ){ m_fnum=fn; }
+
+ //! Sets how long the picture will stay in the buffer (encoder only)
+ void SetExpiryTime( const int expt ){ m_expiry_time=expt; }
+
+ //! Sets a flag to indicate that the picture has been output
+ void SetAsOutput(){m_output=true;}
+
+ //! Sets the chroma format
+ void SetCFormat(ChromaFormat cf){ m_cformat = cf; }
+
+ //! Sets the picture width
+ void SetXl(int xlen);
+
+ //! Sets the picture height
+ void SetYl(int ylen);
+
+ //! Set Luma Depth
+ void SetLumaDepth(unsigned int luma_depth) { m_luma_depth = luma_depth; }
+
+ //! Set Chroma Depth
+ void SetChromaDepth(unsigned int chroma_depth) { m_chroma_depth = chroma_depth; }
+
+ //! Sets the retired reference picture number
+ void SetRetiredPictureNum(int retd_fnum) {m_retd_fnum = retd_fnum;}
+
+ //! Sets the arithmetic coding flag
+ void SetUsingAC(bool using_ac) { m_using_ac = using_ac; }
+
+ private:
+
+ //! The chroma format
+ ChromaFormat m_cformat;
+
+ //! The picture sort
+ PictureSort m_psort;
+
+ //! The set of picture numbers of reference pictures
+ std::vector<int> m_refs;
+
+ //! The number of pictures, after the current picture number, after the (de)coding of which the picture can be deleted
+ int m_expiry_time;
+
+ //! The picture number, in temporal order
+ int m_fnum;
+
+ //! Picture type
+ PictureType m_picture_type;
+
+ //! Reference type
+ ReferenceType m_reference_type;
+
+ //! True if the picture has been output, false if not
+ bool m_output;
+
+ //! The picture number of the retired picture
+ mutable int m_retd_fnum;
+
+ //! Picture luma width
+ int m_xl;
+
+ //! Picture luma height
+ int m_yl;
+
+ //! Picture chroma width
+ int m_cxl;
+
+ //! Picture chroma height
+ int m_cyl;
+
+ //! Luma depth - number of bits required for lumz
+ unsigned int m_luma_depth;
+
+ //! chroma depth - number of bits required for luma
+ unsigned int m_chroma_depth;
+
+ //! arithmetic coding flag
+ bool m_using_ac;
+ };
+
+
+ //! A class for picture component data.
+ /*!
+ A class for encapsulating picture data, derived from TwoDArray.
+ */
+ class PicArray: public TwoDArray<ValueType>
+ {
+ public:
+ //! Default constructor
+ /*!
+ Default constructor creates an empty array.
+ */
+ PicArray(): TwoDArray<ValueType>(){}
+
+ //! Constructor.
+ /*!
+ Contructor creates a two-D array, with specified size and colour
+ format.
+ */
+ PicArray(int height, int width, CompSort cs=Y_COMP):
+ TwoDArray<ValueType>(height, width), m_csort(cs){}
+
+ //copy constructor and assignment= derived by inheritance
+
+ //! Destructor
+ ~PicArray(){}
+
+ //! Return which component is stored
+ const CompSort& CSort() const {return m_csort;}
+
+ //! Set the type of component being stored
+ void SetCSort(const CompSort cs){ m_csort = cs; }
+
+ private:
+
+ CompSort m_csort;
+ };
+
+
+ //! A structure for recording costs, particularly in quantisation.
+ class CostType
+ {
+ public:
+ //! The error (MSE or 4th power)
+ double Error;
+
+ //! The entropy in bits per symbol.
+ double ENTROPY;
+
+ //! The Lagrangian combination of MSE+lambda*entropy
+ double TOTAL;
+ };
+
+
+ //! A class used for correcting estimates of entropy.
+ /*!
+ A class used by the encoder for correcting estimates of entropy. Used
+ for selecting quantisers in subband coefficient coding. Factors can be
+ adjusted in the light of previous experience.
+ */
+ class EntropyCorrector
+ {
+ public:
+ //! Constructor.
+ /*!
+ Constructs arrays of correction factors of size.
+ \param depth the depth of the wavelet transform.
+ */
+ EntropyCorrector(int depth);
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ ////////////////////////////////////////////////////////////////////
+
+ //! Returns the correction factor.
+ /*!
+ Returns the correction factor for the band given also the type of
+ picture and component.
+ */
+ float Factor(const int bandnum, const PictureParams& pp,
+ const CompSort c) const;
+
+ //! Update the correction factors.
+ /*!
+ Update the factors for a given subband, component and picture type.
+ \param bandnum the number of the subband to update
+ \param pp picture parameters
+ \param c component type
+ \param est_bits the number of bits it was estimated would be used
+ \param actual_bits the number of bits that actually were used
+ */
+ void Update(int bandnum, const PictureParams& pp,
+ CompSort c,int est_bits,int actual_bits);
+
+ private:
+ //! Initialises the correction factors
+ void Init();
+
+ TwoDArray<float> m_Yfctrs;
+ TwoDArray<float> m_Ufctrs;
+ TwoDArray<float> m_Vfctrs;
+ };
+
+ //! Parameters for overlapped block motion compensation
+ class OLBParams
+ {
+
+ public:
+
+ //! Default constructor does nothing
+ OLBParams(){}
+
+ //! Constructor
+ /*
+ Constructor rationalises proposed parameters to allow suitable
+ overlap and fit in with chroma format
+ \param xblen the horizontal block length
+ \param yblen the vertical block length
+ \param xblen the horizontal block separation
+ \param yblen the vertical block separation
+
+ */
+ OLBParams(const int xblen, const int yblen,
+ const int xbsep, const int ybsep);
+
+ // Gets ...
+
+ //! Returns the horizontal block length
+ int Xblen() const {return m_xblen;}
+
+ //! Returns the vertical block length
+ int Yblen() const {return m_yblen;}
+
+ //! Returns the horizontal block separation
+ int Xbsep() const {return m_xbsep;}
+
+ //! Returns the vertical block separation
+ int Ybsep() const {return m_ybsep;}
+
+ //! The offset in the horizontal start of the block caused by overlap,=(XBLEN-XBSEP)/2
+ int Xoffset() const {return m_xoffset;}
+
+ //! The offset in the vertical start of the block caused by overlap,=(YBLEN-YBSEP)/2
+ int Yoffset() const {return m_yoffset;}
+
+ // ... and sets
+
+ //! Sets the block width
+ void SetXblen( int xblen ){ m_xblen = xblen; m_xoffset = (m_xblen-m_xbsep)/2;}
+
+ //! Sets the block height
+ void SetYblen( int yblen ){ m_yblen = yblen; m_yoffset = (m_yblen-m_ybsep)/2;}
+
+ //! Sets the block horizontal separation
+ void SetXbsep( int xbsep ){ m_xbsep = xbsep; m_xoffset = (m_xblen-m_xbsep)/2;}
+
+ //! Sets the block vertical separation
+ void SetYbsep( int ybsep ){ m_ybsep = ybsep; m_yoffset = (m_yblen-m_ybsep)/2;}
+
+ bool operator == (const OLBParams bparams) const;
+
+ // overloaded stream operators
+ friend std::ostream & operator<< (std::ostream &, OLBParams &);
+ friend std::istream & operator>> (std::istream &, OLBParams &);
+
+
+ private:
+
+ int m_xblen;
+ int m_yblen;
+ int m_xbsep;
+ int m_ybsep;
+ int m_xoffset;
+ int m_yoffset;
+ };
+
+ //! Parameters relating to the complexity of encoder/decoder
+ class ParseParams
+ {
+ public:
+ //! Default constructor
+ ParseParams();
+
+ // Gets
+
+ //! Get the major version
+ unsigned int MajorVersion() const { return m_major_ver; }
+
+ //! Get the minor version
+ unsigned int MinorVersion() const { return m_minor_ver; }
+
+ //! Get the Profile
+ unsigned int Profile() const { return m_profile; }
+
+ //! Get the Level
+ unsigned int Level() const { return m_level; }
+
+ // Sets
+
+ //! Set the major version
+ void SetMajorVersion(unsigned int major_ver) {m_major_ver = major_ver; }
+
+ //! Set the minor version
+ void SetMinorVersion(unsigned int minor_ver) { m_minor_ver = minor_ver; }
+
+ //! Set the Profile
+ void SetProfile(unsigned int profile) { m_profile = profile; }
+
+ //! Set the Level
+ void SetLevel(unsigned int level) { m_level = level; }
+
+ private:
+ //! Major Version
+ unsigned int m_major_ver;
+ //! Minor Version
+ unsigned int m_minor_ver;
+ //! Profile
+ unsigned int m_profile;
+ //! Level
+ unsigned int m_level;
+ };
+
+ //! Structure to hold code block sizes when spatial partitioning is used
+ class CodeBlocks
+ {
+ public:
+ //! Default Constructor
+ CodeBlocks () : m_hblocks(1), m_vblocks(1)
+ {}
+
+ //! Constructor
+ CodeBlocks (unsigned int hblocks, unsigned int vblocks) :
+ m_hblocks(hblocks),
+ m_vblocks(vblocks)
+ {}
+
+ // Gets
+ //! Return the number of horizontal code blocks
+ unsigned int HorizontalCodeBlocks() const { return m_hblocks; }
+ //! Return the number of vertical code blocks
+ unsigned int VerticalCodeBlocks() const { return m_vblocks; }
+ // Sets
+ //! Set the number of horizontal code blocks
+ void SetHorizontalCodeBlocks(unsigned int hblocks) { m_hblocks = hblocks; }
+ //! Set the number of vertical code blocks
+ void SetVerticalCodeBlocks(unsigned int vblocks) { m_vblocks = vblocks; }
+ private:
+ //! Number of Horizontal code blocks
+ unsigned int m_hblocks;
+ //! Number of Vertical code blocks
+ unsigned int m_vblocks;
+ };
+
+ //! Structure to hold motion parameters when motion comp is used
+ class PicturePredParams
+ {
+ public:
+ PicturePredParams():
+ m_lbparams(3),
+ m_cbparams(3) {}
+
+ //! Return the global motion flag used for encoding/decoding
+ bool UsingGlobalMotion() const { return m_use_global_motion; }
+
+ //! Return the number of picture weight precision bits
+ unsigned int PictureWeightsBits() const { return m_picture_weights_bits; }
+
+ //! Return the Ref1 weight
+ int Ref1Weight() const { return m_ref1_weight; }
+
+ //! Return the Ref2 weight
+ int Ref2Weight() const { return m_ref2_weight; }
+
+ bool CustomRefWeights()
+ {
+ return (m_picture_weights_bits != 1 ||
+ m_ref1_weight != 1 ||
+ m_ref2_weight != 1);
+ }
+
+ //! Return the number of superblocks horizontally
+ int XNumSB() const {return m_x_num_sb;}
+
+ //! Return the number of superblocks vertically
+ int YNumSB() const {return m_y_num_sb;}
+
+ //! Return the number of blocks horizontally
+ int XNumBlocks() const {return m_x_num_blocks;}
+
+ //! Returns the number of blocks vertically
+ int YNumBlocks() const {return m_y_num_blocks;}
+
+ //! Return the Luma block parameters for each macroblock splitting level
+ const OLBParams& LumaBParams(int n) const {return m_lbparams[n];}
+
+ //! Return the Chroma block parameters for each macroblock splitting level
+ const OLBParams& ChromaBParams(int n) const {return m_cbparams[n];}
+
+ //! Return the number of accuracy bits used for motion vectors
+ MVPrecisionType MVPrecision() const { return m_mv_precision; }
+
+ //! Set how many SBs there are horizontally
+ void SetXNumSB(const int xn){m_x_num_sb=xn;}
+
+ //! Set how many SBs there are vertically
+ void SetYNumSB(const int yn){m_y_num_sb=yn;}
+
+ //! Set how many blocks there are horizontally
+ void SetXNumBlocks(const int xn){m_x_num_blocks=xn;}
+
+ //! Set how many blocks there are vertically
+ void SetYNumBlocks(const int yn){m_y_num_blocks=yn;}
+
+ //! Set the block sizes for all SB splitting levels given these prototype block sizes for level=2
+ void SetBlockSizes(const OLBParams& olbparams , const ChromaFormat cformat);
+
+ //! Set block level luma params
+ void SetLumaBlockParams(const OLBParams& olbparams) {m_lbparams[2] = olbparams;}
+
+ //! Set the number of accuracy bits for motion vectors
+ void SetMVPrecision(const MVPrecisionType p)
+ {
+ // Assert in debug mode. Maybe we should throw an exception???
+ TESTM((p >=0 && p <=3), "Motion precision value in range 0..3");
+ m_mv_precision = p;
+ }
+
+ void SetMVPrecision(const MVPrecisionType p) const
+ {
+ // Assert in debug mode. Maybe we should throw an exception???
+ TESTM((p >=0 && p <=3), "Motion precision value in range 0..3");
+ m_mv_precision = p;
+ }
+
+ //! Set the wavelet filter used for picture (de)coding
+ void SetUsingGlobalMotion(bool gm) { m_use_global_motion=gm; }
+
+ //! Set the picture weight precision bits used for (de)coding
+ void SetPictureWeightsPrecision(unsigned int wt_prec) { m_picture_weights_bits=wt_prec; }
+
+ //! Set the ref 1 picture weight
+ void SetRef1Weight(int wt) { m_ref1_weight=wt; }
+
+ //! Set the ref 2 picture weight
+ void SetRef2Weight(int wt) { m_ref2_weight=wt; }
+
+ private:
+
+ //! The number of superblocks horizontally
+ int m_x_num_sb;
+
+ //! The number of superblocks verticaly
+ int m_y_num_sb;
+
+ //! The number of blocks horizontally
+ int m_x_num_blocks;
+
+ //! The number of blocks vertically
+ int m_y_num_blocks;
+
+ OneDArray<OLBParams> m_lbparams;
+
+ OneDArray<OLBParams> m_cbparams;
+
+ //! The precision of motion vectors (number of accuracy bits eg 1=half-pel accuracy)
+ mutable MVPrecisionType m_mv_precision;
+
+ //! picture predicion parameters - precision
+ unsigned int m_picture_weights_bits;
+
+ //! picture predicion parameters - reference picture 1 weight
+ int m_ref1_weight;
+
+ //! picture predicion parameters - reference picture 2 weight
+ int m_ref2_weight;
+
+ //! Global motion fields
+ bool m_use_global_motion;
+
+ };
+
+ //! Parameters common to coder and decoder operation
+ /*!
+ Parameters used throughout both the encoder and the decoder
+ */
+ class CodecParams
+ {
+ public:
+
+ //! Default constructor
+ CodecParams (const VideoFormat& video_format = VIDEO_FORMAT_CUSTOM,
+ PictureType ftype = INTRA_PICTURE,
+ unsigned int num_refs = 0,
+ bool set_defaults=true);
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ ////////////////////////////////////////////////////////////////////
+
+ // Gets ...
+
+ //! Returns the picture coding mode (independent of source format)
+ /*! Returns the picture coding mode (independent of source format)
+ * 0 = Frame coding (no quincunx)
+ * 1 = Field coding (no quincunx)
+ */
+ int PictureCodingMode() const {return m_pic_coding_mode;}
+
+ //! Returns true if the pictures are being coded as fields (mode 1 or 3)
+ bool FieldCoding() const { return (m_pic_coding_mode==1); }
+
+ //! Returns true if the topmost field comes first in time when coding
+ bool TopFieldFirst() const {return m_topfieldfirst;}
+
+ //! Return the picture/field luma width
+ int Xl() const {return m_xl;}
+
+ //! Return the picture/field luma height
+ int Yl() const {return m_yl;}
+
+ //! Return the picture/field chroma width
+ int ChromaXl() const {return m_cxl;}
+
+ //! Return the picture/field chroma height
+ int ChromaYl() const {return m_cyl;}
+
+ //! Returns the luma depth
+ unsigned int LumaDepth() const { return m_luma_depth; }
+
+ //! Returns the chroma depth
+ unsigned int ChromaDepth() const { return m_chroma_depth; }
+
+ //! Return zero transform flag being used for picture (de)coding
+ bool ZeroTransform() const { return m_zero_transform; }
+
+ //! Return the wavelet filter currently being used for picture (de)coding
+ WltFilter TransformFilter() const { return m_wlt_filter; }
+
+ //! Return the transform depth being used for picture (de)coding
+ unsigned int TransformDepth() const { return m_wlt_depth; }
+
+ //! Return multiple quantisers flag being used for picture (de)coding
+ CodeBlockMode GetCodeBlockMode() const { return m_cb_mode; }
+
+ //! Return the spatial partitioning flag being used for picture (de)coding
+ bool SpatialPartition() const { return m_spatial_partition; }
+
+ //! Return the code blocks for a particular level
+ const CodeBlocks &GetCodeBlocks(unsigned int level) const;
+
+ //! Return the video format currently being used for picture (de)coding
+ VideoFormat GetVideoFormat() const { return m_video_format; }
+
+ //! Return the picture prediction params
+ PicturePredParams& GetPicPredParams(){return m_picpredparams;}
+
+ //! Return the picture prediction params
+ const PicturePredParams& GetPicPredParams() const {return m_picpredparams;}
+
+ // ... and Sets
+ //! Sets whether input is coded as fields or quincunxially
+ void SetPictureCodingMode(int pic_coding){m_pic_coding_mode=pic_coding;}
+
+ //! Sets whether the topmost field comes first in time [NB: TBD since this duplicates metadata in the sequence header]
+ void SetTopFieldFirst(bool topf){m_topfieldfirst=topf;}
+
+ //! Set the picture/field luma width
+ void SetXl(const int x){m_xl=x;}
+
+ //! Set the picture/field luma height
+ void SetYl(const int y){m_yl=y;}
+
+ //! Set the frame/field chroma width
+ void SetChromaXl(const int x){m_cxl=x;}
+
+ //! Set the frame/field chroma height
+ void SetChromaYl(const int y){m_cyl=y;}
+
+ //! Set Luma Depth
+ void SetLumaDepth(unsigned int luma_depth) { m_luma_depth = luma_depth; }
+
+ //! Set Chroma Depth
+ void SetChromaDepth(unsigned int chroma_depth) { m_chroma_depth = chroma_depth; }
+
+ //! Set the zero transform flag being used for picture (de)coding
+ void SetZeroTransform(bool zero_transform) { m_zero_transform = zero_transform; }
+
+ //! Set the wavelet filter used for picture (de)coding
+ void SetTransformFilter(const WltFilter wf) { m_wlt_filter=wf; }
+
+ //! Set the wavelet filter used for picture (de)coding
+ void SetTransformFilter(unsigned int wf_idx);
+
+ //! Set the transform depth used for picture (de)coding and allocate for the code blocks array
+ void SetTransformDepth(unsigned int wd);
+
+ //! Set the multiple quantisers flag usedto picture (de)coding
+ void SetCodeBlockMode(unsigned int cb_mode);
+
+ //! Set the spatial partition flag usedto picture (de)coding
+ void SetSpatialPartition(bool spatial_partition) { m_spatial_partition=spatial_partition; }
+
+ //! Set the number of code blocks for a particular level
+ void SetCodeBlocks(unsigned int level, unsigned int hblocks, unsigned int vblocks);
+
+ //! Set the video format used for picture (de)coding
+ void SetVideoFormat(const VideoFormat vd) { m_video_format=vd; }
+
+ protected:
+ //! Return the Wavelet filter associated with the wavelet index
+ WltFilter TransformFilter (unsigned int wf_idx);
+ private:
+
+ //! The picture prediction parameters
+ PicturePredParams m_picpredparams;
+
+ //! The picture coding mode
+ int m_pic_coding_mode;
+
+ //! True if interlaced and top field is first in temporal order
+ bool m_topfieldfirst;
+
+ //! The frame/field luma width
+ int m_xl;
+
+ //! The frame/field luma height
+ int m_yl;
+
+ //! The frame/field chroma width
+ int m_cxl;
+
+ //! The frame/field chroma height
+ int m_cyl;
+
+ //! Luma depth - number of bits required for lumz
+ unsigned int m_luma_depth;
+
+ //! chroma depth - number of bits required for luma
+ unsigned int m_chroma_depth;
+
+ //! The video format being used
+ VideoFormat m_video_format;
+
+ //! Zero transform flag
+ bool m_zero_transform;
+
+ //! The wavelet filter being used
+ WltFilter m_wlt_filter;
+
+ //! Wavelet depth
+ unsigned int m_wlt_depth;
+
+ //! Code block mode
+ CodeBlockMode m_cb_mode;
+
+ //! Spatial partitioning flag
+ bool m_spatial_partition;
+
+ //! Code block array. Number of entries is m_wlt_depth+1
+ OneDArray<CodeBlocks> m_cb;
+ };
+
+ //! Parameters for the encoding process
+ /*!
+ Parameters for the encoding process, derived from CodecParams.
+ */
+ class EncoderParams: public CodecParams
+ {
+ //codec params plus parameters relating solely to the operation of the encoder
+
+ public:
+ //! Default constructor
+ EncoderParams(const VideoFormat& video_format,
+ PictureType ftype = INTER_PICTURE,
+ unsigned int num_refs = 2,
+ bool set_defaults=true);
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ //This means pointers are copied, not the objects they point to.////
+ ////////////////////////////////////////////////////////////////////
+
+ // Gets ...
+
+
+ //! Returns true if we're operating verbosely, false otherwise
+ bool Verbose() const {return m_verbose;}
+
+ //! Returns a flag indicating that we're doing local decoding
+ bool LocalDecode() const {return m_loc_decode;}
+
+ //! Get whether we're doing lossless coding
+ bool Lossless() const {return m_lossless;}
+
+ //! Get whether we're doing full-search motion estimation
+ bool FullSearch() const {return m_full_search; }
+
+ //! Get the horizontal search range for full-search motion estimation
+ int XRangeME() const {return m_x_range_me;}
+
+ //! Get the vertical search range for full-search motion estimation
+ int YRangeME() const {return m_y_range_me;}
+
+ //! Get whether we're doing combined component motion estimation
+ bool CombinedME() const {return m_combined_me; }
+
+ //! Get the quality factor
+ float Qf() const {return m_qf;}
+
+ //! Return the nominal number of L1 pictures before the next I picture
+ /*!
+ Return the nominal number of L1 pictures before the next I picture. Can be
+ overridden by I-picture insertion
+
+ */
+ int NumL1() const {return m_num_L1;}
+
+ //! Return the separation between L1 pictures (and between L1 and I pictures)
+ int L1Sep() const {return m_L1_sep;}
+
+ //! Return the amount we're weighting noise in the U component
+ float UFactor() const {return m_ufactor;}
+
+ //! Return the amount we're weighting noise in the V component
+ float VFactor() const {return m_vfactor;}
+
+ //! Return the number of cycles per degree at the nominal viewing distance for the raster
+ float CPD() const {return m_cpd;}
+
+ //! Return what prefiltering is in place
+ PrefilterType Prefilter() const {return m_prefilter;}
+
+ //! Return the prefiltering strength
+ int PrefilterStrength() const {return m_prefilter_strength;}
+
+ //! Return the Lagrangian parameter to be used for I pictures
+ float ILambda() const {return m_I_lambda;}
+
+ //! Return the Lagrangian parameter to be used for L1 pictures
+ float L1Lambda() const {return m_L1_lambda;}
+
+ //! Return the Lagrangian parameter to be used for L2 pictures
+ float L2Lambda() const {return m_L2_lambda;}
+
+ //! Return the Lagrangian ME parameter to be used for L1 pictures
+ float L1MELambda() const {return m_L1_me_lambda;}
+
+ //! Return the Lagrangian ME parameter to be used for L2 pictures
+ float L2MELambda() const {return m_L2_me_lambda;}
+
+ //! Return the size of the GOP
+ int GOPLength() const;
+
+ //! Return the output path to be used for storing diagnositic data
+ char * OutputPath() const {return ( char* ) m_output_path.c_str();}
+
+ //! Return a reference to the entropy factors
+ const EntropyCorrector& EntropyFactors() const {return *m_ent_correct;}
+
+ //! Return a reference to the entropy factors - we need to be able to change the values of the entropy factors in situ
+ EntropyCorrector& EntropyFactors() {return *m_ent_correct;}
+
+ //! Return the Wavelet filter to be used for intra pictures
+ WltFilter IntraTransformFilter() { return m_intra_wltfilter; }
+
+ //! Return the Wavelet filter to be used for Inter pictures
+ WltFilter InterTransformFilter() { return m_inter_wltfilter; }
+
+ //! Return the Target Bit Rate in kbps
+ int TargetRate() {return m_target_rate;}
+
+ //! Return true if using Arithmetic coding
+ bool UsingAC() const {return m_using_ac;}
+
+ // ... and Sets
+
+ //! Sets verbosity on or off
+ void SetVerbose(bool v){m_verbose=v;}
+
+ //! Sets a flag indicating that we're producing a locally decoded o/p
+ void SetLocalDecode( const bool decode ){m_loc_decode=decode;}
+
+ //! Set whether we're doing lossless coding
+ void SetLossless(const bool l){m_lossless = l;}
+
+ //! Set whether we're doing full-search motion estimation
+ void SetFullSearch(const bool fs){m_full_search = fs;}
+
+ //! Set whether we're doing combined component motion estimation
+ void SetCombinedME(const bool cme){m_combined_me = cme;}
+
+ //! Set the horizontal search range for full-search motion estimation
+ void SetXRangeME(const int xr){m_x_range_me = xr;}
+
+ //! Set the vertical search range for full-search motion estimation
+ void SetYRangeME(const int yr){m_y_range_me = yr;}
+
+ //! Set the quality factor
+ void SetQf(const float qfac){ m_qf=qfac; CalcLambdas(m_qf); }
+
+ //! Set the nominal number of L1 pictures between I pictures
+ void SetNumL1(const int nl){m_num_L1=nl;}
+
+ //! Set the separation between L1 pictures
+ void SetL1Sep(const int lsep){m_L1_sep=lsep;}
+
+ //! Set the amount to weight noise in the U component
+ void SetUFactor(const float uf){m_ufactor=uf;}
+
+ //! Set the amount to weight noise in the V component
+ void SetVFactor(const float vf){m_vfactor=vf;}
+
+ //! Set the number of cycles per degree at the nominal viewing distance
+ void SetCPD(const float cpd){m_cpd=cpd;}
+
+ //! Set denoising value - true or false
+ void SetPrefilter(const PrefilterType pf, const int str){m_prefilter=pf;
+ m_prefilter_strength=str;}
+
+ //! Set the output path to be used for diagnostic data
+ void SetOutputPath(const char * op){ m_output_path = op; }
+
+ //! Sets the entropy factors - TBD: set this up in a constructor and pass encoder params around entirely by reference
+ void SetEntropyFactors(EntropyCorrector* entcorrect){m_ent_correct=entcorrect;}
+ //! Set the Wavelet filter to be used for intra pictures
+ void SetIntraTransformFilter(unsigned int wf_idx);
+
+ //! Set the Wavelet filter to be used for inter pictures
+ void SetInterTransformFilter(unsigned int wf_idx);
+
+ //! Set the Wavelet filter to be used for intra pictures
+ void SetIntraTransformFilter(WltFilter wf) { m_intra_wltfilter = wf; }
+
+ //! Set the number of code blocks for all levels
+ void SetUsualCodeBlocks(const PictureType& ftype);
+
+ //! Set the Wavelet filter to be used for inter pictures
+ void SetInterTransformFilter(WltFilter wf) { m_inter_wltfilter = wf; }
+
+ //! Set the target bit rate
+ void SetTargetRate(const int rate){m_target_rate = rate;}
+
+ //! Set the arithmetic coding flag
+ void SetUsingAC(bool using_ac) {m_using_ac = using_ac;}
+ private:
+
+ //! Calculate the Lagrangian parameters from the quality factor
+ void CalcLambdas(const float qf);
+
+ private:
+
+ //! Code/decode with commentary if true
+ bool m_verbose;
+
+ //! Flag indicating we're doing local decoding
+ bool m_loc_decode;
+
+ //! A flag indicating we're doing lossless coding
+ bool m_lossless;
+
+ //! A flag indicating whether we're doing full-search block matching
+ bool m_full_search;
+
+ //! A flag indicating whether we're doing combined component motion estimation
+ bool m_combined_me;
+
+ //! The horizontal range for full-search block matching
+ int m_x_range_me;
+
+ //! The vertical range for full-search block matching
+ int m_y_range_me;
+
+ //! Quality factor
+ float m_qf;
+
+ //! Number of L1 pictures before next I picture
+ int m_num_L1;
+
+ //! Separation between L1 pictures
+ int m_L1_sep;
+
+ //! factor for weighting U component quantisation errors
+ float m_ufactor;
+
+ //! factor for weighting V component quantisation errors
+ float m_vfactor;
+
+ //! Cycles per degree assumed for viewing the video
+ float m_cpd;
+
+ //! Indicator for prefiltering
+ PrefilterType m_prefilter;
+
+ //! Prefiltering strength
+ int m_prefilter_strength;
+
+ //! Lagrangian parameter for Intra picture coding
+ float m_I_lambda;
+
+ //! Lagrangian parameter for L1 picture coding
+ float m_L1_lambda;
+
+ //! Lagrangian parameter for L2 picture coding
+ float m_L2_lambda;
+
+ //! Lagrangian param for L1 motion estimation
+ float m_L1_me_lambda;
+
+ //! Lagrangian param for L2 motion estimation
+ float m_L2_me_lambda;
+
+ //! Correction factors for quantiser selection
+ EntropyCorrector* m_ent_correct;
+
+ //! Output file path
+ std::string m_output_path;
+
+ //! Wavelet filter for Intra pictures
+ WltFilter m_intra_wltfilter;
+
+ //! Wavelet filter for Inter pictures
+ WltFilter m_inter_wltfilter;
+
+ //! Target bit rate
+ int m_target_rate;
+
+ //! Arithmetic coding flag
+ bool m_using_ac;
+
+ };
+
+ //! Parameters for the decoding process
+ /*!
+ Parameters for the decoding process. Derived from CodecParams.
+ */
+ class DecoderParams: public CodecParams
+ {
+ public:
+ //! Default constructor
+ DecoderParams(const VideoFormat& video_format = VIDEO_FORMAT_CIF, PictureType ftype=INTRA_PICTURE, unsigned int num_refs = 0, bool set_defaults = false);
+
+ //! Returns true if we're operating verbosely, false otherwise
+ bool Verbose() const {return m_verbose;}
+
+ //! Sets verbosity on or off
+ void SetVerbose(bool v){m_verbose=v;}
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ //This means pointers are copied, not the objects they point to.////
+ ////////////////////////////////////////////////////////////////////
+
+
+ private:
+
+ //! Code/decode with commentary if true
+ bool m_verbose;
+
+ };
+
+ //! A simple bounds checking function, very useful in a number of places
+ inline ValueType BChk(const ValueType &num, const ValueType &max)
+ {
+ if(num < 0) return 0;
+ else if(num >= max) return max-1;
+ else return num;
+ }
+
+ //! Class for encapsulating quantiser data
+ class QuantiserLists
+ {
+ public:
+ //! Default constructor
+ QuantiserLists();
+
+ //! Returns 4 times the quantisation factor
+ inline int QuantFactor4( const int index ) const {return m_qflist4[index]; }
+
+ //! Returns the intra Picture quantisation offset for non-zero values
+ inline int IntraQuantOffset4( const int index ) const {return m_intra_offset4[index]; }
+ //! Returns the inter Picture quantisation offset for non-zero values
+ inline int InterQuantOffset4( const int index ) const {return m_inter_offset4[index]; }
+
+ //! Returns the maximum quantiser index supported
+ inline int MaxQuantIndex() const {return m_max_qindex; }
+
+
+ private:
+ unsigned int m_max_qindex;
+ OneDArray<int> m_qflist4;
+ OneDArray<int> m_intra_offset4;
+ OneDArray<int> m_inter_offset4;
+
+ };
+
+ //! A constant list of the quantisers being used in Dirac
+ static const QuantiserLists dirac_quantiser_lists;
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common_types.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common_types.h
new file mode 100644
index 000000000..ef7d7a4a6
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/common_types.h
@@ -0,0 +1,209 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: common_types.h,v 1.21 2008/11/06 04:53:36 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Tim Borer
+* Andrew Kennedy,
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _COMMON_TYPES_H_
+#define _COMMON_TYPES_H_
+
+
+/*! This file contains common enumerated types used throughout the encoder and
+ the end user interfaces to the encoder and decoder
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+* Some basic enumeration types used throughout the codec and by end user ...//
+*/
+
+/*! Types of chroma formatting (formatNK=format not known) */
+typedef enum { format444, format422, format420, formatNK } ChromaFormat;
+
+/*! Types of Wavelet filters supported. filterNK - not known) */
+typedef enum
+{
+ DD9_7=0, /* Deslauriers-Dubuc (9,7) */
+ LEGALL5_3, /* LeGall (5,3) */
+ DD13_7, /* Deslauriers-Dubuc (13,7) */
+ HAAR0, /* Haar, no shift per level*/
+ HAAR1, /* Haar, one shift per level*/
+ FIDELITY, /* Fidelity wavelet */
+ DAUB9_7, /* Integer approximation to Daubechies 97 */
+ filterNK
+} WltFilter;
+
+/*! Enumerated type that defines prefiltering types supported by the
+ encoder. */
+typedef enum
+{
+ NO_PF = 0,
+ DIAGLP,
+ RECTLP,
+ CWM
+} PrefilterType;
+
+static const int NUM_WLT_FILTERS = 8;
+
+/*! Types of picture */
+typedef enum {
+ INTRA_PICTURE=0,
+ INTER_PICTURE
+ } PictureType;
+
+/*! Types of referencing */
+typedef enum {
+ REFERENCE_PICTURE=0,
+ NON_REFERENCE_PICTURE
+} ReferenceType;
+
+/*! Types for video-format */
+typedef enum {
+ VIDEO_FORMAT_CUSTOM=0,
+ VIDEO_FORMAT_QSIF525,
+ VIDEO_FORMAT_QCIF,
+ VIDEO_FORMAT_SIF525,
+ VIDEO_FORMAT_CIF,
+ VIDEO_FORMAT_4SIF525,
+ VIDEO_FORMAT_4CIF,
+ VIDEO_FORMAT_SD_480I60,
+ VIDEO_FORMAT_SD_576I50,
+ VIDEO_FORMAT_HD_720P60,
+ VIDEO_FORMAT_HD_720P50,
+ VIDEO_FORMAT_HD_1080I60,
+ VIDEO_FORMAT_HD_1080I50,
+ VIDEO_FORMAT_HD_1080P60,
+ VIDEO_FORMAT_HD_1080P50,
+ VIDEO_FORMAT_DIGI_CINEMA_2K24,
+ VIDEO_FORMAT_DIGI_CINEMA_4K24,
+ VIDEO_FORMAT_UHDTV_4K60,
+ VIDEO_FORMAT_UHDTV_4K50,
+ VIDEO_FORMAT_UHDTV_8K60,
+ VIDEO_FORMAT_UHDTV_8K50,
+ VIDEO_FORMAT_UNDEFINED
+} VideoFormat;
+
+/*! Types of Colour primaries */
+typedef enum {
+ CP_HDTV_COMP_INTERNET=0,
+ CP_SDTV_525,
+ CP_SDTV_625,
+ CP_DCINEMA,
+ CP_UNDEF
+}ColourPrimaries;
+
+/*! Types of Colour Matrices */
+typedef enum {
+ CM_HDTV_COMP_INTERNET=0,
+ CM_SDTV,
+ CM_REVERSIBLE,
+ CM_UNDEF
+}ColourMatrix;
+
+/*! Types of Transfer functions */
+typedef enum {
+ TF_TV=0,
+ TF_EXT_GAMUT,
+ TF_LINEAR,
+ TF_DCINEMA,
+ TF_UNDEF
+} TransferFunction;
+
+/*! Types of Picture-rate */
+typedef enum {
+ FRAMERATE_CUSTOM=0,
+ FRAMERATE_23p97_FPS,
+ FRAMERATE_24_FPS,
+ FRAMERATE_25_FPS,
+ FRAMERATE_29p97_FPS,
+ FRAMERATE_30_FPS,
+ FRAMERATE_50_FPS,
+ FRAMERATE_59p94_FPS,
+ FRAMERATE_60_FPS,
+ FRAMERATE_14p98_FPS,
+ FRAMERATE_12p5_FPS,
+ FRAMERATE_UNDEFINED
+} FrameRateType;
+
+/*! Types of Aspect Ratio */
+typedef enum {
+ PIXEL_ASPECT_RATIO_CUSTOM=0,
+ PIXEL_ASPECT_RATIO_1_1,
+ PIXEL_ASPECT_RATIO_10_11,
+ PIXEL_ASPECT_RATIO_12_11,
+ PIXEL_ASPECT_RATIO_40_33,
+ PIXEL_ASPECT_RATIO_16_11,
+ PIXEL_ASPECT_RATIO_4_3,
+ PIXEL_ASPECT_RATIO_UNDEFINED
+} PixelAspectRatioType;
+
+
+/*! Types of signal range */
+typedef enum {
+ SIGNAL_RANGE_CUSTOM=0,
+ SIGNAL_RANGE_8BIT_FULL,
+ SIGNAL_RANGE_8BIT_VIDEO,
+ SIGNAL_RANGE_10BIT_VIDEO,
+ SIGNAL_RANGE_12BIT_VIDEO,
+ SIGNAL_RANGE_UNDEFINED
+} SignalRangeType;
+
+/*! Types of motion-vector precision */
+typedef enum {
+ MV_PRECISION_PIXEL=0,
+ MV_PRECISION_HALF_PIXEL,
+ MV_PRECISION_QUARTER_PIXEL,
+ MV_PRECISION_EIGHTH_PIXEL,
+ MV_PRECISION_UNDEFINED
+} MVPrecisionType;
+
+/*! Type of quantiser modes when spatial partitioning is enabled */
+typedef enum
+{
+ QUANT_SINGLE,
+ QUANT_MULTIPLE,
+ QUANT_UNDEF
+} CodeBlockMode;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.cpp
new file mode 100644
index 000000000..747c64998
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.cpp
@@ -0,0 +1,66 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_assertions.cpp,v 1.2 2004/11/22 13:28:05 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+
+#include "dirac_assertions.h"
+using namespace dirac;
+
+namespace dirac
+{
+void dirac_assert( const char *p_fname, int line_number, const char *p_mess )
+{
+ dirac_report( p_fname, line_number, p_mess );
+ // dump core
+ abort ();
+}
+
+void dirac_report( const char *p_fname, int line_number, const char *p_mess )
+{
+ std::string errMess("Assertion ");
+
+ if ( p_mess )
+ errMess = errMess + "^ " + std::string(p_mess) + " ^" +" failed";
+ else
+ errMess += " failure";
+
+ std::cerr << errMess << " in file " << p_fname << " at line " << line_number << std::endl;
+}
+} // namespace dirac
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.h
new file mode 100644
index 000000000..209447e84
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_assertions.h
@@ -0,0 +1,80 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_assertions.h,v 1.3 2004/11/22 14:05:02 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+#ifndef DIRAC_ASSERTIONS_H
+#define DIRAC_ASSERTIONS_H
+namespace dirac
+{
+
+#undef cmpCOND
+#define cmpCOND( exp, trueRes, falseRes ) ( (exp) ? (trueRes) : (falseRes) )
+
+#undef ERREXP
+#define ERREXP(exp,errfn,text) cmpCOND((exp), ((void)0), errfn(__FILE__,__LINE__,text))
+
+#undef ASSERT
+#define ASSERT(exp) ERREXP(exp,dirac_assert,NULL)
+
+#undef ASSERTM
+#define ASSERTM(exp,text) ERREXP(exp,dirac_assert,text)
+
+#undef TEST
+#undef TESTM
+#undef REPORT
+#undef REPORTM
+
+#ifdef DIRAC_DEBUG
+#define TEST(exp) ASSERT(exp)
+#define TESTM(exp,text) ASSERTM(exp,text)
+#define REPORT(exp) ASSERT(exp)
+#define REPORTM(exp,text) ASSERTM(exp,text)
+#else
+#define TEST(exp)
+#define TESTM(exp,text)
+#define REPORT(exp) ERREXP(exp,dirac_report,NULL)
+#define REPORTM(exp,text) ERREXP(exp,dirac_report,text)
+#endif
+
+
+/*! Print a message to standard error and abort if in debug mode */
+void dirac_assert( const char *p_fname, int line_number, const char *p_mess);
+
+/*! Print a message to standard error */
+void dirac_report( const char *p_fname, int line_number, const char *p_mess);
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.cpp
new file mode 100644
index 000000000..b42e42748
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.cpp
@@ -0,0 +1,100 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_exception.cpp,v 1.2 2007/03/19 16:18:59 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+ * Implementation of class DiracException.
+ */
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+using namespace std;
+
+///////////////////////////////// PUBLIC /////////////////////////////////////
+
+
+DiracException::DiracException(
+ const DiracErrorCode& errorCode,
+ const string& errorMessage,
+ const DiracSeverityCode& severityCode)
+: mErrorCode(errorCode),
+ mSeverityCode(severityCode),
+ mErrorMessage(errorMessage)
+{
+}
+
+
+DiracException::DiracException(
+ const DiracException& src)
+: mErrorCode(src.mErrorCode)
+, mSeverityCode(src.mSeverityCode)
+, mErrorMessage(src.mErrorMessage)
+{
+
+}
+
+DiracException::~DiracException()
+{
+}
+
+
+//============================== ACCESS ======================================
+
+DiracErrorCode DiracException::GetErrorCode() const
+{
+ return mErrorCode;
+}
+
+ DiracSeverityCode DiracException::GetSeverityCode() const
+{
+ return mSeverityCode;
+}
+
+std::string DiracException::GetErrorMessage() const
+{
+ return mErrorMessage;
+}
+
+
+//========================== GLOBAL OPERATORS ================================
+ostream& operator<<(
+ ostream& dst,
+ const DiracException& exception)
+{
+ // output the error message
+ dst << exception.GetErrorMessage() << endl;
+ return dst;
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.h
new file mode 100644
index 000000000..44c54cb0d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_exception.h
@@ -0,0 +1,215 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_exception.h,v 1.6 2008/01/31 11:25:16 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+ * Definition of class DiracException.
+ */
+#ifndef DiracException_h
+#define DiracException_h
+
+
+// SYSTEM INCLUDES
+//
+#include <string> // has a string
+#include <iostream> // has an ostringstream
+
+
+namespace dirac {
+
+ /**
+ * Enumeration of Dirac-defined error codes.
+ *
+ *
+ */
+ enum DiracErrorCode {
+ ERR_UNSUPPORTED_STREAM_DATA=0,
+ ERR_END_OF_STREAM,
+ ERR_INVALID_VIDEO_FORMAT,
+ ERR_INVALID_CHROMA_FORMAT,
+ ERR_INVALID_PICTURE_RATE,
+ ERR_INVALID_SIGNAL_RANGE,
+ ERR_INVALID_PIXEL_ASPECT_RATIO,
+ ERR_INVALID_VIDEO_DEPTH,
+ ERR_INVALID_MOTION_VECTOR_PRECISION,
+ ERR_INVALID_INIT_DATA
+
+ };
+
+ /**
+ * Error-severity states
+ */
+ enum DiracSeverityCode {
+ SEVERITY_NO_ERROR=0,
+ SEVERITY_WARNING,
+ SEVERITY_PICTURE_ERROR,
+ SEVERITY_ACCESSUNIT_ERROR,
+ SEVERITY_SEQUENCE_ERROR,
+ SEVERITY_TERMINATE
+ };
+
+/**
+ * DiracException is the class which should be used for all exceptions
+ * within Dirac.
+ */
+class DiracException
+{
+public:
+
+
+ /**
+ * Construct from error source ID, error code, and message.
+ *
+ * @param errorCode The error code.
+ * @param errorMessage The error message.
+ * @param severityCode The error source ID.
+ */
+ DiracException(
+ const DiracErrorCode& errorCode,
+ const std::string& errorMessage,
+ const DiracSeverityCode& severityCode);
+
+ /**
+ * Copy constructor.
+ */
+ DiracException(
+ const DiracException& src);
+
+ /**
+ * Destructor.
+ */
+ virtual ~DiracException();
+
+
+// OPERATORS
+
+
+// ACCESS
+
+ /**
+ * Get the error code of this exception.
+ *
+ * @return The error code of this exception.
+ */
+ DiracErrorCode GetErrorCode() const;
+
+ /**
+ * Get the severity level of this exception.
+ *
+ * @return The severity level of this exception.
+ */
+ DiracSeverityCode GetSeverityCode() const;
+
+ /**
+ * Get the error message of this exception.
+ *
+ * @return The error message of this exception.
+ */
+ std::string GetErrorMessage() const;
+
+
+
+private:
+
+// ATTRIBUTES
+
+ /**
+ * The error code of this exception.
+ */
+ DiracErrorCode mErrorCode;
+
+ /**
+ * Severity of exception
+ */
+ DiracSeverityCode mSeverityCode;
+
+ /**
+ * The error message.
+ */
+ std::string mErrorMessage;
+
+
+
+// UNIMPLEMENTED METHODS
+ DiracException& operator=(const DiracException&);
+
+}; // class DiracException
+
+
+
+
+
+// GLOBAL OPERATORS
+//
+std::ostream& operator<<(std::ostream& dst, const DiracException& exception);
+
+
+// MACROS FOR LOGGING AND THROWING DIRAC EXCEPTIONS
+//
+
+
+/**
+ * Write an exception to the log
+ */
+#define DIRAC_LOG_EXCEPTION(exception) \
+ { \
+ if(exception.GetSeverityCode()!=SEVERITY_NO_ERROR) \
+ std::cerr << exception.GetErrorMessage(); \
+ }
+
+/**
+ * Construct an exception from 3 arguments, log it, and throw it.
+ */
+#define DIRAC_THROW_EXCEPTION(arg1,arg2,arg3) \
+ { \
+ DiracException exception(arg1,arg2, arg3); \
+ DIRAC_LOG_EXCEPTION(exception) \
+ throw exception; \
+ }
+
+/**
+ * Catch a DiracException, log it, and rethrow it.
+ */
+#define DIRAC_CATCH_AND_RETHROW() \
+ catch (const DiracException& e) { \
+ DiracException exception(e); \
+ DIRAC_LOG_EXCEPTION(exception)\
+ throw exception; \
+ }
+
+} // namespace Dirac
+
+#endif // DiracException_h
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_inttypes.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_inttypes.h
new file mode 100644
index 000000000..506c81668
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_inttypes.h
@@ -0,0 +1,48 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_inttypes.h,v 1.1 2008/05/06 09:35:51 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef DIRAC_INTTYPES_H
+#define DIRAC_INTTYPES_H
+
+#ifndef _MSC_VER
+#include <libdirac_common/dirac-stdint.h>
+#else
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#endif //_MSC_VER
+
+#endif //DIRAC_INTTYPES_H
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_types.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_types.h
new file mode 100644
index 000000000..cc7cd7f54
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/dirac_types.h
@@ -0,0 +1,198 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_types.h,v 1.12 2008/11/18 23:25:54 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _DIRAC_TYPES_H
+#define _DIRAC_TYPES_H
+
+#include <libdirac_common/common_types.h>
+
+/*! This file contains common enumerated types used throughout
+ the end user interfaces to the encoder and decoder
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(WIN32) && defined(_WINDLL)
+#define DllExport __declspec( dllexport )
+#else
+#define DllExport
+#endif
+
+/*
+* Major version corresponds to major version of the software.
+* Minor version corresponds to minor version of the software. Bump
+* this up by one whenever there are major feature changes to the software.
+* Patch version corresponds to changes in the API. It should be
+* bumped up by 1 for every committed change to the API
+*/
+#define DIRAC_RESEARCH_MAJOR_VERSION 1 /* 0..255 */
+#define DIRAC_RESEARCH_MINOR_VERSION 0 /* 0..255 */
+#define DIRAC_RESEARCH_PATCH_VERSION 2 /* 0..255 */
+
+#define DIRAC_RESEARCH_VERSION(X, Y, Z) \
+ (((X)<<16) + ((Y)<<8) + (Z))
+
+#define DIRAC_RESEARCH_CURVERSION \
+ DIRAC_RESEARCH_VERSION(DIRAC_RESEARCH_MAJOR_VERSION, \
+ DIRAC_RESEARCH_MINOR_VERSION, \
+ DIRAC_RESEARCH_PATCH_VERSION)
+
+#define DIRAC_RESEARCH_VERSION_ATLEAST(X, Y, Z) \
+ (DIRAC_RESEARCH_CURVERSION >= DIRAC_RESEARCH_VERSION(X, Y, Z))
+
+/*
+* Some basic enumeration types used by end user encoder and decoder ...//
+*/
+typedef ChromaFormat dirac_chroma_t;
+typedef PictureType dirac_picture_type_t;
+typedef ReferenceType dirac_reference_type_t;
+typedef WltFilter dirac_wlt_filter_t;
+
+typedef struct
+{
+ int numerator;
+ int denominator;
+} dirac_rational_t;
+
+typedef dirac_rational_t dirac_frame_rate_t;
+typedef dirac_rational_t dirac_pix_asr_t;
+
+/*! Structure that holds the parase parameters */
+typedef struct
+{
+ //! Major version
+ unsigned int major_ver;
+ //! Minor version
+ unsigned int minor_ver;
+ //! Profile
+ unsigned int profile;
+ //! level
+ unsigned int level;
+} dirac_parseparams_t;
+
+typedef struct
+{
+ unsigned int width;
+ unsigned int height;
+ unsigned int left_offset;
+ unsigned int top_offset;
+} dirac_clean_area_t;
+
+typedef struct
+{
+ unsigned int luma_offset;
+ unsigned int luma_excursion;
+ unsigned int chroma_offset;
+ unsigned int chroma_excursion;
+} dirac_signal_range_t;
+
+typedef struct
+{
+ float kr;
+ float kb;
+} dirac_col_matrix_t;
+
+typedef ColourPrimaries dirac_col_primaries_t;
+typedef TransferFunction dirac_transfer_func_t;
+
+typedef struct
+{
+ dirac_col_primaries_t col_primary;
+ dirac_col_matrix_t col_matrix;
+ dirac_transfer_func_t trans_func;
+} dirac_colour_spec_t;
+
+/*! Structure that holds the source parameters */
+typedef struct
+{
+ /*! numper of pixels per line */
+ unsigned int width;
+ /*! number of lines per frame */
+ unsigned int height;
+ /*! chroma type */
+ dirac_chroma_t chroma;
+ /*! numper of pixels of chroma per line */
+ unsigned int chroma_width;
+ /*! number of lines of chroma per frame */
+ unsigned int chroma_height;
+ /*! source sampling field: 0 - progressive; 1 - interlaced */
+ unsigned int source_sampling;
+ /*! top field comes first : 0 - false; 1 - true. Set by Dirac library. */
+ int topfieldfirst;
+ /*! frame rate */
+ dirac_frame_rate_t frame_rate;
+ /*! pixel aspect ratio */
+ dirac_pix_asr_t pix_asr;
+ /* clean area*/
+ dirac_clean_area_t clean_area;
+ /* signal range*/
+ dirac_signal_range_t signal_range;
+ /* colour specification*/
+ dirac_colour_spec_t colour_spec;
+
+} dirac_sourceparams_t;
+
+/*! Structure that holds the picture parameters */
+typedef struct
+{
+ /*! picture type */
+ dirac_picture_type_t ptype;
+ /*! reference type */
+ dirac_reference_type_t rtype;
+ /*! picture number in decoded order */
+ int pnum;
+} dirac_picparams_t;
+
+
+/*! Structure that holds the frame buffers into which data is written
+(NB we have frame-oriented IO even though we code pictures)*/
+typedef struct
+{
+ /*! buffers to hold the luma and chroma data */
+ unsigned char *buf[3];
+ /*! user data */
+ void *id;
+} dirac_framebuf_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.cpp
new file mode 100644
index 000000000..7fe5515c9
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.cpp
@@ -0,0 +1,1239 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mot_comp.cpp,v 1.47 2009/04/21 01:33:04 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author),
+* Thomas Davies,
+* Steve Bearcroft
+* Mike Ferenduros
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#include <libdirac_common/mot_comp.h>
+#if defined(HAVE_MMX)
+#include <libdirac_common/mot_comp_mmx.h>
+#endif
+#include <libdirac_common/motion.h>
+#include <libdirac_common/picture_buffer.h>
+using namespace dirac;
+
+using std::vector;
+
+
+#define NUM_USED_BLKS(w,sep,len) ((w+sep+(len-sep)/2-1)/sep)
+
+//--public member functions--//
+///////////////////////////////
+
+// Convenience function to perform motion compensation on a picture
+// Static function that motion compensates a picture. It uses the
+// MV precision value in the PicturePredParams to instantiate the
+// appropriate MotionCompensation sub-class.
+void MotionCompensator::CompensatePicture(const PicturePredParams &ppp,
+ const AddOrSub direction ,
+ const MvData& mv_data,
+ Picture* in_pic ,
+ Picture* refsptr[2])
+{
+ switch (ppp.MVPrecision())
+ {
+ case MV_PRECISION_EIGHTH_PIXEL:
+ {
+ MotionCompensator_EighthPixel my_comp(ppp);
+ my_comp.CompensatePicture( direction , mv_data, in_pic, refsptr);
+ break;
+ }
+ case MV_PRECISION_HALF_PIXEL:
+ {
+ MotionCompensator_HalfPixel my_comp(ppp);
+ my_comp.CompensatePicture( direction , mv_data, in_pic, refsptr);
+ break;
+ }
+ case MV_PRECISION_PIXEL:
+ {
+ MotionCompensator_Pixel my_comp(ppp);
+ my_comp.CompensatePicture( direction , mv_data, in_pic, refsptr);
+ break;
+ }
+ case MV_PRECISION_QUARTER_PIXEL:
+ default:
+ {
+ MotionCompensator_QuarterPixel my_comp(ppp);
+ my_comp.CompensatePicture( direction , mv_data, in_pic, refsptr);
+ break;
+ }
+ }
+
+ return;
+}
+
+// Constructor
+// Initialises the lookup tables that is needed for motion
+// motion compensation. Creates the necessary arithmetic objects and
+// calls ReConfig to create weighting blocks to fit the values within
+// m_predparams.
+MotionCompensator::MotionCompensator( const PicturePredParams &ppp ):
+ m_predparams(ppp),
+ luma_or_chroma(true)
+{
+ // Allocate for block weights
+ m_block_weights = new TwoDArray<ValueType>[9];
+ // Allocate for superblock weights
+ m_macro_block_weights = new TwoDArray<ValueType>[9];
+ // Allocate for sub superblock weights
+ m_sub_block_weights = new TwoDArray<ValueType>[9];
+
+ //Configure weighting blocks for the first time
+ ReConfig();
+}
+
+// Destructor
+MotionCompensator::~MotionCompensator()
+{
+ //Tidy up the pointers
+ delete[] m_block_weights;
+ delete[] m_macro_block_weights;
+ delete[] m_sub_block_weights;
+}
+
+//Called to perform motion compensated addition/subtraction on an entire picture.
+void MotionCompensator::CompensatePicture( const AddOrSub direction ,
+ const MvData& mv_data,
+ Picture* my_picture ,
+ Picture* refsptr[2])
+{
+ m_add_or_sub = direction;
+
+ const PictureSort& psort=my_picture->GetPparams().PicSort();
+
+ m_cformat = my_picture->GetPparams().CFormat();
+
+ if (psort.IsInter())
+ {//we can motion compensate
+
+ const std::vector<int>& refs=my_picture->GetPparams().Refs();
+
+ // Now check that references are marked correctly
+ if ( !refsptr[0]->GetPparams().PicSort().IsRef() )
+ {
+ std::cout<<std::endl<<"WARNING! Reference picture (number "<<refs[0];
+ std::cout<<") being used is not marked as a reference. Incorrect output is likely.";
+ }
+ if ( refsptr[0]->GetPparams().PictureNum() != refs[0] )
+ {
+ std::cout<<std::endl<<"WARNING! Reference picture number 0 ";
+ std::cout<<"does not agree("<<refsptr[0]->GetPparams().PictureNum()<<" and ";
+ std::cout<<refs[0]<<"). Incorrect output is likely.";
+ }
+
+
+ if ( refs.size()>1 )
+ {
+ if ( !refsptr[1]->GetPparams().PicSort().IsRef() )
+ {
+ std::cout<<std::endl<<"WARNING! Reference picture (number ";
+ std::cout<<refs[1]<<") being used is not marked as a reference. Incorrect output is likely.";
+ }
+ if ( refsptr[1]->GetPparams().PictureNum() != refs[1])
+ {
+ std::cout<<std::endl<<"WARNING! Reference picture number 1 ";
+ std::cout<<"does not agree("<<refsptr[1]->GetPparams().PictureNum()<<" and ";
+ std::cout<<refs[1]<<"). Incorrect output is likely.";
+ }
+ }
+ else
+ refsptr[1] = refsptr[0];
+
+ luma_or_chroma = true;
+ //now do all the components
+ CompensateComponent( my_picture , refsptr, mv_data , Y_COMP );
+
+ luma_or_chroma = false;
+ CompensateComponent( my_picture , refsptr, mv_data , U_COMP);
+ CompensateComponent( my_picture , refsptr, mv_data , V_COMP);
+ }
+}
+
+//--private member functions--//
+////////////////////////////////
+
+//Needs to be called if the blocksize changes (and
+//on startup). This method creates an array of weighting
+//blocks that are used to acheive correctly overlapping
+//blocks.
+void MotionCompensator::ReConfig()
+{
+ if (luma_or_chroma)
+ m_bparams = m_predparams.LumaBParams(2);
+ else
+ m_bparams = m_predparams.ChromaBParams(2);
+
+ // Calculate the shift required in horizontal and vertical direction for
+ // OBMC and the weighting bits for each reference picture.
+
+ // Total shift = shift assuming equal picture weights +
+ // picture weights precision
+ int blocks_per_mb_row = m_predparams.XNumBlocks()/m_predparams.XNumSB();
+ int blocks_per_sb_row = blocks_per_mb_row>>1;
+ int mb_xlen = m_bparams.Xblen()*blocks_per_mb_row - (m_bparams.Xblen()-m_bparams.Xbsep())*(blocks_per_mb_row-1);
+ int mb_ylen = m_bparams.Yblen();
+ int mb_xsep = mb_xlen - (m_bparams.Xblen()-m_bparams.Xbsep());
+ int mb_ysep = m_bparams.Ybsep();
+ int sb_xlen = m_bparams.Xblen()*blocks_per_sb_row - (m_bparams.Xblen()-m_bparams.Xbsep())*(blocks_per_sb_row-1);
+ int sb_ylen = m_bparams.Yblen();
+ int sb_xsep = sb_xlen - (m_bparams.Xblen() - m_bparams.Xbsep());
+ int sb_ysep = m_bparams.Ybsep();
+
+ for(int i = 0; i < 9; i++)
+ {
+ m_block_weights[i].Resize( m_bparams.Yblen() , m_bparams.Xblen() );
+ m_macro_block_weights[i].Resize( mb_ylen , mb_xlen );
+ m_sub_block_weights[i].Resize( sb_ylen , sb_xlen );
+ }
+
+ // Firstly calculate the non-weighted Weighting blocks. i,e, assuming that
+ // the picture_weight for each reference picture is 1.
+
+ // Calculate non-weighted Block Weights
+ CalculateWeights( m_bparams.Xbsep(), m_bparams.Ybsep(), m_block_weights );
+
+ // Calculate non-weighted "macro" Block Weights
+ CalculateWeights( mb_xsep, mb_ysep , m_macro_block_weights );
+
+ // Calculate non-weighted superblock Weights
+ CalculateWeights( sb_xsep, sb_ysep , m_sub_block_weights );
+}
+
+void MotionCompensator::CompensateComponent( Picture* pic ,
+ Picture* refsptr[2] ,
+ const MvData& mv_data ,
+ const CompSort cs )
+{
+ // Set up references to pictures and references
+ PicArray& pic_data_out = pic->Data( cs );
+
+ // Size of picture component being motion compensated
+
+ const PicArray& ref1up = refsptr[0]->UpData( cs );
+ const PicArray& ref2up = refsptr[1]->UpData( cs );
+
+ // Set up a row of blocks which will contain the MC data, which
+ // we'll add or subtract to pic_data_out
+ TwoDArray<ValueType> pic_data(m_bparams.Yblen(), pic_data_out.LengthX(), 0 );
+
+ // Factors to compensate for subsampling of chroma
+ int xscale_shift = 0;
+ int yscale_shift = 0;
+ if ( cs != Y_COMP )
+ {
+ if (m_cformat == format420)
+ {
+ xscale_shift = 1;
+ yscale_shift = 1;
+ }
+ else if (m_cformat == format422)
+ {
+ xscale_shift = 1;
+ yscale_shift = 0;
+ }
+ }
+
+ ImageCoords pic_size(pic->GetPparams().Xl(), pic->GetPparams().Yl());
+ if ( cs != Y_COMP )
+ {
+ pic_size.x = pic->GetPparams().ChromaXl();
+ pic_size.y = pic->GetPparams().ChromaYl();
+ }
+
+
+ // Reference to the relevant DC array
+ const TwoDArray<ValueType>& dcarray = mv_data.DC( cs );
+
+ // Set up references to the vectors
+ const int num_refs = pic->GetPparams().Refs().size();
+ const MvArray* mv_array1;
+ const MvArray* mv_array2;
+ mv_array1 = &mv_data.Vectors(1);
+ if (num_refs ==2 )
+ mv_array2 = &mv_data.Vectors(2);
+ else
+ mv_array2 = &mv_data.Vectors(1);
+
+ ReConfig();//set all the weighting blocks up
+
+ //Blocks are listed left to right, line by line.
+ MVector mv1,mv2;
+ PredMode block_mode;
+
+ //Coords of the top-left corner of a block
+ ImageCoords pos;
+
+ //Loop for each block in the output image.
+ //The CompensateBlock function will use the image pointed to by ref1up
+ //and add the compensated pixels to the image pointed to by pic_data.
+ size_t wgt_idx;
+
+ int save_from_row = m_bparams.Ybsep()-m_bparams.Yoffset();
+
+ bool row_overlap = ((m_bparams.Yblen() - m_bparams.Ybsep()) > 0);
+
+ // unpadded picture dimensions
+ const int x_end_data = pic_data_out.FirstX() + std::min(pic_data_out.LengthX(), pic_size.x );
+ const int y_end_data = pic_data_out.FirstY() + std::min(pic_data_out.LengthY(), pic_size.y );
+
+ const int blocks_per_mb_row = m_predparams.XNumBlocks()/m_predparams.XNumSB();
+ const int blocks_per_sb_row = blocks_per_mb_row>>1;
+
+ // The picture does not contain integral number of blocks. So not all
+ // blocks need to be processed. Compute the relevant blocks to be
+ // processed
+ int y_num_blocks = std::min((NUM_USED_BLKS(pic_size.y,m_bparams.Ybsep(),m_bparams.Yblen())),
+ m_predparams.YNumBlocks());
+ int x_num_blocks = std::min((NUM_USED_BLKS(pic_size.x,m_bparams.Xbsep(),m_bparams.Xblen())),
+ m_predparams.XNumBlocks());
+
+ //Loop over all the block rows
+ pos.y = -m_bparams.Yoffset();
+ for(int yblock = 0; yblock < y_num_blocks; ++yblock)
+ {
+ pos.x = -m_bparams.Xoffset();
+ int xincr, xb_incr = 0;
+ //loop over all the blocks in a row
+ for(int xblock = 0 ; xblock < x_num_blocks; xblock+=xb_incr)
+ {
+ int split_mode = mv_data.SBSplit()[yblock/blocks_per_mb_row][xblock/blocks_per_mb_row];
+
+ int blk_x, blk_y = 1;
+
+ switch (split_mode)
+ {
+ case 0: // processing superblock
+ blk_x = blocks_per_mb_row;
+ break;
+ case 1: // processing sub-superblock
+ blk_x = blocks_per_sb_row;
+ break;
+ case 2: // processing block
+ default:
+ blk_x = 1;
+ break;
+ }
+
+ //Decide which weights to use.
+ if (pos.x >=0 && (xblock+blk_x) < x_num_blocks)
+ {
+ // block is entirely within picture in x direction
+ if (pos.y < 0)
+ wgt_idx = 1;
+ else if ((yblock+blk_y) < y_num_blocks)
+ wgt_idx = 4;
+ else
+ wgt_idx = 7;
+ }
+ else if (pos.x < 0)
+ {
+ // left edge of block is outside picture in x direction
+ if (pos.y < 0)
+ wgt_idx = 0;
+ else if ((yblock+blk_y) < y_num_blocks)
+ wgt_idx = 3;
+ else
+ wgt_idx = 6;
+ }
+ else
+ {
+ // right edge of block is outside picture in x direction
+ if (pos.y < 0)
+ wgt_idx = 2;
+ else if ((yblock+blk_y) < y_num_blocks)
+ wgt_idx = 5;
+ else
+ wgt_idx = 8;
+ }
+
+
+ block_mode = mv_data.Mode()[yblock][xblock];
+
+ TwoDArray<ValueType> *wt;
+
+ if (split_mode == 0) //Block part of a MacroBlock
+ {
+ wt = &m_macro_block_weights[wgt_idx];
+ xb_incr = blocks_per_mb_row;
+ }
+ else if (split_mode == 1) //Block part of a SubBlock
+ {
+ wt = &m_sub_block_weights[wgt_idx];
+ xb_incr = blocks_per_sb_row;
+ }
+ else
+ {
+ wt = &m_block_weights[wgt_idx];
+ xb_incr = 1;
+ }
+ xincr = m_bparams.Xbsep() * xb_incr;
+
+ mv1 = (*mv_array1)[yblock][xblock];
+ mv1.x >>= xscale_shift;
+ mv1.y >>= yscale_shift;
+
+ mv2 = (*mv_array2)[yblock][xblock];
+ mv2.x >>= xscale_shift;
+ mv2.y >>= yscale_shift;
+
+ CompensateBlock(pic_data, pos, pic_size, block_mode, dcarray[yblock][xblock], ref1up, mv1, ref2up, mv2, *wt);
+
+ //Increment the block horizontal position
+ pos.x += xincr;
+
+ }//xblock
+
+ // Update the pic data
+ // Use only the first Ybsep rows since the remaining rows are
+ // needed for the next row of blocks since we are using overlapped
+ // blocks motion compensation
+ if (m_add_or_sub == SUBTRACT)
+ {
+ int start_y = std::max(pic_data_out.FirstY() , pos.y) ;
+ int end_y = std::min (pic_data_out.FirstY() + pos.y + m_bparams.Ybsep() , y_end_data);
+
+ if (yblock == y_num_blocks - 1)
+ {
+ end_y = pic_data_out.LengthY();
+ if (end_y > y_end_data)
+ end_y = y_end_data;
+
+ }
+
+ for ( int i = start_y, pos_y = 0; i < end_y; i++, pos_y++)
+ {
+ ValueType *pic_row = pic_data[pos_y];
+ ValueType *out_row = pic_data_out[i];
+
+ for ( int j =pic_data_out.FirstX(); j < x_end_data; ++j)
+ {
+ out_row[j] -= static_cast<ValueType>( (pic_row[j] + 32) >> 6 );
+ }
+
+ // Okay, we've done all the actual blocks. Now if the picture is further padded
+ // we need to set the padded values to zero beyond the last block in the row,
+ // for all the picture lines in the block row. Need only do this when we're
+ // subtracting.
+
+ for (int j=pic_size.x; j<pic_data_out.LengthX() ; ++j )
+ {
+ out_row[pic_data_out.FirstX()+j] = 0;
+ }
+ }
+ }
+ else // (m_add_or_sub == ADD)
+ {
+ int start_y = std::max(pic_data_out.FirstY() , pos.y) ;
+ int end_y = std::min (pic_data_out.FirstY() + pos.y + m_bparams.Ybsep() , pic_data_out.FirstY() + pic_data_out.LengthY());
+ if (yblock == (y_num_blocks - 1))
+ {
+ end_y += (m_bparams.Yblen()-m_bparams.Ybsep());
+ if (end_y > pic_size.y)
+ end_y = pic_size.y;
+ }
+#if defined (HAVE_MMX)
+ CompensateComponentAddAndShift_mmx (start_y, end_y, 6, pic_size,
+ pic_data, pic_data_out);
+#else
+ for ( int i = start_y, pic_y = 0; i < end_y; i++, pic_y++)
+ {
+ ValueType *pic_row = pic_data[pic_y];
+ ValueType *out_row = pic_data_out[i];
+
+ for ( int j =0; j < pic_size.x; j++)
+ {
+ out_row[j] += static_cast<ValueType>( (pic_row[j] + 32) >> 6 );
+ }
+ // Pad the remaining pixels of the row with last truepic pixel val
+ for ( int j = pic_size.x; j < pic_data.LengthX(); j++)
+ {
+ out_row[j] = out_row[pic_size.x-1];
+ }
+ }
+#endif
+ }
+ //Increment the block vertical position
+ pos.y += m_bparams.Ybsep();
+
+ if (row_overlap)
+ {
+ // Copy the rows required to motion compensate the next row of
+ // blocks. This is usually Yblen-Ybsep rows.
+ memmove (pic_data[0], pic_data[save_from_row], (m_bparams.Yblen() - save_from_row)*pic_data.LengthX()*sizeof(ValueType));
+ memset( pic_data[m_bparams.Yblen() - save_from_row], 0, save_from_row*pic_data.LengthX()*sizeof(ValueType) );
+ save_from_row = m_bparams.Ybsep();
+ }
+ else
+ {
+ // no row overlap. So reset pic_data to 0.
+ memset( pic_data[0], 0, m_bparams.Yblen()*pic_data.LengthX()*sizeof(ValueType) );
+ }
+ }//yblock
+
+ if ( m_add_or_sub == SUBTRACT)
+ {
+ // Finally, now we've done all the blocks, we must set all padded lines
+ // below the last row equal to 0, if we're subtracting
+ for ( int y=pic_size.y ; y<pic_data_out.LengthY() ; ++y )
+ {
+ ValueType *out_row = pic_data_out[y];
+ for ( int x=0 ; x<pic_data_out.LengthX() ; ++x )
+ {
+ out_row[x] = 0;
+ }
+
+ }
+ }
+ else if ( m_add_or_sub == ADD)
+ {
+ // Edge extension
+ // Finally, now we've done all the blocks, we must set all padded lines
+ // below the last row equal to same as last row, if we're adding
+ ValueType *last_row = &pic_data_out[pic_size.y-1][0];
+ for ( int y=pic_size.y ; y<pic_data_out.LengthY() ; ++y )
+ {
+ ValueType *out_row = pic_data_out[y];
+ for ( int x=0 ; x<pic_data_out.LengthX() ; ++x )
+ {
+ out_row[x] = last_row[x];
+ }
+
+ }
+ }
+}
+
+void MotionCompensator::CompensateBlock(
+ TwoDArray<ValueType> &pic_data ,
+ const ImageCoords& pos ,
+ const ImageCoords& pic_size ,
+ PredMode block_mode,
+ ValueType dc,
+ const PicArray &ref1up_data ,
+ const MVector &mv1 ,
+ const PicArray &ref2up_data ,
+ const MVector &mv2 ,
+ const TwoDArray<ValueType>& wt_array)
+{
+ //Coordinates in the image being written to.
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+ const ImageCoords end_pos( std::min( pos.x + wt_array.LengthX() , pic_size.x ) ,
+ std::min( pos.y + wt_array.LengthY() , pic_size.y ) );
+
+ // Check if we are within original picture bounds
+ if (start_pos.x >= end_pos.x || start_pos.y >= end_pos.y)
+ return;
+
+ TwoDArray<ValueType> val1(end_pos.y - start_pos.y, end_pos.x-start_pos.x);
+ TwoDArray<ValueType> val2(end_pos.y - start_pos.y, end_pos.x-start_pos.x);
+
+ if(block_mode == REF1_ONLY)
+ {
+ BlockPixelPred(val1, pos, pic_size, ref1up_data, mv1);
+ }
+ else if (block_mode == REF2_ONLY)
+ {
+ BlockPixelPred(val1, pos, pic_size, ref2up_data, mv2);
+ }
+ else if(block_mode == REF1AND2)
+ {
+ BlockPixelPred(val1, pos, pic_size, ref1up_data, mv1);
+ BlockPixelPred(val2, pos, pic_size, ref2up_data, mv2);
+ }
+ else
+ {//we have a DC block.
+ DCBlock(val1, dc);
+ }
+ /*
+ * Multiply the block by reference weights. Return result in val1
+ */
+ AdjustBlockByRefWeights(val1, val2, block_mode);
+
+ /*
+ * Multiply the block by OBMC spatial weights. Return result val1
+ */
+ AdjustBlockBySpatialWeights(val1, pos, wt_array);
+
+#if !defined (HAVE_MMX)
+ for (int y = 0, py=0; y < val1.LengthY(); ++y, ++py)
+ {
+ for (int x = 0, px=start_pos.x; x < val1.LengthX(); ++x, ++px)
+ {
+ pic_data[py][px] += val1[y][x];
+ }
+ }
+#else
+ AddMCBlock_mmx(ImageCoords(start_pos.x, 0), pic_data, val1);
+#endif
+}
+
+void MotionCompensator::DCBlock( TwoDArray<ValueType> &block_data ,
+ const ValueType dc)
+{
+
+ //Quick process where we can just copy from the double size image.
+ ValueType *block_curr = &block_data[0][0];
+ for(int y = 0; y < block_data.LengthY(); ++y)
+ {
+ for(int x=0; x < block_data.LengthX(); ++x, ++block_curr)
+ {
+ *block_curr = dc;
+ }
+ }
+}
+
+void MotionCompensator::AdjustBlockByRefWeights (
+ TwoDArray<ValueType>& val1_block,
+ TwoDArray<ValueType>& val2_block,
+ PredMode block_mode)
+{
+ // No need to multiply by reference weights if DC block
+ if (block_mode == INTRA)
+ return;
+
+ if (m_predparams.CustomRefWeights())
+ {
+ int ref_wt_prec_bias = 1;
+ for (int i = m_predparams.PictureWeightsBits()-1; i > 0; --i)
+ {
+ ref_wt_prec_bias <<= 1;
+ }
+ if (block_mode != REF1AND2)
+ {
+ for (int y = 0; y < val1_block.LengthY(); ++y)
+ {
+ for (int x = 0; x < val1_block.LengthX(); ++x)
+ {
+ val1_block[y][x] *= (m_predparams.Ref1Weight() +
+ m_predparams.Ref2Weight());
+ }
+ }
+ }
+ else
+ {
+ for (int y = 0; y < val1_block.LengthY(); ++y)
+ {
+ for (int x = 0; x < val1_block.LengthX(); ++x)
+ {
+ val1_block[y][x] *= m_predparams.Ref1Weight();
+ val2_block[y][x] *= m_predparams.Ref2Weight();
+ val1_block[y][x] += val2_block[y][x];
+ }
+ }
+ }
+ for (int y = 0; y < val1_block.LengthY(); ++y)
+ {
+ for (int x = 0; x < val1_block.LengthX(); ++x)
+ {
+ val1_block[y][x] = (val1_block[y][x] + ref_wt_prec_bias) >> m_predparams.PictureWeightsBits();
+ }
+ }
+ }
+ else
+ {
+ // Default weights
+ if (block_mode == REF1AND2)
+ {
+ for (int y = 0; y < val1_block.LengthY(); ++y)
+ {
+ for (int x = 0; x < val1_block.LengthX(); ++x)
+ {
+ val1_block[y][x] = (val1_block[y][x] + val2_block[y][x] + 1)>>1;
+ }
+ }
+ }
+ // Nothing to do for other block modes when using default weights
+ }
+}
+
+#if !defined (HAVE_MMX)
+void MotionCompensator::AdjustBlockBySpatialWeights (
+ TwoDArray<ValueType>& val_block,
+ const ImageCoords &pos,
+ const TwoDArray<ValueType> &wt_array)
+{
+ ImageCoords start_pos (std::max(0, pos.x), std::max(0, pos.y));
+ ImageCoords wt_start (start_pos.x - pos.x, start_pos.y - pos.y);
+
+ for (int y = 0, wt_y=wt_start.y; y < val_block.LengthY(); ++y, ++wt_y)
+ {
+ for (int x = 0, wt_x=wt_start.x; x < val_block.LengthX(); ++x, ++wt_x)
+ {
+ val_block[y][x] *= wt_array[wt_y][wt_x];
+ }
+ }
+}
+#endif
+
+void MotionCompensator::CalculateWeights( int xbsep, int ybsep,
+ TwoDArray<ValueType>* wts_array)
+{
+ // Firstly calculate the non-weighted Weighting blocks. i,e, assuming that
+ // the picture_weight for each reference picture is 1.
+ // We can create all nine weighting blocks by calculating values
+ // for four blocks and mirroring them to generate the others.
+ CreateBlock( xbsep, ybsep, false , false , wts_array[0] );
+ CreateBlock( xbsep, ybsep, false , true , wts_array[3] );
+ CreateBlock( xbsep, ybsep, true , false , wts_array[1] );
+ CreateBlock( xbsep, ybsep, true , true , wts_array[4] );
+
+ // Note order of flipping is important.
+ FlipX( wts_array[3] , wts_array[5] );
+ FlipX( wts_array[0] , wts_array[2] );
+ FlipY( wts_array[0] , wts_array[6] );
+ FlipX( wts_array[6] , wts_array[8] );
+ FlipY( wts_array[1] , wts_array[7] );
+
+}
+// Calculates a weighting block.
+// bparams defines the block parameters so the relevant weighting arrays can
+// be created.
+// FullX and FullY refer to whether the weight should be adjusted for the
+// edge of an image.
+// eg. 1D Weighting shapes in x direction
+
+// FullX true FullX false
+// *** ********
+// * * *
+// * * *
+//* * *
+void MotionCompensator::CreateBlock( int xbsep, int ybsep,
+ bool FullX , bool FullY ,
+ TwoDArray<ValueType>& WeightArray)
+{
+ // Create temporary arrays
+ int xblen = WeightArray.LengthX();
+ int yblen = WeightArray.LengthY();
+
+ OneDArray<ValueType> HWts( xblen );
+ OneDArray<ValueType> VWts( yblen );
+
+ // Window in the x direction
+ int xoffset = (xblen - xbsep)/2;
+ if ( xoffset != 1 )
+ {
+ for(int x = 0; x < 2*xoffset; ++x)
+ {
+ HWts[x] = 1 + (6*x + xoffset-1)/(2*xoffset-1);
+ HWts[x+xbsep] = 8 - HWts[x];
+ }// x
+ }
+ else
+ {
+ HWts[0]=HWts[1+xbsep]=3;
+ HWts[1]=HWts[xbsep]=5;
+ }
+ for (int x = 2*xoffset; x < xbsep; ++x)
+ HWts[x] = 8;
+
+ // Window in the y direction
+ int yoffset = (yblen - ybsep)/2;
+ if ( yoffset != 1 )
+ {
+ for(int y = 0; y < 2*yoffset; ++y)
+ {
+ VWts[y] = 1 + (6 *y + yoffset-1)/(2*yoffset-1);
+ VWts[y+ybsep] = 8 - VWts[y];
+ }// y
+ }
+ else
+ {
+ VWts[0]=VWts[1+ybsep]=3;
+ VWts[1]=VWts[ybsep]=5;
+ }
+ for (int y = 2*yoffset; y < ybsep; ++y)
+ VWts[y] = 8;
+
+ // Now reflect or pad, as appropriate
+ if (!FullX)
+ {
+ for( int x = 0; x < 2*xoffset; ++x)
+ HWts[x] = 8;
+ }
+
+ // Reflect or pad, as appropriate
+ if (!FullY)
+ {
+ for( int y = 0 ; y < 2*yoffset; ++y)
+ VWts[y] = 8;
+ }
+
+ for(int y = 0; y < yblen; ++y)
+ {
+ for(int x = 0; x < xblen; ++x)
+ {
+ WeightArray[y][x] = VWts[y] * HWts[x];
+ }// x
+ }// y
+}
+
+// Flips the values in an array in the x direction.
+void MotionCompensator::FlipX( const TwoDArray<ValueType>& Original ,
+ TwoDArray<ValueType>& Flipped)
+{
+ int yblen = Original.LengthY();
+ int xblen = Original.LengthX();
+ for(int y = 0; y < yblen; ++y)
+ {
+ for(int x = 0; x < xblen; ++x)
+ {
+ Flipped[y][x] = Original[y][(xblen-1) - x];
+ }// y
+ }// x
+}
+
+// Flips the values in an array in the y direction.
+void MotionCompensator::FlipY( const TwoDArray<ValueType>& Original ,
+ TwoDArray<ValueType>& Flipped)
+{
+ int yblen = Original.LengthY();
+ int xblen = Original.LengthX();
+ for(int y = 0; y < yblen; ++y)
+ {
+ for(int x = 0; x < xblen; ++x)
+ {
+ Flipped[y][x] = Original[(yblen-1) - y][x];
+ }// y
+ }// x
+}
+
+
+// Concrete Sub-Classes
+// Class that implement the BlockPixelPred function based on pixel
+// precision values
+
+// Motion Compesation class that provides pixel precision compensation
+
+MotionCompensator_Pixel::MotionCompensator_Pixel( const PicturePredParams &ppp ) :
+ MotionCompensator( ppp )
+{}
+
+void MotionCompensator_Pixel::BlockPixelPred(
+ TwoDArray<ValueType> &block_data ,
+ const ImageCoords& pos,
+ const ImageCoords& pic_size ,
+ const PicArray &refup_data ,
+ const MVector &mv)
+{
+ //Coordinates in the image being written to.
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+
+ //Where to start in the upconverted image - scaled since ref is upconverted
+ const ImageCoords ref_start( (start_pos.x + mv.x)<<1 , (start_pos.y + mv.y)<<1 );
+
+ //An additional stage to make sure the block to be copied does not fall outside
+ //the reference image.
+ const int refXlen = refup_data.LengthX();
+ //const int refYlen = refup_data.LengthY();
+ const int trueRefXlen = (pic_size.x << 1) - 1;
+ const int trueRefYlen = (pic_size.y << 1) - 1;
+ bool do_bounds_checking = false;
+
+ //Check if there are going to be any problems copying the block from
+ //the upvconverted reference image.
+ if( ref_start.x < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.x + ((block_data.LengthX() - 1)<<1 ) >= trueRefXlen )
+ do_bounds_checking = true;
+ if( ref_start.y < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.y + ((block_data.LengthY() - 1)<<1 ) >= trueRefYlen)
+ do_bounds_checking = true;
+
+ ValueType *block_curr = &block_data[0][0];
+ if( !do_bounds_checking )
+ {
+ ValueType *refup_curr = &refup_data[ref_start.y][ref_start.x];
+ const int refup_next( 2*(refXlen - block_data.LengthX()) ); // - go down a row and back up
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = *refup_curr;
+ }// x
+ }// y
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+
+ for( int y=0, ry=ref_start.y, by=BChk(ry,trueRefYlen);
+ y < block_data.LengthY(); ++y, ry+=2 , by=BChk(ry,trueRefYlen) )
+ {
+ for( int x=0 , rx=ref_start.x , bx=BChk(rx,trueRefXlen);
+ x <block_data.LengthX() ; ++x, ++block_curr, rx+=2 , bx=BChk(rx,trueRefXlen) )
+ {
+ *block_curr = refup_data[by][bx];
+ }// x
+ }// y
+
+ }
+}
+
+
+// Motion Compesation class that provides half-pixel precision compensation
+MotionCompensator_HalfPixel::MotionCompensator_HalfPixel( const PicturePredParams &ppp ) :
+ MotionCompensator( ppp )
+{}
+
+#if !defined (HAVE_MMX)
+void MotionCompensator_HalfPixel::BlockPixelPred(
+ TwoDArray<ValueType> &block_data ,
+ const ImageCoords& pos ,
+ const ImageCoords& pic_size ,
+ const PicArray &refup_data ,
+ const MVector &mv)
+{
+ //Where to start in the upconverted image
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+ const ImageCoords ref_start( ( start_pos.x<<1 ) + mv.x ,( start_pos.y<<1 ) + mv.y );
+
+ //An additional stage to make sure the block to be copied does not fall
+ //outsidethe reference image.
+ const int refXlen = refup_data.LengthX();
+ //const int refYlen = refup_data.LengthY();
+ const int trueRefXlen = (pic_size.x << 1) - 1;
+ const int trueRefYlen = (pic_size.y << 1) - 1;
+
+ bool do_bounds_checking = false;
+
+ //Check if there are going to be any problems copying the block from
+ //the upvconverted reference image.
+
+ if( ref_start.x < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.x + ((block_data.LengthX() -1 )<<1 ) >= trueRefXlen )
+ do_bounds_checking = true;
+ if( ref_start.y < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.y + ((block_data.LengthY() - 1 )<<1 ) >= trueRefYlen)
+ do_bounds_checking = true;
+
+ ValueType *block_curr = &block_data[0][0];
+
+ if( !do_bounds_checking )
+ {
+ ValueType *refup_curr = &refup_data[ref_start.y][ref_start.x];
+ const int refup_next( (refXlen - block_data.LengthX())*2 );// go down 2 rows and back up
+
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = refup_curr[0];
+ }
+ }
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=0, ry=ref_start.y, by=BChk(ry,trueRefYlen);
+ y<block_data.LengthY(); ++y, ry+=2 , by=BChk(ry,trueRefYlen))
+ {
+ for( int x=0 , rx=ref_start.x , bx=BChk(rx,trueRefXlen);
+ x<block_data.LengthX() ;
+ ++x, ++block_curr, rx+=2 , bx=BChk(rx,trueRefXlen))
+ {
+ *block_curr = refup_data[by][bx];
+ }// x
+ }// y
+ }
+}
+#endif
+
+// Motion Compesation class that provides quarter-pixel precision compensation
+MotionCompensator_QuarterPixel::MotionCompensator_QuarterPixel( const PicturePredParams &ppp ) :
+ MotionCompensator( ppp )
+{}
+
+#if !defined (HAVE_MMX)
+void MotionCompensator_QuarterPixel::BlockPixelPred(
+ TwoDArray<ValueType> &block_data ,
+ const ImageCoords& pos ,
+ const ImageCoords& pic_size ,
+ const PicArray &refup_data ,
+ const MVector &mv)
+{
+ // Set up the start point in the reference image by rounding the motion vector
+ // to 1/2 pel accuracy.NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>1 , mv.y>>1 );
+
+ //Get the remainder after rounding. NB rmdr values always 0 or 1
+ const MVector rmdr( mv.x & 1 , mv.y & 1 );
+
+ //Where to start in the upconverted image
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+ const ImageCoords ref_start( ( start_pos.x<<1 ) + roundvec.x ,( start_pos.y<<1 ) + roundvec.y );
+
+ //An additional stage to make sure the block to be copied does not fall outside
+ //the reference image.
+ const int refXlen = refup_data.LengthX();
+ //const int refYlen = refup_data.LengthY();
+ const int trueRefXlen = (pic_size.x<<1) - 1;
+ const int trueRefYlen = (pic_size.y<<1) - 1;
+
+ ValueType *block_curr = &block_data[0][0];
+
+ bool do_bounds_checking = false;
+ //Check if there are going to be any problems copying the block from
+ //the upvconverted reference image.
+ if( ref_start.x < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.x + (block_data.LengthX()<<1 ) >= trueRefXlen )
+ do_bounds_checking = true;
+ if( ref_start.y < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.y + (block_data.LengthY()<<1 ) >= trueRefYlen )
+ do_bounds_checking = true;
+
+ if( !do_bounds_checking )
+ {
+ ValueType *refup_curr = &refup_data[ref_start.y][ref_start.x];
+ const int refup_next( ( refXlen - block_data.LengthX() )*2 ); //go down 2 rows and back to beginning of block line
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = refup_curr[0];
+ }
+ }
+ }
+ else if( rmdr.y == 0 )
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = (refup_curr[0] + refup_curr[1] + 1) >> 1;
+ }
+ }
+ }
+ else if( rmdr.x == 0 )
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = ( refup_curr[0] + refup_curr[refXlen] + 1 ) >> 1;
+ }
+ }
+ }
+ else
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = ( refup_curr[0] + refup_curr[1] +
+ refup_curr[refXlen+0] +
+ refup_curr[refXlen+1] + 2 ) >> 2;
+ }
+ }
+ }
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+
+ //weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (2 - rmdr.x) * (2 - rmdr.y), //tl
+ rmdr.x * (2 - rmdr.y), //tr
+ (2 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+
+ for(int c = 0, uY = ref_start.y,BuY=BChk(uY,trueRefYlen),BuY1=BChk(uY+1,trueRefYlen);
+ c < block_data.LengthY(); ++c, uY += 2,BuY=BChk(uY,trueRefYlen),BuY1=BChk(uY+1,trueRefYlen))
+ {
+ for(int l = 0, uX = ref_start.x,BuX=BChk(uX,trueRefXlen),BuX1=BChk(uX+1,trueRefXlen);
+ l < block_data.LengthX(); ++l, uX += 2,BuX=BChk(uX,trueRefXlen),BuX1=BChk(uX+1,trueRefXlen))
+ {
+
+ block_data[c][l] = ( linear_wts[0] * refup_data[BuY][BuX] +
+ linear_wts[1] * refup_data[BuY][BuX1] +
+ linear_wts[2] * refup_data[BuY1][BuX] +
+ linear_wts[3] * refup_data[BuY1][BuX1] +
+ 2
+ ) >> 2;
+ }//l
+ }//c
+
+ }
+}
+#endif
+
+// Motion Compesation class that provides one eighth-pixel precision
+// compensation
+MotionCompensator_EighthPixel::MotionCompensator_EighthPixel( const PicturePredParams &ppp ) :
+ MotionCompensator( ppp )
+{}
+
+void MotionCompensator_EighthPixel::BlockPixelPred(
+ TwoDArray<ValueType> &block_data ,
+ const ImageCoords& pos ,
+ const ImageCoords& pic_size ,
+ const PicArray &refup_data ,
+ const MVector &mv)
+{
+
+ //Set up the start point in the reference image by rounding the motion vector
+ //NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>2 , mv.y>>2 );
+
+ //Get the remainder after rounding. NB rmdr values always 0,1,2 or 3
+ const MVector rmdr( mv.x & 3 , mv.y & 3 );
+
+ //Where to start in the upconverted image
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+ const ImageCoords ref_start( ( start_pos.x<<1 ) + roundvec.x ,( start_pos.y<<1 ) + roundvec.y );
+
+ //weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (4 - rmdr.x) * (4 - rmdr.y), //tl
+ rmdr.x * (4 - rmdr.y), //tr
+ (4 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+ //An additional stage to make sure the block to be copied does not fall outside
+ //the reference image.
+ const int refXlen = refup_data.LengthX();
+ //const int refYlen = refup_data.LengthY();
+ const int trueRefXlen = (pic_size.x << 1) - 1;
+ const int trueRefYlen = (pic_size.y << 1) - 1;
+ bool do_bounds_checking = false;
+
+ //Check if there are going to be any problems copying the block from
+ //the upvconverted reference image.
+ if( ref_start.x < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.x + (block_data.LengthX()<<1 ) >= trueRefXlen )
+ do_bounds_checking = true;
+ if( ref_start.y < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.y + (block_data.LengthY()<<1 ) >= trueRefYlen)
+ do_bounds_checking = true;
+
+
+ if( !do_bounds_checking )
+ {
+ ValueType *block_curr = &block_data[0][0];
+ ValueType *refup_curr = &refup_data[ref_start.y][ref_start.x];
+
+ const int refup_next = (refup_data.LengthX() - block_data.LengthX() )*2; //go down 2 rows and back up
+
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = refup_curr[0];
+ }
+ }
+ }
+ else if( rmdr.y == 0 )
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = (
+ linear_wts[0] * refup_curr[0] +
+ linear_wts[1] * refup_curr[1] +
+ 8
+ ) >> 4;
+ }
+ }
+ }
+ else if( rmdr.x == 0 )
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = (
+ linear_wts[0] * refup_curr[0] +
+ linear_wts[2] * refup_curr[refXlen+0] +
+ 8
+ ) >> 4;
+ }
+ }
+ }
+ else
+ {
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = (
+ linear_wts[0] * refup_curr[0] +
+ linear_wts[1] * refup_curr[1] +
+ linear_wts[2] * refup_curr[refXlen+0] +
+ linear_wts[3] * refup_curr[refXlen+1] +
+ 8
+ ) >> 4;
+ }
+ }
+ }
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+
+ for(int c = 0, uY = ref_start.y,BuY=BChk(uY,trueRefYlen),BuY1=BChk(uY+1,trueRefYlen);
+ c < block_data.LengthY(); ++c, uY += 2,BuY=BChk(uY,trueRefYlen),BuY1=BChk(uY+1,trueRefYlen))
+ {
+ for(int l = 0, uX = ref_start.x,BuX=BChk(uX,trueRefXlen),BuX1=BChk(uX+1,trueRefXlen);
+ l < block_data.LengthX();
+ ++l, uX += 2,BuX=BChk(uX,trueRefXlen),BuX1=BChk(uX+1,trueRefXlen))
+ {
+
+ block_data[c][l] = (
+ linear_wts[0] * refup_data[BuY][BuX] +
+ linear_wts[1] * refup_data[BuY][BuX1] +
+ linear_wts[2] * refup_data[BuY1][BuX] +
+ linear_wts[3] * refup_data[BuY1][BuX1] +
+ 8
+ ) >> 4;
+ }//l
+ }//c
+
+ }
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.h
new file mode 100644
index 000000000..7974cc1db
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp.h
@@ -0,0 +1,301 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mot_comp.h,v 1.22 2008/08/27 00:17:11 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author),
+* Thomas Davies
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+// Motion Compensation routines.
+// Supports different sizes of blocks as long as the parameters
+// describing them are 'legal'. Blocks overlap the edge of the image
+// being written to but blocks in the reference image are forced to
+// lie completely within the image bounds.
+
+#ifndef _INCLUDED_MOT_COMP
+#define _INCLUDED_MOT_COMP
+
+#include <cstdlib>
+#include <ctime>
+#include <iostream>
+#include <vector>
+#include <libdirac_common/common.h>
+#include <libdirac_common/upconvert.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_common/picture_buffer.h>
+
+namespace dirac
+{
+ class PictureBuffer;
+ class Picture;
+
+ //! Abstract Motion compensator class.
+ /*!
+ Motion compensator class, for doing motion compensation with two
+ references and overlapped blocks, using raised-cosine roll-off.
+ This is an abstract class. It must be sub-classed and the
+ BlockPixelPred must be defined in the sub-classes.
+ */
+ class MotionCompensator
+ {
+
+ public:
+ //! Constructor.
+ /*!
+ Constructor initialises using codec parameters.
+ */
+ MotionCompensator( const PicturePredParams &ppp );
+ //! Destructor
+ virtual ~MotionCompensator();
+
+ //! Convenience function to perform motion compensation on a picture
+ /*!
+ Static function that motion compensates a picture. It uses the
+ MV precision value in the PicturePredParams to instantiate the
+ appropriate MotionCompensation sub-class.
+ \param ppp Picture prediction parameters
+ \param direction whether we're subtracting or adding
+ \param mv_data the motion vector data
+ \param in_pic Pointer to picture being motion compensated
+ \param refptr Array of pointers to reference pictures.
+ */
+ static void CompensatePicture ( const PicturePredParams &ppp,
+ const AddOrSub direction ,
+ const MvData& mv_data,
+ Picture* in_pic ,
+ Picture* refptr[2]);
+
+ //! Compensate a picture
+ /*!
+ Perform motion compensated addition/subtraction on a picture using
+ parameters
+ \param direction whether we're subtracting or adding
+ ` \param mv_data the motion vector data
+ \param in_pic Pointer to picture being motion compensated
+ \param refsptr Array of pointers to reference pictures.
+ */
+ void CompensatePicture( const AddOrSub direction ,
+ const MvData& mv_data,
+ Picture* in_pic ,
+ Picture* refsptr[2] );
+
+ private:
+ //private, body-less copy constructor: this class should not be copied
+ MotionCompensator( const MotionCompensator& cpy );
+ //private, body-less assignment=: this class should not be assigned
+ MotionCompensator& operator=( const MotionCompensator& rhs );
+
+ //functions
+
+ //! Motion-compensate a component
+ void CompensateComponent( Picture* pic ,
+ Picture* refsptr[2] ,
+ const MvData& mv_data , const CompSort cs);
+
+ //! Recalculate the weight matrix and store other key block related parameters.
+ //! DC-compensate an individual block
+ void DCBlock( TwoDArray<ValueType> &block_data ,
+ const ValueType dc);
+ void ReConfig();
+
+ // Calculates a weighting arrays blocks.
+ void CalculateWeights(int xbsep, int ybsep, TwoDArray<ValueType>* wt_array);
+
+ //! Calculates a weighting block.
+ /*!
+ Params defines the block parameters so the relevant weighting
+ arrays can be created. FullX and FullY refer to whether the
+ weight should be adjusted for the edge of an image. eg. 1D
+ Weighting shapes in x direction
+ FullX true FullX false
+ *** ********
+ * * *
+ * * *
+ * * *
+ */
+ void CreateBlock(int xbsep, int ybsep, bool FullX, bool FullY, TwoDArray<ValueType>& WeightArray);
+
+ //! Flips the values in an array in the x direction
+ void FlipX(const TwoDArray<ValueType>& Original, TwoDArray<ValueType>& Flipped);
+
+ //! Flips the values in an array in the y direction.
+ void FlipY(const TwoDArray<ValueType>& Original, TwoDArray<ValueType>& Flipped);
+
+ virtual void CompensateBlock( TwoDArray<ValueType>& pic_data ,
+ const ImageCoords& pos ,
+ const ImageCoords &orig_pic_size,
+ PredMode block_mode,
+ ValueType dc,
+ const PicArray& ref1up_data ,
+ const MVector& mv1 ,
+ const PicArray& ref2up_data ,
+ const MVector& mv2 ,
+ const TwoDArray<ValueType>& Weights );
+ //! Predict pixels in a block. Pure virtual. SubClasses need to define it
+ virtual void BlockPixelPred( TwoDArray<ValueType>& block_data ,
+ const ImageCoords& pos,
+ const ImageCoords &orig_pic_size,
+ const PicArray& refup_data ,
+ const MVector& mv) = 0;
+
+ // Adjust the block value based on reference weights
+ /*
+ * Adjust the block value based on reference weights of each
+ * reference picture.
+ * val1_block - Block predicted from a single reference picture
+ * val2_block - Block predicted from second reference picture
+ * mode is REF1AND2
+ * block_mode - Block prediction mode.
+ *
+ * On return, val1_block will contain the weight reference weight
+ * adjusted block values
+ */
+ void AdjustBlockByRefWeights (TwoDArray<ValueType>& val1_block,
+ TwoDArray<ValueType>& val2_block,
+ PredMode block_mode);
+
+ // Adjust the block value based spatial weighting matrix
+ /*
+ * Adjust the block value based on spatial weighting matrix
+ * val_block - Predicted block
+ * pos - position of top lef corner of block in picture
+ * wt_array - spatial weighting matrix
+ *
+ * On return, val_block will contain the spatial weight adjusted block
+ * values
+ */
+ void AdjustBlockBySpatialWeights (TwoDArray<ValueType>& val_block,
+ const ImageCoords &pos,
+ const TwoDArray<ValueType> &wt_array);
+ protected:
+ //variables
+
+ //! The codec parameters
+ PicturePredParams m_predparams;
+
+ //! The chroma format
+ ChromaFormat m_cformat;
+ bool luma_or_chroma; //true if we're doing luma, false if we're coding chroma
+
+ // A marker saying whether we're doing MC addition or subtraction
+ AddOrSub m_add_or_sub;
+
+ // Block information
+ OLBParams m_bparams;
+ // Arrays of block weights
+ TwoDArray<ValueType>* m_block_weights;
+ // Arrays of super block weights
+ TwoDArray<ValueType>* m_macro_block_weights;
+ // Arrays of sub super block weights
+ TwoDArray<ValueType>* m_sub_block_weights;
+ };
+
+ //! Pixel precision Motion compensator class.
+ class MotionCompensator_Pixel : public MotionCompensator
+ {
+
+ public:
+ //! Constructor.
+ /*!
+ Constructor initialises using codec parameters.
+ */
+ MotionCompensator_Pixel (const PicturePredParams &ppp);
+
+ private:
+ //! Motion-compensate a block.
+ virtual void BlockPixelPred( TwoDArray<ValueType>& block_data ,
+ const ImageCoords& pos,
+ const ImageCoords &orig_pic_size,
+ const PicArray& refup_data ,
+ const MVector& mv);
+ };
+
+ //! Half Pixel precision Motion compensator class.
+ class MotionCompensator_HalfPixel : public MotionCompensator
+ {
+ public:
+ //! Constructor.
+ /*!
+ Constructor initialises using codec parameters.
+ */
+ MotionCompensator_HalfPixel (const PicturePredParams &ppp);
+ private:
+ //! Motion-compensate a block.
+ virtual void BlockPixelPred( TwoDArray<ValueType>& block_data ,
+ const ImageCoords& pos,
+ const ImageCoords &orig_pic_size,
+ const PicArray& refup_data ,
+ const MVector& mv);
+ };
+
+ //! Quarter Pixel precision Motion compensator class.
+ class MotionCompensator_QuarterPixel : public MotionCompensator
+ {
+ public:
+ //! Constructor.
+ /*!
+ Constructor initialises using codec parameters.
+ */
+ MotionCompensator_QuarterPixel (const PicturePredParams &ppp);
+ private:
+ //! Motion-compensate a block.
+ virtual void BlockPixelPred( TwoDArray<ValueType>& block_data ,
+ const ImageCoords& pos,
+ const ImageCoords &orig_pic_size,
+ const PicArray& refup_data ,
+ const MVector& mv);
+ };
+
+ //! Eighth Pixel precision Motion compensator class.
+ class MotionCompensator_EighthPixel : public MotionCompensator
+ {
+ public:
+ //! Constructor.
+ /*!
+ Constructor initialises using codec parameters.
+ */
+ MotionCompensator_EighthPixel (const PicturePredParams &ppp);
+ private:
+ //! Motion-compensate a block.
+ virtual void BlockPixelPred( TwoDArray<ValueType>& block_data ,
+ const ImageCoords& pos,
+ const ImageCoords &orig_pic_size,
+ const PicArray& refup_data ,
+ const MVector& mv);
+ };
+
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.cpp
new file mode 100644
index 000000000..8c1cd0fa7
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.cpp
@@ -0,0 +1,470 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mot_comp_mmx.cpp,v 1.9 2008/01/09 10:50:23 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#if defined(HAVE_MMX)
+#include <mmintrin.h>
+#include <libdirac_common/mot_comp.h>
+#include <libdirac_common/mot_comp_mmx.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_common/dirac_assertions.h>
+using namespace dirac;
+
+inline void check_active_columns(
+ int x, int xmax, ValueType act_cols1[4],
+ ValueType act_cols2[4], ValueType *row1, ValueType *row2)
+{
+ // check if we need any clipping
+ if (x >= 0 && (x+3) < xmax) {
+ // special case, nothing to do
+ memcpy(act_cols1, &row1[x], 4 * sizeof(ValueType));
+ memcpy(act_cols2, &row2[x], 4 * sizeof(ValueType));
+ }
+ else
+ {
+ act_cols1[0] = row1[BChk(x,xmax)];
+ act_cols2[0] = row2[BChk(x,xmax)];
+ act_cols1[1] = row1[BChk(x+1,xmax)];
+ act_cols2[1] = row2[BChk(x+1,xmax)];
+ act_cols1[2] = row1[BChk(x+2,xmax)];
+ act_cols2[2] = row2[BChk(x+2,xmax)];
+ act_cols1[3] = row1[BChk(x+3,xmax)];
+ act_cols2[3] = row2[BChk(x+3,xmax)];
+ }
+}
+
+void MotionCompensator_QuarterPixel::BlockPixelPred(
+ TwoDArray<ValueType> &block_data ,
+ const ImageCoords& pos ,
+ const ImageCoords& orig_pic_size ,
+ const PicArray &refup_data ,
+ const MVector &mv)
+{
+ // Set up the start point in the reference image by rounding the motion vector
+ // to 1/2 pel accuracy.NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>1 , mv.y>>1 );
+
+ //Get the remainder after rounding. NB rmdr values always 0 or 1
+ const MVector rmdr( mv.x & 1 , mv.y & 1 );
+
+ //Where to start in the upconverted image
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+ // check that we are doing MC within true pic boundaries
+ if (start_pos.x >= orig_pic_size.x || start_pos.y >= orig_pic_size.y)
+ return;
+ const ImageCoords ref_start( ( start_pos.x<<1 ) + roundvec.x ,( start_pos.y<<1 ) + roundvec.y );
+
+ //An additional stage to make sure the block to be copied does not fall outside
+ //the reference image.
+ const int refXlen = refup_data.LengthX();
+ const int trueRefXlen = (orig_pic_size.x << 1) - 1;
+ const int trueRefYlen = (orig_pic_size.y << 1) - 1;
+
+ ValueType *block_curr = &block_data[0][0];
+
+ bool do_bounds_checking = false;
+ //Check if there are going to be any problems copying the block from
+ //the upvconverted reference image.
+ if( ref_start.x < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.x + (block_data.LengthX()<<1 ) >= trueRefXlen )
+ do_bounds_checking = true;
+ if( ref_start.y < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.y + (block_data.LengthY()<<1 ) >= trueRefYlen)
+ do_bounds_checking = true;
+
+ if( !do_bounds_checking )
+ {
+ int stopX = (block_data.LengthX()>>2)<<2;
+ ValueType *refup_curr = &refup_data[ref_start.y][ref_start.x];
+ const int refup_next( ( refXlen - block_data.LengthX() )*2 ); //go down 2 rows and back to beginning of block line
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ __m64 m1, m2;
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ int x;
+ for( x=0; x < stopX; x+=4, block_curr+=4, refup_curr+=8 )
+ {
+ m1 = _mm_unpacklo_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ m2 = _mm_unpackhi_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ // *block_curr = refup_curr[0]
+ *(__m64 *)block_curr = _mm_unpacklo_pi16 (m1, m2);
+ }
+ // Mopup the last value
+ for ( x=stopX ; x < block_data.LengthX(); ++x)
+ {
+ *block_curr = *refup_curr;
+ ++block_curr;
+ refup_curr+=2;
+ }
+ }
+ _mm_empty();
+ }
+ else if( rmdr.y == 0 )
+ {
+ __m64 round = _mm_set_pi16 (1, 1, 1, 1);
+ __m64 m1, m2, m3;
+
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ int x;
+ for( x=0; x < stopX; x+=4, block_curr+=4, refup_curr+=8 )
+ {
+ m1 = _mm_unpacklo_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ m3 = _mm_unpackhi_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ m2 = _mm_unpackhi_pi16 (m1, m3);
+ m1 = _mm_unpacklo_pi16 (m1, m3);
+
+ // (refup_curr[0] + refup_curr[1] + 1)>>1
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_add_pi16 (m1, round);
+ *(__m64 *)block_curr = _mm_srai_pi16 (m1, 1);
+ }
+
+ // Mopup the last value
+ for ( x=stopX; x < block_data.LengthX(); ++x)
+ {
+ *block_curr = (( *refup_curr +
+ *(refup_curr+1) + 1
+ ) >> 1);
+ ++block_curr;
+ refup_curr+=2;
+ }
+ }
+ _mm_empty();
+ }
+ else if( rmdr.x == 0 )
+ {
+ __m64 round = _mm_set_pi16 (1, 1, 1, 1);
+ __m64 m1, m2, m3;
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ int x;
+ for( x = 0; x < stopX; x+=4, block_curr+=4, refup_curr+=8 )
+ {
+ m1 = _mm_unpacklo_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ m2 = _mm_unpackhi_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ // m1 now contains r00 r02 r04 r06
+ m1 = _mm_unpacklo_pi16 (m1, m2);
+
+ m3 = _mm_unpacklo_pi16 (*(__m64 *)(refup_curr+refXlen), *(__m64 *)(refup_curr+refXlen+4));
+ m2 = _mm_unpackhi_pi16 (*(__m64 *)(refup_curr+refXlen), *(__m64 *)(refup_curr+refXlen+4));
+ // m1 now contains r10 r12 r14 r16
+ m2 = _mm_unpacklo_pi16 (m3, m2);
+
+ // (refup_curr[0] + (refup_curr+refXlen)[0] + 1)>>1
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_add_pi16 (m1, round);
+ *(__m64 *)block_curr = _mm_srai_pi16 (m1, 1);
+ }
+ for ( x=stopX; x < block_data.LengthX(); ++x)
+ {
+ *block_curr = (( *refup_curr + *(refup_curr+refXlen) +
+ 1
+ ) >> 1);
+ ++block_curr;
+ refup_curr+=2;
+ }
+ }
+ _mm_empty();
+ }
+ else
+ {
+ __m64 round = _mm_set_pi16 (2, 2, 2, 2);
+ __m64 m1, m2, m3;
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ int x;
+ for( x = 0; x < stopX; x+=4, block_curr+=4, refup_curr+=8 )
+ {
+ m1 = _mm_add_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+refXlen));
+ m2 = _mm_add_pi16 (*(__m64 *)(refup_curr+4), *(__m64 *)(refup_curr+refXlen+4));
+ m3 = _mm_unpacklo_pi16 (m1, m2);
+ m1 = _mm_unpackhi_pi16 (m1, m2);
+
+ m2 = _mm_unpackhi_pi16 (m3, m1);
+ m1 = _mm_unpacklo_pi16 (m3, m1);
+
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_add_pi16 (m1, round);
+ *(__m64 *)block_curr = _mm_srai_pi16 (m1, 2);
+ }
+ for ( x=stopX; x < block_data.LengthX(); ++x)
+ {
+ *block_curr = (( *refup_curr +
+ *(refup_curr+1) +
+ *(refup_curr+refXlen) +
+ *(refup_curr+refXlen+1) +
+ 2
+ ) >> 2);
+ ++block_curr;
+ refup_curr+=2;
+ }
+ }
+ _mm_empty();
+ }
+ }
+ else
+ {
+ // We're 2doing bounds checking because we'll fall off the edge of the reference otherwise.
+
+ //weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (2 - rmdr.x) * (2 - rmdr.y), //tl
+ rmdr.x * (2 - rmdr.y), //tr
+ (2 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+ ValueType act_cols1[4], act_cols2[4];
+ int uX, uY, c, l;
+ for(c = 0, uY = ref_start.y; c < block_data.LengthY(); ++c, uY += 2)
+ {
+ for(l = 0, uX=ref_start.x; l < block_data.LengthX(); ++l, ++block_curr, uX += 2)
+ {
+ check_active_columns(uX, trueRefXlen, act_cols1, act_cols2, refup_data[BChk(uY, trueRefYlen)], refup_data[BChk(uY+1, trueRefYlen)]);
+
+ *block_curr = (( linear_wts[0] * act_cols1[0] +
+ linear_wts[1] * act_cols1[1] +
+ linear_wts[2] * act_cols2[0] +
+ linear_wts[3] * act_cols2[1] +
+ 2
+ ) >> 2);
+ }//l
+ }//c
+ }
+}
+
+void MotionCompensator_HalfPixel::BlockPixelPred(
+ TwoDArray<ValueType> &block_data ,
+ const ImageCoords& pos ,
+ const ImageCoords& orig_pic_size ,
+ const PicArray &refup_data ,
+ const MVector &mv)
+{
+ //Where to start in the upconverted image
+ const ImageCoords start_pos( std::max(pos.x,0) , std::max(pos.y,0) );
+ const ImageCoords ref_start( ( start_pos.x<<1 ) + mv.x ,( start_pos.y<<1 ) + mv.y );
+
+ //An additional stage to make sure the block to be copied does not fall outside
+ //the reference image.
+ const int refXlen = refup_data.LengthX();
+ //const int refYlen = refup_data.LengthY();
+ const int trueRefXlen = (orig_pic_size.x << 1) - 1;
+ const int trueRefYlen = (orig_pic_size.y << 1) - 1;
+
+ bool do_bounds_checking = false;
+
+ //Check if there are going to be any problems copying the block from
+ //the upvconverted reference image.
+
+ if( ref_start.x < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.x + ((block_data.LengthX() - 1 )<<1 ) >= trueRefXlen )
+ do_bounds_checking = true;
+ if( ref_start.y < 0 )
+ do_bounds_checking = true;
+ else if( ref_start.y + ((block_data.LengthY() - 1 )<<1 ) >= trueRefYlen)
+ do_bounds_checking = true;
+
+ ValueType *block_curr = &block_data[0][0];
+
+ if( !do_bounds_checking )
+ {
+ ValueType *refup_curr = &refup_data[ref_start.y][ref_start.x];
+ const int refup_next( (refXlen - block_data.LengthX())*2 );// go down 2 rows and back up
+#if 1
+ int stopX = (block_data.LengthX()>>2)<<2;
+ {
+ __m64 m1, m2;
+
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ int x;
+ for( x=0; x < stopX; x+=4, block_curr+=4, refup_curr+=8 )
+ {
+ m1 = _mm_unpacklo_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ m2 = _mm_unpackhi_pi16 (*(__m64 *)refup_curr, *(__m64 *)(refup_curr+4));
+ *(__m64 *)block_curr = _mm_unpacklo_pi16 (m1, m2);
+ }
+ // Mopup the last value
+ for ( x=stopX ; x < block_data.LengthX(); ++x)
+ {
+ *block_curr = *refup_curr;
+ ++block_curr;
+ refup_curr+=2;
+ }
+ }
+ _mm_empty();
+ }
+#else
+
+ for( int y=0; y < block_data.LengthY(); ++y, refup_curr+=refup_next )
+ {
+ for( int x=0; x < block_data.LengthX(); ++x, ++block_curr, refup_curr+=2 )
+ {
+ *block_curr = refup_curr[0];
+ }
+ }
+#endif
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=0, ry=ref_start.y, by=BChk(ry,trueRefYlen);
+ y<block_data.LengthY();
+ ++y, ry+=2,by=BChk(ry,trueRefYlen))
+ {
+ for( int x=0 , rx=ref_start.x , bx=BChk(rx,trueRefXlen);
+ x<block_data.LengthX() ;
+ ++x, ++block_curr, rx+=2 , bx=BChk(rx,trueRefXlen))
+ {
+ *block_curr = refup_data[by][bx];
+ }// x
+ }// y
+ }
+}
+
+void MotionCompensator::AdjustBlockBySpatialWeights (
+ TwoDArray<ValueType>& val_block,
+ const ImageCoords &pos,
+ const TwoDArray<ValueType> &wt_array)
+{
+ ImageCoords start_pos (std::max(0, pos.x), std::max(0, pos.y));
+ ImageCoords wt_start (start_pos.x - pos.x, start_pos.y - pos.y);
+
+ ValueType *val_curr = &val_block[0][0];
+ ValueType *wt_curr = &wt_array[wt_start.y][wt_start.x];
+
+ // go down at row and back to beginning of weights line
+ const int wt_next = wt_array.LengthX() - val_block.LengthX();
+
+ const int stopX = (val_block.LengthX()>>2)<<2;
+
+ for ( int j = 0; j < val_block.LengthY(); ++j, wt_curr += wt_next)
+ {
+ for ( int i = 0; i < stopX; i+=4, val_curr+=4, wt_curr+=4)
+ {
+ /*
+ * NOTE: Using only the low 16 bits of the result of multiplication
+ * by weights because the result is supposed to fit in 16 bit
+ * words. For some weights could result in overflow and errors
+ */
+ __m64 *out = (__m64 *)val_curr;
+ *out = _mm_mullo_pi16 (*(__m64 *)val_curr, *(__m64 *)wt_curr);
+ }
+ for (int i = stopX; i < val_block.LengthX(); ++i, ++val_curr, ++wt_curr)
+ {
+ *val_curr = *val_curr * *wt_curr;
+ }
+ }
+ _mm_empty();
+}
+
+namespace dirac
+{
+ void CompensateComponentAddAndShift_mmx (int start_y, int end_y,
+ int weight_bits,
+ const ImageCoords& orig_pic_size,
+ TwoDArray<ValueType> &comp_data,
+ PicArray &pic_data_out)
+ {
+ if (start_y >= end_y)
+ return;
+ const int round_val = 1<<(weight_bits-1);
+ int stopX = pic_data_out.FirstX() + ((orig_pic_size.x>>2)<<2);
+ int x_end_truepic_data = pic_data_out.FirstX() + orig_pic_size.x;
+ int x_end_data = pic_data_out.FirstX() + pic_data_out.LengthX();
+ __m64 mround_val = _mm_set_pi16 (round_val, round_val, round_val, round_val);
+ ValueType *pic_row = &comp_data[0][comp_data.FirstX()];
+ ValueType *out_row = &pic_data_out[start_y][pic_data_out.FirstX()];
+ for ( int i = start_y; i < end_y; i++)
+ {
+ for ( int j = pic_data_out.FirstX(); j < stopX; j+=4)
+ {
+ __m64 in1 = _mm_add_pi16 (*(__m64 *)pic_row, mround_val);
+ in1 = _mm_srai_pi16 (in1, weight_bits);
+ __m64 *out = (__m64 *)out_row;
+ *out = _mm_add_pi16 (in1, *out);
+ pic_row += 4;
+ out_row += 4;
+ }
+ for ( int j =stopX; j < x_end_truepic_data; j++)
+ {
+ *out_row += static_cast<ValueType>( (*pic_row + round_val) >> weight_bits );
+ ++out_row;
+ ++pic_row;
+ }
+ // Now pad past the true picture with the last true pic val in
+ // current row
+ ValueType last_true_val = *(out_row - 1);
+ for ( int j = x_end_truepic_data; j < x_end_data; ++j)
+ {
+ *out_row = last_true_val;
+ ++out_row;
+ ++pic_row;
+ }
+ }
+ _mm_empty();
+ }
+
+ void AddMCBlock_mmx (const ImageCoords& start_pos,
+ TwoDArray<ValueType> &comp_strip,
+ TwoDArray<ValueType>& block_data)
+ {
+ const int stopX = (block_data.LengthX()>>2)<<2;
+
+ const int comp_next = comp_strip.LengthX()-block_data.LengthX();
+ ValueType *comp_curr = &comp_strip[start_pos.y][start_pos.x];
+ ValueType *block_curr = &block_data[0][0];
+
+ for (int j = 0; j < block_data.LengthY(); ++j, comp_curr += comp_next)
+ {
+ for (int i = 0; i < stopX; i+=4, comp_curr+=4, block_curr+=4)
+ {
+ __m64 *out = (__m64 *)comp_curr;
+ // mc_tmp[y][x] += val
+ *out = _mm_add_pi16 (*(__m64 *)comp_curr, *(__m64 *)block_curr);
+ }
+ for (int i = stopX; i < block_data.LengthX(); ++i, ++comp_curr, ++block_curr)
+ {
+ *comp_curr += *block_curr;
+ }
+ }
+ _mm_empty();
+ }
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.h
new file mode 100644
index 000000000..4be009c61
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mot_comp_mmx.h
@@ -0,0 +1,64 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mot_comp_mmx.h,v 1.4 2008/01/09 10:50:23 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author),
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+// Motion Compensation routines.
+// Supports different sizes of blocks as long as the parameters
+// describing them are 'legal'. Blocks overlap the edge of the image
+// being written to but blocks in the reference image are forced to
+// lie completely within the image bounds.
+
+#ifndef _INCLUDED_MOT_COMP_MMX_H
+#define _INCLUDED_MOT_COMP_MMX_H
+
+#if defined (HAVE_MMX)
+#include <libdirac_common/common.h>
+#include <libdirac_common/motion.h>
+namespace dirac
+{
+
+ void CompensateComponentAddAndShift_mmx (int start_y, int end_y,
+ int weight_bits,
+ const ImageCoords& orig_pic_size,
+ TwoDArray<ValueType> &comp_data,
+ PicArray &pic_data_out);
+
+ void AddMCBlock_mmx (const ImageCoords& start_pos, TwoDArray<ValueType> &comp_strip, TwoDArray<ValueType>& block_data);
+}
+
+#endif // HAVE_MMX
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.cpp
new file mode 100644
index 000000000..cb48bdbb3
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.cpp
@@ -0,0 +1,722 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: motion.cpp,v 1.28 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Chris Bowley,
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+////////////////////////////////////////////////////////////////
+//classes and functions for motion estimation and compensation//
+////////////////////////////////////////////////////////////////
+
+#include <libdirac_common/motion.h>
+using namespace dirac;
+
+#include <cmath>
+
+using namespace std;
+
+//Motion vector and Motion Estimation structures//
+//////////////////////////////////////////////////
+
+MvData::MvData( const PicturePredParams& predparams , const int num_refs ):
+ m_predparams( predparams ),
+ m_vectors( Range(1 , num_refs) ),
+ m_gm_vectors( Range(1 , num_refs) ),
+ m_modes( predparams.YNumBlocks() , predparams.XNumBlocks() ),
+ m_dc( 3 ),
+ m_sb_split( predparams.YNumSB() , predparams.XNumSB() ),
+ m_gm_params( Range(1 , num_refs) )//,
+// m_num_refs(num_refs)
+{
+ InitMvData();
+}
+
+void MvData::InitMvData()
+{
+ // Create the arrays of vectors
+ for ( int i=m_vectors.First() ; i<=m_vectors.Last() ; ++i ){
+ m_vectors[i] = new MvArray( Mode().LengthY() , Mode().LengthX() );
+ m_gm_vectors[i] = new MvArray( Mode().LengthY() , Mode().LengthX() );
+ }
+
+ // create global motion parameter arrays
+ for ( int i=m_gm_params.First() ; i<=m_gm_params.Last() ; ++i ){
+ m_gm_params[i] = new OneDArray<float> ( 8 );
+ }
+
+ // Create the arrays of dc values
+ for ( int i=0 ; i<3 ; ++i )
+ m_dc[i] = new TwoDArray<ValueType>( Mode().LengthY() , Mode().LengthX() , 0);
+}
+
+MvData::~MvData()
+{
+ // Delete the arrays of vectors
+ for ( int i=m_vectors.First() ; i<=m_vectors.Last() ; ++i ){
+ delete m_vectors[i];
+ delete m_gm_vectors[i];
+ }
+
+ // delete array of global motion parameters
+ for ( int i=m_gm_params.First() ; i<=m_gm_params.Last() ; ++i ){
+ delete m_gm_params[i];
+ }
+
+ // Delete the arrays of dc values
+ for ( int i=0 ; i<3 ; ++i )
+ delete m_dc[i];
+}
+
+MEData::MEData(const PicturePredParams& predparams , const int num_refs ):
+ MvData( predparams , num_refs ),
+ m_pred_costs( Range( 1 , num_refs ) ),
+ m_intra_costs( predparams.YNumBlocks() , predparams.XNumBlocks(), 0 ),
+ m_bipred_costs( predparams.YNumBlocks() , predparams.XNumBlocks() ),
+ m_SB_costs( predparams.YNumSB() , predparams.XNumSB() ),
+ m_lambda_map( predparams.YNumBlocks() , predparams.XNumBlocks() ),
+ m_inliers( Range( 1 , num_refs ) ),
+ m_intra_block_ratio(0.0)
+{
+ InitMEData();
+}
+
+void MEData::InitMEData()
+{
+ // Create the arrays of prediction costs
+ for ( int i=m_pred_costs.First() ; i<=m_pred_costs.Last() ; ++i )
+ m_pred_costs[i] = new TwoDArray<MvCostData>( Mode().LengthY() , Mode().LengthX() );
+
+ // Create the arrays of vectors
+ for ( int i=m_inliers.First() ; i<=m_inliers.Last() ; ++i )
+ m_inliers[i] = new TwoDArray<int>( Mode().LengthY() , Mode().LengthX() );
+}
+
+void MEData::SetLambdaMap( const int num_refs , const float lambda )
+{
+ TwoDArray<bool> transition_map1( Mode().LengthY() , Mode().LengthX() );
+ TwoDArray<bool> transition_map2( Mode().LengthY() , Mode().LengthX() );
+
+ FindTransitions( transition_map1 , 1 );
+
+ if ( num_refs==1 )
+ {
+ for ( int j=0 ; j<m_lambda_map.LengthY() ; j++)
+ {
+ for ( int i=0 ; i<m_lambda_map.LengthX() ; i++)
+ {
+ if ( transition_map1[j][i] )
+ m_lambda_map[j][i] = 0.0;
+ else
+ m_lambda_map[j][i] = lambda;
+ if ( i<4 || j<4 )
+ m_lambda_map[j][i] /= 5.0;
+ }// i
+ }// j
+ }
+ else if ( num_refs > 1 )
+ {
+ FindTransitions( transition_map2 , 2 );
+
+ for ( int j=0 ; j<m_lambda_map.LengthY() ; j++)
+ {
+ for ( int i=0 ; i<m_lambda_map.LengthX() ; i++)
+ {
+ if ( transition_map1[j][i] && transition_map2[j][i] )
+ m_lambda_map[j][i] = 0.0;
+ else if (transition_map1[j][i] || transition_map2[j][i] )
+ m_lambda_map[j][i] = lambda/4.0;
+ else
+ m_lambda_map[j][i] = lambda;
+
+ if ( i<4 || j<4 )
+ m_lambda_map[j][i] /= 5.0;
+ }// i
+ }// j
+ }
+
+}
+
+void MEData::SetLambdaMap( const int level , const TwoDArray<float>& l_map , const float wt )
+{
+
+ const int factor = 1<<(2-level);
+ int xstart , xend , ystart , yend;
+
+ for (int j = 0 ; j<m_lambda_map.LengthY() ; ++j )
+ {
+ for (int i = 0 ; i<m_lambda_map.LengthX() ; ++i )
+ {
+ xstart = factor * i;
+ ystart = factor * j;
+ xend = factor * ( i + 1 );
+ yend = factor * ( j + 1 );
+
+ m_lambda_map[j][i] = l_map[ystart][xstart];
+
+ for (int q = ystart ; q<yend ; ++q )
+ for (int p = xstart ; p<xend ; ++p )
+ m_lambda_map[j][i] = std::max( l_map[q][p] , m_lambda_map[j][i] );
+
+ m_lambda_map[j][i] *= wt;
+
+ }// i
+ }// j
+
+}
+
+void MEData::FindTransitions( TwoDArray<bool>& trans_map , const int ref_num )
+{
+
+ const MvArray& mv_array = Vectors( ref_num );
+
+ // Start with a statistical approach - determine thresholds later
+
+ // Compute mean and standard deviation of local SAD variance //
+ ///////////////////////////////////////////////////////////////
+
+ long double total_cost = 0.0;
+ long double mean_cost;
+ long double sd_cost = 0.0;
+ double diff;
+ double threshold;
+
+ // first, mean
+ for ( int j=0 ; j<mv_array.LengthY() ; ++j )
+ for ( int i=0 ; i<mv_array.LengthX() ; ++i )
+ total_cost += PredCosts( ref_num )[j][i].SAD;
+
+ mean_cost = total_cost /
+ static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
+
+ // next , Standard Deviation
+
+ for ( int j=0 ; j<mv_array.LengthY() ; ++j )
+ {
+ for ( int i=0 ; i<mv_array.LengthX() ; ++i )
+ {
+ diff = PredCosts( ref_num )[j][i].SAD - mean_cost;
+ diff *= diff;
+ sd_cost += diff;
+
+ }// i
+ }// j
+
+ // Get the variance ...
+ sd_cost /= static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
+
+ // ... and then the SD
+ sd_cost = std::sqrt( sd_cost );
+
+ threshold = mean_cost + 3*sd_cost;
+
+ // now go through and mark those that go above the threshold
+ for ( int j=0 ; j<mv_array.LengthY() ; ++j )
+ for ( int i=0 ; i<mv_array.LengthX() ; ++i )
+ trans_map[j][i] = ( PredCosts( ref_num )[j][i].SAD >= threshold )? true : false;
+
+
+ // Next look at motion-vector costs
+ TwoDArray<double> val_array( mv_array.LengthY() , mv_array.LengthX() );
+
+ // first, mean
+ total_cost = 0.0;
+ for ( int i=0 ; i<mv_array.LengthX() ; ++i )
+ {
+ val_array[0][i] = 0.0;
+ val_array[val_array.LastY()][i] = 0.0;
+ }// i
+
+ for ( int j=1 ; j<mv_array.LengthY()-1 ; ++j )
+ {
+ val_array[j][0] = 0.0;
+ val_array[j][val_array.LastX()] = 0.0;
+ for ( int i=1 ; i<mv_array.LengthX()-1 ; ++i )
+ {
+ val_array[j][i] =0.0;
+ for (int q=-1 ; q<=1 ; ++q)
+ for (int p=-1 ; p<=1 ; ++p)
+ val_array[j][i] = std::max( val_array[j][i] , (double)Norm1( mv_array[j+q][i+p] - mv_array[j][i] ) );
+
+ total_cost += val_array[j][i];
+
+ }// i
+ }// j
+
+
+ mean_cost = total_cost /
+ static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
+
+ // next , Standard Deviation
+ sd_cost = 0.0;
+
+ for ( int j=1 ; j<mv_array.LengthY()-1 ; ++j )
+ {
+ for ( int i=1 ; i<mv_array.LengthX()-1 ; ++i )
+ {
+ diff = val_array[j][i] - mean_cost;
+ diff *= diff;
+
+ sd_cost += diff;
+
+ }// i
+ }// j
+
+ // Get the variance ...
+ sd_cost /= static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
+
+ // ... and then the SD
+ sd_cost = std::sqrt( sd_cost );
+
+ threshold = mean_cost + 3*sd_cost;
+
+ // now go through and mark those that go above the threshold
+ for ( int j=0 ; j<mv_array.LengthY() ; ++j )
+ for ( int i=0 ; i<mv_array.LengthX() ; ++i )
+ trans_map[j][i] = ( val_array[j][i] >= threshold )? true : false;
+
+ bool contains_trans;
+
+ for ( int j=0 ; j<mv_array.LengthY()/4 ; ++j )
+ {
+ for ( int i=0 ; i<mv_array.LengthX()/4 ; ++i )
+ {
+ contains_trans = false;
+ for ( int q=4*j ; q<4*(j+1) ; ++q )
+ {
+ for ( int p=4*i ; p<4*(i+1) ; ++p )
+ {
+ if (trans_map[q][p])
+ contains_trans = true;
+ }// p
+ }// q
+ for ( int q=4*j ; q<4*(j+1) ; ++q )
+ for ( int p=4*i ; p<4*(i+1) ; ++p )
+ trans_map[q][p] = contains_trans;
+
+ }// i
+ }// j
+
+}
+
+
+MEData::~MEData()
+{
+ // Delete the arrays of prediction costs
+ for ( int i=m_pred_costs.First() ; i<=m_pred_costs.Last() ; ++i )
+ delete m_pred_costs[i];
+
+ for ( int i=m_inliers.First() ; i<=m_inliers.Last() ; ++i )
+ delete m_inliers[i];
+}
+
+void MEData::DropRef( const int rindex ){
+
+ if (rindex==2){}
+ else if (rindex==1){
+ // Swap data for reference 1 and reference 2
+ // so that reference 2 becomes the new reference 1
+
+ MvArray* ptr = m_vectors[1];
+ m_vectors[1] = m_vectors[2];
+ m_vectors[2] = ptr;
+
+ ptr = m_gm_vectors[1];
+ m_gm_vectors[1] = m_gm_vectors[2];
+ m_gm_vectors[2] = ptr;
+
+ OneDArray<float>* ptr2 = m_gm_params[1];
+ m_gm_params[1] = m_gm_params[2];
+ m_gm_params[2] = ptr2;
+
+ TwoDArray<MvCostData>* ptr3 = m_pred_costs[1];
+ m_pred_costs[1] = m_pred_costs[2];
+ m_pred_costs[2] = ptr3;
+
+ TwoDArray<int>* ptr4 = m_inliers[1];
+ m_inliers[1] = m_inliers[2];
+ m_inliers[2] = ptr4;
+ }
+}
+
+namespace dirac
+{
+//! Overloaded operator<< for MvCostData
+/*!
+ Only writes SAD value to stream
+*/
+ostream & operator<< (ostream & stream, MvCostData & cost)
+{
+ stream << cost.SAD << " " << cost.mvcost;
+
+ return stream;
+}
+
+//! Overloaded operator>> for MvCostData
+/*!
+ Only reads SAD value from stream
+*/
+istream & operator>> (istream & stream, MvCostData & cost)
+{
+ stream >> cost.SAD >> cost.mvcost;
+
+ return stream;
+}
+
+//! Overloaded operator>> for PredMode
+/*!
+ No operator<< is specified as enumeration is written as integers
+ operator>> required to specify PredMode input
+*/
+istream & operator>> (istream & stream, PredMode & mode)
+{
+ int temp;
+ stream >> temp;
+ mode = (PredMode)temp;
+
+ return stream;
+}
+
+// Overriden extractor operator for reading MvData data members
+istream &operator>> (istream & stream, MEData & me_data)
+{
+ stream.ignore(1000, '\n');
+
+ // input reference-independent information
+ stream >> me_data.SBSplit();
+ stream >> me_data.SBCosts();
+ stream >> me_data.Mode();
+ stream >> me_data.IntraCosts();
+
+ if (me_data.m_pred_costs.Length() > 1)
+ stream >> me_data.BiPredCosts();
+
+ if (me_data.DC().Length() == 1)
+ {
+ stream >> me_data.DC( Y_COMP );
+ }
+ else if (me_data.DC().Length() == 3)
+ {
+ stream >> me_data.DC( Y_COMP );
+ stream >> me_data.DC( U_COMP );
+ stream >> me_data.DC( V_COMP );
+ }
+
+ // input reference information
+ for (int i=1; i<=me_data.m_pred_costs.Length(); ++i)
+ {
+ stream >> me_data.Vectors(i);
+ stream >> me_data.PredCosts(i);
+ //stream >> me_data.GlobalMotionParameters(i);
+ //stream >> me_data.GlobalMotionVectors(i);
+ //stream >> me_data.GlobalMotionInliers(i);
+ }
+
+ return stream;
+}
+
+// Overriden operator for output of MvData member data (to file)
+ostream &operator<< (ostream & stream, MEData & me_data)
+{
+ // output reference-independent information
+ stream << endl << endl << me_data.SBSplit();
+ stream << endl << me_data.SBCosts();
+ stream << endl << me_data.Mode();
+ stream << endl << me_data.IntraCosts() << endl;
+
+ if (me_data.m_pred_costs.Length() > 1)
+ stream << me_data.BiPredCosts();
+
+ // output component DC values
+ if (me_data.DC().Length() == 1)
+ {
+ stream << endl << me_data.DC( Y_COMP );
+ }
+ else if (me_data.DC().Length() == 3)
+ {
+ stream << endl << me_data.DC( Y_COMP );
+ stream << endl << me_data.DC( U_COMP );
+ stream << endl << me_data.DC( V_COMP );
+ }
+
+ // output reference information
+ for (int i=1; i<=me_data.m_pred_costs.Length(); ++i)
+ {
+ stream << endl << me_data.Vectors(i);
+ stream << endl << me_data.PredCosts(i) << endl;
+ //stream << endl << me_data.GlobalMotionParameters(i) << endl;
+ //stream << endl << me_data.GlobalMotionVectors(i) << endl;
+ //stream << endl << me_data.GlobalMotionInliers(i) << endl;
+ }
+
+ return stream;
+}
+
+int Median( const int val1, const int val2, const int val3)
+{
+ int tmp;
+
+ tmp=val1;
+ tmp+=val2;
+ tmp+=val3;
+
+ tmp -= std::max( std::max( val1 , val2 ) , val3 );
+ tmp -= std::min( std::min( val1 , val2 ) , val3 );
+
+ return tmp;
+}
+
+MVector MvMedian(const MVector& mv1,const MVector& mv2,const MVector& mv3) {
+ //takes median of each vector component
+ MVector tmp_mv;
+
+ tmp_mv.x=mv1.x;
+ tmp_mv.x+=mv2.x;
+ tmp_mv.x+=mv3.x;
+
+ tmp_mv.x-=std::max(std::max(mv1.x,mv2.x),mv3.x);
+ tmp_mv.x-=std::min(std::min(mv1.x,mv2.x),mv3.x);
+
+ tmp_mv.y=mv1.y;
+ tmp_mv.y+=mv2.y;
+ tmp_mv.y+=mv3.y;
+
+ tmp_mv.y-=std::max(std::max(mv1.y,mv2.y),mv3.y);
+ tmp_mv.y-=std::min(std::min(mv1.y,mv2.y),mv3.y);
+
+ return tmp_mv;
+}
+
+int Median(const std::vector<int>& val_list)
+{
+ // take the median of up to 4 elements
+
+ switch (val_list.size() )
+ {
+ case 1 :
+
+ return val_list[0];
+ case 2 : // return the mean
+ return ( ( val_list[0] + val_list[1] + 1 )>>1 );
+ case 3 :
+ return Median(val_list[0], val_list[1], val_list[2] );
+ case 4 :
+ {
+ int med_val(0);
+ int max_val(val_list[0]);
+ int min_val(val_list[0]);
+
+ for (int i=0; i<4; ++i )
+ {
+ med_val += val_list[i];
+ max_val = std::max( max_val , val_list[i] );
+ min_val = std::min( min_val , val_list[i] );
+
+ }// i
+
+ med_val -= ( max_val + min_val );
+
+ return ( (med_val + 1)>>1 );
+ }
+ default :
+ return 0;
+ }
+
+}
+
+MVector MvMedian(const std::vector<MVector>& vect_list){
+ //median of 0-4 vectors
+
+ if ( vect_list.size() == 0 )
+ return 0;
+ else if ( vect_list.size() == 1 )
+ return vect_list[0];
+ else if ( vect_list.size() == 2 )
+ return MvMean( vect_list[0], vect_list[1] );
+ else if ( vect_list.size() == 3 )
+ return MvMedian(vect_list[0], vect_list[1], vect_list[2] );
+ else if ( vect_list.size() == 4 )
+ {
+ MVector tmp_mv(0);
+ MVector max_mv(vect_list[0]);
+ MVector min_mv(vect_list[0]);
+ for (int i=0; i<4; ++i )
+ {
+ tmp_mv.x += vect_list[i].x;
+ max_mv.x=std::max(max_mv.x, vect_list[i].x);
+ min_mv.x=std::min(min_mv.x, vect_list[i].x);
+
+ tmp_mv.y += vect_list[i].y;
+ max_mv.y=std::max(max_mv.y, vect_list[i].y);
+ min_mv.y=std::min(min_mv.y, vect_list[i].y);
+
+ }// i
+
+ tmp_mv.x -= (max_mv.x+min_mv.x);
+ tmp_mv.y -= (max_mv.y+min_mv.y);
+
+ tmp_mv.x = (tmp_mv.x+1)>>1;
+ tmp_mv.y = (tmp_mv.y+1)>>1;
+
+ return tmp_mv;
+
+ }
+ else
+ {
+ MVector median;
+ int num_vals=int(vect_list.size());
+ if (num_vals>0) {
+ int pos=0;
+ std::vector<int> ordered_vals(vect_list.size());
+ //do x first
+ ordered_vals[0]=vect_list[0].x;
+ for (int I=1;I<num_vals;++I){
+ for (int K=0;K<I;++K){
+ if (vect_list[I].x<ordered_vals[K]){
+ pos=K;
+ break;
+ }
+ else
+ pos=K+1;
+ }//K
+ if (pos==I)
+ ordered_vals[I]=vect_list[I].x;
+ else{
+ for (int K=I-1;K>=pos;--K){
+ ordered_vals[K+1]=ordered_vals[K];
+ }
+ ordered_vals[pos]=vect_list[I].x;
+ }
+ }//I
+ if (vect_list.size()%2!=0)
+ median.x=ordered_vals[(num_vals-1)/2];
+ else
+ median.x=(ordered_vals[(num_vals/2)-1]+ordered_vals[num_vals/2]+1)>>1;
+
+ //now do y
+ ordered_vals[0]=vect_list[0].y;
+ for (int I=1;I<num_vals;++I){
+ for (int K=0;K<I;++K){
+ if (vect_list[I].y<ordered_vals[K]){
+ pos=K;
+ break;
+ }
+ else
+ pos=K+1;
+ }//K
+ if (pos==I)
+ ordered_vals[I]=vect_list[I].y;
+ else{
+ for (int K=I-1;K>=pos;--K){
+ ordered_vals[K+1]=ordered_vals[K];
+ }
+ ordered_vals[pos]=vect_list[I].y;
+ }
+ }//I
+ if (num_vals%2!=0)
+ median.y=ordered_vals[(num_vals-1)/2];
+ else
+ median.y=(ordered_vals[(num_vals/2)-1]+ordered_vals[num_vals/2]+1)>>1;
+
+ }
+ else{
+ median.x=0;
+ median.y=0;
+ }
+
+ return median;
+ }
+
+}
+
+
+//! Return the unbiased mean of two motion vectors
+MVector MvMean(const MVector& mv1, const MVector& mv2)
+{
+ //takes mean of each vector component
+ MVector tmp_mv;
+
+ tmp_mv.x = mv1.x;
+ tmp_mv.x += mv2.x+1;
+ tmp_mv.x >>= 1;
+
+ tmp_mv.y = mv1.y;
+ tmp_mv.y += mv2.y+1;
+ tmp_mv.y >>= 1;
+
+ return tmp_mv;
+}
+
+//! Return the mean of a set of unsigned integer values
+unsigned int GetUMean(std::vector<unsigned int>& values)
+{
+ unsigned int sum=0;
+ for (unsigned int I=0;I<values.size();++I)
+ sum+=values[I];
+
+ sum+=(values.size()>>1);
+ sum/=values.size();
+
+ return sum;
+}
+
+//! Return the mean of a set of signed integer values
+int GetSMean(std::vector<int>& values)
+{
+ if (values.size()==0)
+ return 0;
+
+ int sum=0;
+ for (unsigned int i=0;i<values.size();++i)
+ sum+=values[i];
+ if ( sum>=0 )
+ {
+ sum+=(values.size()>>1);
+ sum/=values.size();
+ }
+ else
+ {
+ int old_sum = sum;
+ sum -= values.size()*old_sum;
+ sum+=(values.size()>>1);
+ sum/=values.size();
+ sum += old_sum;
+ }
+
+ return sum;
+}
+
+} // namespace dirac
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.h
new file mode 100644
index 000000000..a985bdbd7
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/motion.h
@@ -0,0 +1,448 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: motion.h,v 1.30 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Chris Bowley,
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/common.h>
+#include <algorithm>
+#ifndef _MOTION_H
+#define _MOTION_H
+
+namespace dirac
+{
+ ////////////////////////////////////////////////////////////////
+ //classes and functions for motion estimation and compensation//
+ ////////////////////////////////////////////////////////////////
+
+ //classes
+
+ //! Horizontal or vertical
+ enum MvElement { HORIZONTAL , VERTICAL };
+
+ //! Motion vector class - just a pair
+ template <class T>
+ class MotionVector
+ {
+ public:
+
+ //! Constructor
+ MotionVector<T>(T a, T b) : x(a), y(b) {};
+ //! Default construct - sets components to 0
+ MotionVector<T>() : x(0), y(0) {};
+ //! Constructor
+ MotionVector<T>(T a) : x(a), y(a) {};
+
+ //! Addition
+ inline MotionVector<T> operator+(const MotionVector<T>& argument) const;
+
+ //! Subtraction
+ inline MotionVector<T> operator-(const MotionVector<T>& argument) const;
+
+ //! Scalar multiplication
+ inline MotionVector<T> operator*(const float argument) const;
+
+ //! Scalar multiplication
+ inline MotionVector<T> operator*(const int argument) const;
+
+ //! Bitshift of each component
+ inline MotionVector<T> operator<<(const int argument) const;
+
+ //! Bitshift of each component
+ inline MotionVector<T> operator>>(const int argument) const;
+
+ //! Array-style element access
+ T& operator[](const int pos){return ( ( pos==0) ? x : y );}
+
+ //! Array-style element access.
+ const T& operator[](const int pos) const {return ( ( pos==0) ? x : y );}
+
+
+ //! x and y components
+ T x,y;
+
+ };
+
+
+ template <class T>
+ inline MotionVector<T> MotionVector<T>::operator+(const MotionVector<T>& argument) const
+ {
+ MotionVector<T> temp;
+ temp.x = x + argument.x;
+ temp.y = y + argument.y;
+
+ return temp;
+ }
+
+ template <class T>
+ inline MotionVector<T> MotionVector<T>::operator-(const MotionVector<T>& argument) const
+ {
+ MotionVector<T> temp;
+ temp.x = x-argument.x;
+ temp.y = y-argument.y;
+
+ return temp;
+ }
+
+ template <class T>
+ inline MotionVector<T> MotionVector<T>::operator*(const float argument) const
+ {
+ MotionVector<T> temp;
+ temp.x = x*argument;
+ temp.y = y*argument;
+
+ return temp;
+ }
+
+ template <class T>
+ inline MotionVector<T> MotionVector<T>::operator*(const int argument) const
+ {
+ MotionVector<T> temp;
+ temp.x = x*argument;
+ temp.y = y*argument;
+
+ return temp;
+ }
+
+ template <class T>
+ inline MotionVector<T> MotionVector<T>::operator<<(const int argument) const
+ {
+ MotionVector<T> temp;
+ temp.x = x<<argument;
+ temp.y = y<<argument;
+
+ return temp;
+ }
+
+ template <class T>
+ inline MotionVector<T> MotionVector<T>::operator>>(const int argument) const
+ {
+ MotionVector<T> temp;
+ temp.x = x>>argument;
+ temp.y = y>>argument;
+
+ return temp;
+ }
+
+ //! Overloaded operator<< for MotionVector class for output to stream
+ template <class T>
+ std::ostream & operator<< (std::ostream & stream, MotionVector<T> & mv)
+ {
+ stream << mv.x << " " << mv.y;
+
+ return stream;
+ }
+
+ //! Overloaded operator>> for MotionVector class for input from stream
+ template <class T>
+ std::istream & operator>> (std::istream & stream, MotionVector<T> & mv)
+ {
+ stream >> mv.x;
+ stream >> mv.y;
+
+ return stream;
+ }
+
+ //! MVector class is a vector of ints
+ typedef MotionVector<int> MVector;
+
+ //! ImageCoords class is a vector of ints
+ typedef MotionVector<int> ImageCoords;
+
+ //! MvArray is a two-D array of MVectors
+ typedef TwoDArray<MVector> MvArray;
+
+ //! An array of float-based motion vectors for doing global motion calcs
+ typedef TwoDArray< MotionVector<float> > MvFloatArray;
+
+ //! Class for recording costs derived in motion estimation
+ class MvCostData
+ {
+ public:
+ //! Constructor
+ MvCostData():
+ SAD(0.0),
+ mvcost(0.0),
+ total(0.0){}
+
+ void SetTotal( const float lambda ){total = SAD + lambda*mvcost;}
+
+ //! The Sum of Absolute Differences - easier to compute than Sum-Squared Differences
+ float SAD;
+
+ //! The (Lagrangian-weighted) motion vector cost - the difference of a motion vector from its neighbouring vectors
+ float mvcost;
+
+ //! Total=SAD+mvcost
+ float total;
+ };
+
+
+ //! Class for all the motion vector data
+ /*!
+ Motion vector data: the motion vectors themselves, the blocks
+ and macroblock modes.
+ */
+ class MvData
+ {
+ public:
+ //! Constructor
+ /*!
+ Constructor takes:
+ \param predparams Picture prediction parameters
+ \param num_refs the number of references being used for the picture
+ */
+ MvData( const PicturePredParams& predparams , const int num_refs);
+
+ //! Destructor
+ ~MvData();
+
+ //! Return a reference to the local picture prediction params
+ PicturePredParams& GetPicPredParams(){return m_predparams;}
+
+ //! Return a reference to the local picture prediction params
+ const PicturePredParams& GetPicPredParams() const{return m_predparams;}
+
+ //! Get the MVs for a reference
+ MvArray& Vectors(const int ref_id){return *( m_vectors[ref_id] );}
+
+ //! Get the MVs for a reference
+ const MvArray& Vectors(const int ref_id) const {return *( m_vectors[ref_id] );}
+
+ //! Get the global MVs for a reference
+ MvArray& GlobalMotionVectors(const int ref_id){return *( m_gm_vectors[ref_id] );}
+
+ //! Get the global MVs for a reference
+ const MvArray& GlobalMotionVectors(const int ref_id) const {return *( m_gm_vectors[ref_id] );}
+
+ //! Get the DC values for each component
+ TwoDArray<ValueType>& DC(CompSort cs){return *( m_dc[cs] );}
+
+ //! Get the DC values for each component
+ const TwoDArray<ValueType>& DC(CompSort cs) const {return *( m_dc[cs] );}
+
+ //! Get a reference to the vector holding component DC values
+ const OneDArray< TwoDArray<ValueType>* >& DC() const {return m_dc;}
+
+ //! Get the block prediction modes
+ TwoDArray<PredMode>& Mode(){return m_modes;}
+
+ //! Get the block prediction modes
+ const TwoDArray<PredMode>& Mode() const {return m_modes;}
+
+ //! Get the SB split level
+ TwoDArray<int>& SBSplit(){return m_sb_split;}
+
+ //! Get the SB split level
+ const TwoDArray<int>& SBSplit() const{return m_sb_split;}
+
+ //! Get the global motion model parameters
+ OneDArray<float>& GlobalMotionParameters(const int ref_id) { return *( m_gm_params[ref_id] ); }
+
+ //! Get the global motion model parameters
+ const OneDArray<float>& GlobalMotionParameters(const int ref_id) const { return *( m_gm_params[ref_id] ); }
+
+ protected:
+ // A local copy of the picture prediction parameters
+ PicturePredParams m_predparams;
+
+ // Initialises the arrays of data
+ void InitMvData();
+
+ // The motion vectors
+ OneDArray<MvArray*> m_vectors;
+
+ // The global motion vectors
+ OneDArray<MvArray*> m_gm_vectors;
+
+ // The block modes
+ TwoDArray<PredMode> m_modes;
+
+ // The DC values
+ OneDArray< TwoDArray<ValueType>* > m_dc;
+
+ // The SB split levels
+ TwoDArray<int> m_sb_split;
+
+ // Global motion model parameters
+ OneDArray< OneDArray<float>* > m_gm_params;
+
+// // Number of reference frames
+// unsigned int m_num_refs;
+ };
+
+ //! Class for all the motion estimation data
+ /*!
+ Motion estimation data: derived from MvData class, also
+ incorporates costs for blocks and macroblocks
+ */
+
+ class MEData: public MvData
+ {
+ public:
+
+ //! Constructor
+ /*!
+ Constructor takes:
+ \param predparams the picture prediction parameters
+ \param num_refs the number of references being used for the picture
+ */
+ MEData( const PicturePredParams& predparams , const int num_refs = 2);
+
+ //! Destructor
+ ~MEData();
+
+ //! drop the data relating to one reference
+ void DropRef( int ref_index );
+
+ //! Get the block cost structures for each reference
+ TwoDArray<MvCostData>& PredCosts(const int ref_id){ return *( m_pred_costs[ref_id] ); }
+
+ //! Get the block cost structures for each reference
+ const TwoDArray<MvCostData>& PredCosts(const int ref_id) const { return *( m_pred_costs[ref_id] ); }
+
+ //! Get the intra costs
+ TwoDArray<float>& IntraCosts(){ return m_intra_costs; }
+
+ //! Get the intra costs
+ const TwoDArray<float>& IntraCosts() const { return m_intra_costs; }
+
+ //! Get the bipred costs
+ TwoDArray<MvCostData>& BiPredCosts(){ return m_bipred_costs; }
+
+ //! Get the bipred costs
+ const TwoDArray<MvCostData>& BiPredCosts() const { return m_bipred_costs; }
+
+ //! Get the SB costs
+ TwoDArray<float>& SBCosts(){ return m_SB_costs; }
+
+ //! Get the SB costs
+ const TwoDArray<float>& SBCosts() const { return m_SB_costs; }
+
+ //! Get the proportion of intra blocks
+ float IntraBlockRatio() const {return m_intra_block_ratio; }
+
+ //! Set the intra block ratio
+ void SetIntraBlockRatio(const float r){ m_intra_block_ratio = r; }
+
+ //! Set up the lambda map by detecting motion discontinuities
+ void SetLambdaMap( const int num_refs , const float lambda );
+
+ //! Set up the lambda map by averaging the lambda map from a lower level
+ void SetLambdaMap( const int level , const TwoDArray<float>& l_map , const float wt );
+
+ //! Get a lambda value for a given block and level
+ const TwoDArray<float>& LambdaMap() const { return m_lambda_map; }
+
+ //! Get the inliers for each reference
+ TwoDArray<int>& GlobalMotionInliers(const int ref_id){ return *( m_inliers[ref_id] ); }
+
+ //! Get the inliers for each reference
+ const TwoDArray<int>& GlobalMotionInliers(const int ref_id) const { return *( m_inliers[ref_id] ); }
+
+ //! Overloaded operator<< for outputing to (file) stream
+ friend std::ostream &operator<< (std::ostream & stream, MEData & me_data);
+
+ //! Overloaded operator>> for input of data from (file) stream
+ friend std::istream &operator>> (std::istream & stream, MEData & me_data);
+
+ private:
+ // Initialises the arrays of data
+ void InitMEData();
+
+ // Finds transitions in the motion vectors
+ void FindTransitions( TwoDArray<bool>& trans_map , const int ref_num );
+
+ // The costs of predicting each block, for each reference
+ OneDArray< TwoDArray<MvCostData>* > m_pred_costs;
+
+ // The costs of predicting each block by DC
+ TwoDArray<float> m_intra_costs;
+
+ // The costs of predicting each block bidirectionally
+ TwoDArray<MvCostData> m_bipred_costs;
+
+ // The costs for each macroblock as a whole
+ TwoDArray<float> m_SB_costs;
+
+ // A map of the lambda values to use
+ TwoDArray<float> m_lambda_map;
+
+ // Global motion inliers
+ OneDArray< TwoDArray<int>* > m_inliers;
+
+ // Intra block ratio
+ float m_intra_block_ratio;
+
+ };
+
+ //motion estimation and coding stuff
+
+ //! Return the median of 3 integers
+ int Median( const int val1, const int val2, const int val3);
+
+ //! Return the median of three motion vectors
+ MVector MvMedian(const MVector& mv1,const MVector& mv2,const MVector& mv3);
+
+
+ //! Return the median of a set of integers
+ int Median(const std::vector<int>& val_list);
+
+ //! Return the median of a set of (up to 4) motion vectors
+ MVector MvMedian(const std::vector<MVector>& vect_list);
+
+ //! Return the mean of two motion vectors
+ MVector MvMean(const MVector& mv1, const MVector& mv2);
+
+ //! Return the squared length of a motion vector
+ inline int Norm2(const MVector& mv){//L^2 norm of a motion vector
+ return mv.x*mv.x+mv.y*mv.y;
+ }
+
+ //! Return the sum of the lengths of a motion vector's componets
+ inline int Norm1(const MVector& mv){//L^1 norm of a motion vector
+ return abs(mv.x)+abs(mv.y);
+ }
+
+ //! Return the mean of a set of unsigned integer values
+ unsigned int GetUMean(std::vector<unsigned int>& values);
+
+ //! Return the mean of a set of signed integer values
+ int GetSMean(std::vector<int>& values);
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.cpp
new file mode 100644
index 000000000..d576d6e12
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.cpp
@@ -0,0 +1,641 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mv_codec.cpp,v 1.35 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Tim Borer,
+* Andrew Kennedy,
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/mv_codec.h>
+
+using namespace dirac;
+
+//public functions//
+////////////////////
+// Constructor
+SplitModeCodec::SplitModeCodec(ByteIO* p_byteio,
+ size_t number_of_contexts)
+ : ArithCodec <MvData> (p_byteio,number_of_contexts)
+{}
+
+
+
+void SplitModeCodec::InitContexts()
+{
+}
+
+// Main code function
+void SplitModeCodec::DoWorkCode( MvData& in_data )
+{
+ for (m_sb_yp = 0; m_sb_yp < in_data.SBSplit().LengthY(); ++m_sb_yp)
+ {
+ for (m_sb_xp = 0; m_sb_xp < in_data.SBSplit().LengthX(); ++m_sb_xp)
+ {
+ CodeVal(in_data);
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+// Main decode function
+void SplitModeCodec::DoWorkDecode( MvData& out_data)
+{
+
+ for (m_sb_yp = 0; m_sb_yp < out_data.SBSplit().LengthY(); ++m_sb_yp)
+ {
+ for (m_sb_xp = 0; m_sb_xp < out_data.SBSplit().LengthX(); ++m_sb_xp)
+ {
+ DecodeVal( out_data );
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+//protected functions//
+///////////////////////
+
+void SplitModeCodec::ResetAll()
+{
+}
+
+//coding functions//
+////////////////////
+
+//prediction functions
+
+unsigned int SplitModeCodec::Prediction(const TwoDArray<int> & split_data ) const
+{
+ int result = 0;
+
+ std::vector < unsigned int > nbrs;
+
+ if (m_sb_xp > 0 && m_sb_yp > 0)
+ {
+ nbrs.push_back( split_data[m_sb_yp-1][m_sb_xp] );
+ nbrs.push_back( split_data[m_sb_yp-1][m_sb_xp-1] );
+ nbrs.push_back( split_data[m_sb_yp][m_sb_xp-1] );
+
+ result = GetUMean(nbrs);
+ }
+ else if (m_sb_xp > 0 && m_sb_yp == 0)
+ result = split_data[m_sb_yp][m_sb_xp-1];
+ else if (m_sb_xp == 0 && m_sb_yp > 0)
+ result = split_data[m_sb_yp-1][m_sb_xp];
+
+ return result;
+}
+
+
+void SplitModeCodec::CodeVal(const MvData& in_data)
+{
+ int val = in_data.SBSplit()[m_sb_yp][m_sb_xp] - Prediction( in_data.SBSplit() );
+
+ if (val < 0) val+=3; //produce prediction mod 3
+
+ EncodeUInt(val, SB_SPLIT_BIN1_CTX, SB_SPLIT_BIN2_CTX);
+}
+
+//decoding functions//
+//////////////////////
+
+
+
+void SplitModeCodec::DecodeVal(MvData& out_data)
+{
+ out_data.SBSplit()[m_sb_yp][m_sb_xp] =
+ (DecodeUInt(SB_SPLIT_BIN1_CTX, SB_SPLIT_BIN2_CTX) +
+ Prediction(out_data.SBSplit())) % 3;
+}
+
+/******************************************************************************/
+
+//public functions//
+////////////////////
+// Constructor
+PredModeCodec::PredModeCodec(ByteIO* p_byteio,
+ size_t number_of_contexts,
+ int num_refs)
+ : ArithCodec <MvData> (p_byteio,number_of_contexts),
+ m_num_refs(num_refs)
+{}
+
+
+
+void PredModeCodec::InitContexts()
+{
+}
+
+// Main code function
+void PredModeCodec::DoWorkCode( MvData& in_data )
+{
+ int step,max;
+ int split_depth;
+
+ for (m_sb_yp = 0, m_sb_tlb_y = 0; m_sb_yp < in_data.SBSplit().LengthY(); ++m_sb_yp, m_sb_tlb_y += 4)
+ {
+ for (m_sb_xp = 0,m_sb_tlb_x = 0; m_sb_xp < in_data.SBSplit().LengthX(); ++m_sb_xp,m_sb_tlb_x += 4)
+ {
+ split_depth = in_data.SBSplit()[m_sb_yp][m_sb_xp];
+
+ step = 4 >> (split_depth);
+ max = (1 << split_depth);
+
+ //now do all the block modes and mvs in the mb
+ for (m_b_yp = m_sb_tlb_y; m_b_yp < m_sb_tlb_y+4; m_b_yp += step)
+ {
+ for (m_b_xp = m_sb_tlb_x; m_b_xp < m_sb_tlb_x+4; m_b_xp += step)
+ {
+ CodeVal(in_data);
+ }//m_b_xp
+ }//m_b_yp
+
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+// Main decode function
+void PredModeCodec::DoWorkDecode( MvData& out_data)
+{
+ int step,max;
+ int split_depth;
+ int xstart,ystart;
+
+ // Then the prediction mode
+ for (m_sb_yp = 0,m_sb_tlb_y = 0; m_sb_yp < out_data.SBSplit().LengthY(); ++m_sb_yp,m_sb_tlb_y += 4)
+ {
+ for (m_sb_xp = 0,m_sb_tlb_x = 0; m_sb_xp < out_data.SBSplit().LengthX(); ++m_sb_xp,m_sb_tlb_x += 4)
+ {
+ split_depth = out_data.SBSplit()[m_sb_yp][m_sb_xp];
+ step = 4 >> (split_depth);
+ max = (1 << split_depth);
+
+ //now do all the block mvs in the mb
+ for (int j = 0; j < max; ++j)
+ {
+ for (int i = 0; i < max; ++i)
+ {
+ xstart = m_b_xp = m_sb_tlb_x + i * step;
+ ystart = m_b_yp = m_sb_tlb_y + j * step;
+
+ DecodeVal(out_data);
+
+ // propagate throughout SB
+ for (m_b_yp = ystart; m_b_yp < ystart+step; m_b_yp++)
+ {
+ for (m_b_xp = xstart; m_b_xp < xstart+step; m_b_xp++)
+ {
+ out_data.Mode()[m_b_yp][m_b_xp] = out_data.Mode()[ystart][xstart];
+ }//m_b_xp
+ }//m_b_yp
+ }//i
+ }//j
+
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+//protected functions//
+///////////////////////
+
+void PredModeCodec::ResetAll()
+{
+}
+
+//coding functions//
+////////////////////
+
+//prediction functions
+
+unsigned int PredModeCodec::Prediction(const TwoDArray < PredMode > & preddata) const
+{
+ unsigned int result = (unsigned int)(INTRA);
+ unsigned int num_ref1_nbrs( 0 );
+ unsigned int num_ref2_nbrs( 0 );
+
+ if (m_b_xp > 0 && m_b_yp > 0)
+ {
+ num_ref1_nbrs += ((unsigned int)( preddata[m_b_yp-1][m_b_xp] ) ) & 1;
+ num_ref1_nbrs += ((unsigned int)( preddata[m_b_yp-1][m_b_xp-1] ) ) & 1;
+ num_ref1_nbrs += ((unsigned int)( preddata[m_b_yp][m_b_xp-1] ) ) & 1;
+
+ result = num_ref1_nbrs>>1;
+
+ if ( m_num_refs==2)
+ {
+ num_ref2_nbrs += ((unsigned int)( preddata[m_b_yp-1][m_b_xp] ) ) & 2;
+ num_ref2_nbrs += ((unsigned int)( preddata[m_b_yp-1][m_b_xp-1] ) ) & 2;
+ num_ref2_nbrs += ((unsigned int)( preddata[m_b_yp][m_b_xp-1] ) ) & 2;
+ num_ref2_nbrs >>= 1;
+ result ^= ( (num_ref2_nbrs>>1)<<1 );
+ }
+ }
+ else if (m_b_xp > 0 && m_b_yp == 0)
+ result = (unsigned int)( preddata[0][m_b_xp-1] );
+ else if (m_b_xp == 0 && m_b_yp > 0)
+ result = (unsigned int)( preddata[m_b_yp-1][0] );
+
+ return result;
+}
+
+void PredModeCodec::CodeVal(const MvData& in_data)
+{
+ // Xor with the prediction so we predict whether REF1 is used or REF2 is
+ // used, separately
+ unsigned int residue = in_data.Mode()[m_b_yp][m_b_xp] ^
+ Prediction( in_data.Mode() );
+
+ // Code REF1 part of the prediction residue (ie the first bit)
+ EncodeSymbol( residue & 1 , PMODE_BIT0_CTX );
+
+ // Code REF2 part of the prediction residue (ie the second bit)
+ if (m_num_refs==2)
+ {
+ EncodeSymbol( residue & 2 , PMODE_BIT1_CTX );
+ }
+
+}
+
+//decoding functions//
+//////////////////////
+
+void PredModeCodec::DecodeVal( MvData& out_data )
+{
+ // Xor with the prediction so we predict whether REF1 is used or REF2 is
+ // used, separately
+ unsigned int residue;
+
+ // Decode REF1 part of the prediction residue (ie the first bit)
+ bool bit;
+ bit = DecodeSymbol( PMODE_BIT0_CTX );
+ residue = (unsigned int) bit;
+
+ // Decode REF2 part of the prediction residue (ie the second bit)
+ if (m_num_refs==2)
+ {
+ bit = DecodeSymbol( PMODE_BIT1_CTX );
+ residue |= ( (unsigned int) bit ) << 1;
+ }
+
+ out_data.Mode()[m_b_yp][m_b_xp] =
+ PredMode( Prediction( out_data.Mode() ) ^ residue );
+}
+
+/******************************************************************************/
+
+
+//public functions//
+////////////////////
+// Constructor
+VectorElementCodec::VectorElementCodec(ByteIO* p_byteio,
+ int ref_id,
+ MvElement horvert,
+ size_t number_of_contexts)
+ : ArithCodec <MvData> (p_byteio,number_of_contexts),
+ m_ref(ref_id),
+ m_hv(horvert)
+{}
+
+
+
+void VectorElementCodec::InitContexts()
+{}
+
+// Main code function
+void VectorElementCodec::DoWorkCode( MvData& in_data )
+{
+ int step,max;
+ int split_depth;
+
+ for (m_sb_yp = 0, m_sb_tlb_y = 0; m_sb_yp < in_data.SBSplit().LengthY(); ++m_sb_yp, m_sb_tlb_y += 4)
+ {
+ for (m_sb_xp = 0,m_sb_tlb_x = 0; m_sb_xp < in_data.SBSplit().LengthX(); ++m_sb_xp,m_sb_tlb_x += 4)
+ {
+ split_depth = in_data.SBSplit()[m_sb_yp][m_sb_xp];
+
+ step = 4 >> (split_depth);
+ max = (1 << split_depth);
+
+ //now do all the block modes and mvs in the mb
+ for (m_b_yp = m_sb_tlb_y; m_b_yp < m_sb_tlb_y+4; m_b_yp += step)
+ {
+ for (m_b_xp = m_sb_tlb_x; m_b_xp < m_sb_tlb_x+4; m_b_xp += step)
+ {
+ if ( in_data.Mode()[m_b_yp][m_b_xp] & m_ref )
+ {
+ CodeVal(in_data);
+ }
+ }//m_b_xp
+ }//m_b_yp
+
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+// Main decode function
+void VectorElementCodec::DoWorkDecode( MvData& out_data)
+{
+ int step,max;
+ int split_depth;
+ int xstart,ystart;
+
+ for (m_sb_yp = 0,m_sb_tlb_y = 0; m_sb_yp < out_data.SBSplit().LengthY(); ++m_sb_yp,m_sb_tlb_y += 4)
+ {
+ for (m_sb_xp = 0,m_sb_tlb_x = 0; m_sb_xp < out_data.SBSplit().LengthX(); ++m_sb_xp,m_sb_tlb_x += 4)
+ {
+ split_depth = out_data.SBSplit()[m_sb_yp][m_sb_xp];
+ step = 4 >> (split_depth);
+ max = (1 << split_depth);
+
+ //now do all the block mvs in the mb
+ for (int j = 0; j < max; ++j)
+ {
+ for (int i = 0; i < max; ++i)
+ {
+ xstart = m_b_xp = m_sb_tlb_x + i * step;
+ ystart = m_b_yp = m_sb_tlb_y + j * step;
+
+ if (out_data.Mode()[m_b_yp][m_b_xp] & m_ref)
+ {
+ DecodeVal( out_data );
+ }
+
+ // propagate throughout SB
+ for (m_b_yp = ystart; m_b_yp < ystart+step; m_b_yp++)
+ {
+ for (m_b_xp = xstart; m_b_xp < xstart+step; m_b_xp++)
+ {
+ out_data.Vectors(m_ref)[m_b_yp][m_b_xp][m_hv] =
+ out_data.Vectors(m_ref)[ystart][xstart][m_hv];
+
+ }//m_b_xp
+ }//m_b_yp
+ }//i
+ }//j
+
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+//protected functions//
+///////////////////////
+
+void VectorElementCodec::ResetAll()
+{
+}
+
+//coding functions//
+////////////////////
+
+//prediction functions
+
+int VectorElementCodec::Prediction(const MvArray& mvarray,
+ const TwoDArray < PredMode > & preddata) const
+{
+ std::vector <int> nbrs;
+ PredMode pmode;
+ int result( 0 );
+
+ if (m_b_xp > 0 && m_b_yp > 0)
+ {
+ pmode = preddata[m_b_yp-1][m_b_xp];
+ if (pmode & m_ref)
+ nbrs.push_back(mvarray[m_b_yp-1][m_b_xp][m_hv]);
+
+ pmode = preddata[m_b_yp-1][m_b_xp-1];
+ if (pmode & m_ref)
+ nbrs.push_back(mvarray[m_b_yp-1][m_b_xp-1][m_hv]);
+
+ pmode = preddata[m_b_yp][m_b_xp-1];
+ if (pmode & m_ref)
+ nbrs.push_back(mvarray[m_b_yp][m_b_xp-1][m_hv]);
+
+ if (nbrs.size() > 0)
+ result = Median(nbrs);
+ }
+ else if (m_b_xp > 0 && m_b_yp == 0)
+ {
+ pmode = preddata[0][m_b_xp-1];
+ if (pmode & m_ref)
+ result = mvarray[0][m_b_xp-1][m_hv];
+ }
+ else if (m_b_xp == 0 && m_b_yp > 0)
+ {
+ pmode = preddata[m_b_yp-1][0];
+ if (pmode & m_ref)
+ result = mvarray[m_b_yp-1][0][m_hv];
+ }
+ return result;
+}
+
+void VectorElementCodec::CodeVal(const MvData& in_data )
+{
+ const MvArray& mv_array = in_data.Vectors(m_ref);
+ const int pred = Prediction( mv_array , in_data.Mode() );
+ const int val = mv_array[m_b_yp][m_b_xp][m_hv] - pred;
+
+ EncodeSInt(val, MV_FBIN1_CTX, MV_FBIN5plus_CTX);
+}
+
+//decoding functions//
+//////////////////////
+
+
+void VectorElementCodec::DecodeVal( MvData& out_data )
+{
+ MvArray& mv_array = out_data.Vectors(m_ref);
+ int pred = Prediction( mv_array , out_data.Mode() );
+ mv_array[m_b_yp][m_b_xp][m_hv] = pred +
+ DecodeSInt(MV_FBIN1_CTX, MV_FBIN5plus_CTX);
+
+}
+
+/******************************************************************************/
+//public functions//
+////////////////////
+// Constructor
+DCCodec::DCCodec(ByteIO* p_byteio,
+ const CompSort csort,
+ size_t number_of_contexts):
+ArithCodec <MvData> (p_byteio,number_of_contexts),
+m_csort( csort )
+{}
+
+
+
+void DCCodec::InitContexts()
+{
+}
+
+// Main code function
+void DCCodec::DoWorkCode( MvData& in_data )
+{
+ int step,max;
+ int split_depth;
+
+ for (m_sb_yp = 0, m_sb_tlb_y = 0; m_sb_yp < in_data.SBSplit().LengthY(); ++m_sb_yp, m_sb_tlb_y += 4)
+ {
+ for (m_sb_xp = 0,m_sb_tlb_x = 0; m_sb_xp < in_data.SBSplit().LengthX(); ++m_sb_xp,m_sb_tlb_x += 4)
+ {
+ split_depth = in_data.SBSplit()[m_sb_yp][m_sb_xp];
+
+ step = 4 >> (split_depth);
+ max = (1 << split_depth);
+
+ //now do all the block modes and mvs in the mb
+ for (m_b_yp = m_sb_tlb_y; m_b_yp < m_sb_tlb_y+4; m_b_yp += step)
+ {
+ for (m_b_xp = m_sb_tlb_x; m_b_xp < m_sb_tlb_x+4; m_b_xp += step)
+ {
+ if(in_data.Mode()[m_b_yp][m_b_xp] == INTRA)
+ {
+ CodeVal(in_data);
+ }
+ }//m_b_xp
+ }//m_b_yp
+
+ }//m_sb_xp
+ }//m_sb_yp
+}
+
+// Main decode function
+void DCCodec::DoWorkDecode( MvData& out_data)
+{
+ int step,max;
+ int split_depth;
+ int xstart,ystart;
+
+ for (m_sb_yp = 0,m_sb_tlb_y = 0; m_sb_yp < out_data.SBSplit().LengthY(); ++m_sb_yp,m_sb_tlb_y += 4)
+ {
+ for (m_sb_xp = 0,m_sb_tlb_x = 0; m_sb_xp < out_data.SBSplit().LengthX(); ++m_sb_xp,m_sb_tlb_x += 4)
+ {
+ //start with split mode
+ split_depth = out_data.SBSplit()[m_sb_yp][m_sb_xp];
+ step = 4 >> (split_depth);
+ max = (1 << split_depth);
+
+ //now do all the block mvs in the mb
+ for (int j = 0; j < max; ++j)
+ {
+ for (int i = 0; i < max; ++i)
+ {
+ xstart = m_b_xp = m_sb_tlb_x + i * step;
+ ystart = m_b_yp = m_sb_tlb_y + j * step;
+
+ if(out_data.Mode()[m_b_yp][m_b_xp] == INTRA)
+ {
+ DecodeVal( out_data );
+ }
+
+ // propagate throughout SB
+ for (m_b_yp = ystart; m_b_yp < ystart+step; m_b_yp++)
+ {
+ for (m_b_xp = xstart; m_b_xp < xstart+step; m_b_xp++)
+ {
+ out_data.DC( m_csort )[m_b_yp][m_b_xp] = out_data.DC( m_csort )[ystart][xstart];
+ }//m_b_xp
+ }//m_b_yp
+ }//i
+ }//j
+
+ }//m_sb_xp
+ }//m_sb_yp
+
+}
+
+//protected functions//
+///////////////////////
+
+void DCCodec::ResetAll()
+{
+}
+
+//coding functions//
+////////////////////
+
+//prediction functions
+
+ValueType DCCodec::Prediction(const TwoDArray < ValueType > & dcdata,
+ const TwoDArray < PredMode > & preddata) const
+{
+ std::vector < int > nbrs;
+ PredMode pmode;
+ ValueType result = 0;
+
+ if (m_b_xp > 0 && m_b_yp > 0)
+ {
+ pmode = preddata[m_b_yp-1][m_b_xp];
+ if (pmode == INTRA)
+ nbrs.push_back( (int) dcdata[m_b_yp-1][m_b_xp] );
+
+ pmode = preddata[m_b_yp-1][m_b_xp-1];
+ if (pmode == INTRA)
+ nbrs.push_back((int)dcdata[m_b_yp-1][m_b_xp-1] );
+
+ pmode = preddata[m_b_yp][m_b_xp-1];
+ if (pmode == INTRA)
+ nbrs.push_back( (int) dcdata[m_b_yp][m_b_xp-1] );
+
+ if (nbrs.size() > 0)
+ result = ValueType(GetSMean(nbrs));
+ }
+ else if (m_b_xp > 0 && m_b_yp == 0)
+ {
+ pmode = preddata[0][m_b_xp-1];
+ if (pmode == INTRA)
+ result = dcdata[0][m_b_xp-1];
+ }
+ else if (m_b_xp == 0 && m_b_yp > 0)
+ {
+ pmode = preddata[m_b_yp-1][0];
+ if (pmode == INTRA)
+ result = dcdata[m_b_yp-1][0];
+ }
+ return result;
+}
+
+void DCCodec::CodeVal(const MvData& in_data)
+{
+ const int val = in_data.DC( m_csort )[m_b_yp][m_b_xp] -
+ Prediction( in_data.DC(m_csort) , in_data.Mode() );
+ EncodeSInt(val, DC_FBIN1_CTX, DC_FBIN2plus_CTX);
+}
+
+//decoding functions//
+//////////////////////
+
+void DCCodec::DecodeVal( MvData& out_data )
+{
+ out_data.DC( m_csort )[m_b_yp][m_b_xp] = DecodeSInt(DC_FBIN1_CTX, DC_FBIN2plus_CTX) +
+ Prediction(out_data.DC( m_csort ), out_data.Mode());
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.h
new file mode 100644
index 000000000..ed76ac92a
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/mv_codec.h
@@ -0,0 +1,301 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: mv_codec.h,v 1.25 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Tim Borer,
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _MV_CODEC_H_
+#define _MV_CODEC_H_
+
+/////////////////////////////////////////////////
+//Class to do motion vector coding and decoding//
+//------using adaptive arithmetic coding-------//
+/////////////////////////////////////////////////
+
+#include <libdirac_common/arith_codec.h>
+#include <libdirac_common/common.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_common/wavelet_utils.h>
+#include <vector>
+
+namespace dirac
+{
+ //! Codes and decodes the split mode
+ /*!
+ Derived from the ArithCodec class, this codes and decodes the split mode
+ */
+ class SplitModeCodec: public ArithCodec<MvData>
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a MvDataCodec object to encode MV data, based on parameters
+ \param p_byteio Input/output for the encoded bits
+ \param number_of_contexts the number of contexts used
+ */
+ SplitModeCodec(ByteIO* p_byteio, size_t number_of_contexts);
+
+
+
+ //! Initialises the contexts
+ void InitContexts();
+
+ private:
+
+ // Position of current SB
+ int m_sb_xp, m_sb_yp;
+
+ private:
+
+ // functions
+ //! Private, bodyless copy constructor: class should not be copied
+ SplitModeCodec(const SplitModeCodec& cpy);
+ //! Private, bodyless copy operator=: class should not be assigned
+ SplitModeCodec& operator=(const SplitModeCodec& rhs);
+
+ // coding functions
+ // Code the SB splitting mode
+ void CodeVal(const MvData& in_data);
+
+ // decoding functions
+ // Decode the SB splitting mode
+ void DecodeVal( MvData& out_data);
+
+ void DoWorkCode( MvData& in_data );
+ void DoWorkDecode(MvData& out_data);
+
+ // Context stuff
+ void ResetAll();
+
+ //prediction stuff
+ unsigned int Prediction(const TwoDArray<int>& mbdata) const;
+
+ };
+
+/******************************************************************************/
+
+ //! Codes and decodes the prediction modes
+ /*!
+ Derived from the ArithCodec class, this codes and decodes the prediction mode.
+ */
+ class PredModeCodec: public ArithCodec<MvData>
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a MvDataCodec object to encode MV data, based on parameters
+ \param p_byteio Input/output for the encoded bits
+ \param number_of_contexts the number of contexts used
+ \param num_refs Number of references
+ */
+ PredModeCodec(ByteIO* p_byteio, size_t number_of_contexts, const int num_refs);
+
+ //! Initialises the contexts
+ void InitContexts();
+
+ private:
+
+ // Position of current block
+ int m_b_xp, m_b_yp;
+ // Position of current SB
+ int m_sb_xp, m_sb_yp;
+ // Position of top-left block of current SB
+ int m_sb_tlb_x, m_sb_tlb_y;
+ // Number of reference pictures
+ int m_num_refs;
+
+ private:
+
+ // functions
+ //! Private, bodyless copy constructor: class should not be copied
+ PredModeCodec(const PredModeCodec& cpy);
+ //! Private, bodyless copy operator=: class should not be assigned
+ PredModeCodec& operator=(const PredModeCodec& rhs);
+
+ // coding functions
+ // Code the block prediction mode
+ void CodeVal(const MvData& in_data);
+
+ // decoding functions
+ // Decode the block prediction mode
+ void DecodeVal(MvData& out_data);
+
+ void DoWorkCode( MvData& in_data );
+ void DoWorkDecode(MvData& out_data);
+
+ // Context stuff
+ void ResetAll();
+
+ //prediction stuff
+ unsigned int Prediction(const TwoDArray<PredMode>& preddata) const;
+
+ };
+
+/******************************************************************************/
+
+ //! Codes and decodes an array of motion vectors
+ /*!
+ Derived from the ArithCodec class, this codes and decodes a motion vector
+ element (vertical or horizontal)
+ */
+ class VectorElementCodec: public ArithCodec<MvData>
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a MvDataCodec object to encode MV data, based on parameters
+ \param p_byteio Input/output for the encoded bits
+ \param ref_id The identity of the reference (1 or 2)
+ \param horvert The identity of the vector element (horizontal or vertical)
+ \param number_of_contexts the number of contexts used
+ */
+ VectorElementCodec(ByteIO* p_byteio, int ref_id, MvElement horvert,
+ size_t number_of_contexts);
+
+
+ //! Initialises the contexts
+ void InitContexts();
+
+ private:
+
+ // Position of current block
+ int m_b_xp, m_b_yp;
+
+ // Position of current SB
+ int m_sb_xp, m_sb_yp;
+
+ // Position of top-left block of current SB
+ int m_sb_tlb_x, m_sb_tlb_y;
+
+ // The identity of the reference (1 or 2)
+ const int m_ref;
+
+ // Whether it's the vertical or horizontal MV element
+ const MvElement m_hv;
+
+ private:
+
+ // functions
+ //! Private, bodyless copy constructor: class should not be copied
+ VectorElementCodec(const VectorElementCodec& cpy);
+ //! Private, bodyless copy operator=: class should not be assigned
+ VectorElementCodec& operator=(const VectorElementCodec& rhs);
+
+ // coding functions
+ // Code the motion vector element
+ void CodeVal(const MvData& in_data);
+
+ // decoding functions
+ // Decode the motion vector element
+ void DecodeVal( MvData& out_data);
+
+ void DoWorkCode( MvData& in_data );
+ void DoWorkDecode(MvData& out_data);
+
+ // Context stuff
+ void ResetAll();
+
+ //prediction stuff
+ int Prediction( const MvArray& mvarray,
+ const TwoDArray<PredMode>& preddata) const;
+
+ };
+
+/******************************************************************************/
+ //! Codes and decodes a set of DC values
+ /*!
+ Derived from the ArithCodec class, this codes and decodes all the DC
+ values for a component
+ */
+ class DCCodec: public ArithCodec<MvData>
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a MvDataCodec object to encode MV data, based on parameters
+ \param p_byteio Input/output for the encoded bits
+ \param csort The identity of the component (Y, U or V)
+ \param number_of_contexts the number of contexts used
+ */
+ DCCodec(ByteIO* p_byteio, const CompSort csort, size_t number_of_contexts);
+
+ //! Initialises the contexts
+ void InitContexts();
+
+ private:
+
+ // The component being coded
+ const CompSort m_csort;
+ // Position of current block
+ int m_b_xp, m_b_yp;
+ // Position of current SB
+ int m_sb_xp, m_sb_yp;
+ // Position of top-left block of current SB
+ int m_sb_tlb_x, m_sb_tlb_y;
+
+ private:
+
+ // functions
+ //! Private, bodyless copy constructor: class should not be copied
+ DCCodec(const DCCodec& cpy);
+ //! Private, bodyless copy operator=: class should not be assigned
+ DCCodec& operator=(const DCCodec& rhs);
+
+ // coding functions
+ // Code the dc value of intra blocks
+ void CodeVal(const MvData& in_data);
+
+ // decoding functions
+ // Decode the dc value of intra blocks
+ void DecodeVal( MvData& out_data);
+
+ void DoWorkCode( MvData& in_data );
+ void DoWorkDecode(MvData& out_data);
+
+ // Context stuff
+ void ResetAll();
+
+ //prediction stuff
+ ValueType Prediction( const TwoDArray<ValueType>& dcdata,
+ const TwoDArray<PredMode>& preddata) const;
+ };
+
+
+}// end namepace dirac
+
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.cpp
new file mode 100644
index 000000000..b6e56ebc3
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.cpp
@@ -0,0 +1,672 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: pic_io.cpp,v 1.28 2008/06/19 10:17:17 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott Robert Ladd,
+* Stuart Cunningham,
+* Tim Borer,
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/pic_io.h>
+#include <libdirac_common/dirac_assertions.h>
+using namespace dirac;
+
+/*************************************Output***********************************/
+StreamPicOutput::~StreamPicOutput()
+{
+}
+
+StreamPicOutput::StreamPicOutput (std::ostream *op_ptr, const SourceParams& sp) :
+ m_sparams(sp),
+ m_op_pic_ptr(op_ptr)
+{
+}
+
+StreamFrameOutput::StreamFrameOutput(std::ostream *op_str,
+ const SourceParams& sp) :
+ StreamPicOutput (op_str, sp)
+{}
+
+StreamFrameOutput::~StreamFrameOutput()
+{
+}
+
+bool StreamFrameOutput::WriteToNextFrame( const Picture& myframe )
+{
+ bool ret_val;
+
+ ret_val=WriteFrameComponent(myframe.Data(Y_COMP), Y_COMP );
+ ret_val&=WriteFrameComponent( myframe.Data(U_COMP), U_COMP );
+ ret_val&=WriteFrameComponent( myframe.Data(V_COMP), V_COMP );
+
+ return ret_val;
+}
+
+bool StreamFrameOutput::WriteFrameComponent( const PicArray& pic_data , const CompSort& cs)
+{
+ if (!m_op_pic_ptr)
+ {
+ std::cerr<<std::endl<<"Can't open picture data file for writing";
+ return false;
+ }
+
+ //initially set up for 10-bit data input, rounded to 8 bits on file output
+ //This will throw out any padding to the right and bottom of a frame
+
+ int xl,yl;
+ if (cs == Y_COMP)
+ {
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl();
+ }
+ else
+ {
+ xl = m_sparams.ChromaWidth();
+ yl = m_sparams.ChromaHeight();
+ }
+
+ unsigned char* tempc=new unsigned char[xl];
+
+ if (m_op_pic_ptr)
+ {
+ for (int j=0 ; j<yl ;++j)
+ {
+ for (int i=0 ; i<xl ; ++i)
+ {
+ tempc[i] = (unsigned char) ( pic_data[j][i] + 128 );
+ }//I
+
+ m_op_pic_ptr->write((char*) tempc,xl);
+
+ }//J
+ }
+ m_op_pic_ptr->flush();
+
+ delete[] tempc;
+
+ //exit success
+ return true;
+}
+
+StreamFieldOutput::StreamFieldOutput(std::ostream *op_str,
+ const SourceParams& sp) :
+ StreamPicOutput(op_str, sp),
+ m_frame_store(NULL)
+{
+ int frame_size = (m_sparams.Xl() * m_sparams.Yl()) +
+ 2 * (m_sparams.ChromaWidth() * m_sparams.ChromaHeight());
+ m_frame_store = new unsigned char[frame_size];
+}
+
+StreamFieldOutput::~StreamFieldOutput()
+{
+ if (m_frame_store)
+ delete [] m_frame_store;
+}
+
+bool StreamFieldOutput::WriteToNextFrame( const Picture& myfield )
+{
+ bool ret_val;
+
+ ret_val=WriteFieldComponent(myfield.Data(Y_COMP) , myfield.GetPparams().PictureNum(), Y_COMP );
+ ret_val&=WriteFieldComponent(myfield.Data(U_COMP) , myfield.GetPparams().PictureNum(), U_COMP );
+ ret_val&=WriteFieldComponent(myfield.Data(V_COMP) , myfield.GetPparams().PictureNum(), V_COMP );
+
+ return ret_val;
+}
+
+bool StreamFieldOutput::WriteFieldComponent( const PicArray& pic_data , int field_num, const CompSort& cs)
+{
+ if (!m_op_pic_ptr)
+ {
+ std::cerr<<std::endl<<"Can't open picture data file for writing";
+ return false;
+ }
+
+ unsigned char *comp;
+ int xl,yl;
+ if (cs == Y_COMP)
+ {
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl();
+ comp = m_frame_store;
+ }
+ else
+ {
+ xl = m_sparams.ChromaWidth();
+ yl = m_sparams.ChromaHeight();
+ if (cs == U_COMP)
+ {
+ comp = m_frame_store + (m_sparams.Xl() * m_sparams.Yl());
+ }
+ else
+ {
+ comp = m_frame_store + (m_sparams.Xl() * m_sparams.Yl()) + (xl*yl);
+ }
+ }
+
+ // Seek offset before writing field to store
+ int start = 0;
+ // Seek offset between writing lines to file
+ int skip = 0;
+ // Seek offset after writing field to file
+ int end = 0;
+
+ bool top_field = m_sparams.TopFieldFirst() ? (!(field_num%2)) :
+ (field_num%2);
+
+ bool write_to_file = (m_sparams.TopFieldFirst() && !top_field) ||
+ (!m_sparams.TopFieldFirst() && top_field);
+
+ if (m_sparams.TopFieldFirst())
+ {
+ if (top_field)
+ {
+ start = 0;
+ skip = 2 * xl * sizeof(char);
+ end = -(xl*yl);
+ }
+ else
+ {
+ start = xl;
+ skip = 2 * xl * sizeof(char);
+ end = 0;
+ }
+ }
+ else
+ {
+ if (!top_field) // i.e. bottom field
+ {
+ start = xl;
+ skip = 2 * xl * sizeof(char);
+ end = -(xl*yl);
+ }
+ else // top field
+ {
+ start = 0;
+ skip = 2 * xl * sizeof(char);
+ end = xl;
+ }
+ }
+
+ unsigned char *tempc = comp + start;
+
+ int field_yl = yl>>1;
+ int field_xl = xl;
+ for (int j=0 ; j<field_yl ;++j)
+ {
+ for (int i=0 ; i<field_xl ; ++i)
+ {
+ tempc[i] = (unsigned char) (pic_data[j][i]+128);
+ }//I
+ tempc += skip;
+ }//J
+ tempc += end;
+
+ if (write_to_file)
+ {
+ m_op_pic_ptr->write((char*) comp,xl*yl);
+ m_op_pic_ptr->flush();
+ return true;
+ }
+ //exit success
+ return false;
+}
+
+MemoryStreamOutput::MemoryStreamOutput(SourceParams &sp, bool interlace)
+{
+ //picture input
+ m_op_pic_ptr =
+ new std::ostream(&m_membuf);
+
+ if (interlace)
+ m_op_pic_str = new StreamFieldOutput(m_op_pic_ptr, sp);
+ else
+ m_op_pic_str = new StreamFrameOutput(m_op_pic_ptr, sp);
+}
+
+MemoryStreamOutput::~MemoryStreamOutput()
+{
+ delete m_op_pic_str;
+ delete m_op_pic_ptr;
+}
+
+void MemoryStreamOutput::SetMembufReference (unsigned char *buf, int buf_size)
+{
+ m_membuf.SetMembufReference(buf, buf_size);
+}
+
+FileStreamOutput::FileStreamOutput(const char* output_name,
+ const SourceParams& sp, bool interlace)
+{
+ //picture output
+ m_op_pic_ptr =
+ new std::ofstream(output_name,std::ios::out | std::ios::binary);
+
+ if (!(*m_op_pic_ptr))
+ {
+ std::cerr << std::endl <<
+ "Can't open output picture data file for output: " <<
+ output_name<<std::endl;
+ return;
+
+ }
+ if (interlace)
+ m_op_pic_str = new StreamFieldOutput(m_op_pic_ptr, sp);
+ else
+ m_op_pic_str = new StreamFrameOutput(m_op_pic_ptr, sp);
+}
+
+FileStreamOutput::~FileStreamOutput()
+{
+ if (m_op_pic_ptr && *m_op_pic_ptr)
+ {
+ static_cast<std::ofstream *>(m_op_pic_ptr)->close();
+ delete m_op_pic_ptr;
+ }
+ delete m_op_pic_str;
+}
+
+
+/**************************************Input***********************************/
+
+
+StreamPicInput::StreamPicInput (std::istream *ip_pic_ptr,
+ const SourceParams &sparams) :
+ m_sparams(sparams),
+ m_ip_pic_ptr(ip_pic_ptr)
+{}
+
+
+StreamPicInput::~StreamPicInput ()
+{}
+
+bool StreamPicInput::End() const
+{
+ return m_ip_pic_ptr->eof();
+}
+
+StreamFrameInput::StreamFrameInput (std::istream *ip_pic_ptr,
+ const SourceParams &sparams) :
+ StreamPicInput(ip_pic_ptr, sparams)
+{}
+
+StreamFrameInput::~StreamFrameInput ()
+{}
+
+void StreamFrameInput::Skip(const int num)
+{
+ const int num_pels = m_sparams.Xl()*m_sparams.Yl();
+ int num_bytes;
+
+ const ChromaFormat cf = m_sparams.CFormat();
+
+ if ( cf == format420 )
+ num_bytes = (num_pels*3)/2;
+ else if ( cf == format422 )
+ num_bytes = num_pels*2;
+ else
+ num_bytes = num_pels*3;
+
+ m_ip_pic_ptr->seekg( num*num_bytes , std::ios::cur );
+}
+
+bool StreamFrameInput::ReadNextPicture(Picture& myframe)
+{
+ //return value. Failure if one of the components can't be read,
+ //success otherwise/.
+
+ bool ret_val;
+
+ ret_val=ReadFrameComponent( myframe.Data(Y_COMP) , Y_COMP);
+ ret_val&=ReadFrameComponent(myframe.Data(U_COMP) , U_COMP);
+ ret_val&=ReadFrameComponent(myframe.Data(V_COMP) , V_COMP);
+
+ return ret_val;
+}
+
+bool StreamFrameInput::ReadFrameComponent(PicArray& pic_data, const CompSort& cs)
+{
+
+ if (! *m_ip_pic_ptr)
+ return false;
+
+ int xl,yl;
+ if (cs == Y_COMP){
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl();
+ }
+ else{
+ if (m_sparams.CFormat()==format420)
+ {
+ xl = m_sparams.Xl()/2;
+ yl = m_sparams.Yl()/2;
+ }
+ else if (m_sparams.CFormat() == format422)
+ {
+ xl = m_sparams.Xl()/2;
+ yl = m_sparams.Yl();
+ }
+ else{
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl();
+ }
+ }
+
+ unsigned char * temp = new unsigned char[xl];//array big enough for one line
+
+ for (int j=0 ; j<yl ; ++j)
+ {
+ m_ip_pic_ptr->read((char*) temp, xl);
+
+ for (int i=0 ; i<xl ; ++i)
+ {
+ pic_data[j][i] = (ValueType) temp[i];
+ }//I
+ for (int i=0 ; i<xl ; ++i)
+ {
+ pic_data[j][i] -= 128;
+ }//I
+
+
+ //pad the columns on the rhs using the edge value
+ for (int i=xl ; i<pic_data.LengthX() ; ++i ){
+ pic_data[j][i] = pic_data[j][xl-1];
+ }//I
+
+ }//J
+
+ delete [] temp;
+
+ //now do the padded lines, using the last true line
+ for (int j=yl ; j<pic_data.LengthY() ; ++j )
+ {
+ for (int i=0 ; i<pic_data.LengthX() ; ++i )
+ {
+ pic_data[j][i] = pic_data[yl-1][i];
+ }//I
+ }//J
+
+ return true;
+}
+
+StreamFieldInput::StreamFieldInput (std::istream *ip_pic_ptr,
+ const SourceParams &sparams) :
+ StreamPicInput(ip_pic_ptr, sparams)
+{}
+
+StreamFieldInput::~StreamFieldInput ()
+{}
+
+void StreamFieldInput::Skip(const int num)
+{
+ REPORTM (num && false, "StreamFieldInput::Skip - Reached unimplemented function");
+}
+
+bool StreamFieldInput::ReadNextPicture(Picture& mypic)
+{
+ // FIXME: this method is BROKEN!
+
+ //return value. Failure if one of the components can't be read,
+ //success otherwise/.
+
+ bool ret_val;
+
+ bool is_field1 = ((mypic.GetPparams().PictureNum()%2) == 0);
+ ret_val=ReadFieldComponent( is_field1, mypic.Data(Y_COMP), Y_COMP);
+ ret_val&=ReadFieldComponent(is_field1, mypic.Data(U_COMP), U_COMP);
+ ret_val&=ReadFieldComponent(is_field1, mypic.Data(V_COMP), V_COMP);
+
+ int picture_size = m_sparams.Xl()*m_sparams.Yl() +
+ 2*m_sparams.ChromaWidth()*m_sparams.ChromaHeight();
+ if (is_field1)
+ {
+ //Seek back to the beginning of frame so that the next field
+ //from the frame can be read
+ m_ip_pic_ptr->seekg (-picture_size, std::ios::cur);
+ }
+
+ return ret_val;
+}
+
+bool StreamFieldInput::ReadNextFrame(Picture& field1, Picture& field2)
+{
+ //return value. Failure if one of the components can't be read,
+ //success otherwise/.
+
+ bool ret_val = false;
+
+ ret_val=ReadFieldComponent( field1.Data(Y_COMP), field2.Data(Y_COMP), Y_COMP);
+ ret_val&=ReadFieldComponent(field1.Data(U_COMP), field2.Data(U_COMP), U_COMP);
+ ret_val&=ReadFieldComponent(field1.Data(V_COMP), field2.Data(V_COMP), V_COMP);
+
+ return ret_val;
+}
+
+bool StreamFieldInput::ReadFieldComponent(PicArray& pic_data1,
+ PicArray& pic_data2,
+ const CompSort& cs)
+{
+ if (! *m_ip_pic_ptr)
+ return false;
+
+ //initially set up for 8-bit file input expanded to 10 bits for array output
+
+ int xl,yl;
+ if (cs == Y_COMP){
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl();
+ }
+ else{
+ if (m_sparams.CFormat()==format420)
+ {
+ xl = m_sparams.Xl()/2;
+ yl = m_sparams.Yl()/2;
+ }
+ else if (m_sparams.CFormat() == format422)
+ {
+ xl = m_sparams.Xl()/2;
+ yl = m_sparams.Yl();
+ }
+ else{
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl();
+ }
+ }
+
+ unsigned char * temp = new unsigned char[xl];//array big enough for one line
+ ValueType *pic;
+
+ for (int j=0 ; j<yl ; j++)
+ {
+ m_ip_pic_ptr->read((char*) temp, xl);
+ if (j % 2 == 0)
+ {
+ pic = m_sparams.TopFieldFirst() ?
+ &pic_data1[j/2][0] : &pic_data2[j/2][0];
+ }
+ else
+ {
+ pic = m_sparams.TopFieldFirst() ?
+ &pic_data2[j/2][0] : &pic_data1[j/2][0];
+ }
+ for (int i=0 ; i<xl ; ++i)
+ {
+ pic[i] = (ValueType) temp[i];
+ }//I
+ for (int i=0 ; i<xl ; ++i)
+ {
+ pic[i] -= 128;
+ }//I
+
+
+ //pad the columns on the rhs using the edge value
+ for (int i=xl ; i<pic_data1.LengthX() ; ++i ){
+ pic[i] = pic[xl-1];
+ }//I
+
+ }//J
+
+ delete [] temp;
+
+ //now do the padded lines, using the last true line
+ for (int j=yl/2 ; j<pic_data1.LengthY() ; ++j )
+ {
+ for (int i=0 ; i<pic_data1.LengthX() ; ++i )
+ {
+ pic_data1[j][i] = pic_data1[yl/2-1][i];
+ pic_data2[j][i] = pic_data2[yl/2-1][i];
+ }//I
+ }//J
+
+ return true;
+}
+
+bool StreamFieldInput::ReadFieldComponent(bool is_field1,
+ PicArray& pic_data,
+ const CompSort& cs)
+{
+ if (! *m_ip_pic_ptr)
+ return false;
+
+ //initially set up for 8-bit file input expanded to 10 bits for array output
+
+ int xl,yl;
+ if (cs == Y_COMP){
+ xl = m_sparams.Xl();
+ yl = m_sparams.Yl()>>1;
+ }
+ else{
+ xl = m_sparams.ChromaWidth();
+ yl = m_sparams.ChromaHeight()>>1;
+ }
+
+ unsigned char * pic = new unsigned char[2*xl];//array big enough for two lines - one for each field
+
+ int start = 0;
+ if ((is_field1 && !m_sparams.TopFieldFirst()) ||
+ (!is_field1 && m_sparams.TopFieldFirst()))
+ {
+ start = xl;
+ }
+
+ for (int j=0 ; j<yl ; j++)
+ {
+ m_ip_pic_ptr->read((char*) pic, 2*xl);
+ // skip to the start of the field
+ unsigned char *field = pic + start;
+ for (int i=0 ; i<xl ; ++i)
+ {
+ pic_data[j][i] = (ValueType) field[i];
+ }//I
+ for (int i=0 ; i<xl ; ++i)
+ {
+ pic_data[j][i] -= 128;
+ }
+ //pad the columns on the rhs using the edge value
+ for (int i=xl ; i<pic_data.LengthX() ; ++i ){
+ pic_data[j][i] = pic_data[j][xl-1];
+ }//I
+
+ }//J
+ delete [] pic;
+
+ //now do the padded lines, using the last true line
+ for (int j=yl ; j<pic_data.LengthY() ; ++j )
+ {
+ for (int i=0 ; i<pic_data.LengthX() ; ++i )
+ {
+ pic_data[j][i] = pic_data[yl-1][i];
+ }//I
+ }//J
+
+ return true;
+}
+
+MemoryStreamInput::MemoryStreamInput(SourceParams& sparams, bool field_input)
+{
+ //picture input
+ m_ip_pic_ptr =
+ new std::istream(&m_membuf);
+
+ if (field_input)
+ m_inp_str = new StreamFieldInput(m_ip_pic_ptr, sparams);
+ else
+ m_inp_str = new StreamFrameInput(m_ip_pic_ptr, sparams);
+}
+
+MemoryStreamInput::~MemoryStreamInput()
+{
+ delete m_ip_pic_ptr;
+ delete m_inp_str;
+}
+
+void MemoryStreamInput::SetMembufReference (unsigned char *buf, int buf_size)
+{
+ m_membuf.SetMembufReference(buf, buf_size);
+}
+
+FileStreamInput::FileStreamInput(const char* input_name,
+ const SourceParams &sparams,
+ bool interlace)
+{
+
+ char input_name_yuv[FILENAME_MAX];
+
+ strncpy(input_name_yuv, input_name, sizeof(input_name_yuv));
+ //strcat(input_name_yuv, ".yuv");
+
+ //picture input
+ m_ip_pic_ptr =
+ new std::ifstream(input_name_yuv,std::ios::in | std::ios::binary);
+
+ if (!(*m_ip_pic_ptr))
+ std::cerr << std::endl<<
+ "Can't open input picture data file: " <<
+ input_name_yuv << std::endl;
+
+ if (interlace)
+ m_inp_str = new StreamFieldInput(m_ip_pic_ptr, sparams);
+ else
+ m_inp_str = new StreamFrameInput(m_ip_pic_ptr, sparams);
+
+}
+
+FileStreamInput::~FileStreamInput()
+{
+ static_cast<std::ifstream *>(m_ip_pic_ptr)->close();
+ delete m_ip_pic_ptr;
+ delete m_inp_str;
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.h
new file mode 100644
index 000000000..375b4c033
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/pic_io.h
@@ -0,0 +1,528 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: pic_io.h,v 1.19 2008/06/19 10:17:17 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott Robert Ladd,
+* Stuart Cunningham,
+* Tim Borer,
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _PIC_IO_H_
+#define _PIC_IO_H_
+
+#include <iostream>
+#include <fstream>
+#include <streambuf>
+
+#include <libdirac_common/common.h>
+#include <libdirac_common/picture.h>
+
+namespace dirac
+{
+
+ //////////////////////////////////////////
+ //--------------------------------------//
+ //- -//
+ //-Uncompressed picture file IO wrapper-//
+ //- -//
+ //--------------------------------------//
+ //////////////////////////////////////////
+
+ // Stream classes for writing/reading frames of uncompressed/decoded data
+ // to stream. Streams currently supported are Memory based streams and
+ // File based streams. These classes need further restructuring.
+ // Anu - 19-11-2004
+
+ // Subclass these to provide functionality for different file formats and
+ // for streaming.
+
+
+ //! Class for outputting pictures
+
+
+ /*!
+ Abstract base class for classes that output frames to stream
+ */
+ class StreamPicOutput
+ {
+ public:
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param op_ptr the output stream object
+ \param sp the source parameters
+ */
+ StreamPicOutput( std::ostream* op_ptr, const SourceParams& sp);
+
+ //! virtual Destructor
+ virtual ~StreamPicOutput();
+
+ //! Write a picture to the next frame to be output
+ virtual bool WriteToNextFrame(const Picture& myframe) = 0;
+
+ //! Get the source parameters
+ SourceParams& GetSourceParams() {return m_sparams;}
+
+ protected:
+ //! Source parameters
+ SourceParams m_sparams;
+ //! Output stream
+ std::ostream* m_op_pic_ptr;
+
+ //! Body-less default Constructor
+ StreamPicOutput();
+ private:
+
+ };
+
+ class StreamFrameOutput : public StreamPicOutput
+ {
+ public:
+
+ /*!
+ Constructor, takes
+ \param op_ptr the output stream object
+ \param sp the source parameters
+ */
+ StreamFrameOutput( std::ostream *op_ptr, const SourceParams& sp);
+
+ //! virtual Destructor
+ virtual ~StreamFrameOutput();
+
+ //! Write the next frame to the output
+ bool WriteToNextFrame(const Picture& myframe);
+
+ protected:
+ //! Write a frame component to file
+ bool WriteFrameComponent(const PicArray& pic_data,
+ const CompSort& cs);
+ private:
+ //! Body-less Default Constructor
+ StreamFrameOutput();
+ };
+
+ class StreamFieldOutput : public StreamPicOutput
+ {
+ public:
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param op_ptr the output stream object
+ \param sp the source parameters
+ */
+ StreamFieldOutput( std::ostream *op_ptr, const SourceParams& sp);
+
+ //! virtual Destructor
+ virtual ~StreamFieldOutput();
+
+ //! Write a field to the next frame to be output
+ bool WriteToNextFrame(const Picture& myfield);
+
+ protected:
+ //! Write a field component to file
+ bool WriteFieldComponent(const PicArray& pic_data,
+ int field_num,
+ const CompSort& cs);
+
+ private:
+ //! Body-less Default Constructor
+ StreamFieldOutput();
+ unsigned char *m_frame_store;
+ };
+
+ /*!
+ Outputs pictures to a memory buffer
+ */
+ class MemoryStreamOutput
+ {
+ public:
+ //! Constructor
+ MemoryStreamOutput(SourceParams &sparams, bool interlace);
+
+ //! Destructor
+ ~MemoryStreamOutput();
+
+ //! Get source parameters
+ SourceParams& GetSourceParams()
+ { return m_op_pic_str->GetSourceParams();}
+
+ StreamPicOutput *GetStream() { return m_op_pic_str; }
+ //! Set the memory buffer to write the data to
+ void SetMembufReference (unsigned char *buf, int buf_size);
+
+ protected:
+ //! Body-less default Constructor
+ MemoryStreamOutput();
+ //! Body-less copy constructor
+ MemoryStreamOutput(const MemoryStreamOutput&);
+ //! Body-less assignment operator
+ MemoryStreamOutput & operator =(const MemoryStreamOutput&);
+
+ protected:
+
+ //! local memory buffer
+ class OutputMemoryBuffer : public std::streambuf
+ {
+ public:
+ //! Memory buffer constructor
+ OutputMemoryBuffer () :
+ m_op_buf(0),
+ m_op_buf_size(0),
+ m_op_idx(0)
+ {}
+
+ //! Set the buffer variables
+ /*! Set the memory buffer variables
+ \param buffer buffer to write data to
+ \param buffer_size size of output buffer
+ */
+ void SetMembufReference (unsigned char *buffer, int buffer_size)
+ {
+ m_op_buf = buffer;
+ m_op_buf_size = buffer_size;
+ m_op_idx = 0;
+ }
+
+ protected:
+ //! Memory buffer to write data to
+ unsigned char *m_op_buf;
+ //! Memory buffer size
+ int m_op_buf_size;
+ //! Index of first available byte in buffer
+ int m_op_idx;
+
+ //! Write Overflow method to write one char at a time
+ virtual int overflow (int c)
+ {
+ if ( c != EOF)
+ {
+ if (m_op_idx == m_op_buf_size)
+ return EOF;
+
+ m_op_buf[m_op_idx] = (char)c;
+ m_op_idx++;
+ }
+ return c;
+ }
+
+ //! xsputn method to write one multiple chars at a time to buffer
+ virtual std::streamsize xsputn (const char *s,
+ std::streamsize num)
+ {
+ std::streamsize bytes_left = m_op_buf_size - m_op_idx;
+ std::streamsize bytes_written = bytes_left > num
+ ? num : bytes_left;
+ memcpy (&m_op_buf[m_op_idx], (unsigned char *)s,
+ bytes_written);
+ m_op_idx += bytes_written;
+ return bytes_written;
+ }
+
+ private:
+ //! Body-less copy constructor
+ OutputMemoryBuffer(const OutputMemoryBuffer&);
+ //! Body-less assignment operator
+ OutputMemoryBuffer& operator =(const OutputMemoryBuffer&);
+ };
+
+ private:
+ //! Output stream Memory buffer
+ OutputMemoryBuffer m_membuf;
+ //! Physical Output stream
+ std::ostream* m_op_pic_ptr;
+ //! Pic output Stream
+ StreamPicOutput *m_op_pic_str;
+ };
+
+ /*!
+ Outputs pictures to a file
+ */
+ class FileStreamOutput
+ {
+ public:
+
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param output_name the name of the output file
+ \param sp the source parameters
+ \param interlace the output is interlaced
+ */
+ FileStreamOutput (const char* output_name,
+ const SourceParams& sp, bool interlace);
+
+ //! Destructor
+ virtual ~FileStreamOutput ();
+
+ StreamPicOutput *GetStream() { return m_op_pic_str; }
+ private:
+ //! Physical Output stream
+ std::ostream* m_op_pic_ptr;
+ //! Pic output Stream
+ StreamPicOutput *m_op_pic_str;
+ };
+
+ //! Picture input class
+ /*!
+ Abstract Class for reading picture data from a stream.
+ */
+
+ class StreamPicInput
+ {
+ public:
+
+ //! Default Constructor
+ StreamPicInput();
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param ip_pic_ptr input stream to read from
+ \param sparams Source parameters
+ */
+ StreamPicInput(std::istream *ip_pic_ptr, const SourceParams& sparams);
+
+ //! Destructor
+ virtual ~StreamPicInput();
+
+ //! Skip n frames of input
+ virtual void Skip( const int n)= 0;
+
+ //! Read the next picture frame/field from the file
+ virtual bool ReadNextPicture(Picture& mypic) = 0;
+
+ //! Get the source parameters
+ SourceParams& GetSourceParams() const {return m_sparams;}
+
+ //! Returns true if we're at the end of the input, false otherwise
+ bool End() const ;
+
+ protected:
+
+ //! Source parameters
+ mutable SourceParams m_sparams;
+
+ //! Input stream
+ std::istream* m_ip_pic_ptr;
+
+ };
+
+ class StreamFrameInput : public StreamPicInput
+ {
+ public:
+
+ //! Default Constructor
+ StreamFrameInput();
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param ip_pic_ptr input stream to read from
+ \param sparams Source parameters
+ */
+ StreamFrameInput(std::istream *ip_pic_ptr, const SourceParams& sparams);
+
+ //! Destructor
+ virtual ~StreamFrameInput();
+
+ //! Skip n frames of input
+ virtual void Skip( const int n);
+
+ //! Read the next frame from the file
+ virtual bool ReadNextPicture(Picture& myframe);
+
+ private:
+
+ //! Read a Frame component from the file
+ bool ReadFrameComponent(PicArray& pic_data,const CompSort& cs);
+
+ };
+
+ class StreamFieldInput : public StreamPicInput
+ {
+ public:
+
+ //! Default Constructor
+ StreamFieldInput();
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param ip_pic_ptr input stream to read from
+ \param sparams Source parameters
+ */
+ StreamFieldInput(std::istream *ip_pic_ptr, const SourceParams& sparams);
+
+ //! Destructor
+ virtual ~StreamFieldInput();
+
+ //! Skip n frames of input
+ virtual void Skip( const int n);
+
+ //! Read the next field from the file
+ virtual bool ReadNextPicture(Picture& myfield);
+
+ //! Read the next frame from the file
+ bool ReadNextFrame(Picture& field1, Picture& field2);
+
+ protected:
+ //! Read both Field components from the file
+ bool ReadFieldComponent(PicArray& pic_data1,
+ PicArray& pic_data2,
+ const CompSort& cs);
+
+ //! Read one Field component from the file
+ bool ReadFieldComponent(bool is_field1, PicArray& pic_data,
+ const CompSort& cs);
+ };
+ /*!
+ Class for reading picture data from memory
+ */
+ class MemoryStreamInput
+ {
+ public:
+ //! Constructor
+ /*! Create a MemoryStreamInput object
+ \param sparams Source parameters
+ \param field_input Treat input as fields, not frames
+ */
+ MemoryStreamInput(SourceParams& sparams, bool field_input);
+
+ //! Destructor
+ ~MemoryStreamInput();
+
+ SourceParams& GetSourceParams ( )
+ { return m_inp_str->GetSourceParams(); }
+
+ //! Set Memory buffer
+ /*! Set the input memory buffer variables
+ \param buf Input Buffer to read data from
+ \param buf_size Input buffer size
+ */
+ void SetMembufReference (unsigned char *buf, int buf_size);
+
+ //! Return the input stream
+ StreamPicInput *GetStream() { return m_inp_str; }
+ protected:
+ //! Body-less copy constructor
+ MemoryStreamInput(const MemoryStreamInput&);
+ //! Body-less assignment operator
+ MemoryStreamInput & operator =(const MemoryStreamInput&);
+
+ protected:
+ //! Class that defines the Input Stream Memory Buffer
+ class InputMemoryBuffer : public std::streambuf
+ {
+ public:
+ //! Constructor
+ InputMemoryBuffer() : m_buffer(0), m_buffer_size(0)
+ {
+ setg ((char *)m_buffer, (char *)m_buffer, (char *)m_buffer);
+ }
+
+ //! Destructor
+ ~InputMemoryBuffer(){}
+
+ //! Set Input Memory buffer variables
+ /*! Initialises the input memory buffer vars
+ \param buffer Input memory buffer
+ \param buffer_size Input memory buffer size
+ */
+ void SetMembufReference (unsigned char *buffer, int buffer_size)
+ {
+ m_buffer = buffer;
+ m_buffer_size = buffer_size;
+
+ setg ((char *)m_buffer, (char *)m_buffer,
+ (char *)(m_buffer + buffer_size));
+ }
+
+ private:
+ //! Body-less copy constructor
+ InputMemoryBuffer (const InputMemoryBuffer& inbuf);
+ //! Body-less assignment operator
+ InputMemoryBuffer& operator = (const InputMemoryBuffer& inbuf);
+
+ //! Input memory buffer
+ unsigned char *m_buffer;
+ //! Input memory buffer size
+ int m_buffer_size;
+ };
+
+ private:
+ //! Input stream buffer
+ InputMemoryBuffer m_membuf;
+
+ //! Input Stream Object
+ StreamPicInput *m_inp_str;
+
+ //! Input stream
+ std::istream* m_ip_pic_ptr;
+ };
+
+ //! Picture input class
+ /*!
+ Class for reading picture data from a file.
+ */
+ class FileStreamInput
+ {
+ public:
+
+ //! Constructor
+ /*!
+ Constructor, takes
+ \param input_name the name of the input picture file
+ \param sparams the source parameters
+ \param interlace input is treated as interlaced
+ */
+ FileStreamInput (const char* input_name, const SourceParams &sparams, bool interlace);
+
+ //! Destructor
+ virtual ~FileStreamInput ();
+
+ SourceParams& GetSourceParams ( )
+ { return m_inp_str->GetSourceParams(); }
+
+ //! Return the input stream
+ StreamPicInput *GetStream() { return m_inp_str; }
+
+ private:
+ StreamPicInput *m_inp_str;
+
+ //! Input stream
+ std::istream* m_ip_pic_ptr;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.cpp
new file mode 100644
index 000000000..ee3da95a3
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.cpp
@@ -0,0 +1,337 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture.cpp,v 1.4 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+//Implementation of picture classes in picture.h
+
+#include <libdirac_common/picture.h>
+#include <libdirac_common/upconvert.h>
+using namespace dirac;
+
+#include <iostream>
+#if defined(HAVE_MMX)
+#include <mmintrin.h>
+#endif
+
+///////////////
+//---Picture---//
+///////////////
+
+Picture::Picture(const PictureParams& pp):
+ m_pparams(pp)
+{
+ for (int c=0;c<3;++c){
+ m_pic_data[c] = NULL;
+ m_up_pic_data[c] = NULL;
+ }
+
+ Init();
+}
+
+Picture::Picture( const Picture& cpy ):
+ m_pparams(cpy.m_pparams)
+{
+
+ //delete data to be overwritten
+ for (int c=0;c<3;++c){
+ m_pic_data[c] = NULL;
+ m_up_pic_data[c] = NULL;
+ }
+
+ //now copy the data across
+ for (int c=0; c<3; ++c ){
+ m_pic_data[c] = new PicArray( *(cpy.m_pic_data[c]) );
+ if (cpy.m_up_pic_data[c] != NULL)
+ m_up_pic_data[c] = new PicArray( *(cpy.m_up_pic_data[c]) );
+ }
+
+}
+
+
+Picture::~Picture()
+{
+ ClearData();
+}
+
+Picture& Picture::operator=(const Picture& rhs)
+{
+ if ( &rhs != this)
+ {
+ m_pparams=rhs.m_pparams;
+
+ // Delete current data
+ ClearData();
+
+ // Copy the data across
+ for (int c=0; c<3; ++c ){
+ m_pic_data[c] = new PicArray( *(rhs.m_pic_data[c]) );
+
+ if (rhs.m_up_pic_data[c] != NULL)
+ m_up_pic_data[c] = new PicArray( *(rhs.m_up_pic_data[c]) );
+ }
+ }
+
+ return *this;
+
+}
+
+void Picture::Fill(ValueType val)
+{
+ for (int c=0; c<3; ++c ){
+ m_pic_data[c]->Fill(val);
+ if (m_up_pic_data[c] != NULL )
+ delete m_up_pic_data[c];
+ }
+}
+
+//Other functions
+
+void Picture::Init()
+{
+ //const ChromaFormat cformat=m_pparams.CFormat();
+
+ //first delete data if we need to
+ ClearData();
+
+ m_pic_data[0]=new PicArray( m_pparams.Yl() , m_pparams.Xl());
+ m_pic_data[0]->SetCSort( Y_COMP );
+
+ m_pic_data[1] = new PicArray( m_pparams.ChromaYl() ,
+ m_pparams.ChromaXl() );
+ m_pic_data[1]->SetCSort( U_COMP );
+
+ m_pic_data[2] = new PicArray( m_pparams.ChromaYl() ,
+ m_pparams.ChromaXl() );
+ m_pic_data[2]->SetCSort( V_COMP );
+}
+
+PicArray& Picture::UpData(CompSort cs)
+{
+ const int c = (int) cs;
+
+ if (m_up_pic_data[c] != NULL )
+ return *(m_up_pic_data[c]);
+ else
+ {//we have to do the upconversion
+
+ m_up_pic_data[c] = new PicArray( 2*m_pic_data[c]->LengthY(),
+ 2*m_pic_data[c]->LengthX() );
+ UpConverter* myupconv;
+ if (c>0)
+ myupconv = new UpConverter(-(1 << (m_pparams.ChromaDepth()-1)),
+ (1 << (m_pparams.ChromaDepth()-1))-1,
+ m_pparams.ChromaXl(), m_pparams.ChromaYl());
+ else
+ myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
+ (1 << (m_pparams.LumaDepth()-1))-1,
+ m_pparams.Xl(), m_pparams.Yl());
+
+ myupconv->DoUpConverter( *(m_pic_data[c]) , *(m_up_pic_data[c]) );
+
+ delete myupconv;
+
+ return *(m_up_pic_data[c]);
+
+ }
+}
+
+const PicArray& Picture::UpData(CompSort cs) const
+{
+ const int c = (int) cs;
+
+ if (m_up_pic_data[c] != NULL)
+ return *(m_up_pic_data[c]);
+ else
+ {//we have to do the upconversion
+
+ m_up_pic_data[c] = new PicArray( 2*m_pic_data[c]->LengthY(),
+ 2*m_pic_data[c]->LengthX() );
+ UpConverter* myupconv;
+ if (c>0)
+ myupconv = new UpConverter(-(1 << (m_pparams.ChromaDepth()-1)),
+ (1 << (m_pparams.ChromaDepth()-1))-1,
+ m_pparams.ChromaXl(), m_pparams.ChromaYl());
+ else
+ myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
+ (1 << (m_pparams.LumaDepth()-1))-1,
+ m_pparams.Xl(), m_pparams.Yl());
+
+ myupconv->DoUpConverter( *(m_pic_data[c]) , *(m_up_pic_data[c]) );
+
+ delete myupconv;
+
+ return *(m_up_pic_data[c]);
+
+ }
+}
+
+void Picture::InitWltData( const int transform_depth )
+{
+
+ int xpad_len, ypad_len;
+ int tx_mul = 1<<transform_depth;
+
+ for (int c=0; c<3; ++c){
+ xpad_len = m_pic_data[c]->LengthX();
+ ypad_len = m_pic_data[c]->LengthY();
+
+ if ( xpad_len%tx_mul != 0 )
+ xpad_len = ( (xpad_len/tx_mul)+1 ) *tx_mul;
+ if ( ypad_len%tx_mul != 0 )
+ ypad_len = ( (ypad_len/tx_mul)+1 ) * tx_mul;
+
+ m_wlt_data[c].Resize( ypad_len, xpad_len );
+ }
+
+}
+
+void Picture::ClipComponent(PicArray& pic_data, CompSort cs) const
+{
+ ValueType *pic = &(pic_data[pic_data.FirstY()][pic_data.FirstX()]);
+ int count = pic_data.LengthY() * pic_data.LengthX();
+
+ ValueType min_val;
+ ValueType max_val;
+
+ min_val = (cs == Y_COMP) ?
+ -(1 << (m_pparams.LumaDepth()-1) ) :
+ -(1 << (m_pparams.ChromaDepth()-1) );
+
+ max_val = (cs == Y_COMP) ?
+ (1 << (m_pparams.LumaDepth()-1) )-1 :
+ (1 << (m_pparams.ChromaDepth()-1) )-1;
+
+#if defined (HAVE_MMX)
+ {
+ int qcount = count >> 2;
+ count = count & 3;
+
+ //__m64 pack_usmax = _mm_set_pi16 (0xffff, 0xffff, 0xffff, 0xffff);
+ //__m64 pack_smin = _mm_set_pi16 (0x8000, 0x8000, 0x8000, 0x8000);
+ __m64 pack_usmax = _mm_set_pi16 (-1, -1, -1, -1);
+ __m64 pack_smin = _mm_set_pi16 (-32768, -32768, -32768, -32768);
+ __m64 high_val = _mm_set_pi16 (max_val, max_val, max_val, max_val);
+ __m64 lo_val = _mm_set_pi16 (min_val, min_val, min_val, min_val);
+
+ __m64 clip_max = _mm_add_pi16 (pack_smin, high_val);
+ __m64 clip_min = _mm_add_pi16 (pack_smin, lo_val);
+
+ __m64 tmp1 = _mm_subs_pu16 ( pack_usmax, clip_max);
+ __m64 tmp2 = _mm_adds_pu16 ( clip_min, tmp1 );
+
+ while (qcount--)
+ {
+ ValueType *p1 = pic;
+ *(__m64 *)p1 = _mm_add_pi16 (pack_smin, *(__m64 *)p1);
+ *(__m64 *)p1 = _mm_adds_pu16 (*(__m64 *)p1, tmp1);
+ *(__m64 *)p1 = _mm_subs_pu16 (*(__m64 *)p1, tmp2);
+ *(__m64 *)p1 = _mm_add_pi16 (lo_val, *(__m64 *)p1);
+ pic += 4;
+ }
+ //Mop up remaining pixels
+ while( count-- )
+ {
+ *pic = std::max( min_val, std::min( max_val , *pic )
+ );
+ pic++;
+ }
+
+ _mm_empty();
+ return;
+ }
+#endif
+
+ // NOTE: depending on a contigous chunk of memory being allocated
+ while (count--)
+ {
+ *pic = std::max( min_val, std::min( max_val, *pic ));
+ pic++;
+ }
+}
+
+void Picture::Clip()
+{
+ //just clips the straight picture data, not the upconverted data
+
+ for (int c=0; c<3; ++c)
+ ClipComponent( *(m_pic_data[c]), (CompSort) c);
+}
+
+void Picture::ClipUpData()
+{
+ //just clips the upconverted data
+
+ for (int c=0; c<3; ++c){
+ if (m_up_pic_data[c])
+ ClipComponent( *(m_up_pic_data[c]), (CompSort) c );
+ }
+
+}
+
+void Picture::ClearData()
+{
+ for (int c=0;c<3;++c){
+ if (m_pic_data[c] != NULL){
+ delete m_pic_data[c];
+ m_pic_data[c] = NULL;
+ }
+
+ if (m_up_pic_data[c] != NULL){
+ delete m_up_pic_data[c];
+ m_up_pic_data[c] = NULL;
+ }
+ }
+
+}
+
+void Picture::ReconfigPicture(const PictureParams &pp )
+{
+
+ PictureParams old_pp = m_pparams;
+ m_pparams = pp;
+
+ // HAve picture dimensions or Chroma format changed ?
+ if (m_pparams.Xl() == old_pp.Xl() &&
+ m_pparams.Yl() == old_pp.Yl() &&
+ m_pparams.CFormat() == old_pp.CFormat())
+ return;
+
+ // Picture dimensions have changed. Re-initialise
+ Init();
+}
+
+
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.h
new file mode 100644
index 000000000..face2d15d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture.h
@@ -0,0 +1,149 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture.h,v 1.4 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _PICTURE_H_
+#define _PICTURE_H_
+
+#include <libdirac_common/common.h>
+#include <libdirac_common/wavelet_utils.h>
+
+namespace dirac
+{
+ //! A class for encapsulating all the data relating to a picture.
+ /*!
+ A class for encapsulating all the data relating to a picture - all the
+ component data, including upconverted data.
+ */
+ class Picture
+ {
+
+ public:
+
+ //! Constructor
+ /*!
+ Constructor initialises the picture parameters and the data
+ */
+ Picture( const PictureParams& pp );
+
+ //! Copy constructor. Private as not currently used [may want to implement reference counting later.]
+ Picture(const Picture& cpy);
+
+ //! Destructor
+ virtual ~Picture();
+
+ //! Assignment =. Private as not currently used [may want to implement reference counting later.]
+ Picture& operator=( const Picture& rhs );
+
+ //! Picture Fill
+ /*!
+ Initialise contents of picture with value provided
+ */
+ void Fill(ValueType val );
+
+ //gets and sets
+ //! Gets the picture parameters
+ PictureParams& GetPparams() const {return m_pparams;}
+
+ //! Sets the picture sort
+ void SetPictureSort( const PictureSort ps ){m_pparams.SetPicSort( ps ); }
+
+ //! Sets the picture type
+ void SetPictureType( const PictureType ftype ){m_pparams.SetPictureType( ftype ); }
+
+ //! Sets the picture type
+ void SetReferenceType( const ReferenceType rtype ){m_pparams.SetReferenceType( rtype ); }
+
+ //! Reconfigures to the new parameters.
+ void ReconfigPicture( const PictureParams &pp );
+
+ //! Returns a given component
+ PicArray& Data(CompSort cs){return *m_pic_data[(int) cs];}
+
+ //! Returns a given component
+ const PicArray& Data(CompSort cs) const{return *m_pic_data[(int) cs];}
+
+ //! Returns a given upconverted component
+ PicArray& UpData(CompSort cs);
+
+ //! Returns a given upconverted component
+ const PicArray& UpData(CompSort cs) const;
+
+ //! Returns the wavelet coefficient data
+ const CoeffArray& WltData( CompSort c ) const { return m_wlt_data[(int) c]; }
+
+ //! Returns the wavelet coefficient data
+ CoeffArray& WltData( CompSort c ) { return m_wlt_data[(int) c]; }
+
+ //! Initialises the wavelet coefficient data arrays;
+ void InitWltData( const int transform_depth );
+
+ //! Clip the data to prevent overshoot
+ /*!
+ Clips the data to lie between 0 and (1<<video_depth)-1
+ */
+ void Clip();
+
+ //! Clip the upconverted data to prevent overshoot
+ /*!
+ Clips the upconverted data to lie between 0 and (1<<video_depth)-1
+ */
+ void ClipUpData();
+
+ protected:
+ mutable PictureParams m_pparams;
+ PicArray* m_pic_data[3];//the picture data
+ mutable PicArray* m_up_pic_data[3];//upconverted data. Mutable because we
+ //create them on the fly even in const
+ //functions.
+
+ CoeffArray m_wlt_data[3];// the wavelet coefficient data
+
+ //! Initialises the picture once the picture parameters have been set
+ virtual void Init();
+
+ //! Delete all the data
+ virtual void ClearData();
+
+ //! Clip an individual component
+ void ClipComponent(PicArray& pic_data, CompSort cs) const;
+
+ };
+
+} // namespace dirac
+
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.cpp
new file mode 100644
index 000000000..cbd311003
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.cpp
@@ -0,0 +1,265 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_buffer.cpp,v 1.7 2008/06/19 10:07:03 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/picture_buffer.h>
+#include <algorithm>
+using namespace dirac;
+
+//Simple constructor for decoder operation
+PictureBuffer::PictureBuffer(){}
+
+//Copy constructor. Why anyone would need this I don't know.
+PictureBuffer::PictureBuffer(const PictureBuffer& cpy)
+ {
+ // first delete all frames in the current buffer
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ delete m_pic_data[i];
+ }//i
+
+ // next create new arrays, copying from the initialising buffer
+ m_pic_data.resize(cpy.m_pic_data.size());
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i){
+ m_pic_data[i] = new Picture( *(cpy.m_pic_data[i]) );
+ }//i
+
+ // now copy the map
+ m_pnum_map = cpy.m_pnum_map;
+
+// // and the reference count
+// m_ref_count = cpy.m_ref_count;
+
+}
+
+//Assignment=. Not sure why this would be used either.
+PictureBuffer& PictureBuffer::operator=(const PictureBuffer& rhs){
+ if (&rhs!=this)
+ {
+ // delete all the frames in the lhs buffer
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ delete m_pic_data[i];
+ }//i
+
+ // next create new arrays, copying from the rhs
+ m_pic_data.resize(rhs.m_pic_data.size());
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ m_pic_data[i] = new Picture( *(rhs.m_pic_data[i]) );
+ }//i
+
+ // now copy the map
+ m_pnum_map = rhs.m_pnum_map;
+
+// // and the reference count
+// m_ref_count = rhs.m_ref_count;
+
+ }
+ return *this;
+}
+
+//Destructor
+PictureBuffer::~PictureBuffer()
+{
+ for (size_t i=0 ; i<m_pic_data.size() ;++i)
+ delete m_pic_data[i];
+}
+
+Picture& PictureBuffer::GetPicture( const unsigned int pnum )
+{//get picture with a given picture number, NOT with a given position in the buffer.
+ //If the picture number does not occur, the first picture in the buffer is returned.
+
+ std::map<unsigned int,unsigned int>::iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos = 0;
+ if (it != m_pnum_map.end())
+ pos = it->second;
+
+ return *(m_pic_data[pos]);
+}
+
+const Picture& PictureBuffer::GetPicture( const unsigned int pnum ) const
+{ //as above, but const version
+
+ std::map<unsigned int,unsigned int>::const_iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos=0;
+ if (it != m_pnum_map.end())
+ pos = it->second;
+
+ return *(m_pic_data[pos]);
+}
+
+Picture& PictureBuffer::GetPicture( const unsigned int pnum, bool& is_present )
+{//get picture with a given picture number, NOT with a given position in the buffer.
+ //If the picture number does not occur, the first picture in the buffer is returned.
+
+ std::map<unsigned int,unsigned int>::iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos = 0;
+ if (it != m_pnum_map.end())
+ {
+ is_present = true;
+ pos = it->second;
+ }
+ else
+ is_present=false;
+
+ return *(m_pic_data[pos]);
+}
+
+const Picture& PictureBuffer::GetPicture( const unsigned int pnum, bool& is_present ) const
+{ //as above, but const version
+
+ std::map<unsigned int,unsigned int>::const_iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos=0;
+ if (it != m_pnum_map.end())
+ {
+ is_present = true;
+ pos = it->second;
+ }
+ else
+ is_present=false;
+
+ return *(m_pic_data[pos]);
+}
+
+bool PictureBuffer::IsPictureAvail( const unsigned int pnum ) const
+{
+
+ std::map<unsigned int,unsigned int>::const_iterator it = m_pnum_map.find(pnum);
+
+ if (it != m_pnum_map.end())
+ return true;
+ else
+ return false;
+}
+
+std::vector<int> PictureBuffer::Members() const
+{
+ std::vector<int> members( 0 );
+ for (unsigned int i=0; i<m_pic_data.size(); ++i )
+ {
+ const PictureParams& pparams = m_pic_data[i]->GetPparams();
+ members.push_back( pparams.PictureNum() );
+ }// i
+
+ return members;
+}
+
+void PictureBuffer::PushPicture( const PictureParams& pp )
+{// Put a new picture onto the top of the stack
+
+ // if picture is present - return
+ if (IsPictureAvail(pp.PictureNum()))
+ return;
+
+// if ( pp.PicSort().IsRef() )
+// m_ref_count++;
+
+ Picture* pptr = new Picture(pp);
+ // add the picture to the buffer
+ m_pic_data.push_back(pptr);
+
+ // put the picture number into the index table
+ std::pair<unsigned int,unsigned int> temp_pair(pp.PictureNum() , m_pic_data.size()-1 );
+ m_pnum_map.insert(temp_pair);
+}
+
+void PictureBuffer::CopyPicture( const Picture& picture )
+{
+ PushPicture(picture.GetPparams());
+
+ bool is_present;
+
+ Picture & p= GetPicture(picture.GetPparams().PictureNum(), is_present);
+ if(is_present)
+ p = picture;
+}
+
+void PictureBuffer::ClearSlot(const unsigned int pos)
+{
+ // Clear a slot corresponding to position pos to take more data
+
+ std::pair<unsigned int,unsigned int>* tmp_pair;
+
+ if (pos<m_pic_data.size())
+ {
+ delete m_pic_data[pos];
+ m_pic_data.erase( m_pic_data.begin()+pos );
+
+ //make a new map
+ m_pnum_map.clear();
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ tmp_pair = new std::pair<unsigned int,unsigned int>( m_pic_data[i]->GetPparams().PictureNum() , i);
+ m_pnum_map.insert(*tmp_pair);
+ delete tmp_pair;
+ }//i
+ }
+}
+
+
+void PictureBuffer::SetRetiredPictureNum(const int show_pnum, const int current_coded_pnum)
+{
+ if ( IsPictureAvail(current_coded_pnum))
+ {
+ PictureParams &pparams = GetPicture(current_coded_pnum).GetPparams();
+ pparams.SetRetiredPictureNum(-1);
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ if (m_pic_data[i]->GetPparams().PicSort().IsRef() ){
+ if ( (m_pic_data[i]->GetPparams().PictureNum() + m_pic_data[i]->GetPparams().ExpiryTime() ) <= show_pnum){
+ pparams.SetRetiredPictureNum(m_pic_data[i]->GetPparams().PictureNum());
+ break;
+ }
+ }
+ }//i
+ }
+}
+
+void PictureBuffer::Remove(const int pnum)
+{
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i){
+ if ( m_pic_data[i]->GetPparams().PictureNum() == pnum)
+ ClearSlot(i);
+ }//i
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.h
new file mode 100644
index 000000000..86613720e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/picture_buffer.h
@@ -0,0 +1,198 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_buffer.h,v 1.4 2008/06/19 10:07:03 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _PICTURE_BUFFER_H_
+#define _PICTURE_BUFFER_H_
+
+#include <vector>
+#include <map>
+#include <libdirac_common/picture.h>
+#include <libdirac_common/common.h>
+
+namespace dirac
+{
+ //! Holds pictures both for reference and to overcome reordering delay
+ /*!
+ The buffer holds pictures in a stack to overcome both reordering due to
+ bi-directional prediction and use as references for subsequence motion
+ estimation. Pictures, and components of pictures, can be accessed by their
+ picture numbers. GOP parameters can be included in the constructors so
+ that pictures can be given types (I picture, L1 picture or L2 picture) on
+ being pushed onto the stack; alternatively, these parameters can be
+ overridden.
+ */
+ class PictureBuffer{
+ public:
+ //! Default Constructor
+ PictureBuffer();
+
+ //! Constructor
+ /*!
+ Creates a PictureBuffer using the chroma format. Suitable for
+ compressing when there are no L2 pictures, or when the temporal
+ prediction structure is to be determined on the fly.
+
+ \param cf the Chroma format of pictures in the buffer
+ \param xlen the luma width of pictures in the buffer
+ \param ylen the luma height of pictures in the buffer
+ \param luma_depth the video depth of the luma comp in the buffer
+ \param chroma_depth the video depth of the chroma comp in the buffer
+ \param using_ac True if using Arithmetic coding to code coefficient data
+
+ */
+ PictureBuffer(ChromaFormat cf,
+ const int xlen,
+ const int ylen,
+ const unsigned int luma_depth,
+ const unsigned int chroma_depth,
+ bool using_ac);
+
+ //! Constructor
+ /*!
+ Creates a PictureBuffer using the chroma format, the number of L1
+ pictures between I pictures and the separation in pictures between L1
+ pictures. Suitable for compressing when there is a full GOP structure
+ or when the temporal prediction structure is to be determined on
+ the fly.
+
+ \param cf the Chroma format of pictures in the buffer
+ \param numL1 the number of Layer 1 pictures before the next I picture. 0 means that there is only one I picture.
+ \param L1sep the number of Layer 2 pictures between Layer 1 pictures
+ \param xlen the luma width of pictures in the buffer
+ \param ylen the luma height of pictures in the buffer
+ \param luma_depth the video depth of the luma comp in the buffer
+ \param chroma_depth the video depth of the chroma comp in the buffer
+ \param interlace Set true if material is being coded in interlaced mode
+ \param using_ac True if using Arithmetic coding to code coefficient data
+ */
+ PictureBuffer(ChromaFormat cf,
+ const int numL1,
+ const int L1sep,
+ const int xlen,
+ const int ylen,
+ const unsigned int luma_depth,
+ const unsigned int chroma_depth,
+ bool interlace,
+ bool using_ac);
+
+ //! Copy constructor
+ /*!
+ Copy constructor. Removes the current contents of the pictureture buffer
+ and copies in the contents of the initialising buffer.
+ */
+ PictureBuffer(const PictureBuffer& cpy);
+
+ //! Operator=.
+ /*!
+ Operator=. Assigns all elements of the rhs to the lhs.
+ */
+ PictureBuffer& operator=(const PictureBuffer& rhs);
+
+ //! Destructor
+ ~PictureBuffer();
+
+ //! Get picture with a given picture number (NOT with a given position in the buffer)
+ Picture& GetPicture(const unsigned int pnum );
+
+ //! Get picture with a given picture number (NOT with a given position in the buffer)
+ const Picture& GetPicture(const unsigned int pnum) const;
+
+ //! Get picture with a given picture number, setting a flag to true if it's there
+ Picture& GetPicture(const unsigned int pnum, bool& is_present);
+
+ //! Get picture with a given picture number, setting a flag to true if it's there
+ const Picture& GetPicture(const unsigned int pnum, bool& is_present) const;
+
+ //! Return true if picture with the particular picture number is available else return false
+ bool IsPictureAvail(const unsigned int pnum) const;
+
+ //! Returns a list of member pictures
+ std::vector<int> Members() const;
+
+ //! Put a new picture into the top of the buffer
+ /*!
+ Put a new picture into the top of the buffer. Picture parameters
+ associated with the picture will be as given by the picture parameter
+ object.
+ */
+ void PushPicture(const PictureParams& pp);
+
+ //! Put a copy of a new picture into the buffer
+ /*!
+ Put a copy of a new picture into the buffer.
+ */
+ void CopyPicture( const Picture& picture );
+
+ //! Sets the reference picture number that will be cleaned
+ /*!
+ Indicate which picture which has been output and which is no longer
+ required for reference. Expiry times are set in each picture's
+ picture parameters.
+ \param show_pnum picture number in display order that can be output
+ \param current_coded_pnum picture number in display order of picture currently being coded
+ */
+ void SetRetiredPictureNum(const int show_pnum, const int current_coded_pnum);
+
+ //! Delete picture
+ /*!
+ Delete picture.
+ \param pnum picture number in display order to be deleted from picture buffer
+ */
+ void Remove(int pnum);
+
+ private:
+ //! Clear internal data slot number pos
+ /*!
+ Clear internal data slot number pos
+ */
+ void ClearSlot(const unsigned int pos);
+
+// //! the count of the number of reference pictures in the buffer
+// int m_ref_count;
+
+ //! the buffer storing all the values
+ std::vector<Picture*> m_pic_data;
+
+ //!the map from picture numbers to position in the buffer
+ std::map<unsigned int,unsigned int> m_pnum_map;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.cpp
new file mode 100644
index 000000000..5535a66da
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.cpp
@@ -0,0 +1,200 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: upconvert.cpp,v 1.11 2007/11/22 15:19:28 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author), Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/upconvert.h>
+using namespace dirac;
+
+#include <iostream>
+
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#define CLIP(x,min,max) MAX(MIN(x,max),min)
+
+UpConverter::UpConverter (int min_val, int max_val, int orig_xlen, int orig_ylen) :
+ m_min_val(min_val),
+ m_max_val(max_val),
+ m_orig_xl(orig_xlen),
+ m_orig_yl(orig_ylen)
+{}
+
+//Up-convert by a factor of two.
+void UpConverter::DoUpConverter(const PicArray& pic_data, PicArray& up_data)
+{
+
+ m_width_old = std::min (pic_data.LengthX(), m_orig_xl);
+ m_height_old = std::min (pic_data.LengthY(), m_orig_yl);
+ m_width_new = std::min(2*m_width_old, up_data.LengthX());
+ m_height_new = std::min(2*m_height_old, up_data.LengthY());
+
+ // Filter params
+ const int filter_size = 4;
+ const int filter_shift = 5;
+ const short taps[4] = {21,-7,3,-1};
+
+
+ //Variables that will be used by the filter calculations
+ ValueType sum;
+ int ypos(0);
+
+
+ //There are three y loops to cope with the leading edge, middle
+ //and trailing edge of each column.
+
+ for(int y = 0 ; y < filter_size; ++y , ypos += 2)
+ {
+
+ //We are filtering each column but doing it bit by bit.
+ //This means our main loop is in the x direction and
+ //there is a much greater chance the data we need will
+ //be in the cache.
+ for(int x = 0 , xpos = 0; x < m_width_old; x++ , xpos+=2 )
+ {
+ // Copy a Pixel from the original image in each even position
+ up_data[ypos][xpos] = pic_data[y][x];
+
+ //Work out the next pixel from filtered values.
+ //Excuse the complicated ternary stuff but it sorts out the edge
+ sum = 1 << (filter_shift-1);
+ sum += (pic_data[y][x] + pic_data[y+1][x]) * taps[0];
+ sum += (pic_data[(y>=1)?(y-1):0][x] + pic_data[y+2][x]) * taps[1];
+ sum += (pic_data[(y>=2)?(y-2):0][x] + pic_data[y+3][x]) * taps[2];
+ sum += (pic_data[(y>=3)?(y-3):0][x] + pic_data[y+4][x]) * taps[3];
+
+ sum >>= filter_shift;
+ up_data[ypos+1][xpos] = CLIP(sum, m_min_val, m_max_val);
+ }// x, xpos
+
+ // The row loop.
+ RowLoop( up_data , ypos, filter_size, filter_shift, taps );
+ }// y, ypos
+ // This loop is like the last one but it deals with the centre
+ // section of the image and so the ternary operations are dropped
+ // from the filter section.
+ for(int y = filter_size; y < m_height_old - filter_size; ++y , ypos += 2)
+ {
+ for(int x = 0 , xpos=0; x < m_width_old; x++ , xpos+=2 )
+ {
+ up_data[ypos][xpos] = pic_data[y][x];
+
+ sum = 1 << (filter_shift-1);
+
+ for (int t=0; t<filter_size; ++t)
+ sum += (pic_data[y-t][x] + pic_data[y+1+t][x]) * taps[t];
+
+ sum >>= filter_shift;
+ up_data[ypos+1][xpos] = CLIP(sum, m_min_val, m_max_val);
+ }// x,xpos
+ RowLoop( up_data , ypos, filter_size, filter_shift, taps );
+
+ }// y, ypos
+ // Another similar loop! - this time we are dealing with
+ // the trailing edge so the ternary stuff is back in the
+ // filter calcs but in the second parameter.
+ for(int y = m_height_old - filter_size; y < m_height_old; ++y , ypos+=2)
+ {
+ for(int x = 0 , xpos=0 ; x < m_width_old; x++ , xpos+=2)
+ {
+ up_data[ypos][xpos]=pic_data[y][x];
+
+ sum = 1 << (filter_shift-1);
+ sum += (pic_data[y][x] + pic_data[((y+1)<m_height_old)?(y+1):(m_height_old-1)][x]) * taps[0];
+ sum += (pic_data[y - 1][x] + pic_data[((y+2)<m_height_old)?(y+2):(m_height_old-1)][x]) * taps[1];
+ sum += (pic_data[y - 2][x] + pic_data[((y+3)<m_height_old)?(y+3):(m_height_old-1)][x]) * taps[2];
+ sum += (pic_data[y - 3][x] + pic_data[((y+4)<m_height_old)?(y+4):(m_height_old-1)][x]) * taps[3];
+
+ sum >>= filter_shift;
+ up_data[ypos+1][xpos] = CLIP(sum, m_min_val, m_max_val);
+ }//x,xpos
+ RowLoop( up_data , ypos, filter_size, filter_shift, taps );
+
+ }//y,ypos
+}
+
+void UpConverter::RowLoop(PicArray&up_data, const int row_num,
+const int filter_size, const int filter_shift, const short taps[4] )
+{
+ const int dble_size( filter_size<<1 );
+
+ //Calculation variable
+ ValueType sum;
+ int ypos;
+
+ //Leading row Edge
+ //Note the factor of two difference as we only want to fill in every other
+ //line as the others have already been created
+ for(int j = 0; j < 2; ++j)
+ {
+ ypos = row_num + j;
+
+ for(int x = 0; x < dble_size ; x+=2)
+ {
+ sum = 1 << (filter_shift-1);
+ sum += (up_data[ypos][x] + up_data[ypos][x+2]) * taps[0];
+ sum += (up_data[ypos][(x>=2)?(x-2):0] + up_data[ypos][x+4]) * taps[1];
+ sum += (up_data[ypos][(x>=4)?(x-4):0] + up_data[ypos][x+6]) * taps[2];
+ sum += (up_data[ypos][(x>=6)?(x-6):0] + up_data[ypos][x+8]) * taps[3];
+
+
+ sum >>= filter_shift;
+ up_data[ypos][x+1] = CLIP(sum, m_min_val, m_max_val);
+ }// x
+ //Middle of row
+ for(int x = dble_size; x<m_width_new-dble_size ; x+=2 )
+ {
+ sum = 1 << (filter_shift-1);
+
+ for (int t=0; t<filter_size; ++t)
+ sum += (up_data[ypos][x-2*t] + up_data[ypos][x+2+2*t]) * taps[t];
+
+
+ sum >>= filter_shift;
+ up_data[ypos][x+1] = CLIP(sum, m_min_val, m_max_val);
+ }// x
+ //Trailing row edge
+ for(int x = m_width_new - dble_size ; x<m_width_new ; x+=2)
+ {
+ sum = 1 << (filter_shift-1);
+ sum += (up_data[ypos][x] + up_data[ypos][(((x+2)<m_width_new)?(x+2):(m_width_new-2))]) * taps[0];
+ sum += (up_data[ypos][x-2] + up_data[ypos][(((x+4)<m_width_new)?(x+4):(m_width_new-2))]) * taps[1];
+ sum += (up_data[ypos][x-4] + up_data[ypos][(((x+6)<m_width_new)?(x+6):(m_width_new-2))]) * taps[2];
+ sum += (up_data[ypos][x-6] + up_data[ypos][(((x+8)<m_width_new)?(x+8):(m_width_new-2))]) * taps[3];
+
+ sum >>= filter_shift;
+ up_data[ypos][x+1] = CLIP(sum, m_min_val, m_max_val);
+ }// x
+ }
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.h
new file mode 100644
index 000000000..94d81026e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert.h
@@ -0,0 +1,98 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: upconvert.h,v 1.13 2007/11/22 15:19:28 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author), Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _UPCONVERT_H_
+#define _UPCONVERT_H_
+
+#include <libdirac_common/common.h>
+
+namespace dirac
+{
+ //Optimised upconversion class - no array resizes.
+ //Uses integer math - no floats!
+ //
+
+ //! Upconversion class
+ /*!
+ Class to upconvert data by a factor of 2 in both dimensions
+ */
+ class UpConverter
+ {
+
+ public:
+
+ //! Constructor
+ UpConverter(int min_val, int max_val, int orig_xlen, int orig_ylen);
+
+ //! Destructor
+ ~UpConverter() {};
+
+ //! Upconvert the picture data
+ /*!
+ Upconvert the picture data, where the parameters are
+ \param pic_data is the original data
+ \param up_data is the upconverted data
+ */
+ void DoUpConverter(const PicArray& pic_data, PicArray& up_data);
+
+ private:
+ //! Private body-less copy constructor: class should not be copied
+ UpConverter(const UpConverter& cpy);
+
+ //! Private body-less assignment: class should not be assigned
+ UpConverter& operator=(const UpConverter& rhs);
+
+ //! Applies the filter to a row and its successor
+ void RowLoop(PicArray& up_data, const int row_num,
+ const int filter_size, const int filter_shift, const short taps[4] );
+
+ private:
+ //Variable to keep the loops in check
+ int m_width_old, m_height_old;
+ int m_width_new, m_height_new;
+
+
+ const int m_min_val;
+ const int m_max_val;
+
+ const int m_orig_xl;
+ const int m_orig_yl;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert_mmx.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert_mmx.cpp
new file mode 100644
index 000000000..12f102714
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/upconvert_mmx.cpp
@@ -0,0 +1,39 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: upconvert_mmx.cpp,v 1.7 2007/11/22 15:19:28 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Thomas Davies (upconvert.cpp)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+// MMX version deleted - new version TBC //
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.cpp
new file mode 100644
index 000000000..683fd3065
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.cpp
@@ -0,0 +1,534 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: video_format_defaults.cpp,v 1.36 2008/10/20 04:21:45 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author).
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <sstream>
+#include <libdirac_common/video_format_defaults.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+
+namespace dirac
+{
+void SetDefaultCodecParameters(CodecParams &cparams,
+ PictureType ptype,
+ unsigned int num_refs)
+{
+ std::ostringstream errstr;
+ // Transform parameters
+ cparams.SetZeroTransform(false);
+ cparams.SetTransformDepth(4);
+ WltFilter wf;
+ SetDefaultTransformFilter(ptype, cparams.GetVideoFormat(), wf);
+ cparams.SetTransformFilter(wf);
+ cparams.SetCodeBlockMode(QUANT_SINGLE);
+ cparams.SetSpatialPartition(false);
+
+ // Default is set to progressive specified irrespective
+ // of whether the source material is interlaced or progressive.
+ // Overridden from command line of encoder or in bytestream for decoder.
+ cparams.SetPictureCodingMode(0);
+ cparams.SetTopFieldFirst(true);
+ switch (cparams.GetVideoFormat())
+ {
+ case VIDEO_FORMAT_QSIF525:
+ case VIDEO_FORMAT_QCIF:
+ case VIDEO_FORMAT_CUSTOM:
+ case VIDEO_FORMAT_SIF525:
+ case VIDEO_FORMAT_CIF:
+ case VIDEO_FORMAT_4CIF:
+ case VIDEO_FORMAT_4SIF525:
+ case VIDEO_FORMAT_SD_480I60:
+ case VIDEO_FORMAT_SD_576I50:
+ case VIDEO_FORMAT_HD_720P60:
+ case VIDEO_FORMAT_HD_720P50:
+ case VIDEO_FORMAT_HD_1080I60:
+ case VIDEO_FORMAT_HD_1080I50:
+ case VIDEO_FORMAT_HD_1080P60:
+ case VIDEO_FORMAT_HD_1080P50:
+ case VIDEO_FORMAT_DIGI_CINEMA_2K24:
+ case VIDEO_FORMAT_DIGI_CINEMA_4K24:
+ case VIDEO_FORMAT_UHDTV_4K60:
+ case VIDEO_FORMAT_UHDTV_4K50:
+ case VIDEO_FORMAT_UHDTV_8K60:
+ case VIDEO_FORMAT_UHDTV_8K50:
+ cparams.SetSpatialPartition(true);
+ break;
+ default:
+ errstr << "Unsupported video format " << cparams.GetVideoFormat()
+ << std::endl;
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_VIDEO_FORMAT,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ break;
+ }
+
+ if (ptype == INTER_PICTURE)
+ {
+ ASSERTM (num_refs > 0 && num_refs < 3, "Number of reference frames should be 1 or 2 fo INTER frames" );
+ OLBParams bparams;
+ PicturePredParams& predparams = cparams.GetPicPredParams();
+ predparams.SetUsingGlobalMotion(false);
+ SetDefaultBlockParameters(bparams, cparams.GetVideoFormat());
+ predparams.SetLumaBlockParams(bparams);
+ predparams.SetMVPrecision(MV_PRECISION_HALF_PIXEL);
+ // NOTE: FIXME - need to add global motion params here
+ predparams.SetPictureWeightsPrecision(1);
+ predparams.SetRef1Weight(1);
+ predparams.SetRef2Weight(1);
+ cparams.SetPictureCodingMode(0);
+ }
+}
+
+void SetDefaultSourceParameters(const VideoFormat &vf, SourceParams& sparams)
+{
+ std::ostringstream errstr;
+ sparams.SetVideoFormat(vf);
+ sparams.SetCFormat(format420);
+ sparams.SetSourceSampling(0);
+ sparams.SetTopFieldFirst(true);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_1_1);
+ sparams.SetSignalRange(SIGNAL_RANGE_8BIT_FULL);
+ sparams.SetLeftOffset(0);
+ sparams.SetTopOffset(0);
+ sparams.SetColourSpecification(1);
+
+ switch (vf)
+ {
+ case VIDEO_FORMAT_CUSTOM:
+ sparams.SetXl(640);
+ sparams.SetYl(480);
+ sparams.SetTopFieldFirst(false);
+ sparams.SetFrameRate(FRAMERATE_23p97_FPS);
+ sparams.SetCleanWidth(640);
+ sparams.SetCleanHeight(480);
+ sparams.SetColourSpecification(0);
+ break;
+ case VIDEO_FORMAT_QSIF525:
+ sparams.SetXl(176);
+ sparams.SetYl(120);
+ sparams.SetTopFieldFirst(false);
+ sparams.SetFrameRate(FRAMERATE_14p98_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_10_11);
+ sparams.SetCleanWidth(176);
+ sparams.SetCleanHeight(120);
+ sparams.SetColourSpecification(1);
+ break;
+ case VIDEO_FORMAT_QCIF:
+ sparams.SetXl(176);
+ sparams.SetYl(144);
+ sparams.SetFrameRate(FRAMERATE_12p5_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_12_11);
+ sparams.SetCleanWidth(176);
+ sparams.SetCleanHeight(144);
+ sparams.SetColourSpecification(2);
+ break;
+ case VIDEO_FORMAT_SIF525:
+ sparams.SetXl(352);
+ sparams.SetYl(240);
+ sparams.SetTopFieldFirst(false);
+ sparams.SetFrameRate(FRAMERATE_14p98_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_10_11);
+ sparams.SetCleanWidth(352);
+ sparams.SetCleanHeight(240);
+ sparams.SetColourSpecification(1);
+ break;
+ case VIDEO_FORMAT_CIF:
+ sparams.SetXl(352);
+ sparams.SetYl(288);
+ sparams.SetFrameRate(FRAMERATE_12p5_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_12_11);
+ sparams.SetCleanWidth(352);
+ sparams.SetCleanHeight(288);
+ sparams.SetColourSpecification(2);
+ break;
+ case VIDEO_FORMAT_4SIF525:
+ sparams.SetXl(704);
+ sparams.SetYl(480);
+ sparams.SetTopFieldFirst(false);
+ sparams.SetFrameRate(FRAMERATE_14p98_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_10_11);
+ sparams.SetCleanWidth(704);
+ sparams.SetCleanHeight(480);
+ sparams.SetColourSpecification(1);
+ break;
+ case VIDEO_FORMAT_4CIF:
+ sparams.SetXl(704);
+ sparams.SetYl(576);
+ sparams.SetFrameRate(FRAMERATE_12p5_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_12_11);
+ sparams.SetCleanWidth(704);
+ sparams.SetCleanHeight(576);
+ sparams.SetColourSpecification(2);
+ break;
+ case VIDEO_FORMAT_SD_480I60:
+ sparams.SetXl(720);
+ sparams.SetYl(480);
+ sparams.SetCFormat(format422);
+ sparams.SetSourceSampling(1);
+ sparams.SetTopFieldFirst(false);
+ sparams.SetFrameRate(FRAMERATE_29p97_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_10_11);
+ sparams.SetCleanWidth(704);
+ sparams.SetCleanHeight(480);
+ sparams.SetLeftOffset(8);
+ sparams.SetSignalRange(SIGNAL_RANGE_10BIT_VIDEO);
+ sparams.SetColourSpecification(1);
+ break;
+ case VIDEO_FORMAT_SD_576I50:
+ sparams.SetXl(720);
+ sparams.SetYl(576);
+ sparams.SetCFormat(format422);
+ sparams.SetSourceSampling(1);
+ sparams.SetFrameRate(FRAMERATE_25_FPS);
+ sparams.SetPixelAspectRatio(PIXEL_ASPECT_RATIO_12_11);
+ sparams.SetCleanWidth(704);
+ sparams.SetCleanHeight(576);
+ sparams.SetLeftOffset(8);
+ sparams.SetSignalRange(SIGNAL_RANGE_10BIT_VIDEO);
+ sparams.SetColourSpecification(2);
+ break;
+ case VIDEO_FORMAT_HD_720P50:
+ case VIDEO_FORMAT_HD_720P60:
+ sparams.SetXl(1280);
+ sparams.SetYl(720);
+ sparams.SetCFormat(format422);
+ if (vf == VIDEO_FORMAT_HD_720P50)
+ sparams.SetFrameRate(FRAMERATE_50_FPS);
+ else
+ sparams.SetFrameRate(FRAMERATE_59p94_FPS);
+ sparams.SetCleanWidth(1280);
+ sparams.SetCleanHeight(720);
+ sparams.SetSignalRange(SIGNAL_RANGE_10BIT_VIDEO);
+ sparams.SetColourSpecification(3);
+ break;
+ case VIDEO_FORMAT_HD_1080I60:
+ case VIDEO_FORMAT_HD_1080I50:
+ case VIDEO_FORMAT_HD_1080P60:
+ case VIDEO_FORMAT_HD_1080P50:
+ sparams.SetXl(1920);
+ sparams.SetYl(1080);
+ sparams.SetCFormat(format422);
+ switch (vf)
+ {
+ case VIDEO_FORMAT_HD_1080I60:
+ sparams.SetSourceSampling(1);
+ sparams.SetFrameRate(FRAMERATE_29p97_FPS);
+ break;
+ case VIDEO_FORMAT_HD_1080I50:
+ sparams.SetSourceSampling(1);
+ sparams.SetFrameRate(FRAMERATE_25_FPS);
+ break;
+ case VIDEO_FORMAT_HD_1080P60:
+ sparams.SetFrameRate(FRAMERATE_59p94_FPS);
+ break;
+ case VIDEO_FORMAT_HD_1080P50:
+ sparams.SetFrameRate(FRAMERATE_50_FPS);
+ break;
+ default:
+ break;
+ }
+ sparams.SetSignalRange(SIGNAL_RANGE_10BIT_VIDEO);
+ sparams.SetCleanWidth(1920);
+ sparams.SetCleanHeight(1080);
+ sparams.SetColourSpecification(3);
+ break;
+ case VIDEO_FORMAT_DIGI_CINEMA_2K24:
+ sparams.SetXl(2048);
+ sparams.SetYl(1080);
+ sparams.SetCFormat(format444);
+ sparams.SetFrameRate(FRAMERATE_24_FPS);
+ sparams.SetCleanWidth(2048);
+ sparams.SetCleanHeight(1080);
+ sparams.SetSignalRange(SIGNAL_RANGE_12BIT_VIDEO);
+ sparams.SetColourSpecification(4);
+ break;
+ case VIDEO_FORMAT_DIGI_CINEMA_4K24:
+ sparams.SetXl(4096);
+ sparams.SetYl(2160);
+ sparams.SetCFormat(format444);
+ sparams.SetFrameRate(FRAMERATE_24_FPS);
+ sparams.SetCleanWidth(4096);
+ sparams.SetCleanHeight(2160);
+ sparams.SetSignalRange(SIGNAL_RANGE_12BIT_VIDEO);
+ sparams.SetColourSpecification(4);
+ break;
+ case VIDEO_FORMAT_UHDTV_4K60:
+ case VIDEO_FORMAT_UHDTV_4K50:
+ sparams.SetXl(3840);
+ sparams.SetYl(2160);
+ sparams.SetCFormat(format422);
+ sparams.SetSourceSampling(0);
+ switch (vf)
+ {
+ case VIDEO_FORMAT_UHDTV_4K60:
+ sparams.SetFrameRate(FRAMERATE_59p94_FPS);
+ break;
+ case VIDEO_FORMAT_UHDTV_4K50:
+ sparams.SetFrameRate(FRAMERATE_50_FPS);
+ break;
+ default:
+ break;
+ }
+ sparams.SetSignalRange(SIGNAL_RANGE_10BIT_VIDEO);
+ sparams.SetCleanWidth(3840);
+ sparams.SetCleanHeight(2160);
+ sparams.SetColourSpecification(3);
+ break;
+ case VIDEO_FORMAT_UHDTV_8K60:
+ case VIDEO_FORMAT_UHDTV_8K50:
+ sparams.SetXl(7680);
+ sparams.SetYl(4320);
+ sparams.SetCFormat(format422);
+ sparams.SetSourceSampling(0);
+ switch (vf)
+ {
+ case VIDEO_FORMAT_UHDTV_8K60:
+ sparams.SetFrameRate(FRAMERATE_59p94_FPS);
+ break;
+ case VIDEO_FORMAT_UHDTV_8K50:
+ sparams.SetFrameRate(FRAMERATE_50_FPS);
+ break;
+ default:
+ break;
+ }
+ sparams.SetSignalRange(SIGNAL_RANGE_10BIT_VIDEO);
+ sparams.SetCleanWidth(7680);
+ sparams.SetCleanHeight(4320);
+ sparams.SetColourSpecification(3);
+ break;
+ default:
+ errstr << "Unsupported video format " << sparams.GetVideoFormat()
+ << std::endl;
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_VIDEO_FORMAT,
+ errstr.str(),
+ SEVERITY_PICTURE_ERROR);
+ break;
+ }
+}
+
+void SetDefaultEncoderParameters(EncoderParams& encparams)
+{
+ encparams.SetLossless(false);
+ encparams.SetQf(5.5f);
+ encparams.GetPicPredParams().SetMVPrecision(MV_PRECISION_HALF_PIXEL);
+ encparams.SetUsingAC(true);
+
+ switch (encparams.GetVideoFormat())
+ {
+ case VIDEO_FORMAT_4SIF525:
+ case VIDEO_FORMAT_4CIF:
+ case VIDEO_FORMAT_SD_480I60:
+ case VIDEO_FORMAT_SD_576I50:
+ encparams.SetL1Sep(3);
+ encparams.SetNumL1(7);
+ encparams.SetCPD(32.0f);
+ break;
+
+ case VIDEO_FORMAT_HD_720P60:
+ case VIDEO_FORMAT_HD_720P50:
+ encparams.SetL1Sep(3);
+ encparams.SetNumL1(15);
+ encparams.SetCPD(20.0f);
+ break;
+
+ case VIDEO_FORMAT_HD_1080I60:
+ case VIDEO_FORMAT_HD_1080I50:
+ case VIDEO_FORMAT_HD_1080P60:
+ case VIDEO_FORMAT_HD_1080P50:
+ encparams.SetL1Sep(3);
+ encparams.SetNumL1(7);
+ encparams.SetCPD(32.0f);
+ break;
+ case VIDEO_FORMAT_UHDTV_4K60:
+ case VIDEO_FORMAT_UHDTV_4K50:
+ case VIDEO_FORMAT_UHDTV_8K60:
+ case VIDEO_FORMAT_UHDTV_8K50:
+ encparams.SetL1Sep(6);
+ encparams.SetNumL1(7);
+ encparams.SetCPD(48.0f);
+ break;
+ case VIDEO_FORMAT_CIF:
+ default:
+ encparams.SetL1Sep(3);
+ encparams.SetNumL1(19);
+ encparams.SetCPD(20.0f);
+ break;
+ }
+
+}
+
+void SetDefaultBlockParameters(OLBParams& bparams,
+ const VideoFormat& video_format)
+{
+ switch (video_format)
+ {
+ case VIDEO_FORMAT_QCIF:
+ case VIDEO_FORMAT_QSIF525:
+ case VIDEO_FORMAT_CUSTOM:
+ case VIDEO_FORMAT_SIF525:
+ case VIDEO_FORMAT_CIF:
+ case VIDEO_FORMAT_4SIF525:
+ case VIDEO_FORMAT_4CIF:
+ case VIDEO_FORMAT_SD_480I60:
+ case VIDEO_FORMAT_SD_576I50:
+ bparams.SetXblen(12);
+ bparams.SetYblen(12);
+ bparams.SetXbsep(8);
+ bparams.SetYbsep(8);
+ break;
+
+ case VIDEO_FORMAT_HD_720P60:
+ case VIDEO_FORMAT_HD_720P50:
+ bparams.SetXblen(16);
+ bparams.SetYblen(16);
+ bparams.SetXbsep(12);
+ bparams.SetYbsep(12);
+ break;
+
+ case VIDEO_FORMAT_HD_1080I60:
+ case VIDEO_FORMAT_HD_1080I50:
+ case VIDEO_FORMAT_HD_1080P60:
+ case VIDEO_FORMAT_HD_1080P50:
+ case VIDEO_FORMAT_DIGI_CINEMA_2K24:
+ case VIDEO_FORMAT_DIGI_CINEMA_4K24:
+ bparams.SetXblen(24);
+ bparams.SetYblen(24);
+ bparams.SetXbsep(16);
+ bparams.SetYbsep(16);
+ break;
+ case VIDEO_FORMAT_UHDTV_4K60:
+ case VIDEO_FORMAT_UHDTV_4K50:
+ case VIDEO_FORMAT_UHDTV_8K60:
+ case VIDEO_FORMAT_UHDTV_8K50:
+ bparams.SetXblen(36);
+ bparams.SetYblen(36);
+ bparams.SetXbsep(24);
+ bparams.SetYbsep(24);
+ break;
+ default:
+ bparams.SetXblen(12);
+ bparams.SetYblen(12);
+ bparams.SetXbsep(8);
+ bparams.SetYbsep(8);
+ break;
+ }
+}
+
+void SetDefaultBlockParameters(OLBParams& bparams, int pidx)
+{
+ switch (pidx)
+ {
+ case 0: // custom - so undefined values
+ return;
+ case 1:
+ bparams = OLBParams(8, 8, 4, 4);
+ break;
+ case 2:
+ bparams = OLBParams(12, 12, 8, 8);
+ break;
+ case 3:
+ bparams = OLBParams(16, 16, 12, 12);
+ break;
+ case 4:
+ bparams = OLBParams(24, 24, 16, 16);
+ break;
+ default:
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ "Block params index out of range [0-4]",
+ SEVERITY_PICTURE_ERROR);
+ break;
+ }
+}
+
+unsigned int BlockParametersIndex (const OLBParams& bparams)
+{
+ OLBParams bparams_1(8, 8, 4, 4);
+ OLBParams bparams_2(12, 12, 8, 8);
+ OLBParams bparams_3(16, 16, 12, 12);
+ OLBParams bparams_4(24, 24, 16, 16);
+
+ if (bparams == bparams_1)
+ return 1;
+ else if (bparams == bparams_2)
+ return 2;
+ else if (bparams == bparams_3)
+ return 3;
+ else if (bparams == bparams_4)
+ return 4;
+ else
+ return 0;
+}
+
+void SetDefaultTransformFilter(const PictureType ptype, const VideoFormat video_format,
+ WltFilter &wf)
+{
+ switch (video_format)
+ {
+ case VIDEO_FORMAT_QCIF:
+ case VIDEO_FORMAT_QSIF525:
+ case VIDEO_FORMAT_CUSTOM:
+ case VIDEO_FORMAT_SIF525:
+ case VIDEO_FORMAT_CIF:
+ case VIDEO_FORMAT_4SIF525:
+ case VIDEO_FORMAT_4CIF:
+ case VIDEO_FORMAT_SD_480I60:
+ case VIDEO_FORMAT_SD_576I50:
+ case VIDEO_FORMAT_HD_720P60:
+ case VIDEO_FORMAT_HD_720P50:
+ case VIDEO_FORMAT_HD_1080I60:
+ case VIDEO_FORMAT_HD_1080I50:
+ case VIDEO_FORMAT_HD_1080P60:
+ case VIDEO_FORMAT_HD_1080P50:
+ case VIDEO_FORMAT_DIGI_CINEMA_2K24:
+ case VIDEO_FORMAT_DIGI_CINEMA_4K24:
+ case VIDEO_FORMAT_UHDTV_4K60:
+ case VIDEO_FORMAT_UHDTV_4K50:
+ case VIDEO_FORMAT_UHDTV_8K60:
+ case VIDEO_FORMAT_UHDTV_8K50:
+ default:
+ if (ptype == INTRA_PICTURE)
+ wf = DD13_7;
+ else
+ wf = DD13_7;
+ break;
+ }
+}
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.h
new file mode 100644
index 000000000..97426a833
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/video_format_defaults.h
@@ -0,0 +1,102 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: video_format_defaults.h,v 1.7 2008/10/01 00:26:20 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Andrew Kennedy (Original Author),
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/**
+* Returns structures containing default parameter values for different video-formats
+*/
+#ifndef video_format_defaults_h
+#define video_format_defaults_h
+
+//LOCAL INCLUDES
+#include <libdirac_common/common.h> // SeqParams
+
+namespace dirac
+{
+ /**
+ * Sets default codec parameters - common to encoder and decoder
+ *@param cparams Codec Params objects for setting defaults
+ *@param ptype Picture type i,e, INTRA or INTER
+ *@param num_refs Number of reference frames
+ */
+ void SetDefaultCodecParameters (CodecParams &cparams, PictureType ptype, unsigned int num_refs);
+
+ /**
+ * Sets default encoder parameters
+ *@param encparams Params objects for setting defaults
+ */
+ void SetDefaultEncoderParameters(EncoderParams& encparams);
+
+ /**
+ * Sets default Source parameters
+ *@param vf Video Format
+ *@param sparams Params object for setting defaults
+ */
+ void SetDefaultSourceParameters(const VideoFormat &vf, SourceParams& sparams);
+
+ /**
+ * Sets default block parameters
+ *@param bparams Params object for setting defaults
+ *@param video_format Video format
+ */
+ void SetDefaultBlockParameters(OLBParams& bparams,
+ const VideoFormat& video_format);
+
+ /**
+ * Sets default block parameters
+ *@param bparams Params object for setting defaults
+ *@param pidx Index into Block Parameters table
+ */
+ void SetDefaultBlockParameters(OLBParams& bparams,
+ int pidx);
+ /**
+ * Returns index of block parameters in Defaults table
+ *@param bparams Params object for getting index
+ */
+ unsigned int BlockParametersIndex(const OLBParams& bparams);
+
+ /**
+ * Sets the default Transform filter depending on picture type
+ *@param ptype Picture type i.e. intra or inter
+ *@param video_format The video format
+ *@param wf WltFilter object for getting the default wavelet filter
+ */
+ void SetDefaultTransformFilter( const PictureType ptype, const VideoFormat video_format,
+ WltFilter &wf);
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.cpp
new file mode 100644
index 000000000..43f95e787
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.cpp
@@ -0,0 +1,1570 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: wavelet_utils.cpp,v 1.44 2008/10/20 04:21:02 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/wavelet_utils.h>
+#include <libdirac_common/common.h>
+#include <cstdlib>
+
+using namespace dirac;
+
+// Default constructor
+CodeBlock::CodeBlock()
+:
+ m_skipped( false ){
+ Init( 0 , 0 , 0 , 0 );
+}
+
+// Constructor
+CodeBlock::CodeBlock( const int xstart ,
+ const int ystart ,
+ const int xend ,
+ const int yend)
+:
+ m_skipped( false )
+{
+ Init( xstart , ystart , xend , yend );
+}
+
+// Initialises the code block
+void CodeBlock::Init( const int xstart ,
+ const int ystart ,
+ const int xend ,
+ const int yend ){
+ m_xstart = xstart;
+ m_xend = xend;
+ m_ystart = ystart;
+ m_yend= yend;
+
+ m_xl = xend - xstart;
+ m_yl = yend - ystart;
+}
+
+
+// Default constructor
+Subband::Subband(){
+ // this space intentionally left blank
+}
+
+// Constructor
+Subband::Subband(int xpos,int ypos, int xlen, int ylen):
+ m_xp( xpos ),
+ m_yp( ypos ),
+ m_xl( xlen ),
+ m_yl( ylen ),
+ m_wt( 1.0 ),
+ m_code_block_array(),
+ m_skipped( false ){
+ SetNumBlocks( 1 , 1 );
+}
+
+// Constructor
+Subband::Subband(int xpos,int ypos, int xlen, int ylen, int d)
+ :
+ m_xp( xpos ),
+ m_yp( ypos ),
+ m_xl( xlen ),
+ m_yl( ylen ),
+ m_wt( 1.0 ),
+ m_depth( d ),
+ m_code_block_array(),
+ m_skipped( false )
+{
+ SetNumBlocks( 1 , 1 );
+}
+
+void Subband::SetWt( const float w )
+{
+ m_wt = w;
+}
+
+void Subband::SetNumBlocks( const int ynum , const int xnum){
+ m_code_block_array.Resize( ynum , xnum );
+
+ OneDArray<int> xbounds( xnum + 1 );
+ OneDArray<int> ybounds( ynum + 1 );
+
+ for (int i=0; i<=xnum ; ++i)
+ {
+ xbounds[i] = ( i * m_xl )/xnum + m_xp;
+ }// i
+
+ for (int j=0; j<=ynum ; ++j)
+ {
+ ybounds[j] = ( j * m_yl )/ynum + m_yp;
+ }// j
+
+ for (int j=0; j<m_code_block_array.LengthY() ; ++j)
+ for (int i=0; i<m_code_block_array.LengthX() ; ++i)
+ m_code_block_array[j][i].Init( xbounds[i] , ybounds[j] ,
+ xbounds[i+1] , ybounds[j+1] );
+
+}
+
+//! Destructor
+Subband::~Subband(){}
+
+//subband list methods
+
+void SubbandList::Init(const int depth,const int xlen,const int ylen){
+ int xl=xlen;
+ int yl=ylen;
+
+ Clear();
+ Subband* tmp;
+
+ for (int level = 1; level <= depth; ++level){
+ xl/=2;
+ yl/=2;
+ /* HH */
+ tmp=new Subband( xl , yl , xl , yl , level);
+ AddBand( *tmp );
+ delete tmp;
+
+ /* LH */
+ tmp=new Subband( 0 , yl , xl , yl , level);
+ AddBand( *tmp );
+ delete tmp;
+
+ /* HL */
+ tmp=new Subband(xl , 0 , xl , yl , level);
+ AddBand( *tmp );
+ delete tmp;
+
+ if (level == depth){
+ /* LL */
+ tmp=new Subband( 0 , 0 , xl , yl , level);
+ AddBand( *tmp );
+ delete tmp;
+ }
+ }
+ //now set the parent-child relationships
+ int len = bands.size();
+ (*this)(len).SetParent(0);
+ (*this)(len-3).SetParent(0);
+ (*this)(len-2).SetParent(0);
+ (*this)(len-1).SetParent(0);
+
+ for (int level = 2; level <= depth; ++level){
+ //do parent-child relationship for other bands
+ (*this)( len-3*(level) ).SetParent( len-3*(level-1) );
+ (*this)(len-3*(level)+1).SetParent(len-3*(level-1)+1);
+ (*this)(len-3*(level)+2).SetParent(len-3*(level-1)+2);
+ }// level
+
+}
+
+void CoeffArray::SetBandWeights (const EncoderParams& encparams,
+ const PictureParams& pparams,
+ const CompSort csort,
+ const float cpd_scale_factor)
+{
+ const WltFilter wltfilter = encparams.TransformFilter();
+ const bool field_coding = encparams.FieldCoding();
+ const ChromaFormat cformat = pparams.CFormat();
+ const float cpd = encparams.CPD()*cpd_scale_factor;
+ const PictureSort psort = pparams.PicSort();
+
+ int xlen, ylen, xl, yl, xp, yp;
+ float xfreq, yfreq;
+ float temp(0.0);
+
+ // Compensate for chroma subsampling
+ float chroma_xfac(1.0);
+ float chroma_yfac(1.0);
+
+ if( csort != Y_COMP)
+ {
+ if( cformat == format422)
+ {
+ chroma_xfac = 2.0;
+ chroma_yfac = 1.0;
+ }
+ else if( cformat == format420 )
+ {
+ chroma_xfac = 2.0;
+ chroma_yfac = 2.0;
+ }
+
+ }
+
+ xlen = 2 * m_band_list(1).Xl();
+ ylen = 2 * m_band_list(1).Yl();
+
+ if (cpd != 0.0)
+ {
+ for( int i = 1; i<=m_band_list.Length() ; i++ )
+ {
+ xp = m_band_list(i).Xp();
+ yp = m_band_list(i).Yp();
+ xl = m_band_list(i).Xl();
+ yl = m_band_list(i).Yl();
+
+
+ xfreq = cpd * ( float(xp) + (float(xl)/2.0) ) / float(xlen);
+ yfreq = cpd * ( float(yp) + (float(yl)/2.0) ) / float(ylen);
+
+ if(field_coding)
+ yfreq/=2.0;
+
+ temp = PerceptualWeight( xfreq/chroma_xfac , yfreq/chroma_yfac , csort );
+
+ m_band_list(i).SetWt(temp);
+ }// i
+
+ // Make sure dc is always the lowest weight
+ float min_weight=m_band_list(m_band_list.Length()).Wt();
+
+ for( int b=1 ; b<=m_band_list.Length()-1 ; b++ )
+ min_weight = ((min_weight>m_band_list(b).Wt()) ? m_band_list(b).Wt() : min_weight);
+
+ m_band_list( m_band_list.Length() ).SetWt( min_weight );
+
+ // Now normalize weights so that white noise is always weighted the same
+
+ // Overall factor to ensure that white noise ends up with the same RMS, whatever the weight
+ double overall_factor=0.0;
+ //fraction of the total number of samples belonging to each subband
+ double subband_fraction;
+
+ for( int i=1 ; i<=m_band_list.Length() ; i++ )
+ {
+ subband_fraction = 1.0/((double) m_band_list(i).Scale() * m_band_list(i).Scale());
+ overall_factor += subband_fraction/( m_band_list(i).Wt() * m_band_list(i).Wt() );
+ }
+ overall_factor = std::sqrt( overall_factor );
+
+ //go through and normalise
+
+ for( int i=m_band_list.Length() ; i>0 ; i-- )
+ m_band_list(i).SetWt( m_band_list(i).Wt() * overall_factor );
+ }
+ else
+ {//cpd=0 so set all weights to 1
+
+ for( int i=1 ; i<=m_band_list.Length() ; i++ )
+ m_band_list(i).SetWt( 1.0 );
+
+ }
+
+ //Finally, adjust to compensate for the absence of scaling in the transform
+ //Factor used to compensate:
+ double lfac;
+ double hfac;
+ int filt_shift;
+
+ switch (wltfilter){
+ case DD9_7 :
+ lfac = 1.218660804;;
+ hfac = 0.780720058;
+ filt_shift = 1;
+
+ break;
+
+ case LEGALL5_3 :
+ lfac = 1.179535649;
+ hfac = 0.81649658;
+ filt_shift = 1;
+
+ break;
+
+ case DD13_7 :
+ lfac = 1.235705971;
+ hfac = 0.780719354;
+ filt_shift = 1;
+
+ break;
+
+ case HAAR0 :
+ lfac = 1.414213562;
+ hfac = 0.707106781;
+ filt_shift = 0;
+
+ break;
+
+ case HAAR1 :
+ lfac = 1.414213562;
+ hfac = 0.707106781;
+ filt_shift = 1;
+
+ break;
+
+ case DAUB9_7 :
+ lfac = 1.149604398;
+ hfac = 0.869864452;
+ filt_shift = 1;
+
+ break;
+
+ default:
+ lfac = 1.0;
+ hfac = 1.0;
+ filt_shift = 0;
+
+ }
+
+
+ int idx;
+ int shift;
+ int depth = (m_band_list.Length()-1)/3;
+
+ // Do the DC subband
+ idx = m_band_list.Length();
+ double cf = (1<<(depth*filt_shift)) / std::pow(lfac,2*depth ) ;
+
+ m_band_list(idx).SetWt( m_band_list(idx).Wt()*cf);
+
+ // Do the non-DC subbands
+ for (int level=1; level<=depth; level++)
+ {
+ shift = (depth-level+1)*filt_shift;
+ for ( int orient=3;orient>=1; --orient )
+ {
+ idx = 3*(depth-level)+orient;
+
+ // index into the subband list
+ idx = 3*(depth-level)+orient;
+
+ // Divide through by the weight for the LF subband that was decomposed
+ // to create this level
+ cf = 1.0/ std::pow(lfac,2*(depth-level) );
+
+ if ( m_band_list(idx).Xp() != 0 && m_band_list(idx).Yp() != 0)
+ // HH subband
+ cf /= (hfac * hfac);
+ else
+ // LH or HL subband
+ cf /= (lfac * hfac);
+
+ cf *= double(1<<shift);
+
+ m_band_list(idx).SetWt( m_band_list(idx).Wt()*cf );
+
+ }// orient
+ }//level
+
+
+}
+
+// Returns a perceptual noise weighting based on extending CCIR 959 values
+// assuming a two-d isotropic response. Also has a fudge factor of 20% for chroma
+float CoeffArray::PerceptualWeight( const float xf ,
+ const float yf ,
+ const CompSort cs )
+{
+ double freq_sqd( xf*xf + yf*yf );
+
+ if ( cs != Y_COMP )
+ freq_sqd *= 1.2;
+
+ return 0.255 * std::pow( 1.0 + 0.2561*freq_sqd , 0.75) ;
+
+}
+
+
+
+//wavelet transform methods
+///////////////////////////
+
+//public methods
+
+WaveletTransform::WaveletTransform(int d, WltFilter f)
+ : m_depth(d),
+ m_filt_sort(f)
+{
+ switch( m_filt_sort ){
+
+ case DD9_7 :
+ m_vhfilter = new VHFilterDD9_7;
+ break;
+
+ case LEGALL5_3 :
+ m_vhfilter = new VHFilterLEGALL5_3;
+ break;
+
+ case DD13_7 :
+ m_vhfilter = new VHFilterDD13_7;
+ break;
+
+ case HAAR0 :
+ m_vhfilter = new VHFilterHAAR0;
+ break;
+
+ case HAAR1 :
+ m_vhfilter = new VHFilterHAAR1;
+ break;
+
+ default :
+ m_vhfilter = new VHFilterDAUB9_7;
+ }
+}
+
+//! Destructor
+WaveletTransform::~WaveletTransform(){ delete m_vhfilter; }
+
+void WaveletTransform::Transform(const Direction d, PicArray& pic_data, CoeffArray& coeff_data) {
+
+ int xl,yl;
+
+ SubbandList& bands = coeff_data.BandList();
+
+ if (d == FORWARD){
+ xl=coeff_data.LengthX();
+ yl=coeff_data.LengthY();
+
+ // First copy picture data into coeff_data and pad
+ for ( int j=0; j<pic_data.LengthY(); ++j){
+ for ( int i=0; i<pic_data.LengthX(); ++i)
+ coeff_data[j][i] = CoeffType( pic_data[j][i] );
+ for ( int i=pic_data.LengthX(); i<coeff_data.LengthX(); ++i)
+ coeff_data[j][i] = coeff_data[j][pic_data.LastX()];
+ }// j
+ for ( int j=pic_data.LengthY(); j<coeff_data.LengthY(); ++j){
+ for ( int i=0; i<coeff_data.LengthX(); ++i)
+ coeff_data[j][i] = coeff_data[pic_data.LastY()][i];
+ }
+
+ for (int l = 1; l <= m_depth; ++l , xl>>=1 , yl>>=1){
+ m_vhfilter->Split(0,0,xl,yl,coeff_data);
+ }
+
+ bands.Init( m_depth , coeff_data.LengthX() , coeff_data.LengthY() );
+ }
+ else{
+ xl = coeff_data.LengthX()/(1<<(m_depth-1));
+ yl = coeff_data.LengthY()/(1<<(m_depth-1));
+
+ for (int l = 1; l <= m_depth; ++l, xl<<=1 , yl<<=1 )
+ m_vhfilter->Synth(0,0,xl,yl,coeff_data);
+
+ //band list now inaccurate, so clear
+ bands.Clear();
+
+ // Lastly, copy coeff_data back into picture data
+ for ( int j=0; j<pic_data.LengthY(); ++j){
+ for ( int i=0; i<pic_data.LengthX(); ++i){
+ pic_data[j][i] = ValueType( coeff_data[j][i] );
+ }// i
+ }// j
+ }
+}
+
+// Private functions //
+///////////////////////
+// NOTEL MMX version is defined in wavelet_utils_mmx.cpp
+// the corresponding changes are made in wavelet_utils_mmx.cpp as well
+void VHFilter::Interleave( const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ TwoDArray<CoeffType> temp_data( yl , xl );
+ const int xl2( xl>>1);
+ const int yl2( yl>>1);
+ const int yend( yp + yl );
+
+ // Make a temporary copy of the subband
+ for (int j = yp; j<yend ; j++ )
+ memcpy( temp_data[j-yp] , coeff_data[j]+xp , xl * sizeof( CoeffType ) );
+
+ // Re-order to interleave
+ for (int j = 0, s=yp; j<yl2 ; j++, s+=2)
+ {
+ for (int i = 0 , r=xp ; i<xl2 ; i++ , r += 2)
+ coeff_data[s][r] = temp_data[j][i];
+ for (int i = xl2, r=xp+1; i<xl ; i++ , r += 2)
+ coeff_data[s][r] = temp_data[j][i];
+ }// j
+
+ for (int j = yl2, s=yp+1 ; j<yl ; j++ , s += 2)
+ {
+ for (int i = 0 , r=xp ; i<xl2 ; i++ , r += 2)
+ coeff_data[s][r] = temp_data[j][i];
+ for (int i = xl2, r=xp+1; i<xl ; i++ , r += 2)
+ coeff_data[s][r] = temp_data[j][i];
+ }// j
+
+}
+
+#if !defined(HAVE_MMX)
+void VHFilter::ShiftRowLeft(CoeffType *row, int length, int shift)
+{
+ for (int i = 0; i < length; ++i)
+ row[i] <<= shift;
+}
+
+void VHFilter::ShiftRowRight(CoeffType *row, int length, int shift)
+{
+ const CoeffType halfway( 1<<(shift-1) );
+ for (int i = 0; i < length; ++i)
+ row[i] = ((row[i]+halfway)>>shift);
+}
+#endif
+
+void VHFilter::DeInterleave( const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ TwoDArray<CoeffType> temp_data( yl , xl );
+ const int xl2( xl>>1);
+ const int yl2( yl>>1);
+ const int xend( xp + xl );
+ const int yend( yp + yl );
+
+ // Make a temporary copy of the subband
+ for (int j = yp; j<yend ; j++ )
+ memcpy( temp_data[j-yp] , coeff_data[j]+xp , xl * sizeof( CoeffType ) );
+
+ // Re-order to de-interleave
+ for (int j = yp, s=0; j<yp+yl2 ; j++, s+=2)
+ {
+ for (int i = xp , r=0 ; i<xp+xl2 ; i++ , r += 2)
+ coeff_data[j][i] = temp_data[s][r];
+ for (int i = xp+xl2, r=1; i<xend ; i++ , r += 2)
+ coeff_data[j][i] = temp_data[s][r];
+ }// j
+
+ for (int j = yp+yl2, s=1 ; j<yend ; j++ , s += 2)
+ {
+ for (int i = xp , r=0 ; i<xp+xl2 ; i++ , r += 2)
+ coeff_data[j][i] = temp_data[s][r];
+ for (int i = xp+xl2, r=1; i<xend ; i++ , r += 2)
+ coeff_data[j][i] = temp_data[s][r];
+ }// j
+
+}
+
+void VHFilterDAUB9_7::Split (const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ CoeffType* line_data;
+
+ // Positional variables
+ int i,j,k;
+
+ // Objects to do lifting stages
+ // (in revese order and type from synthesis)
+ const PredictStep97< 6497 > predictA;
+ const PredictStep97< 217 > predictB;
+ const UpdateStep97< 3616 > updateA;
+ const UpdateStep97< 1817 > updateB;
+
+ //first do horizontal
+
+ for (j = yp; j < yend; ++j)
+ {
+ // First lifting stage
+ line_data = coeff_data[j];
+ // Shift left by one bit to give us more accuracy
+ ShiftRowLeft(line_data, xl, 1);
+
+ predictA.Filter( line_data[xp+1] , line_data[xp+2] , line_data[xp] );
+ predictB.Filter( line_data[xp] , line_data[xp+1] , line_data[xp+1] );
+
+ for ( k = xp+3; k < xend-1; k+=2)
+ {
+ predictA.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ predictB.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ }// i
+
+ predictA.Filter( line_data[xend-1] , line_data[xend-2] , line_data[xend-2] );
+ predictB.Filter( line_data[xend-2] , line_data[xend-3] , line_data[xend-1] );
+
+
+ //second lifting stage
+
+ updateA.Filter( line_data[xp+1] , line_data[xp+2] , line_data[xp] );
+ updateB.Filter( line_data[xp] , line_data[xp+1] , line_data[xp+1] );
+
+ for ( k = xp+3; k < xend-1; k+=2)
+ {
+ updateA.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ updateB.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ }// i
+
+ updateA.Filter( line_data[xend-1] , line_data[xend-2] , line_data[xend-2] );
+ updateB.Filter( line_data[xend-2] , line_data[xend-3] , line_data[xend-1] );
+
+ }// j
+
+ // next do vertical
+
+ // First lifting stage
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predictA.Filter( coeff_data[yp+1][i] , coeff_data[yp+2][i] , coeff_data[yp][i] );
+ predictB.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ }// i
+
+ // middle bit
+ for ( k = yp+3 ; k<yend-1 ; k+=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predictA.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ predictB.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ }// i
+ }// j
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predictA.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ predictB.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ }// i
+
+ // Second lifting stage
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ updateA.Filter( coeff_data[yp+1][i] , coeff_data[yp+2][i] , coeff_data[yp][i] );
+ updateB.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ }// i
+
+ // middle bit
+ for ( k = yp+3 ; k<yend-1 ; k+=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ updateA.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ updateB.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ }// i
+ }// j
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ updateA.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ updateB.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ }// i
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp ,yp ,xl ,yl , coeff_data );
+
+}
+
+void VHFilterDAUB9_7::Synth (const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+
+ int i,j,k;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ const PredictStep97< 1817 > predictB;
+ const PredictStep97< 3616 > predictA;
+ const UpdateStep97< 217 > updateB;
+ const UpdateStep97< 6497 > updateA;
+
+ CoeffType* line_data;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl , yl , coeff_data );
+
+ // Next, do the vertical synthesis
+ // First lifting stage
+
+ // Begin with the bottom edge
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predictB.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ predictA.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ }// i
+ // Next, do the middle bit
+ for ( k = yend-3 ; k>yp+1 ; k-=2)
+ {
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predictB.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ predictA.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ }// i
+ }// j
+ // Then do the top edge
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predictB.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ predictA.Filter( coeff_data[yp+1][i] , coeff_data[yp+2][i] , coeff_data[yp][i] );
+ }// i
+
+ // Second lifting stage
+
+ // Begin with the bottom edge
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ updateB.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ updateA.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ }// i
+ // Next, do the middle bit
+ for ( k = yend-3 ; k>yp+1 ; k-=2)
+ {
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ updateB.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ updateA.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ }// i
+ }// j
+ // Then do the top edge
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ updateB.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ updateA.Filter( coeff_data[yp+1][i] , coeff_data[yp+2][i] , coeff_data[yp][i] );
+ }// i
+
+
+ // Next do the horizontal synthesis
+ for (j = yend-1; j >= yp ; --j)
+ {
+ // First lifting stage
+ line_data = coeff_data[j];
+
+ predictB.Filter( line_data[xend-2] , line_data[xend-3] , line_data[xend-1] );
+ predictA.Filter( line_data[xend-1] , line_data[xend-2] , line_data[xend-2] );
+
+ for ( k = xend-3; k > xp+1; k-=2)
+ {
+ predictB.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ predictA.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ }// i
+
+ predictB.Filter( line_data[xp] , line_data[xp+1] , line_data[xp+1] );
+ predictA.Filter( line_data[xp+1] , line_data[xp+2] , line_data[xp] );
+
+ // Second lifting stage
+
+ updateB.Filter( line_data[xend-2] , line_data[xend-3] , line_data[xend-1] );
+ updateA.Filter( line_data[xend-1] , line_data[xend-2] , line_data[xend-2] );
+
+ for ( k = xend-3; k > xp+1; k-=2)
+ {
+ updateB.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ updateA.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ }// i
+
+ updateB.Filter( line_data[xp] , line_data[xp+1] , line_data[xp+1] );
+ updateA.Filter( line_data[xp+1] , line_data[xp+2] , line_data[xp] );
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+
+ }
+
+}
+
+#if !defined HAVE_MMX
+// NOTE: MMX version is defined in wavelet_utils_mmx.cpp
+// the corresponding changes are made in wavelet_utils_mmx.cpp as well
+void VHFilterLEGALL5_3::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ CoeffType* line_data;
+
+ // Positional variables
+ int i,j,k;
+
+ // Objects to do lifting stages
+ // (in revese order and type from synthesis)
+ const PredictStepShift< 1 > predict;
+ const UpdateStepShift< 2 > update;
+
+ //first do horizontal
+
+ for (j = yp; j < yend; ++j)
+ {
+ // First lifting stage
+ line_data = &coeff_data[j][xp];
+ // Shift left by one bit to give us more accuracy
+ ShiftRowLeft(line_data, xl, 1);
+
+ predict.Filter( line_data[1] , line_data[2] , line_data[0] );
+ update.Filter( line_data[0] , line_data[1] , line_data[1] );
+
+ for (k = 3; k < xl-1; k+=2)
+ {
+ predict.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ update.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ }// i
+
+ predict.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] );
+ update.Filter( line_data[xl-2] , line_data[xl-3] , line_data[xl-1] );
+
+ }// j
+
+ // next do vertical
+
+ // First lifting stage
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+1][i] , coeff_data[yp+2][i] , coeff_data[yp][i] );
+ update.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ }// i
+
+ // middle bit
+ for (k = yp+3 ; k<yend-1 ; k+=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ update.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ }// i
+ }// j
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ update.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ }// i
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp , yp , xl , yl , coeff_data );
+}
+
+
+// NOTE: MMX version is defined in wavelet_utils_mmx.cpp
+// the corresponding changes are made in wavelet_utils_mmx.cpp as well
+void VHFilterLEGALL5_3::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ int i,j,k;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ const PredictStepShift< 2 > predict;
+ const UpdateStepShift< 1 > update;
+
+ CoeffType* line_data;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl , yl , coeff_data );
+
+ // Next, do the vertical synthesis
+ // First lifting stage
+
+ // Begin with the bottom edge
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predict.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ update.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ }// i
+ // Next, do the middle bit
+ for ( k = yend-3 ; k>yp+1 ; k-=2)
+ {
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predict.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ update.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ }// i
+ }// j
+ // Then do the top edge
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predict.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ update.Filter( coeff_data[yp+1][i] , coeff_data[yp+2][i] , coeff_data[yp][i] );
+ }// i
+
+ // Next do the horizontal synthesis
+ for (j = yend-1; j >= yp ; --j)
+ {
+ // First lifting stage
+ line_data = &coeff_data[j][xp];
+
+ predict.Filter( line_data[xl-2] , line_data[xl-3] , line_data[xl-1] );
+ update.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] );
+
+ for ( k = xl-3; k > 1; k-=2)
+ {
+ predict.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ update.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ }// i
+
+ predict.Filter( line_data[0] , line_data[1] , line_data[1] );
+ update.Filter( line_data[1] , line_data[2] , line_data[0] );
+
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+
+ }
+
+}
+#endif
+
+void VHFilterDD9_7::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ CoeffType* line_data;
+
+ // Positional variables
+ int i,j,k;
+
+ PredictStepFourTap< 4 , 9 , -1 > predict;
+ UpdateStepShift< 2 > update;
+
+ //first do horizontal
+
+ for (j = yp; j < yend; ++j)
+ {
+ line_data = &coeff_data[j][xp];
+ // Shift left by one bit to give us more accuracy
+ ShiftRowLeft(line_data, xl, 1);
+
+ // First lifting stage
+ predict.Filter( line_data[1] , line_data[0] , line_data[2] , line_data[0] , line_data[4] );
+ for (k=3 ; k<xl-3 ; k+=2)
+ {
+ predict.Filter( line_data[k] , line_data[k-1] , line_data[k+1] , line_data[k-3] , line_data[k+3] );
+ }// i
+ predict.Filter( line_data[xl-3] , line_data[xl-4] , line_data[xl-2] , line_data[xl-6] , line_data[xl-2] );
+ predict.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] , line_data[xl-4] , line_data[xl-2] );
+
+ //Second lifting stage
+
+ update.Filter( line_data[0] , line_data[1] , line_data[1] );
+ for (i=2 ; i<xl-1 ; i+=2 )
+ {
+ update.Filter( line_data[i] , line_data[i-1] , line_data[i+1] );
+ }// i
+
+ }// j
+
+ // next do vertical
+
+ // First lifting stage
+ // top line
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+1][i] , coeff_data[yp][i] , coeff_data[yp+2][i] , coeff_data[yp][i] , coeff_data[yp+4][i] );
+ }// i
+
+ // middle bit
+ for ( k = yp+3 ; k<yend-3 ; k+=2)
+ {
+ for ( i = xp ; i<xend ; ++i)
+ {
+ predict.Filter( coeff_data[k][i] , coeff_data[k-1][i] , coeff_data[k+1][i] , coeff_data[k-3][i] , coeff_data[k+3][i] );
+ }// i
+ }// j
+
+ // bottom lines
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yend-3][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] , coeff_data[yend-6][i] , coeff_data[yend-2][i] );
+ predict.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] );
+ }// i
+
+ //Second lifting stage
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+
+ }// i
+ // middle bit
+ for ( j = yp+2 ; j<yend-1 ; j+=2 , k+=2)
+ {
+ for ( i = xp ; i<xend ; ++i)
+ {
+ update.Filter( coeff_data[j][i] , coeff_data[j-1][i] , coeff_data[j+1][i] );
+ }// i
+ }// j
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp , yp , xl , yl , coeff_data );
+
+
+
+}
+
+#if !defined(HAVE_MMX)
+// NOTE: MMX version is defined in wavelet_utils_mmx.cpp
+// the corresponding changes are made in wavelet_utils_mmx.cpp as well
+void VHFilterDD9_7::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ int i,j;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ PredictStepShift<2> predict;
+ UpdateStepFourTap< 4 , 9 , -1> update;
+
+ CoeffType* line_data;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl ,yl , coeff_data );
+
+ // First, do the vertical synthesis
+
+ // First lifting stage
+ // Middle bit
+ for ( j=yend-2 ; j>=yp+2 ; j-=2 )
+ {
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predict.Filter( coeff_data[j][i] , coeff_data[j-1][i] , coeff_data[j+1][i] );
+ }// i
+ }// j
+
+ // top line
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ predict.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ }// i
+
+
+ // Second lifting stage
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+
+ update.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] );
+ update.Filter( coeff_data[yend-3][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] , coeff_data[yend-6][i] , coeff_data[yend-2][i] );
+ }// i
+
+ // middle bit
+ for ( j=yend-5 ; j>=yp+3 ; j-=2)
+ {
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ update.Filter( coeff_data[j][i] , coeff_data[j-1][i] , coeff_data[j+1][i] , coeff_data[j-3][i] , coeff_data[j+3][i] );
+ }// i
+ }// k
+
+ for ( i = xend-1 ; i>=xp ; --i)
+ {
+ update.Filter( coeff_data[yp+1][i] , coeff_data[yp][i] , coeff_data[yp+2][i] , coeff_data[yp][i] , coeff_data[yp+4][i] );
+ }// i
+
+ // Next do the horizontal synthesis
+ for (j = yend-1; j >= yp; --j)
+ {
+ line_data = &coeff_data[j][xp];
+
+ // First lifting stage
+ for (i=xl-2 ; i>=2 ; i-=2)
+ {
+ predict.Filter( line_data[i] , line_data[i-1] , line_data[i+1] );
+ }// i
+ predict.Filter( line_data[0] , line_data[1] , line_data[1] );
+
+ // Second lifting stage
+ update.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] , line_data[xl-4] , line_data[xl-2] );
+ update.Filter( line_data[xl-3] , line_data[xl-4] , line_data[xl-2] , line_data[xl-6] , line_data[xl-2] );
+ for (i=xl-5 ; i>=3 ; i-=2)
+ {
+ update.Filter( line_data[i] , line_data[i-1] , line_data[i+1] , line_data[i-3] , line_data[i+3] );
+ }// i
+ update.Filter( line_data[1] , line_data[0] , line_data[2] , line_data[0] , line_data[4] );
+
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+
+ }// j
+
+}
+#endif
+
+void VHFilterDD13_7::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ PredictStepFourTap< 4 , 9 , -1 > predict;
+ UpdateStepFourTap< 5 , 9 , -1> update;
+
+ CoeffType* line_data;
+
+ // Positional variables
+ int i,j,k;
+
+ //first do horizontal
+
+ for (j = yp; j < yend; ++j)
+ {
+ line_data = &coeff_data[j][xp];
+ // Shift left by one bit to give us more accuracy
+ ShiftRowLeft(line_data, xl, 1);
+
+ // First lifting stage
+ predict.Filter( line_data[1] , line_data[0] ,line_data[2] , line_data[0] , line_data[4] );
+ for (k=3 ; k<xl-3 ; k+=2)
+ {
+ predict.Filter( line_data[k] , line_data[k-1] , line_data[k+1] , line_data[k-3] , line_data[k+3] );
+ }// i
+
+ predict.Filter( line_data[xl-3] , line_data[xl-4] , line_data[xl-2] , line_data[xl-6] , line_data[xl-2] );
+ predict.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] , line_data[xl-4] , line_data[xl-2] );
+
+ //second lifting stage
+ update.Filter( line_data[0] , line_data[1] , line_data[1] , line_data[3] , line_data[1] );
+ update.Filter( line_data[2] , line_data[1] , line_data[3] , line_data[5] , line_data[1] );
+ for (k=4 ; k<xl-3 ; k+=2)
+ {
+ update.Filter( line_data[k] , line_data[k-1] , line_data[k+1] , line_data[k-3] , line_data[k+3] );
+ }// i
+
+ update.Filter( line_data[xl-2] , line_data[xl-3] , line_data[xl-1] , line_data[xl-5] , line_data[xl-1] );
+ }// j
+
+ // next do vertical
+
+ // First lifting stage
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+1][i] , coeff_data[yp][i] , coeff_data[yp+2][i] , coeff_data[yp][i] , coeff_data[yp+4][i] );
+ }// i
+
+ // middle bit
+ for ( k = yp+3 ; k<yend-3 ; k+=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[k][i] , coeff_data[k-1][i] , coeff_data[k+1][i] , coeff_data[k-3][i] , coeff_data[k+3][i] );
+ }// i
+ }// j
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yend-3][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] , coeff_data[yend-6][i] , coeff_data[yend-2][i] );
+ predict.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] );
+ }// i
+
+ // Second lifting stage
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] , coeff_data[yp+3][i] , coeff_data[yp+1][i] );
+ update.Filter( coeff_data[yp+2][i] , coeff_data[yp+1][i] , coeff_data[yp+3][i] , coeff_data[yp+5][i] , coeff_data[yp+1][i] );
+ }// i
+
+ // middle bit
+ for ( k = yp+4 ; k<yend-3 ; k+=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[k][i] , coeff_data[k-1][i] , coeff_data[k+1][i] , coeff_data[k-3][i] , coeff_data[k+3][i] );
+ }// i
+ }// j
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] , coeff_data[yend-5][i] , coeff_data[yend-1][i] );
+ }// i
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp , yp , xl , yl , coeff_data );
+}
+
+#if !defined(HAVE_MMX)
+// NOTE: MMX version is defined in wavelet_utils_mmx.cpp
+// the corresponding changes are made in wavelet_utils_mmx.cpp as well
+void VHFilterDD13_7::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ int i,j,k;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ PredictStepFourTap< 5 , 9 , -1 > predict;
+ UpdateStepFourTap< 4 , 9 , -1> update;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl , yl , coeff_data );
+
+ // Next, do the vertical synthesis
+
+ // First lifting stage
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] , coeff_data[yend-5][i] , coeff_data[yend-1][i] );
+ }// i
+
+ // middle bit
+ for ( k = yend-4 ; k>=yp+4 ; k-=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[k][i] , coeff_data[k-1][i] , coeff_data[k+1][i] , coeff_data[k-3][i] , coeff_data[k+3][i] );
+ }// i
+ }// j
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+2][i] , coeff_data[yp+1][i] , coeff_data[yp+3][i] , coeff_data[yp+5][i] , coeff_data[yp+1][i] );
+ predict.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] , coeff_data[yp+3][i] , coeff_data[yp+1][i] );
+
+ }// i
+
+ // Second lifting stage
+ // bottom edge
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] );
+ update.Filter( coeff_data[yend-3][i] , coeff_data[yend-4][i] , coeff_data[yend-2][i] , coeff_data[yend-6][i] , coeff_data[yend-2][i] );
+
+ }// i
+
+ // middle bit
+ for ( k = yend-5 ; k>=yp+3 ; k-=2)
+ {
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[k][i] , coeff_data[k-1][i] , coeff_data[k+1][i] , coeff_data[k-3][i] , coeff_data[k+3][i] );
+ }// i
+ }// j
+
+ // top edge - j=xp
+ for ( i = xp ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[yp+1][i] , coeff_data[yp][i] , coeff_data[yp+2][i] , coeff_data[yp][i] , coeff_data[yp+4][i] );
+ }// i
+
+ // Next do the horizontal synthesis
+
+ CoeffType* line_data;
+
+ for (j = yend-1; j >= yp ; --j)
+ {
+ line_data = &coeff_data[j][xp];
+
+ // First lifting stage
+
+ predict.Filter( line_data[xl-2] , line_data[xl-3] , line_data[xl-1] , line_data[xl-5] , line_data[xl-1] );
+
+ for (k=xl-4 ; k>=4 ; k-=2)
+ {
+ predict.Filter( line_data[k] , line_data[k-1] , line_data[k+1] , line_data[k-3] , line_data[k+3] );
+
+ }// i
+ predict.Filter( line_data[2] , line_data[1] , line_data[3] , line_data[5] , line_data[1] );
+ predict.Filter( line_data[0] , line_data[1] , line_data[1] , line_data[3] , line_data[1] );
+
+ //second lifting stage
+ update.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] , line_data[xl-4] , line_data[xl-2] );
+ update.Filter( line_data[xl-3] , line_data[xl-4] , line_data[xl-2] , line_data[xl-6] , line_data[xl-2] );
+
+ for (k=xl-5 ; k>=3 ; k-=2)
+ {
+ update.Filter( line_data[k] , line_data[k-1] , line_data[k+1] , line_data[k-3] , line_data[k+3] );
+ }// i
+
+ update.Filter( line_data[1] , line_data[0] , line_data[2] , line_data[0] , line_data[4] );
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+
+ }// j
+}
+#endif
+
+void VHFilterHAAR0::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ // first do Horizontal
+ for (int j = yp; j < yend; ++j)
+ {
+ for (int i = xp+1; i < xend; i+=2)
+ {
+ // odd sample
+ // x(2n+1) -= x(2n)
+ coeff_data[j][i] -= coeff_data[j][i-1];
+ // even sample
+ // x(2n) += x(2n+1)/2
+ coeff_data[j][i-1] += ((coeff_data[j][i]+1)>>1);
+ }
+ }
+
+ // next do vertical
+ for (int j = yp+1; j < yend; j+=2)
+ {
+ for (int i = xp; i < xend; ++i)
+ {
+ coeff_data[j][i] -= coeff_data[j-1][i];
+ coeff_data[j-1][i] += ((coeff_data[j][i]+1)>>1);
+ }
+ }
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp , yp , xl , yl , coeff_data );
+}
+
+void VHFilterHAAR0::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl , yl , coeff_data );
+
+ // First do the vertical
+ for (int j = yp+1; j < yend; j+=2)
+ {
+ for (int i = xp; i < xend; ++i)
+ {
+ coeff_data[j-1][i] -= ((coeff_data[j][i]+1)>>1);
+ coeff_data[j][i] += coeff_data[j-1][i];
+ }
+ }
+
+ // Next do the horizontal
+ for (int j = yp; j < yend; ++j)
+ {
+ for (int i = xp+1; i < xend; i+=2)
+ {
+ coeff_data[j][i-1] -= ((coeff_data[j][i]+1)>>1);
+ coeff_data[j][i] += coeff_data[j][i-1];
+ }
+ }
+}
+
+void VHFilterHAAR1::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ CoeffType* line_data;
+
+ // first do Horizontal
+ for (int j = yp; j < yend; ++j)
+ {
+ line_data = &(coeff_data[j][xp]);
+ ShiftRowLeft(line_data, xl, 1);
+ for (int i = xp+1; i < xend; i+=2)
+ {
+ // odd sample
+ // x(2n+1) -= x(2n)
+ coeff_data[j][i] -= coeff_data[j][i-1];
+ // even sample
+ // x(2n) += x(2n+1)/2
+ coeff_data[j][i-1] += ((coeff_data[j][i]+1)>>1);
+ }
+ }
+
+ // next do vertical
+ for (int j = yp+1; j < yend; j+=2)
+ {
+ for (int i = xp; i < xend; ++i)
+ {
+ coeff_data[j][i] -= coeff_data[j-1][i];
+ coeff_data[j-1][i] += ((coeff_data[j][i]+1)>>1);
+ }
+ }
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp , yp , xl , yl , coeff_data );
+}
+
+void VHFilterHAAR1::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ CoeffType* line_data;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl , yl , coeff_data );
+
+ // First do the vertical
+ for (int j = yp+1; j < yend; j+=2)
+ {
+ for (int i = xp; i < xend; ++i)
+ {
+ coeff_data[j-1][i] -= ((coeff_data[j][i]+1)>>1);
+ coeff_data[j][i] += coeff_data[j-1][i];
+ }
+ }
+
+ // Next do the horizontal
+ for (int j = yp; j < yend; ++j)
+ {
+ for (int i = xp+1; i < xend; i+=2)
+ {
+ coeff_data[j][i-1] -= ((coeff_data[j][i]+1)>>1);
+ coeff_data[j][i] += coeff_data[j][i-1];
+ }
+ line_data = &coeff_data[j][xp];
+ ShiftRowRight(line_data, xl, 1);
+ }
+}
+
+void VHFilterHAAR2::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+
+ CoeffType* line_data;
+
+ // first do Horizontal
+ for (int j = yp; j < yend; ++j)
+ {
+ line_data = &coeff_data[j][xp];
+ ShiftRowLeft(line_data, xl, 2);
+ for (int i = xp+1; i < xend; i+=2)
+ {
+ // odd sample
+ // x(2n+1) -= x(2n)
+ coeff_data[j][i] -= coeff_data[j][i-1];
+ // even sample
+ // x(2n) += x(2n+1)/2
+ coeff_data[j][i-1] += ((coeff_data[j][i]+1)>>1);
+ }
+ }
+
+ // next do vertical
+ for (int j = yp+1; j < yend; j+=2)
+ {
+ for (int i = xp; i < xend; ++i)
+ {
+ coeff_data[j][i] -= coeff_data[j-1][i];
+ coeff_data[j-1][i] += ((coeff_data[j][i]+1)>>1);
+ }
+ }
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave( xp , yp , xl , yl , coeff_data );
+}
+
+void VHFilterHAAR2::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ CoeffType* line_data;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations can be in-place
+ Interleave( xp , yp , xl , yl , coeff_data );
+
+ // First do the vertical
+ for (int j = yp+1; j < yend; j+=2)
+ {
+ for (int i = xp; i < xend; ++i)
+ {
+ coeff_data[j-1][i] -= ((coeff_data[j][i]+1)>>1);
+ coeff_data[j][i] += coeff_data[j-1][i];
+ }
+ }
+
+ // Next do the horizontal
+ for (int j = yp; j < yend; ++j)
+ {
+ for (int i = xp+1; i < xend; i+=2)
+ {
+ coeff_data[j][i-1] -= ((coeff_data[j][i]+1)>>1);
+ coeff_data[j][i] += coeff_data[j][i-1];
+ }
+ line_data = &coeff_data[j][xp];
+ ShiftRowRight(line_data, xl, 2);
+ }
+}
+
+
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.h
new file mode 100644
index 000000000..2ca565f3b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils.h
@@ -0,0 +1,731 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: wavelet_utils.h,v 1.32 2008/10/20 04:21:02 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _WAVELET_UTILS_H_
+#define _WAVELET_UTILS_H_
+
+#include <libdirac_common/arrays.h>
+#include <libdirac_common/common.h>
+#include <vector>
+#include <cmath>
+#include <iostream>
+
+//utilities for subband and wavelet transforms
+//Includes fast transform using lifting
+
+namespace dirac
+{
+
+ class PicArray;
+ class Subband;
+
+ //! Class for encapsulating metadata concerning a block of coefficients in a subband
+ class CodeBlock
+ {
+
+ friend class Subband;
+
+ public:
+ //! Constructor
+ /*
+ Default constructor - sets all dimensions to zero
+ */
+ CodeBlock();
+
+ //! Constructor
+ /*
+ Initialise the code block
+ \param xstart the x-coord of the first coefficient in the block
+ \param xend one past the last coefficient, horizontally
+ \param ystart the y-coord of the first coefficient in the block
+ \param yend one past the last coefficient, vertically
+ */
+ CodeBlock( const int xstart , const int ystart , const int xend , const int yend);
+
+ //! Returns the horizontal start of the block
+ int Xstart() const { return m_xstart; }
+
+ //! Returns the vertical start of the block
+ int Ystart() const { return m_ystart; }
+
+ //! Returns one past the last coefficient coord, horizontally
+ int Xend() const { return m_xend; }
+
+ //! Returns one past the last coefficient coord, vertically
+ int Yend() const { return m_yend; }
+
+ //! Returns the width of the code block
+ int Xl() const { return m_xl; }
+
+ //! Returns the height of the code block
+ int Yl() const { return m_yl; }
+
+ //! Returns the quantisation index associated to the code block
+ int QuantIndex() const{ return m_quantindex; }
+
+ //! Returns true if the code-block is skipped, false if not
+ bool Skipped() const { return m_skipped; }
+
+ //! Sets the quantisation index
+ void SetQuantIndex( const int quantindex ){ m_quantindex = quantindex; }
+
+ //! Sets whether the code block is skipped or not
+ void SetSkip( bool skip ){ m_skipped = skip; }
+
+ private:
+
+ //! Initialise the code block
+ /*
+ Initialise the code block
+ \param xstart the x-coord of the first coefficient in the block
+ \param xend one past the last coefficient, horizontally
+ \param ystart the y-coord of the first coefficient in the block
+ \param yend one past the last coefficient, vertically
+ */
+ void Init( const int xstart , const int ystart , const int xend , const int yend );
+
+ private:
+
+ int m_xstart;
+ int m_ystart;
+ int m_xend;
+ int m_yend;
+ int m_xl;
+ int m_yl;
+
+ int m_quantindex;
+
+ bool m_skipped;
+ };
+
+
+ //! Class encapsulating all the metadata relating to a wavelet subband
+ class Subband
+ {
+ public:
+
+ //! Default constructor
+ Subband();
+
+ //! Constructor
+ /*!
+ The constructor parameters are
+ \param xpos the xposition of the subband when packed into a
+ big array with all the others
+ \param ypos the xposition of the subband
+ \param xlen the width of the subband
+ \param ylen the height of the subband
+ */
+ Subband(int xpos, int ypos, int xlen, int ylen);
+
+ //! Constructor
+ /*!
+ The constructor parameters are
+ \param xpos the xposition of the subband when packed into a
+ big array with all the others
+ \param ypos the xposition of the subband
+ \param xlen the width of the subband
+ \param ylen the height of the subband
+ \param d the depth of the subband in the wavelet transform
+ */
+ Subband(int xpos, int ypos, int xlen, int ylen, int d);
+
+ //! Destructor
+ ~Subband();
+
+ //Default (shallow) copy constructor and operator= used
+
+ //! Return the width of the subband
+ int Xl() const {return m_xl;}
+
+ //! Return the horizontal position of the subband
+ int Xp() const {return m_xp;}
+
+ //! Return the height of the subband
+ int Yl() const {return m_yl;}
+
+ //! Return the vertical position of the subband
+ int Yp() const {return m_yp;}
+
+ //! Return the index of the maximum bit of the largest coefficient
+ int Max() const {return m_max_bit;}
+
+ //! Return the subband perceptual weight
+ double Wt() const {return m_wt;}
+
+ //! Return the depth of the subband in the transform
+ int Depth() const {return m_depth;}
+
+ //! Return the scale of the subband, viewed as a subsampled version of the picture
+ int Scale() const {return ( 1<<m_depth );}
+
+ //! Return a quantisation index
+ int QuantIndex() const {return m_qindex;}
+
+ //! Return a flag indicating whether we have separate quantisers for each code block
+ bool UsingMultiQuants() const {return m_multi_quants; }
+
+ //! Return the index of the parent subband
+ int Parent() const {return m_parent;}
+
+ //! Return the indices of any child subbands
+ const std::vector<int>& Children() const {return m_children;}
+
+ //! Return the index of a specific child band
+ int Child(const int n) const {return m_children[n];}
+
+ //! Return the code blocks
+ TwoDArray<CodeBlock>& GetCodeBlocks(){ return m_code_block_array; }
+
+ //! Return the code blocks
+ const TwoDArray<CodeBlock>& GetCodeBlocks() const { return m_code_block_array; }
+
+ //! Returns true if subband is skipped, false if not
+ bool Skipped() const { return m_skipped; }
+
+ //! Set the perceptual weight
+ void SetWt( const float w );
+
+ //! Set the parent index
+ void SetParent( const int p ){ m_parent=p; }
+
+ //! Set the subband depth
+ void SetDepth( const int d ){ m_depth=d;}
+
+ //! Set the index of the maximum bit of the largest coefficient
+ void SetMax( const int m ){ m_max_bit=m; };
+
+ //! Set the number of (spatial) quantisers in the subband. Creates code block structure
+ void SetNumBlocks( const int ynum , const int xnum );
+
+ //! Set the quantisation index
+ void SetQuantIndex( const int idx){ m_qindex = idx; }
+
+ //! Set the number of (spatial) quantisers in the subband. Creates code block structure
+ void SetUsingMultiQuants( const bool multi){ m_multi_quants = multi; }
+
+ //! Set whether the subband is skipped or not
+ void SetSkip(const bool skip ){ m_skipped = skip; }
+
+ private:
+ // subband bounds
+ int m_xp , m_yp , m_xl , m_yl;
+
+ // perceptual weight for quantisation
+ double m_wt;
+
+ // depth in the transform
+ int m_depth;
+
+ // quantiser index
+ int m_qindex;
+
+ // position of parent in a subband list
+ int m_parent;
+
+ // positions of children in the subband list
+ std::vector<int> m_children;
+
+ // position of the MSB of the largest absolute value
+ int m_max_bit;
+
+ // The code blocks
+ TwoDArray<CodeBlock> m_code_block_array;
+
+ // A flag indicating whether we're using one qf for each code block
+ bool m_multi_quants;
+
+ // Whether the subband is skipped or not
+ bool m_skipped;
+ };
+
+ //! A class encapulating all the subbands produced by a transform
+ class SubbandList
+ {
+ public:
+ //! Constructor
+ SubbandList(){}
+
+ //! Destructor
+ ~SubbandList(){}
+
+ //Default (shallow) copy constructor and operator= used
+ //! Initialise the list
+ void Init(const int depth,const int xlen,const int ylen);
+
+ //! Return the length of the subband list
+ int Length() const {return bands.size();}
+
+ //! Return the subband at position n (1<=n<=length)
+ Subband& operator()(const int n){return bands[n-1];}
+
+ //! Return the subband at position n (1<=n<=length)
+ const Subband& operator()(const int n) const {return bands[n-1];}
+
+ //! Add a band to the list
+ void AddBand(const Subband& b){bands.push_back(b);}
+
+ //! Remove all the bands from the list
+ void Clear(){bands.clear();}
+
+ private:
+
+ //! Given x and y spatial frequencies in cycles per degree, returns a weighting value
+ float PerceptualWeight( const float xf , const float yf , const CompSort cs);
+
+ private:
+ std::vector<Subband> bands;
+ };
+
+ class CoeffArray;
+ //! A virtual parent class to do vertical and horizontal splitting with wavelet filters
+ class VHFilter
+ {
+
+ public:
+
+ VHFilter(){}
+
+ virtual ~VHFilter(){}
+
+ //! Split a subband into 4
+ virtual void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0;
+
+ //! Create a single band from 4 quadrant bands
+ virtual void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data)=0;
+
+ //! Return the value of the additional bitshift
+ virtual int GetShift() const =0;
+
+ protected:
+
+ //! Interleave data from separate subbands into even and odd positions for in-place calculation - called by Synth
+ inline void Interleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data );
+
+
+ //! De-interleave data even and odd positions into separate subbands - called by Split
+ inline void DeInterleave( const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data );
+
+ //! Shift all vals in Row by 'shift' bits to the left to increase accuracy by 'shift' bits. Used in Analysis stage of filter
+ void ShiftRowLeft(CoeffType *row, int length, int shift);
+
+ //! Shift all vals in Row by 'shift' bits to the right to counter the shift in the Analysis stage. This function is used in the Synthesis stage
+ void ShiftRowRight(CoeffType *row, int length, int shift);
+ };
+
+ //! Class to do Daubechies (9,7) filtering operations
+ class VHFilterDAUB9_7 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 1;}
+
+
+ };
+
+ //! Class to do (5,3) wavelet filtering operations
+ class VHFilterLEGALL5_3 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 1;}
+
+
+#ifdef HAVE_MMX
+ inline void HorizSynth (int xp, int xl, int ystart, int yend, CoeffArray &coeff_data);
+#endif
+
+ };
+
+ //! A short filter that's actually close to Daubechies (9,7) but with just two lifting steps
+ class VHFilterDD9_7 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 1;}
+ };
+
+
+ //! An extension of DD9_7, with a better low-pass filter but more computation
+ class VHFilterDD13_7 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 1;}
+
+ };
+
+ //! Class to do Haar wavelet filtering operations
+ class VHFilterHAAR0 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 0;}
+
+
+ };
+
+ //! Class to do Haar wavelet filtering operations with a single shift per level
+ class VHFilterHAAR1 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 1;}
+
+ };
+
+
+ //! Class to do Haar wavelet filtering operations with a double shift per level
+ class VHFilterHAAR2 : public VHFilter
+ {
+
+ public:
+
+ //! Split a subband into 4
+ void Split(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Create a single band from 4 quadrant bands
+ void Synth(const int xp, const int yp, const int xl, const int yl, CoeffArray& coeff_data);
+
+ //! Return a correction factor to compensate for non-unity power gain of low-pass filter
+ double GetLowFactor() const { return 1.414213562;}
+
+ //! Return a correction factor to compensate for non-unity power gain of high-pass filter
+ double GetHighFactor() const { return 0.707106781;}
+
+ //! Return the value of the additional bitshift
+ int GetShift() const {return 2;}
+
+ };
+
+
+
+ // Lifting steps used in the filters
+
+ //! Class to do two-tap prediction lifting step
+ template<int shift>
+ class PredictStepShift
+ {
+
+ public:
+
+ //! Constructor
+ PredictStepShift(){}
+
+ // Assume default copy constructor, assignment= and destructor //
+
+ //! Do the filtering
+ /*
+ Do the filtering.
+ \param in_val the value being predicted
+ \param val1 the first value being used for prediction
+ \param val2 the second value being used for prediction
+ */
+ inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
+ {
+ in_val -= (( val1 + val2 + (1<<(shift-1)) ) >>shift );
+ }
+
+ };
+
+ //! Class to do two-tap updating lifting step
+ template<int shift>
+ class UpdateStepShift
+ {
+
+ public:
+ //! Constructor
+ UpdateStepShift(){}
+
+ //! Do the filtering
+ /*
+ Do the filtering.
+ \param in_val the value being updated
+ \param val1 the first value being used for updating
+ \param val2 the second value being used for updating
+ */
+ inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
+ {
+ in_val += ( ( val1 + val2 + (1<<(shift-1)) ) >>shift );
+ }
+
+ };
+
+ //! Class to do symmetric four-tap prediction lifting step
+ template <int shift , int tap1, int tap2>
+ class PredictStepFourTap
+ {
+ public:
+
+ //! Constructor
+ PredictStepFourTap(){}
+
+ // Assume default copy constructor, assignment= and destructor //
+
+ //! Do the filtering
+ inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 ,
+ const CoeffType& val3, const CoeffType& val4 ) const
+ {
+ in_val -= ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)))>>shift;
+ }
+ };
+
+ //! Class to do symmetric four-tap update lifting step
+ template <int shift , int tap1 , int tap2>
+ class UpdateStepFourTap
+ {
+
+ public:
+ //! Constructor
+ UpdateStepFourTap(){}
+
+ //! Do the filtering
+ inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2 ,
+ const CoeffType& val3, const CoeffType& val4 ) const
+ {
+ in_val += ( tap1*( val1 + val2 ) + tap2*( val3 + val4 ) + (1<<(shift-1)) )>>shift;
+ }
+ };
+
+ //! Class to do two-tap prediction lifting step for Daubechies (9,7)
+ template <int gain> class PredictStep97
+ {
+ public:
+
+ //! Constructor
+ PredictStep97(){}
+
+ // Assume default copy constructor, assignment= and destructor //
+
+ //! Do the filtering
+ /*
+ Do the filtering.
+ \param in_val the value being predicted
+ \param val1 the first value being used for prediction
+ \param val2 the second value being used for prediction
+ */
+ inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
+ {
+ in_val -= static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
+ }
+ };
+
+ //! Class to do two-tap update lifting step for Daubechies (9,7)
+ template <int gain> class UpdateStep97
+ {
+
+ public:
+ //! Constructor
+ UpdateStep97(){}
+
+ //! Do the filtering
+ /*
+ Do the filtering.
+ \param in_val the value being updated
+ \param val1 the first value being used for updating
+ \param val2 the second value being used for updating
+ */
+ inline void Filter(CoeffType& in_val, const CoeffType& val1, const CoeffType& val2) const
+ {
+ in_val += static_cast< CoeffType >( (gain * static_cast< int >( val1 + val2 )) >>12 );
+ }
+ };
+
+ //! A class for wavelet coefficient data.
+ /*!
+ A class for encapsulating coefficient data, derived from TwoDArray..
+ */
+ class CoeffArray: public TwoDArray<CoeffType>
+ {
+ public:
+ //! Default constructor
+ /*!
+ Default constructor creates an empty array.
+ */
+ CoeffArray(): TwoDArray<CoeffType>(){}
+
+ //! Constructor.
+ /*!
+ Contructor creates a two-D array, with specified size and colour
+ format.
+ */
+ CoeffArray(int height, int width, CompSort cs=Y_COMP):
+ TwoDArray<CoeffType>(height, width), m_csort(cs){}
+
+ //copy constructor and assignment= derived by inheritance
+
+ //! Destructor
+ ~CoeffArray(){}
+
+ //! Return which component is stored
+ const CompSort& CSort() const {return m_csort;}
+
+ //! Set the type of component being stored
+ void SetCSort(const CompSort cs){ m_csort = cs; }
+
+ //! Returns the set of subbands
+ SubbandList& BandList(){return m_band_list;}
+
+ //! Returns the set of subbands
+ const SubbandList& BandList() const {return m_band_list;}
+
+ //! Sets the subband weights
+ /*!
+ Sets perceptual weights for the subbands. Takes into account both perceptual factors
+ (weight noise less at higher spatial frequencies) and the scaling needed for the
+ wavelet transform.
+ */
+ void SetBandWeights (const EncoderParams& encparams,
+ const PictureParams& pparams,
+ const CompSort csort,
+ const float cpd_scale_factor);
+
+ private:
+
+ CompSort m_csort;
+
+ // The subband list to be used for conventional transform apps
+ SubbandList m_band_list;
+
+ private:
+
+ //! Given x and y spatial frequencies in cycles per degree, returns a weighting value
+ float PerceptualWeight(float xf,float yf,CompSort cs);
+
+ };
+
+ //! A class to do wavelet transforms
+ /*!
+ A class to do forward and backward wavelet transforms by iteratively splitting or merging the
+ lowest frequency band.
+ */
+ class WaveletTransform
+ {
+ public:
+ //! Constructor
+ WaveletTransform(int d = 4, WltFilter f = DAUB9_7);
+
+ //! Destructor
+ virtual ~WaveletTransform();
+
+ //! Transforms the data to and from the wavelet domain
+ /*!
+ Transforms the data to and from the wavelet domain.
+ \param d the direction of the transform
+ \param pic_data the data to be transformed
+ \param coeff_data array that holds the transform coefficient data
+ */
+ void Transform(const Direction d, PicArray& pic_data, CoeffArray& coeff_data);
+
+ private:
+
+
+ private:
+
+ // Private variables
+
+ //! Depth of the transform
+ int m_depth;
+
+ //! The (vertical and horizontal) wavelet filter set to be used
+ WltFilter m_filt_sort;
+
+ //! A class to do the vertical and horizontal filtering required
+ VHFilter* m_vhfilter;
+
+ private:
+ // Private functions
+ //! Private, bodyless copy constructor: class should not be copied
+ WaveletTransform(const WaveletTransform& cpy);
+
+ //! Private, bodyless copy operator=: class should not be assigned
+ WaveletTransform& operator=(const WaveletTransform& rhs);
+
+ };
+}// end namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils_mmx.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils_mmx.cpp
new file mode 100644
index 000000000..0a8953f8d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_common/wavelet_utils_mmx.cpp
@@ -0,0 +1,1625 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: wavelet_utils_mmx.cpp,v 1.13 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author),
+* Thomas Davies (wavelet_utils.cpp)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+/*!
+ * MMX version of wavelet transform routines. Note that these routines
+ * assume that wavelet coefficients, of type CoeffType, are in fact
+ * shorts. This is set in libdirac_common/common.h. Turning MMX on
+ * reduces the supported wavelet depth to a maximum of 4 or 5
+ * (depending on the filter) by the use of only 16 bits for coefficients.
+ */
+
+
+#ifdef HAVE_MMX
+#include <libdirac_common/wavelet_utils.h>
+#include <cstdlib>
+#include <mmintrin.h>
+using namespace dirac;
+
+static TwoDArray<CoeffType> t_temp_data;
+
+#if 0
+//Attempt1
+inline void Interleave_mmx( const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xl2( xl>>1);
+ const int yl2( yl>>1);
+ const int yend( yp + yl );
+
+ if (coeff_data.LengthX() > t_temp_data.LengthX() ||
+ coeff_data.LengthY() > t_temp_data.LengthY())
+ {
+ t_temp_data.Resize(coeff_data.LengthY(), coeff_data.LengthX());
+ }
+
+ // Make a temporary copy of the subband
+ for (int j = yp; j<yend ; j++ )
+ memcpy( t_temp_data[j-yp] , coeff_data[j]+xp , xl * sizeof( CoeffType ) );
+
+ int stopx = (xl2>>2)<<2;
+ // Re-order to interleave
+ for (int j = 0, s=yp; j<yl2 ; j++, s+=2)
+ {
+ CoeffType *tmp1 = &t_temp_data[j][0];
+ CoeffType *out = &coeff_data[s][xp];
+ for (int i = 0 , t = xp ; i<xp+stopx ; i+=4 , t+=8)
+ {
+ __m64 m1 = *(__m64 *)tmp1;
+ __m64 m2 = *(__m64 *)(tmp1+xl2);
+ *(__m64 *)out = _mm_unpacklo_pi16 (m1, m2);
+ out+=4;
+ *(__m64 *)out = _mm_unpackhi_pi16 (m1, m2);
+ out+=4;
+ tmp1 += 4;
+ }
+ for (int i = xp+stopx , r=2*(xp+stopx) ; i<xl2 ; i++ , r += 2)
+ {
+ *out = *tmp1;
+ ++out;
+ *out = *(tmp1+xl2);
+ ++out;
+ ++tmp1;
+ }
+ }// j
+
+ for (int j = yl2, s=yp+1 ; j<yl ; j++ , s += 2)
+ {
+ CoeffType *tmp1 = &t_temp_data[j][0];
+ //CoeffType *tmp2 = &t_temp_data[j][xl2];
+ CoeffType *out = &coeff_data[s][xp];
+ for (int i = 0 , t=xp; i<stopx ; i+=4 , t += 8)
+ {
+ __m64 m1 = *(__m64 *)tmp1;
+ __m64 m2 = *(__m64 *)(tmp1+xl2);
+ *(__m64 *)out = _mm_unpacklo_pi16 (m1, m2);
+ out+=4;
+ *(__m64 *)out = _mm_unpackhi_pi16 (m1, m2);
+ out+=4;
+ tmp1 += 4;
+ }
+ for (int i = stopx , r=2*(xp+stopx) ; i<xl2 ; i++ , r += 2)
+ {
+ *out = *tmp1;
+ ++out;
+ *out = *(tmp1+xl2);
+ ++out;
+ ++tmp1;
+ }
+ }// j
+
+ _mm_empty();
+}
+#endif
+
+void VHFilter::ShiftRowLeft(CoeffType *row, int length, int shift)
+{
+ int xstop = length/4*4;
+ CoeffType *shift_row = row;
+ for (int i = 0; i < xstop; i+=4, shift_row+=4)
+ *(__m64 *)shift_row = _mm_slli_pi16 (*(__m64 *)shift_row, shift);
+
+ // mopup
+ for (int i = xstop; i < length; ++i)
+ row[i] <<= shift;
+
+ _mm_empty();
+}
+
+void VHFilter::ShiftRowRight(CoeffType *row, int length, int shift)
+{
+ CoeffType *shift_row = row;
+ int round_val = 1<<(shift-1);
+ __m64 mmx_round = _mm_set_pi16( round_val, round_val, round_val, round_val);
+
+ int xstop = length/4*4;
+ for (int i = 0; i < xstop; i+=4, shift_row+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)shift_row, mmx_round);
+ *(__m64 *)shift_row = _mm_srai_pi16(tmp, shift);
+ }
+ // mopup
+ for (int i = xstop; i < length; ++i)
+ row[i] = ((row[i]+round_val)>>shift);
+ _mm_empty();
+}
+
+inline void Interleave_mmx( const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ const int xl2( xl>>1);
+ const int yl2( yl>>1);
+ const int yend( yp + yl );
+
+ if (coeff_data.LengthX() > t_temp_data.LengthX() ||
+ coeff_data.LengthY() > t_temp_data.LengthY())
+ {
+ t_temp_data.Resize(coeff_data.LengthY(), coeff_data.LengthX());
+ }
+
+ // Make a temporary copy of the subband. We are doing a vertical
+ // interleave while copying
+ for (int j = yp, s=0; j<yp+yl2 ; j++, s+=2 )
+ memcpy( t_temp_data[s] , coeff_data[j]+xp , xl * sizeof( CoeffType ) );
+ for (int j = yp+yl2, s=1; j<yend ; j++, s+=2 )
+ memcpy( t_temp_data[s] , coeff_data[j]+xp , xl * sizeof( CoeffType ) );
+
+ int stopx = (xl2>>2)<<2;
+ // Re-order to horizontally interleave
+ for (int j = 0, s=yp; j<yl ; j++, ++s)
+ {
+ CoeffType *tmp1 = &t_temp_data[j][0];
+ CoeffType *out = &coeff_data[s][xp];
+ for (int i = 0 , t = xp ; i<xp+stopx ; i+=4 , t+=8)
+ {
+ __m64 m1 = *(__m64 *)tmp1;
+ __m64 m2 = *(__m64 *)(tmp1+xl2);
+ *(__m64 *)out = _mm_unpacklo_pi16 (m1, m2);
+ out+=4;
+ *(__m64 *)out = _mm_unpackhi_pi16 (m1, m2);
+ out+=4;
+ tmp1 += 4;
+ }
+ for (int i = xp+stopx , r=2*(xp+stopx) ; i<xl2 ; i++ , r += 2)
+ {
+ *out = *tmp1;
+ ++out;
+ *out = *(tmp1+xl2);
+ ++out;
+ ++tmp1;
+ }
+ }// j
+
+ _mm_empty();
+}
+
+void VHFilterDD9_7::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ int i, j;
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+ const int ymid = yp+yl/2;
+
+ PredictStepShift<2> predict;
+ __m64 pred_round = _mm_set_pi16 (1<<(2-1), 1<<(2-1), 1<<(2-1), 1<<(2-1));
+
+ int xstop = xp + ((xl>>2)<<2);
+
+ // First lifting stage
+ // Top edge
+ CoeffType *in1 = coeff_data[ymid];
+ CoeffType *in2 = coeff_data[ymid];
+ CoeffType *out = coeff_data[yp];
+ for ( i = xp ; i < xstop ; i+=4 )
+ {
+ // tmp = val + val2
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)in1, *(__m64 *)in2);
+ // unbiased rounding tmp = (tmp + 1<<(shift-1))>>shift
+ tmp = _mm_add_pi16(tmp, pred_round);
+ tmp = _mm_srai_pi16(tmp, 2);
+ // in_val -= tmp;
+ *(__m64 *)out = _mm_sub_pi16 (*(__m64*)out, tmp);
+ out += 4;
+ in1 += 4;
+ in2 += 4;
+ }
+
+ // Middle bit
+ for ( j=1 ; j < yl/2 ; ++j )
+ {
+ in1 = coeff_data[ymid+j-1];
+ in2 = coeff_data[ymid+j];
+ out = coeff_data[yp+j];
+ for ( i = xp ; i < xstop ; i+=4 )
+ {
+ // tmp = val + val2
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)in1, *(__m64 *)in2);
+ // unbiased rounding tmp = (tmp + 1<<(shift-1))>>shift
+ tmp = _mm_add_pi16(tmp, pred_round);
+ tmp = _mm_srai_pi16(tmp, 2);
+ // in_val -= tmp;
+ *(__m64 *)out = _mm_sub_pi16 (*(__m64*)out, tmp);
+ out += 4;
+ in1 += 4;
+ in2 += 4;
+ }
+ }
+
+ // Mopup
+ if (xstop != xend)
+ {
+ for ( i = xstop ; i < xend ; i++)
+ {
+ predict.Filter( coeff_data[yp][i] , coeff_data[ymid][i] , coeff_data[ymid][i] );
+ }// i
+
+ for ( j=1 ; j < yl/2 ; ++j )
+ {
+ for ( i = xstop ; i < xend ; i++)
+ {
+ predict.Filter( coeff_data[yp+j][i] , coeff_data[ymid+j-1][i] , coeff_data[ymid+j][i] );
+ }// i
+ }// j
+ }
+
+ // Second lifting stage
+ UpdateStepFourTap< 4 , 9 , -1> update;
+ // rounding factor for update step
+ __m64 update_round = _mm_set_pi32 (1<<(4-1), 1<<(4-1));
+ // top edge
+ in1 = coeff_data[yp];
+ in2 = coeff_data[yp+1];
+ CoeffType *in3 = coeff_data[yp];
+ CoeffType *in4 = coeff_data[yp+2];
+ out = coeff_data[ymid];
+ __m64 tap1 = _mm_set_pi16 (9, 9, 9, 9);
+ __m64 tap2 = _mm_set_pi16 (-1, -1, -1, -1);
+
+ for ( i = xp ; i < xstop ; i+=4 )
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }
+
+ // middle bit
+ for ( j=1 ; j < yl/2 - 2 ; ++j)
+ {
+ in1 = coeff_data[yp+j];
+ in2 = coeff_data[yp+j+1];
+ in3 = coeff_data[yp+j-1];
+ in4 = coeff_data[yp+j+2];
+ out = coeff_data[ymid+j];
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+ }// k
+
+ // bottom edge
+ in1 = coeff_data[ymid-2];
+ in2 = coeff_data[ymid-1];
+ in3 = coeff_data[ymid-3];
+ in4 = coeff_data[ymid-1];
+ out = coeff_data[yend-2];
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }
+
+ in1 = coeff_data[ymid-1];
+ in2 = coeff_data[ymid-1];
+ in3 = coeff_data[ymid-2];
+ in4 = coeff_data[ymid-1];
+ out = coeff_data[yend-1];
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }
+
+ if (xstop != xend)
+ {
+ for ( i = xstop ; i < xend ; i++)
+ {
+ update.Filter( coeff_data[ymid][i] , coeff_data[yp][i], coeff_data[yp+1][i], coeff_data[yp][i],coeff_data[yp+2][i]);
+ }// i
+
+ // middle bit
+ for ( j=1 ; j < yl/2 - 2 ; ++j)
+ {
+ for ( i = xstop ; i < xend ; i++)
+ {
+ update.Filter( coeff_data[ymid+j][i] , coeff_data[yp+j][i], coeff_data[yp+j+1][i], coeff_data[yp+j-1][i],coeff_data[yp+j+2][i]);
+ }// i
+ }// k
+
+ for ( i = xstop ; i < xend ; i++)
+ {
+ update.Filter( coeff_data[yend - 2][i] , coeff_data[ymid-2][i], coeff_data[ymid-1][i], coeff_data[ymid-3][i],coeff_data[ymid-1][i]);
+ update.Filter( coeff_data[yend - 1][i] , coeff_data[ymid-1][i], coeff_data[ymid-1][i], coeff_data[ymid-2][i],coeff_data[ymid-1][i]);
+ }// i
+ }
+
+
+ // Horizontal sythesis
+
+ const int xmid = xl/2;
+ xstop = xmid %4 ? ((xmid>>2)<<2) + 1 : xmid -3;
+
+ for (j = yp; j < yend; ++j)
+ {
+ CoeffType *line_data = &coeff_data[j][xp];
+
+ // First lifting stage acts on even samples i.e. the low pass ones
+ predict.Filter( line_data[0] , line_data[xmid] , line_data[xmid] );
+ for (i=1 ; i < xmid ; ++i)
+ {
+ predict.Filter( line_data[i] , line_data[xmid+i-1] , line_data[xmid+i] );
+ }
+
+ // Second lifting stage
+ update.Filter( line_data[xmid] , line_data[0] , line_data[1] , line_data[0] , line_data[2] );
+
+ for (i=1 ; i < xmid - 2; ++i)
+ {
+ update.Filter( line_data[xmid+i] , line_data[i] , line_data[i+1] , line_data[i-1] , line_data[i+2] );
+ }// i
+ update.Filter( line_data[xl-2] , line_data[xmid-2] , line_data[xmid-1] , line_data[xmid-3] , line_data[xmid-1] );
+ update.Filter( line_data[xl-1] , line_data[xmid-1] , line_data[xmid-1] , line_data[xmid-2] , line_data[xmid-1] );
+
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+
+ }// j
+ _mm_empty();
+ Interleave_mmx( xp , yp , xl ,yl , coeff_data );
+}
+
+void VHFilterDD13_7::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ int i,j,k;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ PredictStepFourTap< 5 , 9 , -1 > predict;
+ __m64 pred_round = _mm_set_pi32 (1<<(5-1), 1<<(5-1));
+ UpdateStepFourTap< 4 , 9 , -1> update;
+ __m64 update_round = _mm_set_pi32 (1<<(4-1), 1<<(4-1));
+
+ // Next, do the vertical synthesis
+ int ymid = yp + yl/2;
+
+ int xstop = xp + ((xl>>2)<<2);
+ // First lifting stage - odd samples
+ // bottom edge
+ CoeffType *out = coeff_data[ymid-1];
+ CoeffType *in1 = coeff_data[yend-2];
+ CoeffType *in2 = coeff_data[yend-1];
+ CoeffType *in3 = coeff_data[yend-3];
+ CoeffType *in4 = coeff_data[yend-1];
+
+ __m64 tap1 = _mm_set_pi16 (9, 9, 9, 9);
+ __m64 tap2 = _mm_set_pi16 (-1, -1, -1, -1);
+ for ( i = xp ; i<xstop; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, pred_round);
+ val3 = _mm_add_pi32 (val3, pred_round);
+ val1 = _mm_srai_pi32(val1, 5);
+ val3 = _mm_srai_pi32(val3, 5);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_sub_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+
+ // middle bit
+ for ( j = 2 ; j < yl/2 -1 ; ++j)
+ {
+ out = coeff_data[yp+j];
+ in1 = coeff_data[ymid+j-1];
+ in2 = coeff_data[ymid+j];
+ in3 = coeff_data[ymid+j-2];
+ in4 = coeff_data[ymid+j+1];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, pred_round);
+ val3 = _mm_add_pi32 (val3, pred_round);
+ val1 = _mm_srai_pi32(val1, 5);
+ val3 = _mm_srai_pi32(val3, 5);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_sub_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+ }// j
+
+ // top edge - j=xp
+ out = coeff_data[yp+1];
+ in1 = coeff_data[ymid];
+ in2 = coeff_data[ymid+1];
+ in3 = coeff_data[ymid+2];
+ in4 = coeff_data[ymid];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, pred_round);
+ val3 = _mm_add_pi32 (val3, pred_round);
+ val1 = _mm_srai_pi32(val1, 5);
+ val3 = _mm_srai_pi32(val3, 5);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_sub_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }
+
+ out = coeff_data[yp];
+ in1 = coeff_data[ymid];
+ in2 = coeff_data[ymid];
+ in3 = coeff_data[ymid+1];
+ in4 = coeff_data[ymid];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, pred_round);
+ val3 = _mm_add_pi32 (val3, pred_round);
+ val1 = _mm_srai_pi32(val1, 5);
+ val3 = _mm_srai_pi32(val3, 5);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_sub_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }
+
+ // Mopup
+ if ( xstop != xend)
+ {
+ // Mopup bottom edge
+ for ( i = xstop ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[ymid-1][i] , coeff_data[yend-2][i] , coeff_data[yend-1][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ }// i
+
+ // Mopup middle bit
+ for ( k = 2 ; k < yl/2 - 1 ; ++k)
+ {
+ for ( i = xstop ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+k][i] , coeff_data[ymid+k-1][i] , coeff_data[ymid+k][i] , coeff_data[ymid+k-2][i] , coeff_data[ymid+k+1][i] );
+ }// i
+ }// k
+
+ //Mopup top edge
+ for ( i = xstop ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+1][i] , coeff_data[ymid][i] , coeff_data[ymid+1][i] , coeff_data[ymid+2][i] , coeff_data[ymid][i] );
+ predict.Filter( coeff_data[yp][i] , coeff_data[ymid][i] , coeff_data[ymid][i] , coeff_data[ymid+1][i] , coeff_data[ymid][i] );
+
+ }// i
+
+ }
+
+ // Second lifting stage
+ // top edge - j=xp
+ out = coeff_data[ymid];
+ in1 = coeff_data[yp];
+ in2 = coeff_data[yp+1];
+ in3 = coeff_data[yp];
+ in4 = coeff_data[yp+2];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+
+
+ // middle bit
+ for ( k = 1 ; k < yl/2 - 2 ; ++k)
+ {
+ out = coeff_data[ymid+k];
+ in1 = coeff_data[k];
+ in2 = coeff_data[k+1];
+ in3 = coeff_data[k-1];
+ in4 = coeff_data[k+2];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+ }// k
+
+ // bottom edge
+ out = coeff_data[yend-2];
+ in1 = coeff_data[ymid-2];
+ in2 = coeff_data[ymid-1];
+ in3 = coeff_data[ymid-3];
+ in4 = coeff_data[ymid-1];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+
+ out = coeff_data[yend-1];
+ in1 = coeff_data[ymid-1];
+ in2 = coeff_data[ymid-1];
+ in3 = coeff_data[ymid-2];
+ in4 = coeff_data[ymid-1];
+ for ( i = xp ; i<xstop ; i+=4)
+ {
+ __m64 val1, val2, val3, val4, tmp1, tmp2;
+
+ val1 = _mm_add_pi16(*(__m64*)in1, *(__m64*)in2);
+ tmp1 = _mm_mullo_pi16 (val1, tap1);
+ tmp2 = _mm_mulhi_pi16 (val1, tap1);
+ val3 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val1 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val2 = _mm_add_pi16(*(__m64*)in3, *(__m64*)in4);
+ tmp1 = _mm_mullo_pi16 (val2, tap2);
+ tmp2 = _mm_mulhi_pi16 (val2, tap2);
+ val4 = _mm_unpackhi_pi16 (tmp1, tmp2);
+ val2 = _mm_unpacklo_pi16 (tmp1, tmp2);
+
+ val1 = _mm_add_pi32 (val1, val2);
+ val3 = _mm_add_pi32 (val3, val4);
+ val1 = _mm_add_pi32 (val1, update_round);
+ val3 = _mm_add_pi32 (val3, update_round);
+ val1 = _mm_srai_pi32(val1, 4);
+ val3 = _mm_srai_pi32(val3, 4);
+ val1 = _mm_packs_pi32 (val1, val3);
+
+ *(__m64*)out = _mm_add_pi16 (*(__m64*)out,val1);
+ in1 +=4;
+ in2 +=4;
+ in3 +=4;
+ in4 +=4;
+ out +=4;
+ }// i
+
+
+ // Mopup
+ if ( xstop != xend)
+ {
+ // bottom edge
+ for ( i = xstop ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[yend-1][i] , coeff_data[ymid-1][i] , coeff_data[ymid-1][i] , coeff_data[ymid-2][i] , coeff_data[ymid-1][i] );
+ update.Filter( coeff_data[yend-2][i] , coeff_data[ymid-2][i] , coeff_data[ymid-1][i] , coeff_data[ymid-3][i] , coeff_data[ymid-1][i] );
+
+ }// i
+
+ // middle bit
+ for ( k = 1 ; k < yl/2 - 2 ; ++k)
+ {
+ for ( i = xstop ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[ymid+k][i] , coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] , coeff_data[k+2][i] );
+ }// i
+ }// j
+
+ // top edge - j=xp
+ for ( i = xstop ; i<xend ; ++ i)
+ {
+ update.Filter( coeff_data[ymid][i] , coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp][i] , coeff_data[yp+2][i] );
+ }// i
+ }
+
+ // Next do the horizontal synthesis
+
+ CoeffType* line_data;
+ int xmid = xl/2;
+
+ for (j = yp; j < yend ; ++j)
+ {
+ line_data = &coeff_data[j][xp];
+
+ // First lifting stage
+
+ predict.Filter( line_data[0] , line_data[xmid] , line_data[xmid] , line_data[xmid+1] , line_data[xmid] );
+ predict.Filter( line_data[1] , line_data[xmid] , line_data[xmid+1] , line_data[xmid+2] , line_data[xmid] );
+
+ for (k=2 ; k < xmid-1 ; ++k)
+ {
+ predict.Filter( line_data[k] , line_data[xmid+k-1] , line_data[xmid+k] , line_data[xmid+k-2] , line_data[xmid+k+1] );
+
+ }// i
+ predict.Filter( line_data[xmid-1] , line_data[xl-2] , line_data[xl-1] , line_data[xl-3] , line_data[xl-1] );
+
+ //second lifting stage
+
+ update.Filter( line_data[xmid] , line_data[0] , line_data[1] , line_data[0] , line_data[2] );
+ for (k=1 ; k<xmid-2 ; ++k)
+ {
+ update.Filter( line_data[xmid+k] , line_data[k] , line_data[k+1] , line_data[k-1] , line_data[k+2] );
+ }// i
+ update.Filter( line_data[xl-2] , line_data[xmid-2] , line_data[xmid-1] , line_data[xmid-3] , line_data[xmid-1] );
+ update.Filter( line_data[xl-1] , line_data[xmid-1] , line_data[xmid-1] , line_data[xmid-2] , line_data[xmid-1] );
+
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+
+ }// j
+
+ _mm_empty();
+ // Interleave subbands
+ Interleave_mmx( xp , yp , xl , yl , coeff_data );
+}
+
+#if 0
+//Opts - Attempt1
+void VHFilterLEGALL5_3::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ int i,j,k;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ const PredictStepShift< 2 > predict;
+ const UpdateStepShift< 1 > update;
+
+ CoeffType* line_data;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations
+ // can be in-place
+ Interleave_mmx( xp , yp , xl , yl , coeff_data );
+
+ // Next, do the vertical synthesis
+ // First lifting stage
+ int xstop = (xend>>2)<<2;
+
+ // Begin the top edge
+ CoeffType *row1, *row2, *row3, *row4;
+
+ row1 = &coeff_data[yp][xp];
+ row2 = &coeff_data[yp+1][xp];
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row2);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row1 = _mm_sub_pi16 (*(__m64*)row1, tmp);
+
+ row1 += 4;
+ row2 += 4;
+ }
+ // Mopup
+ for ( i = xstop ; i < xend ; ++i)
+ {
+ predict.Filter( coeff_data[yp][i] , coeff_data[yp+1][i] , coeff_data[yp+1][i] );
+ }// i
+
+
+ // Next, do the middle bit
+ for ( k = yp+2 ; k < yend-2 ; k+=2)
+ {
+ CoeffType *row1 = &coeff_data[k-2][xp];
+ CoeffType *row2 = &coeff_data[k-1][xp];
+ CoeffType *row3 = &coeff_data[k][xp];
+ CoeffType *row4 = &coeff_data[k+1][xp];
+
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row4, *(__m64 *)row2);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row3 = _mm_sub_pi16 (*(__m64*)row3, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row1, *(__m64 *)row3);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row2 = _mm_add_pi16 (*(__m64*)row2, tmp);
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+
+ //Mopup
+ for ( i = xstop ; i < xend ; ++i)
+ {
+ predict.Filter( coeff_data[k][i] , coeff_data[k+1][i] , coeff_data[k-1][i] );
+ update.Filter( coeff_data[k-1][i] , coeff_data[k-2][i] , coeff_data[k][i] );
+ }// i
+ }// j
+
+ // Finally with the bottom edge
+ row1 = &coeff_data[yend-4][xp];
+ row2 = &coeff_data[yend-3][xp];
+ row3 = &coeff_data[yend-2][xp];
+ row4 = &coeff_data[yend-1][xp];
+
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row4);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row3 = _mm_sub_pi16 (*(__m64*)row3, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row3, *(__m64 *)row1);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row2 = _mm_add_pi16 (*(__m64*)row2, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row3, *(__m64 *)row3);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row4 = _mm_add_pi16 (*(__m64*)row4, tmp);
+
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+ // mopup
+ for ( i = xstop ; i < xend ; ++i)
+ {
+ predict.Filter( coeff_data[yend-2][i] , coeff_data[yend-3][i] , coeff_data[yend-1][i] );
+ update.Filter( coeff_data[yend-3][i] , coeff_data[yend-2][i] , coeff_data[yend-4][i] );
+ update.Filter( coeff_data[yend-1][i] , coeff_data[yend-2][i] , coeff_data[yend-2][i] );
+ }// i
+
+
+ // Next do the horizontal synthesis
+ for (j = yp; j < yend ; ++j)
+ {
+ // First lifting stage
+ line_data = &coeff_data[j][xp];
+
+ predict.Filter( line_data[0] , line_data[1] , line_data[1] );
+
+ for ( k = 2; k < xl -2; k+=2)
+ {
+ predict.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ update.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ }// i
+
+ predict.Filter( line_data[xl-2] , line_data[xl-3] , line_data[xl-1] );
+ update.Filter( line_data[xl-3] , line_data[xl-2] , line_data[xl-4] );
+ update.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] );
+
+ }
+ _mm_empty();
+}
+#endif
+
+#if 0
+//Opts Attempt 2
+void VHFilterLEGALL5_3::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ PicArray& coeff_data)
+{
+ int i,j,k;
+ const int yend( yp+yl );
+
+ const int xl2 (xl>>1);
+ const int ymid (yp + (yl>>1));
+ const PredictStepShift< 2 > predict;
+ const UpdateStepShift< 1 > update;
+
+ CoeffType* line_data;
+
+
+ // Next, do the vertical synthesis
+ // First lifting stage
+
+ int xstop = (xl>>2)<<2;
+
+ CoeffType *row1, *row2, *row3, *row4;
+ // First do the top edge
+ row1 = &coeff_data[yp][xp];
+ row2 = &coeff_data[ymid][xp];
+ for ( i = 0 ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row2);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row1 = _mm_sub_pi16 (*(__m64*)row1, tmp);
+ row1+=4;
+ row2+=4;
+ }// i
+
+ //mopup
+ for ( i = xstop ; i < xl ; ++i)
+ {
+ predict.Filter( *row1 , *row2 , *row2);
+ ++row1;
+ ++row2;
+ }// i
+
+ // Next, do the middle bit
+ for ( k = 1 ; k < ymid-1 ; ++k)
+ {
+ row1 = &coeff_data[k-1][xp];
+ row2 = &coeff_data[k][xp];
+ row3 = &coeff_data[ymid+k-1][xp];
+ row4 = &coeff_data[ymid+k][xp];
+
+ for ( i = 0 ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row3, *(__m64 *)row4);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row2 = _mm_sub_pi16 (*(__m64*)row2, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row1);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row3 = _mm_add_pi16 (*(__m64*)row3, tmp);
+
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+
+ for ( i = xstop ; i < xl ; ++i)
+ {
+ predict.Filter( *row2 , *row4 , *row3 );
+ update.Filter( *row3 , *row2 , *row1 );
+ ++row1;
+ ++row2;
+ ++row3;
+ ++row4;
+ }// i
+ }// j
+
+
+ // Finally with the bottom edge
+ row1 = &coeff_data[ymid-2][xp];
+ row2 = &coeff_data[ymid-1][xp];
+ row3 = &coeff_data[yend-2][xp];
+ row4 = &coeff_data[yend-1][xp];
+ for ( i = xp ; i< xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row3, *(__m64 *)row4);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row2 = _mm_sub_pi16 (*(__m64*)row2, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row1);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row3 = _mm_add_pi16 (*(__m64*)row3, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row2);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row4 = _mm_add_pi16 (*(__m64*)row4, tmp);
+
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+ // mopup
+ for ( i = xstop ; i< xl ; ++i)
+ {
+ predict.Filter( *row2 , *row3 , *row4 );
+ update.Filter( *row3 , *row1 , *row2 );
+ update.Filter( *row4 , *row2 , *row2 );
+ ++row1;
+ ++row2;
+ ++row3;
+ ++row4;
+ }// i
+
+ // Next do the horizontal synthesis
+ xstop = (((xl2 - 2)>>2)<<2) + 1;
+ //xstop = 1;
+ for (j = yp; j < yend ; ++j)
+ {
+ // First lifting stage
+ line_data = &coeff_data[j][xp];
+ predict.Filter( line_data[0] , line_data[xl2] , line_data[xl2] );
+
+ for ( k = 1; k < xstop; k+=4)
+ {
+ //predict.Filter( line_data[k] , line_data[xl2+k] , line_data[xl2+k-1] );
+ __m64 m1 = _mm_add_pi16 (*(__m64 *)(line_data+xl2+k), *(__m64 *)(line_data+xl2+k-1));
+ m1 = _mm_srai_pi16 (m1, 2);
+ *(__m64 *)(line_data+k) = _mm_sub_pi16 (*(__m64 *)(line_data+k), m1);
+
+ //update.Filter( line_data[xl2+k-1] , line_data[k] , line_data[k-1] );
+ m1 = _mm_add_pi16 (*(__m64 *)(line_data+k), *(__m64 *)(line_data+k-1));
+ m1 = _mm_srai_pi16(m1, 1);
+ *(__m64 *)(line_data+xl2+k-1) = _mm_add_pi16 (*(__m64*)(line_data+xl2+k-1), m1);
+
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+
+
+ for ( k = xstop; k < xl2-1; ++k)
+ {
+ predict.Filter( line_data[k] , line_data[xl2+k] , line_data[xl2+k-1] );
+ update.Filter( line_data[xl2+k-1] , line_data[k] , line_data[k-1] );
+ }// i
+
+ predict.Filter( line_data[xl2-1] , line_data[xl-2] , line_data[xl-1] );
+ update.Filter( line_data[xl-2] , line_data[xl2-2] , line_data[xl2-1] );
+ update.Filter( line_data[xl-1] , line_data[xl2-1] , line_data[xl2-1] );
+ }
+ _mm_empty();
+
+ // Finally interleave subbands
+ Interleave_mmx( xp , yp , xl , yl , coeff_data );
+}
+#endif
+
+//Attempt 3
+
+inline void VHFilterLEGALL5_3::HorizSynth (int xp, int xl, int ystart, int yend, CoeffArray &coeff_data)
+{
+ static const PredictStepShift< 2 > predict;
+ static const UpdateStepShift< 1 > update;
+ int j, k;
+ // Next do the horizontal synthesis
+ for (j = ystart; j <= yend ; ++j)
+ {
+ // First lifting stage
+ CoeffType *line_data = &coeff_data[j][xp];
+
+ predict.Filter( line_data[0] , line_data[1] , line_data[1] );
+
+ for ( k = 2; k < xl -2; k+=2)
+ {
+ predict.Filter( line_data[k] , line_data[k+1] , line_data[k-1] );
+ update.Filter( line_data[k-1] , line_data[k-2] , line_data[k] );
+ }// i
+
+ predict.Filter( line_data[xl-2] , line_data[xl-3] , line_data[xl-1] );
+ update.Filter( line_data[xl-3] , line_data[xl-2] , line_data[xl-4] );
+ update.Filter( line_data[xl-1] , line_data[xl-2] , line_data[xl-2] );
+ // Shift right by one bit to counter the shift in the analysis stage
+ ShiftRowRight(line_data, xl, 1);
+ }
+}
+
+void VHFilterLEGALL5_3::Synth(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray &coeff_data)
+{
+ int i, k;
+
+ const int xend( xp+xl );
+ const int yend( yp+yl );
+
+ const PredictStepShift< 2 > predict;
+ __m64 pred_round = _mm_set_pi16 (1<<(2-1), 1<<(2-1), 1<<(2-1), 1<<(2-1));
+ const UpdateStepShift< 1 > update;
+ __m64 update_round = _mm_set_pi16 (1, 1, 1, 1);
+
+ int horiz_start = 0;
+ int horiz_end = 0;
+
+ // Firstly reorder to interleave subbands, so that subsequent calculations
+ // can be in-place
+ Interleave_mmx( xp , yp , xl , yl , coeff_data );
+
+ // Next, do the vertical synthesis
+ // First lifting stage
+ int xstop = (xend>>2)<<2;
+
+ // Begin the top edge
+ CoeffType *row1, *row2, *row3, *row4;
+
+ row1 = &coeff_data[yp][xp];
+ row2 = &coeff_data[yp+1][xp];
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row2);
+ tmp = _mm_add_pi16 (tmp, pred_round);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row1 = _mm_sub_pi16 (*(__m64*)row1, tmp);
+
+ row1 += 4;
+ row2 += 4;
+ }
+ // Mopup
+ for ( i = xstop ; i < xend ; ++i)
+ {
+ predict.Filter( *row1, *row2, *row2 );
+ ++row1;
+ ++row2;
+ }// i
+
+
+ // Next, do the middle bit
+ for ( k = yp+2 ; k < yend-2 ; k+=2)
+ {
+ CoeffType *row1 = &coeff_data[k-2][xp];
+ CoeffType *row2 = &coeff_data[k-1][xp];
+ CoeffType *row3 = &coeff_data[k][xp];
+ CoeffType *row4 = &coeff_data[k+1][xp];
+
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row4, *(__m64 *)row2);
+ tmp = _mm_add_pi16 (tmp, pred_round);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row3 = _mm_sub_pi16 (*(__m64*)row3, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row1, *(__m64 *)row3);
+ tmp = _mm_add_pi16 (tmp, update_round);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row2 = _mm_add_pi16 (*(__m64*)row2, tmp);
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+
+ //Mopup
+ for ( i = xstop ; i < xend ; ++i)
+ {
+ predict.Filter( *row3, *row2, *row4 );
+ update.Filter( *row2, *row1, *row3 );
+ ++row1;
+ ++row2;
+ ++row3;
+ ++row4;
+ }// i
+ horiz_end = k - 2;
+ // Do the horizontal synthesis
+ HorizSynth (xp, xl, horiz_start, horiz_end, coeff_data);
+ horiz_start = horiz_end + 1;
+ }// j
+
+ // Finally with the bottom edge
+ row1 = &coeff_data[yend-4][xp];
+ row2 = &coeff_data[yend-3][xp];
+ row3 = &coeff_data[yend-2][xp];
+ row4 = &coeff_data[yend-1][xp];
+
+ for ( i = xp ; i < xstop ; i+=4)
+ {
+ __m64 tmp = _mm_add_pi16 (*(__m64 *)row2, *(__m64 *)row4);
+ tmp = _mm_add_pi16 (tmp, pred_round);
+ tmp = _mm_srai_pi16(tmp, 2);
+ *(__m64 *)row3 = _mm_sub_pi16 (*(__m64*)row3, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row3, *(__m64 *)row1);
+ tmp = _mm_add_pi16 (tmp, update_round);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row2 = _mm_add_pi16 (*(__m64*)row2, tmp);
+
+ tmp = _mm_add_pi16 (*(__m64 *)row3, *(__m64 *)row3);
+ tmp = _mm_add_pi16 (tmp, update_round);
+ tmp = _mm_srai_pi16(tmp, 1);
+ *(__m64 *)row4 = _mm_add_pi16 (*(__m64*)row4, tmp);
+
+ row1 += 4;
+ row2 += 4;
+ row3 += 4;
+ row4 += 4;
+ }// i
+ // mopup
+ for ( i = xstop ; i < xend ; ++i)
+ {
+ predict.Filter( *row3, *row2, *row4 );
+ update.Filter( *row2, *row1, *row3 );
+ update.Filter( *row4, *row3, *row3 );
+ ++row1;
+ ++row2;
+ ++row3;
+ ++row4;
+ }// i
+
+ _mm_empty();
+ // Last lines of horizontal synthesis
+ HorizSynth (xp, xl, horiz_start, yend-1, coeff_data);
+}
+
+
+void DeInterleave_mmx( const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray &coeff_data)
+{
+ const int xl2( xl>>1);
+ const int yl2( yl>>1);
+ const int yend( yp + yl );
+
+ if (coeff_data.LengthX() > t_temp_data.LengthX() ||
+ coeff_data.LengthY() > t_temp_data.LengthY())
+ {
+ t_temp_data.Resize(coeff_data.LengthY(), coeff_data.LengthX());
+ }
+
+ // Make a temporary copy of the subband
+ for (int j = yp; j<yend ; j++ )
+ memcpy( t_temp_data[j-yp] , coeff_data[j]+xp , xl * sizeof( CoeffType ) );
+
+ int stopx = (xl2>>2)<<2;
+
+ for (int j = yp, s=0; j<(yp+yl2) ; j++, s+=2)
+ {
+ CoeffType *tmp1 = &t_temp_data[s][0];
+ CoeffType *out1 = &coeff_data[j][xp];
+ CoeffType *out2 = &coeff_data[j][xl2];
+ int r = xp;
+ for (int i = 0; i<xp+stopx ; i+=4 , r+=8)
+ {
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)tmp1, *(__m64 *)(tmp1+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)tmp1, *(__m64 *)(tmp1+4));
+ *(__m64 *)out1 = _mm_unpacklo_pi16 (m1, m2);
+ *(__m64 *)out2 = _mm_unpackhi_pi16 (m1, m2);
+ out1 += 4;
+ out2 += 4;
+ tmp1+=8;
+ }
+ //mopup
+ for (int i = xp+stopx; i < xp+xl2; ++i, r+=2)
+ {
+ coeff_data[j][i] = t_temp_data[s][r];
+ coeff_data[j][i+xl2] = t_temp_data[s][r+1];
+ }
+ }// j
+
+ for (int j = yl2, s=1; j< yend ; j++, s+=2)
+ {
+ CoeffType *tmp1 = &t_temp_data[s][0];
+ CoeffType *out1 = &coeff_data[j][xp];
+ CoeffType *out2 = &coeff_data[j][xl2];
+ int r = xp;
+ for (int i = 0; i<xp+stopx ; i+=4 , r+=8)
+ {
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)tmp1, *(__m64 *)(tmp1+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)tmp1, *(__m64 *)(tmp1+4));
+ *(__m64 *)out1 = _mm_unpacklo_pi16 (m1, m2);
+ *(__m64 *)out2 = _mm_unpackhi_pi16 (m1, m2);
+ out1 += 4;
+ out2 += 4;
+ tmp1+=8;
+ }
+ //mopup
+ for (int i = xp+stopx; i < xp+xl2; ++i, r+=2)
+ {
+ coeff_data[j][i] = t_temp_data[s][r];
+ coeff_data[j][i+xl2] = t_temp_data[s][r+1];
+ }
+ }// j
+ _mm_empty();
+}
+
+void VHFilterLEGALL5_3::Split(const int xp ,
+ const int yp ,
+ const int xl ,
+ const int yl ,
+ CoeffArray& coeff_data)
+{
+ //version based on integer-like types
+ //using edge-extension rather than reflection
+
+ const int xend=xp+xl;
+ const int yend=yp+yl;
+ const int xl2 = xl>>1;
+ const int yl2 = yl>>1;
+
+ CoeffType* line_data;
+
+ // Positional variables
+ int i,j,k;
+
+ // Objects to do lifting stages
+ // (in revese order and type from synthesis)
+ const PredictStepShift< 1 > predict;
+ __m64 pred_round = _mm_set_pi16 (1, 1, 1, 1);
+ const UpdateStepShift< 2 > update;
+ __m64 update_round = _mm_set_pi16 (1<<(2-1), 1<<(2-1), 1<<(2-1), 1<<(2-1));
+
+ // Lastly, have to reorder so that subbands are no longer interleaved
+ DeInterleave_mmx( xp , yp , xl , yl , coeff_data );
+ //first do horizontal
+
+ for (j = yp; j < yend; ++j)
+ {
+ // First lifting stage
+ line_data = &coeff_data[j][xp];
+ // Shift left by one bit to give us more accuracy
+ ShiftRowLeft(line_data, xl, 1);
+
+ predict.Filter( line_data[xp+xl2] , line_data[1] , line_data[0] );
+ update.Filter( line_data[0] , line_data[xp+xl2] , line_data[xp+xl2] );
+
+ for (k = 1; k < xp+xl2-1; k+=1)
+ {
+ predict.Filter( line_data[xp+xl2+k] , line_data[k+1] , line_data[k] );
+ update.Filter( line_data[k] , line_data[xp+xl2+k-1] , line_data[xp+xl2+k] );
+ }// i
+
+ predict.Filter( line_data[xl-1] , line_data[xp+xl2-1] , line_data[xp+xl2-1] );
+ update.Filter( line_data[xp+xl2-1] , line_data[xl-2] , line_data[xl-1] );
+
+ }// j
+
+ // next do vertical
+
+ // First lifting stage
+
+ // top edge - j=xp
+ int stopX = (xl>>2)<<2;
+ CoeffType *in_val = &coeff_data[yp+yl2][xp];
+ CoeffType *val1 = &coeff_data[1][xp];
+ CoeffType *val2 = &coeff_data[0][xp];
+ for ( i = xp ; i<(xp+stopX); i+=4)
+ {
+ //predict.Filter( coeff_data[yp+yl2][i] , coeff_data[1][i] , coeff_data[0][i] );
+ __m64 m1 = _mm_add_pi16 (*(__m64 *)val1, *(__m64 *)val2);
+ m1 = _mm_add_pi16 (m1, pred_round);
+ m1 = _mm_srai_pi16(m1, 1);
+ *(__m64 *)in_val = _mm_sub_pi16 (*(__m64 *)in_val, m1);
+
+ //update.Filter( coeff_data[0][i] , coeff_data[yp+yl2][i] , coeff_data[yp+yl2][i] );
+ m1 = _mm_add_pi16 (*(__m64 *)in_val, *(__m64 *)in_val);
+ m1 = _mm_add_pi16 (m1, update_round);
+ m1 = _mm_srai_pi16(m1, 2);
+ *(__m64 *)val2 = _mm_add_pi16 (*(__m64 *)val2, m1);
+ in_val += 4;
+ val1 += 4;
+ val2 += 4;
+ }// i
+ // mopup
+ for ( i = xp+stopX ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+yl2][i] , coeff_data[1][i] , coeff_data[0][i] );
+ update.Filter( coeff_data[0][i] , coeff_data[yp+yl2][i] , coeff_data[yp+yl2][i] );
+ }// i
+
+ // middle bit
+ for (k = 1 ; k<yp+yl2-1 ; k+=1)
+ {
+ CoeffType *in_val = &coeff_data[yp+yl2+k][xp];
+ CoeffType *in_val2 = &coeff_data[yp+yl2+k-1][xp];
+ CoeffType *val1 = &coeff_data[k+1][xp];
+ CoeffType *val2 = &coeff_data[k][xp];
+ for ( i = xp ; i<xp+stopX ; i+=4)
+ {
+ //predict.Filter( coeff_data[yp+yl2+k][i] , coeff_data[k+1][i] , coeff_data[k][i] );
+ __m64 m1 = _mm_add_pi16 (*(__m64 *)val1, *(__m64 *)val2);
+ m1 = _mm_add_pi16 (m1, pred_round);
+ m1 = _mm_srai_pi16(m1, 1);
+ *(__m64 *)in_val = _mm_sub_pi16 (*(__m64 *)in_val, m1);
+
+ //update.Filter( coeff_data[k][i] , coeff_data[yp+yl2+k-1][i] , coeff_data[yp+yl2+k][i] );
+ m1 = _mm_add_pi16 (*(__m64 *)in_val, *(__m64 *)in_val2);
+ m1 = _mm_add_pi16 (m1, update_round);
+ m1 = _mm_srai_pi16(m1, 2);
+ *(__m64 *)val2 = _mm_add_pi16 (*(__m64 *)val2, m1);
+
+ in_val += 4;
+ in_val2 += 4;
+ val1 += 4;
+ val2 += 4;
+ }// i
+
+ //mopup
+ for ( i = xp+stopX ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yp+yl2+k][i] , coeff_data[k+1][i] , coeff_data[k][i] );
+ update.Filter( coeff_data[k][i] , coeff_data[yp+yl2+k-1][i] , coeff_data[yp+yl2+k][i] );
+ }// i
+ }// j
+
+ in_val = &coeff_data[yend-1][xp];
+ val2 = &coeff_data[yp+yl2-1][xp];
+ CoeffType *in_val2 = &coeff_data[yend-2][xp];
+ // bottom edge
+ for ( i = xp ; i<xp+stopX ; i+=4)
+ {
+ //predict.Filter( coeff_data[yend-1][i] , coeff_data[yp+yl2-1][i] , coeff_data[yp+yl2-1][i] );
+ __m64 m1 = _mm_add_pi16 (*(__m64 *)val2, *(__m64 *)val2);
+ m1 = _mm_add_pi16 (m1, pred_round);
+ m1 = _mm_srai_pi16(m1, 1);
+ *(__m64 *)in_val = _mm_sub_pi16 (*(__m64 *)in_val, m1);
+
+ //update.Filter( coeff_data[yp+yl2-1][i] , coeff_data[yend-2][i] , coeff_data[yend-1][i] );
+ m1 = _mm_add_pi16 (*(__m64 *)in_val2, *(__m64 *)in_val);
+ m1 = _mm_add_pi16 (m1, update_round);
+ m1 = _mm_srai_pi16(m1, 2);
+ *(__m64 *)val2 = _mm_add_pi16 (*(__m64 *)val2, m1);
+
+ in_val += 4;
+ in_val2 += 4;
+ val2 += 4;
+ }// i
+ // mopup
+ for ( i = xp+stopX ; i<xend ; ++ i)
+ {
+ predict.Filter( coeff_data[yend-1][i] , coeff_data[yp+yl2-1][i] , coeff_data[yp+yl2-1][i] );
+ update.Filter( coeff_data[yp+yl2-1][i] , coeff_data[yend-2][i] , coeff_data[yend-1][i] );
+ }// i
+ _mm_empty();
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.cpp
new file mode 100644
index 000000000..3067c241e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.cpp
@@ -0,0 +1,163 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: comp_decompress.cpp,v 1.32 2009/01/21 05:18:09 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju,
+* Andrew Kennedy,
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#include <libdirac_decoder/comp_decompress.h>
+#include <libdirac_common/wavelet_utils.h>
+#include <libdirac_common/band_codec.h>
+#include <libdirac_common/band_vlc.h>
+using namespace dirac;
+
+#include <vector>
+
+#include <ctime>
+
+using std::vector;
+
+//Constructor
+CompDecompressor::CompDecompressor( DecoderParams& decp, const PictureParams& pp)
+:
+ m_decparams(decp),
+ m_pparams(pp),
+ m_psort( pp.PicSort() )
+{}
+
+
+void CompDecompressor::Decompress(ComponentByteIO* p_component_byteio,
+ CoeffArray& coeff_data,
+ SubbandList& bands)
+{
+
+ // Set up the code blocks
+ SetupCodeBlocks( bands );
+
+ for ( int b=bands.Length() ; b>=1 ; --b ){
+ // Multiple quantiser are used only if
+ // a. The global code_block_mode is QUANT_MULTIPLE
+ // and
+ // b. More than one code block is present in the subband.
+ bands(b).SetUsingMultiQuants(
+ m_decparams.SpatialPartition() &&
+ m_decparams.GetCodeBlockMode() == QUANT_MULTIPLE &&
+ (bands(b).GetCodeBlocks().LengthX() > 1 ||
+ bands(b).GetCodeBlocks().LengthY() > 1)
+ );
+
+ // Read the header data first
+ SubbandByteIO subband_byteio(bands(b), *p_component_byteio);
+ subband_byteio.Input();
+
+ if ( !bands(b).Skipped() ){
+ if (m_pparams.UsingAC()){
+ // A pointer to the object(s) we'll be using for coding the bands
+ BandCodec* bdecoder;
+
+ if ( b>=bands.Length()-3){
+ if ( m_psort.IsIntra() && b==bands.Length() )
+ bdecoder=new IntraDCBandCodec(&subband_byteio,
+ TOTAL_COEFF_CTXS ,bands);
+ else
+ bdecoder=new LFBandCodec(&subband_byteio ,
+ TOTAL_COEFF_CTXS, bands ,
+ b, m_psort.IsIntra());
+ }
+ else
+ bdecoder=new BandCodec( &subband_byteio , TOTAL_COEFF_CTXS ,
+ bands , b, m_psort.IsIntra());
+
+ bdecoder->Decompress(coeff_data , subband_byteio.GetBandDataLength());
+ delete bdecoder;
+ }
+ else{
+ // A pointer to the object(s) we'll be using for coding the bands
+ BandVLC* bdecoder;
+
+ if ( m_psort.IsIntra() && b==bands.Length() )
+ bdecoder=new IntraDCBandVLC(&subband_byteio, bands);
+ else
+ bdecoder=new BandVLC( &subband_byteio , 0, bands ,
+ b, m_psort.IsIntra());
+
+ bdecoder->Decompress(coeff_data , subband_byteio.GetBandDataLength());
+ delete bdecoder;
+ }
+ }
+ else{
+ SetToVal( coeff_data , bands(b) , 0 );
+ }
+ }
+}
+
+void CompDecompressor::SetupCodeBlocks( SubbandList& bands )
+{
+ int xregions;
+ int yregions;
+
+ for (int band_num = 1; band_num<=bands.Length() ; ++band_num)
+ {
+ if (m_decparams.SpatialPartition())
+ {
+ int level = m_decparams.TransformDepth() - (band_num-1)/3;
+ const CodeBlocks &cb = m_decparams.GetCodeBlocks(level);
+ xregions = cb.HorizontalCodeBlocks();
+ yregions = cb.VerticalCodeBlocks();
+ }
+ else
+ {
+ xregions = 1;
+ yregions = 1;
+ }
+
+ bands( band_num ).SetNumBlocks( yregions ,xregions );
+
+ }// band_num
+}
+
+void CompDecompressor::SetToVal( CoeffArray& coeff_data ,
+ const Subband& node ,
+ CoeffType val )
+{
+
+ for (int j=node.Yp() ; j<node.Yp()+node.Yl() ; ++j)
+ for (int i=node.Xp() ; i<node.Xp()+node.Xl() ; ++i)
+ coeff_data[j][i]=val;
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.h
new file mode 100644
index 000000000..6468c4ba7
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/comp_decompress.h
@@ -0,0 +1,129 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: comp_decompress.h,v 1.14 2008/06/19 10:33:24 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author), Scott R Ladd
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+
+#ifndef _COMP_DECOMPRESS_H_
+#define _COMP_DECOMPRESS_H_
+
+#include <libdirac_common/arrays.h>
+#include <libdirac_common/wavelet_utils.h>
+#include <libdirac_common/common.h>
+#include <libdirac_byteio/component_byteio.h>
+
+namespace dirac
+{
+ //! Decompress a picture component
+ /*!
+ This class decompresses one of the three components (Y, U, or V) of a
+ picture according to a given set or parameters. CompDecompressor is used
+ by PictureCompressor..
+ */
+ class CompDecompressor
+ {
+ public:
+ //! Constructor
+ /*!
+ Create and initialize a component decompressor with the given
+ characteristics.
+ \param decp decoding parameters
+ \param fp picture parameters
+ */
+ CompDecompressor( DecoderParams& decp, const PictureParams& fp);
+
+ //! Decompress a picture component
+ /*!
+ Decompress a PicArray containing a picture component (Y, U, or V).
+
+ \param p_component_byteio Bytestream of component data
+ \param coeff_data contains the component data to be decompressed
+ \param bands the subband metadata
+ */
+ void Decompress(ComponentByteIO *p_component_byteio,
+ CoeffArray& coeff_data,
+ SubbandList& bands);
+
+ private:
+ //! Copy constructor is private and body-less
+ /*!
+ Copy constructor is private and body-less. This class should not
+ be copied.
+
+ */
+ CompDecompressor(const CompDecompressor& cpy);
+
+ //! Assignment = is private and body-less
+ /*!
+ Assignment = is private and body-less. This class should not be
+ assigned.
+
+ */
+ CompDecompressor& operator=(const CompDecompressor& rhs);
+
+ //! Sets the data of a specific subband node to a given value
+ /*!
+ Sets the data of a specific subband node to a given value
+
+ \param pic_data contains the component data
+ \param node subband node
+ \param val the value to set
+ */
+ void SetToVal(CoeffArray& pic_data,const Subband& node,CoeffType val);
+
+ //! Set up the code block structures for each subband
+ /*!
+ Set up the code block structures for each subband
+ \param bands the set of all the subbands
+ */
+ void SetupCodeBlocks( SubbandList& bands );
+
+ //! Copy of the decompression parameters provided to the constructor
+ DecoderParams& m_decparams;
+
+ //! Reference to the picture parameters provided to the constructor
+ const PictureParams& m_pparams;
+
+ //! Reference to the picture sort
+ const PictureSort& m_psort;
+
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/decoder_types.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/decoder_types.h
new file mode 100644
index 000000000..0f04c19be
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/decoder_types.h
@@ -0,0 +1,61 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: decoder_types.h,v 1.2 2008/02/13 03:36:11 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+
+#ifndef DECODER_TYPES_H
+#define DECODER_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+* Different states the parser is in
+*/
+typedef enum {
+ STATE_BUFFER, /* need more data input */
+ STATE_SEQUENCE, /* start of sequence detected */
+ STATE_PICTURE_AVAIL, /* decoded frame available */
+ STATE_SEQUENCE_END, /* end of sequence detected */
+ STATE_INVALID /* invalid state. Stop further processing */
+ } DecoderState;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.cpp
new file mode 100644
index 000000000..3940b35fe
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.cpp
@@ -0,0 +1,287 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_cppparser.cpp,v 1.13 2008/05/02 06:05:04 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author),
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <sstream>
+#include <cstdio>
+#include <cstring>
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_decoder/dirac_cppparser.h>
+#include <libdirac_decoder/seq_decompress.h>
+#include <libdirac_common/picture.h>
+#include <libdirac_byteio/parseunit_byteio.h>
+#include <sstream>
+using namespace dirac;
+
+
+InputStreamBuffer::InputStreamBuffer()
+{
+ m_chunk_buffer = new char[m_buffer_size];
+
+ setg (m_chunk_buffer, //beginning of read area
+ m_chunk_buffer, //read position
+ m_chunk_buffer); //end position
+}
+
+std::ios::pos_type InputStreamBuffer::Rewind()
+{
+ return Seek(0, std::ios::beg);
+}
+
+std::ios::pos_type InputStreamBuffer::Tell()
+{
+ return gptr() - eback();
+}
+
+std::ios::pos_type InputStreamBuffer::Seek(std::ios::pos_type bytes, std::ios::seekdir dir)
+{
+ char *new_pos;
+
+ switch (dir)
+ {
+ case std::ios::beg:
+ new_pos = eback() + bytes;
+ break;
+ case std::ios::end:
+ new_pos = egptr() + bytes;
+ break;
+ default:
+ new_pos = gptr() + bytes;
+ break;
+ }
+ if (new_pos > egptr() || new_pos < eback())
+ return -1;
+
+ setg(eback(), //start of read
+ new_pos, //current read position
+ egptr()); //end of stream positon
+
+ return 0;
+}
+
+void InputStreamBuffer::Copy(char *start, int bytes)
+{
+ //std::cerr << "eback=" << m_chunk_buffer - eback()
+ // << "gptr=" << gptr() -m_chunk_buffer
+ // << "egptr=" << egptr() - m_chunk_buffer << endl;
+
+ int bytes_left = m_buffer_size - (egptr() - m_chunk_buffer);
+ if (bytes_left < bytes)
+ {
+ char *temp = new char [m_buffer_size + bytes];
+ memcpy (temp, m_chunk_buffer, m_buffer_size);
+ setg (temp, temp+(gptr()-m_chunk_buffer), temp + (egptr() - m_chunk_buffer));
+ delete [] m_chunk_buffer;
+ m_chunk_buffer = temp;
+ }
+ //std::cerr << "eback=" << m_chunk_buffer - eback()
+ // << "gptr=" << gptr() -m_chunk_buffer
+ // << "egptr=" << egptr() - m_chunk_buffer << endl;
+
+ memcpy (egptr(), start, bytes);
+ setg(m_chunk_buffer, gptr(), egptr()+bytes);
+
+ //std::cerr << "eback=" << m_chunk_buffer - eback()
+ // << "gptr=" << gptr() -m_chunk_buffer
+ // << "egptr=" << egptr() - m_chunk_buffer << endl;
+}
+
+void InputStreamBuffer::PurgeProcessedData()
+{
+ //std::cerr << "eback=" << m_chunk_buffer - eback()
+ // << "gptr=" << gptr() -m_chunk_buffer
+ // << "egptr=" << egptr() - m_chunk_buffer << endl;
+
+ if (gptr() != m_chunk_buffer)
+ {
+ memmove (m_chunk_buffer, gptr(), egptr() - gptr());
+ setg(m_chunk_buffer, m_chunk_buffer, m_chunk_buffer+(egptr() - gptr()));
+ }
+ //std::cerr << "eback=" << m_chunk_buffer - eback()
+ // << "gptr=" << gptr() -m_chunk_buffer
+ // << "egptr=" << egptr() - m_chunk_buffer << endl;
+}
+
+InputStreamBuffer::~InputStreamBuffer()
+{
+ delete [] m_chunk_buffer;
+}
+
+
+DiracParser::DiracParser(bool verbose) :
+ m_state(STATE_BUFFER),
+ m_next_state(STATE_SEQUENCE),
+ m_show_pnum(-1),
+ m_decomp(0),
+ m_verbose(verbose)
+{
+
+
+
+}
+
+DiracParser::~DiracParser()
+{
+ delete m_decomp;
+}
+
+void DiracParser::SetBuffer (char *start, char *end)
+{
+ TEST (end > start);
+ m_dirac_byte_stream.AddBytes(start, end-start);
+}
+
+DecoderState DiracParser::Parse()
+{
+ while(true)
+ {
+ ParseUnitByteIO *p_parse_unit=NULL;
+ ParseUnitType pu_type=PU_UNDEFINED;
+
+ // look for end-of-sequence flag
+ if(m_next_state==STATE_SEQUENCE_END)
+ {
+ if (!m_decomp)
+ return STATE_BUFFER;
+
+ // look to see if all pictures have been processed
+ if(m_decomp->Finished())
+ {
+ // if so....delete
+ delete m_decomp;
+ m_decomp=NULL;
+ m_next_state = STATE_BUFFER;
+ return STATE_SEQUENCE_END;
+ }
+ else
+ // otherwise....get remaining pictures from buffer
+ pu_type = PU_CORE_PICTURE;
+ }
+
+ // get next parse unit from stream
+ if(m_next_state!=STATE_SEQUENCE_END)
+ {
+ p_parse_unit=m_dirac_byte_stream.GetNextParseUnit();
+ if(p_parse_unit==NULL)
+ return STATE_BUFFER;
+ pu_type=p_parse_unit->GetType();
+ }
+
+ switch(pu_type)
+ {
+ case PU_SEQ_HEADER:
+
+ if(!m_decomp)
+ {
+ m_decomp = new SequenceDecompressor (*p_parse_unit, m_verbose);
+ m_next_state=STATE_BUFFER;
+ return STATE_SEQUENCE;
+ }
+
+ m_decomp->NewAccessUnit(*p_parse_unit);
+ break;
+
+ case PU_CORE_PICTURE:
+ {
+ if (!m_decomp)
+ continue;
+
+ const Picture *my_picture = m_decomp->DecompressNextPicture(p_parse_unit);
+ if (my_picture)
+ {
+ int picturenum_decoded = my_picture->GetPparams().PictureNum();
+ if (picturenum_decoded != m_show_pnum)
+ {
+ m_show_pnum = my_picture->GetPparams().PictureNum();
+ if (m_verbose)
+ {
+ std::cout << std::endl;
+ std::cout << "Picture ";
+ std::cout<< m_show_pnum << " available";
+ }
+ m_state = STATE_PICTURE_AVAIL;
+ return m_state;
+ }
+ }
+ break;
+ }
+ case PU_END_OF_SEQUENCE:
+ m_next_state = STATE_SEQUENCE_END;
+ break;
+
+ case PU_AUXILIARY_DATA:
+ case PU_PADDING_DATA:
+ if (m_verbose)
+ std::cerr << "Ignoring Auxiliary/Padding data" << std::endl;
+ // Ignore auxiliary and padding data and continue parsing
+ break;
+ case PU_LOW_DELAY_PICTURE:
+ if (m_verbose)
+ std::cerr << "Low delay picture decoding not yet supported" << std::endl;
+ return STATE_INVALID;
+
+ default:
+ return STATE_INVALID;
+ }
+
+ }
+}
+
+const SourceParams& DiracParser::GetSourceParams() const
+{
+ return m_decomp->GetSourceParams();
+}
+
+const DecoderParams& DiracParser::GetDecoderParams() const
+{
+ return m_decomp->GetDecoderParams();
+}
+
+const ParseParams& DiracParser::GetParseParams() const
+{
+ return m_decomp->GetParseParams();
+}
+
+const PictureParams* DiracParser::GetNextPictureParams() const
+{
+ return m_decomp->GetNextPictureParams();
+}
+
+const Picture* DiracParser::GetNextPicture() const
+{
+ return m_decomp->GetNextPicture();
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.h
new file mode 100644
index 000000000..1634dd390
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_cppparser.h
@@ -0,0 +1,190 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_cppparser.h,v 1.8 2008/05/02 06:05:04 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+
+#ifndef DIRAC_CPPPARSER_H
+#define DIRAC_CPPPARSER_H
+
+#include <istream>
+#include <streambuf>
+#include <libdirac_decoder/decoder_types.h> //for DecoderState
+#include <libdirac_common/common.h>
+#include <libdirac_byteio/dirac_byte_stream.h>
+
+namespace dirac
+{
+ class SequenceDecompressor;
+ class Picture;
+
+ //! Input Stream Buffer Class.
+ class InputStreamBuffer : public std::streambuf
+ {
+ public:
+ //! Constructor
+ InputStreamBuffer ();
+
+ //! Destructor
+ ~InputStreamBuffer();
+
+ //! Rewind buffer to start of data
+ std::ios::pos_type Rewind();
+
+ //! Seek to position specified by bytes offset from pos
+ /*!
+ Seek takes
+ \param bytes offset in bytes
+ \param pos the position from which the offset is applied
+ */
+ std::ios::pos_type Seek(std::ios::pos_type bytes,
+ std::ios::seekdir pos = std::ios::cur);
+
+ //! Return the current read position in the buffer
+ std::ios::pos_type Tell();
+
+ //! Copy data into buffer
+ /*!
+ Copy take
+ \param start memory area start
+ \param bytes number of bytes to copy starting from start
+ */
+ void Copy(char *start, int bytes);
+
+ //! Delete all processed data from buffer
+ void PurgeProcessedData();
+
+ private:
+
+ //! Private body-less copy constructor
+ InputStreamBuffer (const InputStreamBuffer& inbuf);
+
+ //! Private body-less assignment operator
+ InputStreamBuffer& operator = (const InputStreamBuffer& inbuf);
+
+ //! Buffer size
+ static const int m_buffer_size = 1232896;
+
+ //! Buffere
+ char *m_chunk_buffer;
+ };
+
+ //! Dirac Stream Parser Class
+ /*!
+ This class is a wrapper around the SequenceDecompressor class. The
+ Sequence Decompressor class needs a full picture of data to be available
+ to decompress a picture successfully. So, the DiracParser class uses
+ the InputStreamBuffer class to store data until a chunk is available
+ to be processed and then invokes the SequenceDecompressor functions to
+ process data. A chunk of data can be a start of sequence, a picture or
+ end of sequence data. The istream used to instantiate the
+ SequenceDecompressor object is created using an InputStreamBuffer
+ object which is manipulated the DiracParser. This ensures that data is
+ always available for processing by the SequenceDecompressor object.
+ */
+ class DiracParser
+ {
+ public:
+ //! Constructor
+ /*!
+ Constructor takes
+ \param verbose boolean flag. Set to true for verbose output
+ */
+ DiracParser(bool verbose = false );
+
+ //! Destructor
+ ~DiracParser();
+
+ //! Adds bytes to encoder
+ /*! SetBuffer takes
+ \param start Start of input buffer
+ \param end End of input buffer
+ */
+ void SetBuffer (char *start, char *end);
+
+ //! Parse the data in internal buffer
+ /*!
+ Parses the data in the input buffer. This function returns one
+ of the following values
+ \n STATE_BUFFER : Not enough data in internal buffer to process
+ \n STATE_SEQUENCE : Start of sequence detected
+ \n STATE_PICTURE_AVAIL : Decoded picture available
+ \n STATE_SEQUENCE_END : End of sequence detected
+ \n STATE_INVALID : Invalid stream. Stop further processing
+ */
+ DecoderState Parse();
+
+ //! Return the parse parameters of the current sequence
+ const ParseParams& GetParseParams() const;
+
+ //! Return the source parameters of the current sequence
+ const SourceParams& GetSourceParams() const;
+
+ //! Return the picture parameters of the next picture to be decoded
+ const PictureParams* GetNextPictureParams() const;
+
+ //! Return the decoded picture
+ const Picture* GetNextPicture() const;
+
+ //! Return the coding parameters of the current sequence
+ const DecoderParams& GetDecoderParams() const;
+
+ private:
+
+ private:
+
+ //! private body-less copy constructor
+ DiracParser (const DiracParser &dp);
+ //! private body-less assignement constructor
+ DiracParser& operator = (const DiracParser &dp);
+ //! Current state of parser
+ DecoderState m_state;
+ //! Next state the parser will enter
+ DecoderState m_next_state;
+ //! picture number of last picture decoded in display order
+ int m_show_pnum;
+ //! Sequence decompressor object
+ SequenceDecompressor *m_decomp;
+ //! verbose flag
+ bool m_verbose;
+ //! Byte Stream Buffer
+ DiracByteStream m_dirac_byte_stream;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.cpp
new file mode 100644
index 000000000..629746634
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.cpp
@@ -0,0 +1,409 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_parser.cpp,v 1.22 2008/06/19 10:33:24 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <cstring>
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_decoder/dirac_cppparser.h>
+#include <libdirac_decoder/dirac_parser.h>
+#include <libdirac_common/dirac_exception.h>
+#include <libdirac_common/picture.h>
+#if defined (HAVE_MMX)
+#include <mmintrin.h>
+
+#endif
+using namespace dirac;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern DllExport dirac_decoder_t *dirac_decoder_init(int verbose)
+{
+ dirac_decoder_t* decoder = new dirac_decoder_t;
+ memset (decoder, 0, sizeof(dirac_decoder_t));
+
+ bool verbosity = verbose > 0 ? true : false;
+ DiracParser *parser = new DiracParser(verbosity);
+ decoder->parser = static_cast<void *>(parser);
+
+ decoder->fbuf = new dirac_framebuf_t;
+ decoder->fbuf->id = NULL;
+ decoder->fbuf->buf[0] = decoder->fbuf->buf[1] = decoder->fbuf->buf[2] = NULL;
+ return decoder;
+}
+
+extern DllExport void dirac_decoder_close(dirac_decoder_t *decoder)
+{
+ TEST (decoder != NULL);
+ TEST (decoder->parser != NULL);
+ DiracParser *parser = static_cast<DiracParser *>(decoder->parser);
+
+ delete parser;
+
+ delete decoder->fbuf;
+
+ delete decoder;
+
+ decoder = NULL;
+}
+
+extern DllExport void dirac_buffer (dirac_decoder_t *decoder, unsigned char *start, unsigned char *end)
+{
+ TEST (decoder != NULL);
+ TEST (decoder->parser != NULL);
+ DiracParser *parser = static_cast<DiracParser *>(decoder->parser);
+
+ parser->SetBuffer((char *)start, (char *)end);
+}
+
+static void set_sequence_params (const DiracParser * const parser, dirac_decoder_t *decoder)
+{
+ TEST (parser != NULL);
+ TEST (decoder != NULL);
+
+ dirac_sourceparams_t *src_params = &decoder->src_params;
+ dirac_parseparams_t *parse_params = &decoder->parse_params;
+ const SourceParams& srcparams = parser->GetSourceParams();
+ const ParseParams& pparams = parser->GetParseParams();
+
+ parse_params->major_ver = pparams.MajorVersion();
+ parse_params->minor_ver = pparams.MinorVersion();
+ parse_params->profile = pparams.Profile();
+ parse_params->level = pparams.Level();
+
+ src_params->width = srcparams.Xl();
+ src_params->height = srcparams.Yl();
+
+ src_params->chroma = (dirac_chroma_t)srcparams.CFormat();
+ src_params->chroma_width = srcparams.ChromaWidth();
+ src_params->chroma_height = srcparams.ChromaHeight();
+
+ // set the source parmeters
+ src_params->source_sampling = srcparams.SourceSampling();
+ src_params->topfieldfirst = srcparams.TopFieldFirst() ? 1 : 0;
+
+ src_params->frame_rate.numerator = srcparams.FrameRate().m_num;
+ src_params->frame_rate.denominator = srcparams.FrameRate().m_denom;
+
+ src_params->pix_asr.numerator = srcparams.PixelAspectRatio().m_num;
+ src_params->pix_asr.denominator = srcparams.PixelAspectRatio().m_denom;
+
+ // clean area
+ src_params->clean_area.width = srcparams.CleanWidth();
+ src_params->clean_area.height = srcparams.CleanHeight();
+ src_params->clean_area.left_offset = srcparams.LeftOffset();
+ src_params->clean_area.top_offset = srcparams.TopOffset();
+
+ // signal range
+ src_params->signal_range.luma_offset = srcparams.LumaOffset();
+ src_params->signal_range.luma_excursion = srcparams.LumaExcursion();
+ src_params->signal_range.chroma_offset = srcparams.ChromaOffset();
+ src_params->signal_range.chroma_excursion = srcparams.ChromaExcursion();
+
+ // Colour specfication
+ src_params->colour_spec.col_primary = srcparams.ColourPrimariesIndex();
+ src_params->colour_spec.trans_func = srcparams.TransferFunctionIndex();
+ switch(srcparams.ColourMatrixIndex())
+ {
+ case CM_SDTV:
+ src_params->colour_spec.col_matrix.kr = 0.299f;
+ src_params->colour_spec.col_matrix.kb = 0.114f;
+ break;
+ case CM_REVERSIBLE:
+ src_params->colour_spec.col_matrix.kr = 0.25f;
+ src_params->colour_spec.col_matrix.kb = 0.25f;
+ break;
+ case CM_HDTV_COMP_INTERNET:
+ default:
+ src_params->colour_spec.col_matrix.kr = 0.2126f;
+ src_params->colour_spec.col_matrix.kb = 0.0722f;
+ break;
+ }
+}
+
+static void set_frame_component (const PicArray& pic_data, const CompSort cs, dirac_decoder_t *decoder)
+{
+ TEST (decoder->fbuf != NULL);
+ int xl, yl;
+
+ unsigned char *buf;
+
+ switch (cs)
+ {
+ case U_COMP:
+ xl = decoder->src_params.chroma_width;
+ yl = decoder->src_params.chroma_height;
+ buf = decoder->fbuf->buf[1];
+ break;
+ case V_COMP:
+ xl = decoder->src_params.chroma_width;
+ yl = decoder->src_params.chroma_height;
+ buf = decoder->fbuf->buf[2];
+ break;
+
+ case Y_COMP:
+ default:
+ xl = decoder->src_params.width;
+ yl = decoder->src_params.height;
+ buf = decoder->fbuf->buf[0];
+ break;
+ }
+
+ TEST (buf != NULL);
+
+#if defined HAVE_MMX
+ int last_idx = (xl>>3)<<3;
+ __m64 tmp = _mm_set_pi16(128, 128, 128, 128);
+ for (int j=0 ; j<yl ;++j)
+ {
+ for (int i=0 ; i<last_idx ; i+=8 )
+ {
+ __m64 pic1 = *(__m64 *)&pic_data[j][i];
+ pic1 = _mm_add_pi16 (pic1, tmp);
+ __m64 pic2 = *(__m64 *)(&pic_data[j][i+4]);
+ pic2 = _mm_add_pi16 (pic2, tmp);
+ __m64 *tmp = (__m64 *)&buf[j*xl+i];
+ *tmp = _mm_packs_pu16 (pic1, pic2);
+ }//i
+ }//j
+ _mm_empty();
+
+ // mop up remaining pixels
+ for (int j=0 ; j<yl ;++j)
+ {
+ for (int i=last_idx ; i<xl ; i++ )
+ {
+ buf[j*xl+i]=(unsigned char) (pic_data[j][i]+128);
+ }//i
+ }//j
+ return;
+#else
+
+ for (int j=0 ; j<yl ;++j)
+ {
+ for (int i=0 ; i<xl ; ++i)
+ {
+ buf[j*xl+i]=(unsigned char) (pic_data[j][i]+128);
+ }//i
+ }//j
+
+#endif
+}
+
+static void set_field_component (const PicArray& pic_data, const CompSort cs, dirac_decoder_t *decoder, unsigned int pic_num)
+{
+ TEST (decoder->fbuf != NULL);
+ int xl, yl;
+
+ unsigned char *buf;
+
+ switch (cs)
+ {
+ case U_COMP:
+ xl = decoder->src_params.chroma_width;
+ yl = decoder->src_params.chroma_height;
+ buf = decoder->fbuf->buf[1];
+ break;
+ case V_COMP:
+ xl = decoder->src_params.chroma_width;
+ yl = decoder->src_params.chroma_height;
+ buf = decoder->fbuf->buf[2];
+ break;
+
+ case Y_COMP:
+ default:
+ xl = decoder->src_params.width;
+ yl = decoder->src_params.height;
+ buf = decoder->fbuf->buf[0];
+ break;
+ }
+
+ TEST (buf != NULL);
+
+ // Seek offset before writing field to store
+ int start = 0;
+ // Seek offset between writing fields to store
+ int skip = 0;
+
+
+ bool top_field = decoder->src_params.topfieldfirst ? (!(pic_num%2)) :
+ (pic_num%2);
+
+ if (top_field) // i.e. top field
+ {
+ start = 0;
+ skip = 2 * xl * sizeof(char);
+ }
+ else // else bottom field
+ {
+ start = xl;
+ skip = 2 * xl * sizeof(char);
+ }
+
+ unsigned char *tempc = buf + start;
+
+ int field_yl = yl>>1;
+ int field_xl = xl;
+
+ for (int j=0 ; j<field_yl ;++j)
+ {
+ for (int i=0 ; i<field_xl ; ++i)
+ {
+ tempc[i] = (unsigned char) (pic_data[j][i]+128);
+ }//I
+ tempc += skip;
+ }
+}
+
+static void set_frame_data (const DiracParser * const parser, dirac_decoder_t *decoder)
+{
+ TEST (parser != NULL);
+ TEST (decoder != NULL);
+ TEST (decoder->fbuf != NULL);
+ TEST (decoder->state == STATE_PICTURE_AVAIL);
+
+ const Picture* my_picture = parser->GetNextPicture();
+
+ if (my_picture)
+ {
+ int pic_num = my_picture->GetPparams().PictureNum();
+
+ if (!parser->GetDecoderParams().FieldCoding())
+ {
+ set_frame_component (my_picture->Data(Y_COMP), Y_COMP, decoder);
+ set_frame_component (my_picture->Data(U_COMP), U_COMP, decoder);
+ set_frame_component (my_picture->Data(V_COMP), V_COMP, decoder);
+ }
+ else
+ {
+ set_field_component (my_picture->Data(Y_COMP), Y_COMP, decoder, pic_num);
+ set_field_component (my_picture->Data(U_COMP), U_COMP, decoder, pic_num);
+ set_field_component (my_picture->Data(V_COMP), V_COMP, decoder, pic_num);
+ }
+ }
+ return;
+}
+
+extern DllExport dirac_decoder_state_t dirac_parse (dirac_decoder_t *decoder)
+{
+ TEST (decoder != NULL);
+ TEST (decoder->parser != NULL);
+ DiracParser *parser = static_cast<DiracParser *>(decoder->parser);
+
+ unsigned int pic_num;
+
+ while(true)
+ {
+ try
+ {
+ decoder->state = parser->Parse();
+
+ switch (decoder->state)
+ {
+ case STATE_BUFFER:
+ return decoder->state;
+ break;
+
+ case STATE_SEQUENCE:
+ set_sequence_params(parser, decoder);
+ decoder->frame_avail = 0;
+ return decoder->state;
+ break;
+
+ case STATE_PICTURE_AVAIL:
+ {
+ const Picture *my_picture = parser->GetNextPicture();
+ if (my_picture)
+ {
+ pic_num = parser->GetNextPicture()->GetPparams().PictureNum();
+ decoder->frame_num = pic_num;
+ set_frame_data (parser, decoder);
+
+ /* A full frame is only available if we're doing
+ * progressive coding or have decoded the second field.
+ * Will only return when a full frame is available
+ */
+ if (!parser->GetDecoderParams().FieldCoding() ||
+ pic_num%2)
+ {
+ /* Frame number currently available for display */
+ decoder->frame_num = pic_num;
+ if (parser->GetDecoderParams().FieldCoding())
+ decoder->frame_num = pic_num>>1;
+ decoder->frame_avail = 1;
+ return decoder->state;
+ }
+ }
+ break;
+ }
+
+ case STATE_INVALID:
+ return decoder->state;
+ break;
+
+ case STATE_SEQUENCE_END:
+ return decoder->state;
+ break;
+
+ default:
+ break;
+ }
+ }//try
+ catch (const DiracException& e)
+ {
+ return STATE_INVALID;
+ }
+ }
+
+ return decoder->state;
+}
+
+extern DllExport void dirac_set_buf (dirac_decoder_t *decoder, unsigned char *buf[3], void *id)
+{
+ TEST (decoder != NULL);
+ TEST (decoder->fbuf != NULL);
+
+ decoder->fbuf->buf[0] = buf[0];
+ decoder->fbuf->buf[1] = buf[1];
+ decoder->fbuf->buf[2] = buf[2];
+ decoder->fbuf->id = id;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.h
new file mode 100644
index 000000000..75bdcc7c2
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/dirac_parser.h
@@ -0,0 +1,183 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_parser.h,v 1.8 2008/02/13 03:36:11 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef DIRAC_PARSER_H
+#define DIRAC_PARSER_H
+
+#include <libdirac_common/dirac_types.h>
+#include <libdirac_decoder/decoder_types.h>
+
+/*! \file
+\brief C interface to Dirac decoder.
+
+ A set of 'C' functions that define the public interface to the Dirac decoder.
+ Refer to the the reference decoder source code, decoder/decmain.cpp for
+ an example of how to use the "C" interface. The pseudocode below gives
+ a brief description of the "C" interface usage.
+
+\verbatim
+ #include <libdirac_decoder/dirac_parser.h>/n
+ Initialise the decoder
+
+ dirac_decoder_t *decoder_handle = dirac_decoder_init();
+ do
+ {
+ dirac_decoder_state_t state = dirac_parse (decoder_handle);
+ switch (state)
+ {
+ case STATE_BUFFER:
+ read more data.
+ Pass data to the decoder.
+ dirac_buffer (decoder_handle, data_start, data_end)
+ break;
+
+ case STATE_SEQUENCE:
+ handle start of sequence.
+ The decoder returns the sequence parameters in the
+ seq_params member of the decoder handle.
+ Allocate space for the frame data buffers and pass
+ this to the decoder.
+ dirac_set_buf (decoder_handle, buf, NULL);
+ break;
+
+ case STATE_SEQUENCE_END:
+ Deallocate frame data buffers
+ break;
+
+ case STATE_PICTURE_AVAIL:
+ Handle picture data.
+ The decoder sets the fbuf member in the decoder
+ handle to the frame decoded.
+ break;
+
+ case STATE_INVALID:
+ Unrecoverable error. Stop all processing
+ break;
+ }
+ } while (data available && decoder state != STATE_INVALID
+
+ Free the decoder resources
+ dirac_decoder_close(decoder_handle)
+ \endverbatim
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef DecoderState dirac_decoder_state_t;
+
+/*! Structure that holds the information returned by the parser */
+typedef struct
+{
+ /*! parser state */
+ dirac_decoder_state_t state;
+ /*! parse parameters */
+ dirac_parseparams_t parse_params;
+ /*! source parameters */
+ dirac_sourceparams_t src_params;
+ /*! frame (NOT picture) number */
+ unsigned int frame_num;
+ /*! void pointer to internal parser */
+ void *parser;
+ /*! frame (NOT picture) buffer to hold luma and chroma data */
+ dirac_framebuf_t *fbuf;
+ /*! boolean flag that indicates if a decoded frame (NOT picture) is available */
+ int frame_avail;
+ /*! verbose output */
+ int verbose;
+
+} dirac_decoder_t;
+
+/*!
+ Decoder Init
+ Initialise the decoder.
+ \param verbose boolean flag to set verbose output
+ \return decoder handle
+*/
+extern DllExport dirac_decoder_t *dirac_decoder_init(int verbose);
+
+/*!
+ Release the decoder resources
+ \param decoder Decoder object
+*/
+extern DllExport void dirac_decoder_close(dirac_decoder_t *decoder);
+
+/*!
+ Parses the data in the input buffer. This function returns the
+ following values.
+ \n STATE_BUFFER: Not enough data in internal buffer to process
+ \n STATE_SEQUENCE: Start of sequence detected. The seq_params member
+ in the decoder object is set to the details of the
+ next sequence to be processed.
+ \n STATE_PICTURE_START: Start of picture detected. The frame_params member
+ of the decoder object is set to the details of the
+ next frame to be processed.
+ \n STATE_PICTURE_AVAIL: Decoded picture available. The frame_aprams member
+ of the decoder object is set the the details of
+ the decoded frame available. The fbuf member of
+ the decoder object has the luma and chroma data of
+ the decompressed frame.
+ \n STATE_SEQUENCE_END: End of sequence detected.
+ \n STATE_INVALID: Invalid stream. Stop further processing.
+
+ \param decoder Decoder object
+ \return Decoder state
+
+*/
+extern DllExport dirac_decoder_state_t dirac_parse (dirac_decoder_t *decoder);
+
+/*!
+ Copy data into internal buffer
+ \param decoder Decoder object
+ \param start Start of data
+ \param end End of data
+*/
+extern DllExport void dirac_buffer (dirac_decoder_t *decoder, unsigned char *start, unsigned char *end);
+
+/*!
+ Set the output buffer into which the decoder copies the decoded data
+ \param decoder Decoder object
+ \param buf Array of char buffers to hold luma and chroma data
+ \param id User data
+*/
+extern DllExport void dirac_set_buf (dirac_decoder_t *decoder, unsigned char *buf[3], void *id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.cpp
new file mode 100644
index 000000000..fe413551f
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.cpp
@@ -0,0 +1,372 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_decompress.cpp,v 1.9 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju,
+* Andrew Kennedy,
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+//Decompression of pictures
+/////////////////////////
+
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_decoder/picture_decompress.h>
+#include <libdirac_decoder/comp_decompress.h>
+#include <libdirac_common/mot_comp.h>
+#include <libdirac_common/mv_codec.h>
+#include <libdirac_byteio/picture_byteio.h>
+#include <libdirac_common/dirac_exception.h>
+using namespace dirac;
+
+#include <iostream>
+#include <memory>
+
+using std::vector;
+using std::auto_ptr;
+
+PictureDecompressor::PictureDecompressor(DecoderParams& decp, ChromaFormat cf)
+:
+m_decparams(decp),
+m_cformat(cf)
+{
+}
+
+PictureDecompressor::~PictureDecompressor()
+{
+}
+
+
+bool PictureDecompressor::Decompress(ParseUnitByteIO& parseunit_byteio,
+ PictureBuffer& my_buffer)
+{
+ // get current byte position
+ //int start_pos = parseunit_byteio.GetReadBytePosition();
+ try {
+
+ // read picture data
+ PictureByteIO picture_byteio(m_pparams,
+ parseunit_byteio);
+
+ picture_byteio.Input();
+
+ PictureSort fs;
+
+ if (m_pparams.GetPictureType() == INTRA_PICTURE)
+ fs.SetIntra();
+ else
+ fs.SetInter();
+
+ if (m_pparams.GetReferenceType() == REFERENCE_PICTURE)
+ fs.SetRef();
+ else
+ fs.SetNonRef();
+
+ m_pparams.SetPicSort(fs);
+
+ if (m_pparams.GetReferenceType() == REFERENCE_PICTURE)
+ // Now clean the reference pictures from the buffer
+ CleanReferencePictures( my_buffer );
+
+ // Check if the picture can be decoded
+ if (m_pparams.PicSort().IsInter()){
+ const std::vector<int>& refs = m_pparams.Refs();
+
+ for (unsigned int i = 0; i < refs.size(); ++i)
+ if ( !my_buffer.IsPictureAvail(refs[i]) )
+ return false;
+ }
+
+ // decode the rest of the picture
+
+ if ( m_decparams.Verbose() ){
+ std::cout<<std::endl<<"Decoding picture "<<m_pparams.PictureNum()<<" in display order";
+ if ( m_pparams.PicSort().IsInter() ){
+ std::cout<<std::endl<<"References: "<<m_pparams.Refs()[0];
+ if ( m_pparams.Refs().size()>1 )
+ std::cout<<" and "<<m_pparams.Refs()[1];
+ }
+ }
+
+ PictureSort psort = m_pparams.PicSort();
+ auto_ptr<MvData> mv_data;
+
+ if ( psort.IsInter() )
+ //do all the MV stuff
+ DecompressMVData( mv_data, picture_byteio );
+
+ // Read the transform header
+ TransformByteIO transform_byteio(picture_byteio, m_pparams, m_decparams);
+ transform_byteio.Input();
+
+ if (m_pparams.PicSort().IsIntra() && m_decparams.ZeroTransform()){
+ DIRAC_THROW_EXCEPTION(
+ ERR_UNSUPPORTED_STREAM_DATA,
+ "Intra pictures cannot have Zero-Residual",
+ SEVERITY_PICTURE_ERROR);
+ }
+
+ // Add a picture to the buffer to decode into
+ PushPicture(my_buffer);
+
+ //Reference to the picture being decoded
+ Picture& my_picture = my_buffer.GetPicture(m_pparams.PictureNum());
+
+ if (!m_decparams.ZeroTransform()){
+ //decode components
+ Picture& pic = my_buffer.GetPicture( m_pparams.PictureNum() );
+
+ CompDecompressor my_compdecoder( m_decparams , pic.GetPparams() );
+
+ PicArray* comp_data[3];
+ CoeffArray* coeff_data[3];
+
+ const int depth( m_decparams.TransformDepth() );
+ WaveletTransform wtransform( depth, m_decparams.TransformFilter() );
+
+ pic.InitWltData( depth );
+
+ for (int c=0; c<3; ++c){
+ ComponentByteIO component_byteio((CompSort) c, transform_byteio);
+ comp_data[c] = &pic.Data((CompSort) c);
+ coeff_data[c] = &pic.WltData((CompSort) c);
+
+ SubbandList& bands = coeff_data[c]->BandList();
+
+ bands.Init(depth , coeff_data[c]->LengthX() , coeff_data[c]->LengthY());
+ my_compdecoder.Decompress(&component_byteio, *(coeff_data[c]), bands );
+
+ wtransform.Transform(BACKWARD,*(comp_data[c]), *(coeff_data[c]));
+ }
+ }
+ else
+ my_picture.Fill(0);
+
+ if ( psort.IsInter() ){
+ Picture* my_pic = &my_buffer.GetPicture( m_pparams.PictureNum() );
+
+ const std::vector<int>& refs = m_pparams.Refs();
+ Picture* ref_pics[2];
+
+ ref_pics[0] = &my_buffer.GetPicture( refs[0] );
+ if (refs.size()>1)
+ ref_pics[1] = &my_buffer.GetPicture( refs[1] );
+ else
+ ref_pics[1] = ref_pics[0];
+
+ //motion compensate to add the data back in if we don't have an I picture
+ MotionCompensator::CompensatePicture( m_decparams.GetPicPredParams() , ADD , *(mv_data.get()) ,
+ my_pic, ref_pics );
+ }
+
+ my_picture.Clip();
+
+ if (m_decparams.Verbose())
+ std::cout<<std::endl;
+
+
+ //exit success
+ return true;
+
+ }// try
+ catch (const DiracException& e) {
+ // skip picture
+ throw e;
+ }
+
+ //exit failure
+ return false;
+}
+
+void PictureDecompressor::CleanReferencePictures( PictureBuffer& my_buffer )
+{
+ if ( m_decparams.Verbose() )
+ std::cout<<std::endl<<"Cleaning reference buffer: ";
+ // Do picture buffer cleaning
+ int retd_pnum = m_pparams.RetiredPictureNum();
+
+ if ( retd_pnum >= 0 && my_buffer.IsPictureAvail(retd_pnum) && my_buffer.GetPicture(retd_pnum).GetPparams().PicSort().IsRef() )
+ {
+ my_buffer.Remove(retd_pnum);
+ if ( m_decparams.Verbose() )
+ std::cout<<retd_pnum<<" ";
+ }
+}
+
+void PictureDecompressor::SetMVBlocks()
+{
+ PicturePredParams& predparams = m_decparams.GetPicPredParams();
+ OLBParams olb_params = predparams.LumaBParams(2);
+ predparams.SetBlockSizes(olb_params, m_cformat);
+
+ // Calculate the number of macro blocks
+ int xnum_sb = (m_decparams.Xl()+predparams.LumaBParams(0).Xbsep()-1)/
+ predparams.LumaBParams(0).Xbsep();
+ int ynum_sb = (m_decparams.Yl()+predparams.LumaBParams(0).Ybsep()-1)/
+ predparams.LumaBParams(0).Ybsep();
+
+ predparams.SetXNumSB(xnum_sb);
+ predparams.SetYNumSB(ynum_sb);
+
+ // Set the number of blocks
+ predparams.SetXNumBlocks(4*xnum_sb);
+ predparams.SetYNumBlocks(4*ynum_sb);
+
+ // Note that we do not have an integral number of superblocks in a picture
+ // So it is possible that part of a superblock and some blocks can fall
+ // of the edge of the true picture. We need to take this into
+ // consideration while doing Motion Compensation
+}
+
+void PictureDecompressor::PushPicture(PictureBuffer &my_buffer)
+{
+ m_pparams.SetCFormat(m_cformat);
+
+ m_pparams.SetXl(m_decparams.Xl());
+ m_pparams.SetYl(m_decparams.Yl());
+
+ m_pparams.SetLumaDepth(m_decparams.LumaDepth());
+ m_pparams.SetChromaDepth(m_decparams.ChromaDepth());
+
+ my_buffer.PushPicture(m_pparams);
+}
+
+void PictureDecompressor::DecompressMVData( std::auto_ptr<MvData>& mv_data,
+ PictureByteIO& picture_byteio )
+{
+ PicturePredParams& predparams = m_decparams.GetPicPredParams();
+ MvDataByteIO mvdata_byteio (picture_byteio, m_pparams, predparams);
+
+ // Read in the picture prediction parameters
+ mvdata_byteio.Input();
+
+ SetMVBlocks();
+ mv_data.reset(new MvData( predparams, m_pparams.NumRefs() ));
+
+ // decode mv data
+ if (m_decparams.Verbose())
+ std::cout<<std::endl<<"Decoding motion data ...";
+
+ int num_bits;
+
+ // Read in the split mode data header
+ mvdata_byteio.SplitModeData()->Input();
+ // Read the mode data
+ num_bits = mvdata_byteio.SplitModeData()->DataBlockSize();
+ SplitModeCodec smode_decoder( mvdata_byteio.SplitModeData()->DataBlock(), TOTAL_MV_CTXS);
+ smode_decoder.Decompress( *(mv_data.get()) , num_bits);
+
+ // Read in the prediction mode data header
+ mvdata_byteio.PredModeData()->Input();
+ // Read the mode data
+ num_bits = mvdata_byteio.PredModeData()->DataBlockSize();
+ PredModeCodec pmode_decoder( mvdata_byteio.PredModeData()->DataBlock(), TOTAL_MV_CTXS, m_pparams.NumRefs());
+ pmode_decoder.Decompress( *(mv_data.get()) , num_bits);
+
+ // Read in the MV1 horizontal data header
+ mvdata_byteio.MV1HorizData()->Input();
+ // Read the MV1 horizontal data
+ num_bits = mvdata_byteio.MV1HorizData()->DataBlockSize();
+ VectorElementCodec vdecoder1h( mvdata_byteio.MV1HorizData()->DataBlock(), 1,
+ HORIZONTAL, TOTAL_MV_CTXS);
+ vdecoder1h.Decompress( *(mv_data.get()) , num_bits);
+
+ // Read in the MV1 vertical data header
+ mvdata_byteio.MV1VertData()->Input();
+ // Read the MV1 data
+ num_bits = mvdata_byteio.MV1VertData()->DataBlockSize();
+ VectorElementCodec vdecoder1v( mvdata_byteio.MV1VertData()->DataBlock(), 1,
+ VERTICAL, TOTAL_MV_CTXS);
+ vdecoder1v.Decompress( *(mv_data.get()) , num_bits);
+
+ if ( m_pparams.NumRefs()>1 )
+ {
+ // Read in the MV2 horizontal data header
+ mvdata_byteio.MV2HorizData()->Input();
+ // Read the MV2 horizontal data
+ num_bits = mvdata_byteio.MV2HorizData()->DataBlockSize();
+ VectorElementCodec vdecoder2h( mvdata_byteio.MV2HorizData()->DataBlock(), 2,
+ HORIZONTAL, TOTAL_MV_CTXS);
+ vdecoder2h.Decompress( *(mv_data.get()) , num_bits);
+
+ // Read in the MV2 vertical data header
+ mvdata_byteio.MV2VertData()->Input();
+ // Read the MV2 vertical data
+ num_bits = mvdata_byteio.MV2VertData()->DataBlockSize();
+ VectorElementCodec vdecoder2v( mvdata_byteio.MV2VertData()->DataBlock(), 2,
+ VERTICAL, TOTAL_MV_CTXS);
+ vdecoder2v.Decompress( *(mv_data.get()) , num_bits);
+ }
+
+ // Read in the Y DC data header
+ mvdata_byteio.YDCData()->Input();
+ // Read the Y DC data
+ num_bits = mvdata_byteio.YDCData()->DataBlockSize();
+ DCCodec ydc_decoder( mvdata_byteio.YDCData()->DataBlock(), Y_COMP, TOTAL_MV_CTXS);
+ ydc_decoder.Decompress( *(mv_data.get()) , num_bits);
+
+ // Read in the U DC data header
+ mvdata_byteio.UDCData()->Input();
+ // Read the U DC data
+ num_bits = mvdata_byteio.UDCData()->DataBlockSize();
+ DCCodec udc_decoder( mvdata_byteio.YDCData()->DataBlock(), U_COMP, TOTAL_MV_CTXS);
+ udc_decoder.Decompress( *(mv_data.get()) , num_bits);
+
+ // Read in the Y DC data header
+ mvdata_byteio.YDCData()->Input();
+ // Read the Y DC data
+ num_bits = mvdata_byteio.YDCData()->DataBlockSize();
+ DCCodec vdc_decoder( mvdata_byteio.VDCData()->DataBlock(), V_COMP, TOTAL_MV_CTXS);
+ vdc_decoder.Decompress( *(mv_data.get()) , num_bits);
+}
+
+void PictureDecompressor::InitCoeffData( CoeffArray& coeff_data, const int xl, const int yl ){
+
+ // First set the dimensions up //
+ int xpad_len = xl;
+ int ypad_len = yl;
+
+ // The pic dimensions must be a multiple of 2^(transform depth)
+ int tx_mul = (1<<m_decparams.TransformDepth());
+
+ if ( xpad_len%tx_mul != 0 )
+ xpad_len = ( (xpad_len/tx_mul)+1 ) *tx_mul;
+ if ( ypad_len%tx_mul != 0 )
+ ypad_len = ( (ypad_len/tx_mul)+1 ) * tx_mul;
+
+ coeff_data.Resize( ypad_len, xpad_len );
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.h
new file mode 100644
index 000000000..31efbe5db
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/picture_decompress.h
@@ -0,0 +1,156 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_decompress.h,v 1.2 2008/04/29 08:51:52 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+
+#ifndef _PICTURE_DECOMPRESS_H_
+#define _PICTURE_DECOMPRESS_H_
+
+#include <libdirac_common/picture_buffer.h>
+#include <libdirac_common/common.h>
+#include <libdirac_byteio/picture_byteio.h>
+#include <libdirac_byteio/transform_byteio.h>
+
+namespace dirac
+{
+ class MvData;
+
+ //! Compress a single image picture
+ /*!
+ This class decompresses a single picture at a time, using parameters
+ supplied at its construction. PictureDecompressor is used by
+ SequenceDecompressor.
+ */
+ class PictureDecompressor{
+ public:
+ //! Constructor
+ /*!
+ Creates a PictureDecompressor with specific set of parameters the
+ control the decompression process. It decodes motion data before
+ decoding each component of the picture.
+
+ \param decp decoder parameters
+ \param cf the chroma format of the picture being decompressed
+ */
+ PictureDecompressor(DecoderParams& decp, ChromaFormat cf);
+
+ //! Destructor
+ /*!
+ Releases resources.
+ */
+ ~PictureDecompressor();
+
+ //! Decompress the next picture into the buffer
+ /*!
+ Decompresses the next picture from the stream and place at the end
+ of a picture buffer.
+ Returns true if able to decode successfully, false otherwise
+
+ \param parseunit_byteio Picture info in Dirac-stream format
+ \param my_buffer picture buffer into which the picture is placed
+ */
+ bool Decompress(ParseUnitByteIO& parseunit_byteio,
+ PictureBuffer& my_buffer);
+
+ //! Returns the picture parameters of the current picture being decoded
+ const PictureParams& GetPicParams() const{ return m_pparams; }
+
+ private:
+ //! Copy constructor is private and body-less
+ /*!
+ Copy constructor is private and body-less. This class should not be copied.
+
+ */
+ PictureDecompressor(const PictureDecompressor& cpy);
+
+ //! Assignment = is private and body-less
+ /*!
+ Assignment = is private and body-less. This class should not be
+ assigned.
+ */
+ PictureDecompressor& operator=(const PictureDecompressor& rhs);
+
+ //! Initialise the padded coefficient data for the IDWT and subband decoding
+ void InitCoeffData( CoeffArray& coeff_data, const int xl, const int yl );
+
+ //! Removes all the reference pictures in the retired list
+ void CleanReferencePictures( PictureBuffer& my_buffer );
+
+ //! Decodes component data
+ void CompDecompress(TransformByteIO *p_transform_byteio,
+ PictureBuffer& my_buffer,int pnum, CompSort cs);
+
+ //! Decodes the motion data
+ void DecompressMVData( std::auto_ptr<MvData>& mv_data, PictureByteIO& picture_byteio );
+
+
+ //! Set the number of superblocks and blocks
+ void SetMVBlocks();
+
+ //! Add a picture to the picture buffer
+ void PushPicture(PictureBuffer &my_buffer);
+
+ //Member variables
+
+ //! Parameters for the decompression, as provided in constructor
+ DecoderParams& m_decparams;
+
+ //! Chroma format of the picture being decompressed
+ ChromaFormat m_cformat;
+
+ //! An indicator which is true if the picture has been skipped, false otherwise
+ bool m_skipped;
+
+ //! An indicator that is true if we use global motion vectors, false otherwise
+ bool m_use_global;
+
+ //! An indicator that is true if we use block motion vectors, false otherwise
+ bool m_use_block_mv;
+
+ //! Prediction mode to use if we only have global motion vectors
+ PredMode m_global_pred_mode;
+
+ //! Current Picture Parameters
+ PictureParams m_pparams;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.cpp
new file mode 100644
index 000000000..09421e934
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.cpp
@@ -0,0 +1,170 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: seq_decompress.cpp,v 1.25 2008/08/14 00:51:08 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Anuradha Suraparaju,
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+///////////////////////////////////////////
+//---------------------------------------//
+//Class to manage decompressing sequences//
+//---------------------------------------//
+///////////////////////////////////////////
+
+#include <libdirac_common/video_format_defaults.h>
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_decoder/seq_decompress.h>
+#include <libdirac_common/common.h>
+#include <libdirac_common/picture_buffer.h>
+#include <libdirac_decoder/picture_decompress.h>
+#include <libdirac_byteio/accessunit_byteio.h>
+using namespace dirac;
+
+SequenceDecompressor::SequenceDecompressor(ParseUnitByteIO& parseunit,bool verbosity)
+:
+m_all_done(false),
+m_current_code_pnum(0),
+m_delay(1),
+m_show_pnum(-1),
+m_highest_pnum(0)
+{
+ // read unit
+ NewAccessUnit(parseunit);
+
+ if ( m_decparams.FieldCoding() )
+ m_delay = 2;
+
+ m_decparams.SetVerbose( verbosity );
+
+ m_pbuffer= new PictureBuffer( );
+
+ m_pdecoder = new PictureDecompressor (m_decparams , m_srcparams.CFormat());
+
+}
+
+SequenceDecompressor::~SequenceDecompressor()
+{
+ delete m_pbuffer;
+ delete m_pdecoder;
+}
+
+const PictureParams* SequenceDecompressor::GetNextPictureParams() const
+{
+ return &m_pdecoder->GetPicParams();
+}
+
+void SequenceDecompressor::NewAccessUnit(ParseUnitByteIO& parseunit_byteio)
+{
+ // read sequence header
+ SequenceHeaderByteIO seqheader_byteio(parseunit_byteio,m_parse_params, m_srcparams, m_decparams);
+ seqheader_byteio.Input();
+
+}
+
+const Picture* SequenceDecompressor::DecompressNextPicture(ParseUnitByteIO* p_parseunit_byteio)
+{
+ //this function decodes the next picture in coding order and returns the next picture in display order
+ //In general these will differ, and because of re-ordering there is a m_delay which needs to be imposed.
+ //This creates problems at the start and at the end of the sequence which must be dealt with.
+ //At the start we just keep outputting picture 0. At the end you will need to loop for longer to get all
+ //the pictures out. It's up to the calling function to do something with the decoded pictures as they
+ //come out - write them to screen or to file, as required.
+
+ TEST (m_pdecoder != NULL);
+
+ // Remove the last displayed picture from the buffer if it wasn't a reference
+ if ( m_show_pnum>0 )
+ {
+ if ( m_decparams.Verbose() )
+ std::cout<<std::endl<<"Cleaning display buffer: ";
+ if ( m_pbuffer->IsPictureAvail(m_show_pnum-1) &&
+ m_pbuffer->GetPicture(m_show_pnum-1).GetPparams().PicSort().IsNonRef() )
+ {
+ m_pbuffer->Remove(m_show_pnum-1);
+ if ( m_decparams.Verbose() )
+ std::cout<<(m_show_pnum-1)<<" ";
+ }
+ }
+
+ bool new_picture_to_display=false;
+
+ if (p_parseunit_byteio)
+ {
+ if (m_decparams.Verbose())
+ std::cout<<std::endl<<"Calling picture decompression function";
+ new_picture_to_display = m_pdecoder->Decompress(*p_parseunit_byteio,
+ *m_pbuffer);
+ }
+
+ if (m_show_pnum < 0 && new_picture_to_display == false)
+ return NULL;
+
+ if (m_pbuffer->IsPictureAvail(m_show_pnum+1 ))
+ ++m_show_pnum;
+ else if (new_picture_to_display && m_pdecoder->GetPicParams().PicSort().IsNonRef())
+ {
+ // if a decoded future non reference frame is available it implies
+ // that some frames have been skipped because of possible truncation
+ // errors
+ m_show_pnum = m_pdecoder->GetPicParams().PictureNum();
+ }
+
+ m_highest_pnum = std::max(m_pdecoder->GetPicParams().PictureNum(), m_highest_pnum);
+
+ if (m_pbuffer->IsPictureAvail(m_show_pnum))
+ return &m_pbuffer->GetPicture(m_show_pnum);
+ else
+ return NULL;
+}
+
+const Picture* SequenceDecompressor::GetNextPicture()
+{
+ if (m_pbuffer->IsPictureAvail(m_show_pnum))
+ return &m_pbuffer->GetPicture(m_show_pnum);
+ else
+ return NULL;
+}
+
+bool SequenceDecompressor::Finished()
+{
+ if (m_show_pnum>=m_highest_pnum)
+ return true;
+
+ if (!m_pbuffer->IsPictureAvail(m_show_pnum+1 ))
+ ++m_show_pnum;
+
+ return false;
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.h
new file mode 100644
index 000000000..008ffc11d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_decoder/seq_decompress.h
@@ -0,0 +1,190 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: seq_decompress.h,v 1.13 2008/05/02 06:05:04 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _SEQ_DECOMPRESS_H_
+#define _SEQ_DECOMPRESS_H_
+
+///////////////////////////////////////////
+//---------------------------------------//
+//Class to manage decompressing sequences//
+//---------------------------------------//
+///////////////////////////////////////////
+
+#include "libdirac_common/common.h"
+#include "libdirac_byteio/parseunit_byteio.h"
+#include <iostream>
+
+namespace dirac
+{
+ class PictureBuffer;
+ class Picture;
+ class PictureDecompressor;
+
+ //! Decompresses a sequence of pictures from a stream.
+ /*!
+ This class decompresses a sequence of frames, picture by picture.
+ */
+ class SequenceDecompressor{
+ public:
+
+ //! Constructor
+ /*!
+ Initializes the decompressor with an input stream and level of
+ output detail.
+ \param parseunit First access-unit of new sequence
+ \param verbosity when true, increases the amount of information displayed during decompression
+ */
+ SequenceDecompressor(ParseUnitByteIO& parseunit, bool verbosity);
+
+ //! Destructor
+ /*!
+ Closes files and releases resources.
+ */
+ ~SequenceDecompressor();
+
+ //! Marks beginning of a new AccessUnit
+ /*!
+ \param parseunit_byteio AccessUnit info in Dirac-stream format
+ */
+ void NewAccessUnit(ParseUnitByteIO& parseunit_byteio);
+
+
+ //! Decompress the next picture in sequence
+ /*!
+ This function decodes the next picture in coding order and returns
+ the next picture in display order. In general these will differ, and
+ because of re-ordering there is a delay which needs to be imposed.
+ This creates problems at the start and at the end of the sequence
+ which must be dealt with. At the start we just keep outputting
+ picture 0. At the end you will need to loop for longer to get all
+ the pictures out. It's up to the calling function to do something
+ with the decoded pictures as they come out -- write them to screen
+ or to file, as required.
+
+ \param p_parseunit_byteio Picture information in Dirac-stream format
+ \return reference to the next locally decoded picture available for display
+ */
+ const Picture* DecompressNextPicture(ParseUnitByteIO* p_parseunit_byteio);
+
+ //! Get the next picture available for display
+ const Picture* GetNextPicture();
+
+ //! Get the next picture parameters
+ const PictureParams* GetNextPictureParams() const;
+ //! Determine if decompression is complete.
+ /*!
+ Indicates whether or not the last picture in the sequence has been
+ decompressed.
+ \return true if last picture has been compressed; false if not
+ */
+ bool Finished();
+ //! Interrogates for parse parameters.
+ /*!
+ Returns the parse parameters used for this decompression run.
+
+ \return parse parameters.
+ */
+ ParseParams & GetParseParams() { return m_parse_params; }
+
+
+ //! Interrogates for source parameters.
+ /*!
+ Returns the source parameters used for this decompression run.
+
+ \return source parameters.
+ */
+ SourceParams & GetSourceParams() { return m_srcparams; }
+
+
+ //! Interrogates for coding parameters.
+ /*!
+ Returns the decoder parameters used for this decompression run.
+
+ \return decoder parameters.
+ */
+ DecoderParams & GetDecoderParams() { return m_decparams; }
+ private:
+ //! Copy constructor is private and body-less
+ /*!
+ Copy constructor is private and body-less. This class should not
+ be copied.
+
+ */
+ SequenceDecompressor(const SequenceDecompressor& cpy);
+
+ //! Assignment = is private and body-less
+ /*!
+ Assignment = is private and body-less. This class should not be
+ assigned.
+
+ */
+ SequenceDecompressor& operator=(const SequenceDecompressor& rhs);
+
+
+ //Member variables
+
+ //! Completion flag, returned via the Finished method
+ bool m_all_done;
+ //! Parameters for the decompression, as provided in constructor
+ DecoderParams m_decparams;
+ //! The parse parameters obtained from the stream header
+ ParseParams m_parse_params;
+ //! The source parameters obtained from the stream header
+ SourceParams m_srcparams;
+ //! A picture buffer used for local storage of pictures whilst pending re-ordering or being used for reference.
+ PictureBuffer* m_pbuffer;
+ //! Number of the picture in coded order which is to be decoded
+ int m_current_code_pnum;
+ //! A delay so that we don't display what we haven't decoded
+ int m_delay;
+ //! Index, in display order, of the last picture read
+ int m_last_picture_read;
+ //! Index, in display order of the picture to be displayed next - computed from delay and current_code_pnum
+ int m_show_pnum;
+ //! Picture decompressor object
+ PictureDecompressor *m_pdecoder;
+ //! Highest picture-num processed - for tracking end-of-sequence
+ int m_highest_pnum;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.cpp
new file mode 100644
index 000000000..07762d7ec
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.cpp
@@ -0,0 +1,156 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: comp_compress.cpp,v 1.49 2009/01/21 05:18:09 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju
+* Andrew Kennedy
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+//Compression of an individual component,
+//after motion compensation if appropriate
+//////////////////////////////////////////
+
+#include <libdirac_encoder/comp_compress.h>
+#include <libdirac_common/band_codec.h>
+#include <libdirac_common/band_vlc.h>
+#include <libdirac_common/motion.h>
+
+using namespace dirac;
+
+#include <ctime>
+#include <vector>
+#include <iostream>
+
+CompCompressor::CompCompressor( EncoderParams& encp,const PictureParams& pp)
+: m_encparams(encp),
+ m_pparams(pp),
+ m_psort( m_pparams.PicSort() ),
+ m_cformat( m_pparams.CFormat() )
+{}
+
+ComponentByteIO* CompCompressor::Compress( CoeffArray& coeff_data ,
+ SubbandList& bands,
+ CompSort csort,
+ const OneDArray<unsigned int>& estimated_bits)
+{
+ // Need to transform, select quantisers for each band,
+ // and then compress each component in turn
+
+ unsigned int num_band_bytes( 0 );
+
+ // create byte output
+ ComponentByteIO *p_component_byteio = new ComponentByteIO(csort);
+
+ // Loop over all the bands (from DC to HF) quantising and coding them
+ for (int b=bands.Length() ; b>=1 ; --b )
+ {
+
+ // create subband byte io
+ SubbandByteIO subband_byteio(bands(b));
+
+ if ( !bands(b).Skipped() )
+ { // If not skipped ...
+ if (m_pparams.UsingAC())
+ {
+ // A pointer to an object for coding the subband data
+ BandCodec* bcoder;
+
+
+ // Pick the right codec according to the picture type and subband
+ if (b >= bands.Length()-3)
+ {
+ if ( m_psort.IsIntra() && b == bands.Length() )
+ bcoder=new IntraDCBandCodec(&subband_byteio,
+ TOTAL_COEFF_CTXS , bands );
+ else
+ bcoder=new LFBandCodec(&subband_byteio ,TOTAL_COEFF_CTXS,
+ bands , b, m_psort.IsIntra());
+ }
+ else
+ bcoder=new BandCodec(&subband_byteio , TOTAL_COEFF_CTXS ,
+ bands , b, m_psort.IsIntra() );
+
+ num_band_bytes = bcoder->Compress(coeff_data);
+
+
+ delete bcoder;
+ }
+ else
+ {
+ // A pointer to an object for coding the subband data
+ BandVLC* bcoder;
+
+ if ( m_psort.IsIntra() && b == bands.Length() )
+ bcoder=new IntraDCBandVLC(&subband_byteio, bands );
+ else
+ bcoder=new BandVLC(&subband_byteio , 0, bands , b,
+ m_psort.IsIntra() );
+
+ num_band_bytes = bcoder->Compress(coeff_data);
+
+ delete bcoder;
+ }
+ // Update the entropy correction factors
+ m_encparams.EntropyFactors().Update(b , m_pparams , csort ,
+ estimated_bits[b] , 8*num_band_bytes);
+ }
+ else
+ { // ... skipped
+ SetToVal( coeff_data , bands(b) , 0 );
+ }
+
+ // output sub-band data
+ p_component_byteio->AddSubband(&subband_byteio);
+
+
+ }//b
+
+ return p_component_byteio;
+}
+
+void CompCompressor::SetToVal(CoeffArray& coeff_data,const Subband& node,ValueType val)
+{
+
+ for (int j=node.Yp() ; j<node.Yp() + node.Yl() ; ++j)
+ {
+ for (int i=node.Xp(); i<node.Xp() + node.Xl() ; ++i)
+ {
+ coeff_data[j][i] = val;
+ }// i
+ }// j
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.h
new file mode 100644
index 000000000..e21150904
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/comp_compress.h
@@ -0,0 +1,114 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: comp_compress.h,v 1.19 2008/05/07 05:47:00 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author), Scott R Ladd
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _COMP_COMPRESS_H_
+#define _COMP_COMPRESS_H_
+
+#include <libdirac_common/arrays.h>
+#include <libdirac_common/wavelet_utils.h>
+#include <libdirac_common/common.h>
+#include <libdirac_byteio/component_byteio.h>
+
+namespace dirac
+{
+ class MEData;
+
+ //! Compress a picture component
+ /*!
+ This class compresses one of the three components (Y, U, or V) of a
+ picture according to a given set or parameters. CompCompressor is used
+ by PictureCompressor.
+ */
+ class CompCompressor
+ {
+ public:
+ //! Constructor
+ /*!
+ Create and initialize a component compressor with the given
+ characteristics.
+ \param encp encoding parameters
+ \param fp picture parameters
+ */
+ CompCompressor( EncoderParams & encp, const PictureParams& fp);
+
+ //! Compress a picture component
+ /*!
+ Compress a PicArray containing a picture component (Y, U, or V).
+ \param coeff_data the component data to be compressed
+ \param bands Subbands list
+ \param csort Chroma format
+ \param estimated_bits the list of estimated number of bits in each subband
+ \return Picture-component in Dirac-bytestream format
+ */
+ ComponentByteIO* Compress( CoeffArray& coeff_data ,
+ SubbandList& bands,
+ CompSort csort,
+ const OneDArray<unsigned int>& estimated_bits);
+
+ private:
+ //! Copy constructor is private and body-less. This class should not be copied.
+ CompCompressor(const CompCompressor& cpy);
+
+ //! Assignment = is private and body-less. This class should not be assigned.
+ CompCompressor& operator=(const CompCompressor& rhs);
+
+ //! Set a subband to a constant value
+ void SetToVal(CoeffArray& coeff_data,const Subband& node,ValueType val);
+
+
+ private:
+
+ // member variables
+ EncoderParams& m_encparams;
+
+ const PictureParams& m_pparams;
+
+ const PictureSort& m_psort;
+
+ const ChromaFormat& m_cformat;
+
+ float m_lambda;
+
+ };
+
+} // namespace dirac
+
+
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.cpp
new file mode 100644
index 000000000..09ba3f570
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.cpp
@@ -0,0 +1,1179 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_encoder.cpp,v 1.57 2008/11/18 23:25:54 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author),
+* Andrew Kennedy
+* Thomas Davies
+* Myo Tun (Brunel University)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <cstring>
+#include <sstream>
+#include <fstream>
+#include <queue>
+#include <string>
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_common/common.h>
+#include <libdirac_common/picture.h>
+#include <libdirac_common/pic_io.h>
+#include <libdirac_encoder/dirac_encoder.h>
+#include <libdirac_encoder/seq_compress.h>
+#include <libdirac_byteio/dirac_byte_stream.h>
+#include <libdirac_common/video_format_defaults.h>
+#include <libdirac_common/dirac_exception.h>
+
+using namespace dirac;
+using namespace std;
+
+template <class T, class S >
+void copy_2dArray (const TwoDArray<T> & in, S *out)
+{
+ for (int j=0 ; j<in.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<in.LengthX() ; ++i)
+ {
+ // out[j*in.LengthX() + i] = in[j][i];
+ *out++ = S( in[j][i] );
+ }// i
+ }// j
+}
+
+void copy_2dArray (const TwoDArray<PredMode> & in, int *out)
+{
+ for (int j=0 ; j<in.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<in.LengthX() ; ++i)
+ {
+ // out[j*in.LengthX() + i] = in[j][i];
+ *out++ = in[j][i];
+ }// i
+ }// j
+}
+
+void copy_2dArray (const TwoDArray<bool> & in, int *out)
+{
+ for (int j=0 ; j<in.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<in.LengthX() ; ++i)
+ {
+ // out[j*in.LengthX() + i] = in[j][i];
+ *out++ = in[j][i];
+ }// i
+ }// j
+}
+
+void copy_mv ( const MvArray& mv, dirac_mv_t *dmv)
+{
+ for (int j=0 ; j<mv.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<mv.LengthX() ; ++i)
+ {
+ //dmv[j*mv.LengthX() + i].x = mv[j][i].x;
+ //dmv[j*mv.LengthX() + i].y = mv[j][i].y;
+ (*dmv).x = mv[j][i].x;
+ (*dmv).y = mv[j][i].y;
+ dmv++;
+ }// i
+ }// j
+}
+
+void copy_mv_cost (const TwoDArray<MvCostData> &pc, dirac_mv_cost_t *dpc)
+{
+ for (int j=0 ; j<pc.LengthY() ; ++j)
+ {
+ for (int i=0 ; i<pc.LengthX() ; ++i)
+ {
+ //dpc[j*pc.LengthX() + i].SAD = pc[j][i].SAD;
+ //dpc[j*pc.LengthX() + i].mvcost = pc[j][i].mvcost;
+ (*dpc).SAD = pc[j][i].SAD;
+ (*dpc).mvcost = pc[j][i].mvcost;
+ dpc++;
+ }// i
+ }// j
+}
+
+/*
+ Function that allocates the locally managed instrumentation data
+*/
+void alloc_instr_data(dirac_instr_t *instr)
+{
+ instr->sb_split_mode = new int [instr->sb_ylen*instr->sb_xlen];
+ memset (instr->sb_split_mode, 0, sizeof(int)*instr->sb_ylen*instr->sb_xlen);
+
+ instr->sb_costs = new float [instr->sb_ylen*instr->sb_xlen];
+ memset (instr->sb_costs, 0, sizeof(float)*instr->sb_ylen*instr->sb_xlen);
+
+ instr->pred_mode = new int [instr->mv_ylen * instr->mv_xlen];
+ memset (instr->pred_mode, 0, sizeof(int)*instr->mv_ylen*instr->mv_xlen);
+
+ instr->intra_costs = new float [instr->mv_ylen * instr->mv_xlen];
+ memset (instr->intra_costs, 0, sizeof(float)*instr->mv_ylen*instr->mv_xlen);
+
+ instr->bipred_costs = new dirac_mv_cost_t [instr->mv_ylen * instr->mv_xlen];
+ memset (instr->bipred_costs, 0, sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
+
+ instr->dc_ycomp = new short [instr->mv_ylen * instr->mv_xlen];
+ memset (instr->dc_ycomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
+
+ instr->dc_ucomp = new short [instr->mv_ylen * instr->mv_xlen];
+ memset (instr->dc_ucomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
+
+ instr->dc_vcomp = new short [instr->mv_ylen * instr->mv_xlen];
+ memset (instr->dc_vcomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
+
+ for (int i = 0; i < 2; i++)
+ {
+ instr->mv[i] = new dirac_mv_t[instr->mv_ylen * instr->mv_xlen];
+ memset (instr->mv[i], 0,
+ sizeof(dirac_mv_t)*instr->mv_ylen*instr->mv_xlen);
+ }
+
+ for (int i = 0; i < 2; i++)
+ {
+ instr->pred_costs[i] = new dirac_mv_cost_t[instr->mv_ylen * instr->mv_xlen];
+ memset (instr->pred_costs[i], 0,
+ sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
+ }
+}
+
+/*
+ Function that frees the locally managed instrumentation data
+*/
+void dealloc_instr_data(dirac_instr_t *instr)
+{
+ if (instr->sb_split_mode)
+ delete [] instr->sb_split_mode;
+
+ if (instr->sb_costs)
+ delete [] instr->sb_costs;
+
+ if (instr->pred_mode)
+ delete [] instr->pred_mode;
+
+ if (instr->intra_costs)
+ delete [] instr->intra_costs;
+
+ if (instr->bipred_costs)
+ delete [] instr->bipred_costs;
+
+ if (instr->dc_ycomp)
+ delete [] instr->dc_ycomp;
+
+ if (instr->dc_ucomp)
+ delete [] instr->dc_ucomp;
+
+ if (instr->dc_vcomp)
+ delete [] instr->dc_vcomp;
+
+ for (int i = 0; i < 2; i++)
+ {
+ if (instr->mv[i])
+ delete [] instr->mv[i];
+ }
+ for (int i = 0; i < 2; i++)
+ {
+ if (instr->pred_costs[i])
+ delete [] instr->pred_costs[i];
+ }
+}
+
+/*
+ Wrapper class around the SequenceCompressor Class. This class is used
+ by the "C" encoder interface
+*/
+class DiracEncoder
+{
+public:
+ // constructor
+ DiracEncoder(const dirac_encoder_context_t *enc_ctx, bool verbose);
+ // destructor
+ ~DiracEncoder();
+
+ // Load the next frame of uncompressed data into the SequenceCompressor
+ bool LoadNextFrame(unsigned char *data, int size);
+ // Compress the next picture (frame/field) of data
+ int CompressNextPicture();
+
+ // Set the encode frame in encoder to the encoded frame data
+ int GetEncodedData(dirac_encoder_t *encoder);
+
+ // Set the locally decoded frame data in encoder
+ int GetDecodedData (dirac_encoder_t *encoder);
+
+ // Set the instrumentation data in encoder
+ void GetInstrumentationData (dirac_encoder_t *encoder);
+
+ // Set the end of sequence infomration in encoder
+ int GetSequenceEnd(dirac_encoder_t *encoder);
+
+ // Set the buffer to hold the locally decoded frame
+ void SetDecodeBuffer (unsigned char *buffer, int buffer_size);
+
+ // Return the encoder parameters
+ const EncoderParams& GetEncParams() const { return m_encparams; }
+
+ // Return the source parameters
+ const SourceParams& GetSrcParams() const { return m_srcparams; }
+
+ // Return the pts offset
+ int GetPTSOffset() const { return m_seqcomp->PTSOffset(); }
+
+ // Signal End of Sequence
+ void SignalEOS() { m_eos_signalled = true; m_seqcomp->SignalEOS(); }
+
+ // End of Sequence
+ bool EOS() { return m_eos_signalled == true; }
+
+private:
+
+ // Set the encoder parameters
+ void SetEncoderParams (const dirac_encoder_context_t *enc_ctx);
+
+ // Set the source parameters
+ void SetSourceParams (const dirac_encoder_context_t *enc_ctx);
+
+ // Get the picture statistics
+ void GetPictureStats(dirac_encoder_t *encoder);
+
+ // Get the seuqence statistics
+ void GetSequenceStats(dirac_encoder_t *encoder,
+ const DiracByteStats& dirac_seq_stats);
+
+private:
+ // sequence compressor
+ SequenceCompressor *m_seqcomp;
+ // Source parameters
+ SourceParams m_srcparams;
+ // encoder parameters
+ EncoderParams m_encparams;
+ // locally encoded picture in coded order
+ const EncPicture *m_enc_picture;
+ // locally encoded frame ME data
+ const MEData *m_enc_medata;
+ // locally decoded picture number in display order
+ int m_decpnum;
+ //locally decoded picture type
+ PictureSort m_decpsort;
+ // locally decoded picture number in display order
+ int m_show_pnum;
+ // total number of frames/fields loaded so far
+ int m_num_loaded_pictures;
+ // total number of frames/fields encoded so far
+ int m_num_coded_pictures;
+ // verbose flag
+ bool m_verbose;
+ // input stream for uncompressed input pictures
+ MemoryStreamInput *m_inp_ptr;
+ // output stream for locally decoded pictures
+ MemoryStreamOutput *m_out_ptr;
+ // buffer to hold locally decoded frame. Set by SetDecodeBuffer
+ unsigned char *m_dec_buf;
+ // size of buffer to hold locally decoded data. Set by SetDecodeBuffer
+ int m_dec_bufsize;
+ // Flag that determines if locally decoded pictures are to be returned. Set
+ // in Constructor
+ bool m_return_decoded_pictures;
+ // Flag that determines if instrumentation data is to be returned. Set
+ // in Constructor
+ bool m_return_instr_data;
+
+ // Output destination for compressed data in bitstream format
+ DiracByteStream m_dirac_byte_stream;
+
+ //Rate Control parameters
+ // Total Number of bits for a GOP
+ int m_gop_bits;
+
+ // Total Number GOPs in the input sequence
+ int m_gop_count;
+
+ // To count the number of pictures for calculating the GOP bit rate
+ int m_picture_count;
+
+ // field 1 stats if interlaced
+ dirac_enc_picstats_t m_field1_stats;
+
+ // End of sequence flag. Set to true when user app signals end of
+ // sequence
+ bool m_eos_signalled;
+
+};
+
+/*
+ Instrumentation callback. This function is passed as a parameter to the
+ SequenceCompressor constructor. It is called by the
+ FrameCompressor::Compress function once the frame is successfully compressed
+*/
+void DiracEncoder::GetInstrumentationData (dirac_encoder_t *encoder)
+{
+ ASSERT (encoder != NULL);
+ dirac_instr_t *instr = &encoder->instr;
+ dirac_instr_t old_instr = *instr;
+
+ if (!m_return_instr_data || m_enc_picture == NULL)
+ return;
+
+ const PictureParams& pparams = m_enc_picture->GetPparams();
+ const PictureSort psort = pparams.PicSort();
+
+ instr->pnum = pparams.PictureNum();
+ instr->ptype = psort.IsIntra() ? INTRA_PICTURE : INTER_PICTURE;
+ instr->rtype = psort.IsRef() ? REFERENCE_PICTURE : NON_REFERENCE_PICTURE;
+ instr->num_refs = 0;
+ encoder->instr_data_avail = 1;
+
+ if (psort.IsIntra())
+ {
+ // no MV data for Intra coded data
+ return;
+ }
+
+ TESTM (m_enc_medata != NULL, "ME data available");
+
+ // Reference info
+ instr->num_refs = pparams.Refs().size();
+ ASSERTM (instr->num_refs <= 2, "Max # reference frames is 2");
+
+ for (int i=0; i<instr->num_refs; ++i)
+ instr->refs[i] = pparams.Refs()[i];
+
+ // Block separation params
+ instr->ybsep = m_encparams.GetPicPredParams().LumaBParams(2).Ybsep();
+ instr->xbsep = m_encparams.GetPicPredParams().LumaBParams(2).Xbsep();
+
+ // Num superblocks
+ instr->sb_ylen = m_enc_medata->SBSplit().LengthY();
+ instr->sb_xlen = m_enc_medata->SBSplit().LengthX();
+
+ // Motion vector array dimensions
+ instr->mv_ylen = m_enc_medata->Vectors(1).LengthY();
+ instr->mv_xlen = m_enc_medata->Vectors(1).LengthX();
+
+ if (old_instr.sb_ylen != instr->sb_ylen ||
+ old_instr.sb_xlen != instr->sb_xlen ||
+ old_instr.mv_ylen != instr->mv_ylen ||
+ old_instr.mv_xlen != instr->mv_xlen)
+ {
+ dealloc_instr_data(instr);
+ alloc_instr_data(instr);
+ }
+
+ copy_2dArray (m_enc_medata->SBSplit(), instr->sb_split_mode);
+ copy_2dArray (m_enc_medata->SBCosts(), instr->sb_costs);
+ copy_2dArray (m_enc_medata->Mode(), instr->pred_mode);
+ copy_2dArray (m_enc_medata->IntraCosts(), instr->intra_costs);
+
+ if (instr->num_refs > 1)
+ {
+ copy_mv_cost (m_enc_medata->BiPredCosts(), instr->bipred_costs);
+ }
+
+ copy_2dArray (m_enc_medata->DC( Y_COMP ), instr->dc_ycomp);
+ if (m_enc_medata->DC().Length() == 3)
+ {
+ copy_2dArray (m_enc_medata->DC( U_COMP ), instr->dc_ucomp);
+ copy_2dArray (m_enc_medata->DC( V_COMP ), instr->dc_vcomp);
+ }
+
+ for (int i=1; i<=instr->num_refs; ++i)
+ {
+ copy_mv (m_enc_medata->Vectors(i), instr->mv[i-1]);
+ copy_mv_cost (m_enc_medata->PredCosts(i), instr->pred_costs[i-1]);
+ }
+}
+
+DiracEncoder::DiracEncoder(const dirac_encoder_context_t *enc_ctx,
+ bool verbose) :
+ m_srcparams(static_cast<VideoFormat>(enc_ctx->enc_params.video_format), true),
+ m_encparams(static_cast<VideoFormat>(enc_ctx->enc_params.video_format), INTER_PICTURE, 2, true),
+ m_show_pnum(-1),
+ m_num_loaded_pictures(0),
+ m_num_coded_pictures(0),
+ m_verbose(verbose),
+ m_dec_buf(0),
+ m_dec_bufsize(0),
+ m_return_decoded_pictures(enc_ctx->decode_flag > 0),
+ m_return_instr_data(enc_ctx->instr_flag > 0),
+ m_gop_bits(0),
+ m_gop_count(0),
+ m_picture_count(0),
+ m_eos_signalled(false)
+{
+ // Setup source parameters
+ SetSourceParams (enc_ctx);
+ // Setup encoder parameters
+ m_encparams.SetVerbose( verbose );
+ SetEncoderParams (enc_ctx);
+
+ // Set up the input data stream (uncompressed data)
+ m_inp_ptr = new MemoryStreamInput(m_srcparams, m_encparams.FieldCoding());
+ // Set up the output data stream (locally decoded frame)
+ m_out_ptr = new MemoryStreamOutput(m_srcparams, m_encparams.FieldCoding());
+
+ // initialise the sequence compressor
+ if (!m_encparams.FieldCoding())
+ {
+ m_seqcomp = new FrameSequenceCompressor (m_inp_ptr->GetStream(), m_encparams, m_dirac_byte_stream);
+ }
+ else
+ {
+ m_seqcomp = new FieldSequenceCompressor (m_inp_ptr->GetStream(), m_encparams, m_dirac_byte_stream);
+ }
+}
+
+void DiracEncoder::SetDecodeBuffer (unsigned char *buffer, int buffer_size)
+{
+ m_dec_buf = buffer;
+ m_dec_bufsize = buffer_size;
+ m_return_decoded_pictures = true;
+}
+
+DiracEncoder::~DiracEncoder()
+{
+ delete m_seqcomp;
+ delete m_inp_ptr;
+ delete m_out_ptr;
+}
+
+void DiracEncoder::SetSourceParams (const dirac_encoder_context_t *enc_ctx)
+{
+ m_srcparams.SetCFormat( enc_ctx->src_params.chroma );
+ m_srcparams.SetXl( enc_ctx->src_params.width );
+ m_srcparams.SetYl( enc_ctx->src_params.height );
+
+ m_srcparams.SetCleanWidth( m_srcparams.Xl() );
+ m_srcparams.SetCleanHeight( m_srcparams.Yl() );
+ m_srcparams.SetLeftOffset( 0 );
+ m_srcparams.SetTopOffset( 0 );
+
+ m_srcparams.SetSourceSampling( enc_ctx->src_params.source_sampling );
+ if (m_srcparams.FrameRate().m_num != (unsigned int)enc_ctx->src_params.frame_rate.numerator ||
+ m_srcparams.FrameRate().m_denom != (unsigned int)enc_ctx->src_params.frame_rate.denominator)
+ {
+ m_srcparams.SetFrameRate( enc_ctx->src_params.frame_rate.numerator,
+ enc_ctx->src_params.frame_rate.denominator );
+ }
+ if (m_srcparams.PixelAspectRatio().m_num != (unsigned int)enc_ctx->src_params.pix_asr.numerator ||
+ m_srcparams.PixelAspectRatio().m_denom != (unsigned int)enc_ctx->src_params.pix_asr.denominator)
+ {
+ m_srcparams.SetPixelAspectRatio( enc_ctx->src_params.pix_asr.numerator,
+ enc_ctx->src_params.pix_asr.denominator );
+ }
+ // TO DO: CLEAN AREA and signal range
+ // FIXME: Dirac currently support 8BIT_VIDEO only. Accept from command line
+ // when Dirac supports multiple signal ranges.
+ m_srcparams.SetSignalRange(SIGNAL_RANGE_8BIT_VIDEO);
+
+}
+
+void DiracEncoder::SetEncoderParams (const dirac_encoder_context_t *enc_ctx)
+{
+ TEST (enc_ctx != NULL);
+ OLBParams bparams(12, 12, 8, 8);
+
+ m_encparams.SetLocalDecode(enc_ctx->decode_flag);
+ m_encparams.SetXl( enc_ctx->src_params.width );
+ m_encparams.SetYl( enc_ctx->src_params.height );
+ m_encparams.SetChromaXl( enc_ctx->src_params.chroma_width );
+ m_encparams.SetChromaYl( enc_ctx->src_params.chroma_height );
+
+ if (enc_ctx->enc_params.picture_coding_mode > 1)
+ {
+ std::ostringstream errstr;
+
+ errstr << "Picture coding mode "
+ << enc_ctx->enc_params.picture_coding_mode
+ << " out of supported range [0-1]";
+ DIRAC_THROW_EXCEPTION(
+ ERR_INVALID_INIT_DATA,
+ errstr.str(),
+ SEVERITY_TERMINATE);
+ }
+
+ m_encparams.SetPictureCodingMode(enc_ctx->enc_params.picture_coding_mode);
+ if (m_encparams.FieldCoding())
+ {
+ // Change coding dimensions to field dimensions
+ m_encparams.SetYl( enc_ctx->src_params.height>>1 );
+ m_encparams.SetChromaYl( enc_ctx->src_params.chroma_height >> 1);
+ }
+
+ unsigned int luma_depth = static_cast<unsigned int> (
+ std::log((double)m_srcparams.LumaExcursion())/std::log(2.0) + 1 );
+ m_encparams.SetLumaDepth(luma_depth);
+
+ unsigned int chroma_depth = static_cast<unsigned int> (
+ std::log((double)m_srcparams.ChromaExcursion())/std::log(2.0) + 1 );
+ m_encparams.SetChromaDepth(chroma_depth);
+
+ m_encparams.SetFullSearch(enc_ctx->enc_params.full_search);
+ m_encparams.SetCombinedME(enc_ctx->enc_params.combined_me);
+ m_encparams.SetXRangeME(enc_ctx->enc_params.x_range_me);
+ m_encparams.SetYRangeME(enc_ctx->enc_params.y_range_me);
+ m_encparams.SetCPD(enc_ctx->enc_params.cpd);
+ m_encparams.SetQf(enc_ctx->enc_params.qf);
+ m_encparams.SetTargetRate(enc_ctx->enc_params.trate);
+ m_encparams.SetLossless(enc_ctx->enc_params.lossless);
+ m_encparams.SetL1Sep(enc_ctx->enc_params.L1_sep);
+ m_encparams.SetNumL1(enc_ctx->enc_params.num_L1);
+ m_encparams.SetPrefilter(enc_ctx->enc_params.prefilter,
+ enc_ctx->enc_params.prefilter_strength);
+ m_encparams.SetUFactor(1.5f);
+ m_encparams.SetVFactor(0.75f);
+ m_encparams.GetPicPredParams().SetMVPrecision(enc_ctx->enc_params.mv_precision);
+ m_encparams.SetUsingAC(enc_ctx->enc_params.using_ac);
+ bparams.SetYblen( enc_ctx->enc_params.yblen );
+ bparams.SetXblen( enc_ctx->enc_params.xblen );
+ bparams.SetYbsep( enc_ctx->enc_params.ybsep );
+ bparams.SetXbsep( enc_ctx->enc_params.xbsep );
+
+ // Now rationalise the GOP options
+ // this stuff should really be done in a constructor!
+ if (m_encparams.NumL1()<0)
+ {
+ //don't have a proper GOP
+ m_encparams.SetL1Sep( std::max(1 , m_encparams.L1Sep()) );
+ }
+ else if (m_encparams.NumL1() == 0)
+ {
+ //have I-frame only coding
+ m_encparams.SetL1Sep(0);
+ }
+ m_encparams.GetPicPredParams().SetBlockSizes( bparams , enc_ctx->src_params.chroma );
+
+ // Set transforms parameters
+ m_encparams.SetIntraTransformFilter(enc_ctx->enc_params.intra_wlt_filter);
+ m_encparams.SetInterTransformFilter(enc_ctx->enc_params.inter_wlt_filter);
+ m_encparams.SetSpatialPartition(enc_ctx->enc_params.spatial_partition);
+
+ m_encparams.SetTransformDepth(enc_ctx->enc_params.wlt_depth);
+ m_encparams.SetCodeBlockMode(enc_ctx->enc_params.spatial_partition && enc_ctx->enc_params.multi_quants ? QUANT_MULTIPLE : QUANT_SINGLE);
+}
+
+
+bool DiracEncoder::LoadNextFrame (unsigned char *data, int size)
+{
+ TESTM (m_seqcomp->Finished() != true, "Did not reach end of sequence");
+ m_inp_ptr->SetMembufReference(data, size);
+ if (m_seqcomp->LoadNextFrame())
+ {
+ if (!m_encparams.FieldCoding())
+ m_num_loaded_pictures++;
+ else
+ m_num_loaded_pictures+=2;
+ return true;
+ }
+ return false;
+}
+
+int DiracEncoder::CompressNextPicture ()
+{
+ TESTM (m_seqcomp->Finished() != true, "Did not reach end of sequence");
+
+ if (!m_num_loaded_pictures)
+ return 0;
+
+ const EncPicture *mypicture = m_seqcomp->CompressNextPicture();
+
+ m_decpnum = -1;
+
+ if (mypicture){
+ m_enc_picture = m_seqcomp->GetPictureEncoded();
+ if (m_enc_picture->GetPparams().PicSort().IsIntra()==false)
+ m_enc_medata = &m_enc_picture->GetMEData();
+ else
+ m_enc_medata = NULL;
+
+ if (m_return_decoded_pictures &&
+ mypicture->GetPparams().PictureNum() != m_show_pnum){
+ int ret_val;
+ m_show_pnum = mypicture->GetPparams().PictureNum();
+ TEST (! (m_return_decoded_pictures && !m_dec_buf) );
+ if (m_return_decoded_pictures && m_dec_buf)
+ {
+ // write locally decoded picture to decode buffer
+ m_out_ptr->SetMembufReference(m_dec_buf, m_dec_bufsize);
+ ret_val = m_out_ptr->GetStream()->WriteToNextFrame(*mypicture);
+
+ if (ret_val)
+ {
+ m_decpnum = m_show_pnum;
+ m_decpsort = mypicture->GetPparams().PicSort();
+ }
+ }
+ }
+ }
+ else{
+ m_enc_picture = NULL;
+ m_enc_medata = NULL;
+ }
+
+ if(!m_dirac_byte_stream.IsUnitAvailable())
+ return 0;
+
+ if (mypicture){
+ m_num_coded_pictures++;
+ TESTM (m_enc_picture != 0, "Encoder picture available");
+ }
+ return 1;
+}
+
+void DiracEncoder::GetPictureStats(dirac_encoder_t *encoder)
+{
+
+ dirac_enc_picstats_t *pstats = &encoder->enc_pstats;
+ DiracByteStats dirac_byte_stats = m_dirac_byte_stream.GetLastUnitStats();
+
+ pstats->mv_bits = dirac_byte_stats.GetBitCount(STAT_MV_BYTE_COUNT);
+ // pstats->mv_hdr_bits = poutput.MVBytes() * 8;
+
+ pstats->ycomp_bits = dirac_byte_stats.GetBitCount(STAT_YCOMP_BYTE_COUNT);
+ // pstats->ycomp_hdr_bits = poutput.ComponentHeadBytes( Y_COMP ) * 8;
+
+ pstats->ucomp_bits = dirac_byte_stats.GetBitCount(STAT_UCOMP_BYTE_COUNT);
+ // pstats->ucomp_hdr_bits = poutput.ComponentHeadBytes( U_COMP ) * 8;
+
+ pstats->vcomp_bits = dirac_byte_stats.GetBitCount(STAT_VCOMP_BYTE_COUNT);
+ // pstats->vcomp_hdr_bits = poutput.ComponentHeadBytes( V_COMP ) * 8;
+
+ pstats->pic_bits = dirac_byte_stats.GetBitCount(STAT_TOTAL_BYTE_COUNT);
+ // pstats->pic_hdr_bits = poutput.PictureHeadBytes() * 8;
+
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+ if (compressor->GetEncParams().Verbose())
+ {
+ std::cout<<std::endl<<"Number of MV bits="<<pstats->mv_bits;
+ std::cout<<std::endl<<"Number of bits for Y="<<pstats->ycomp_bits;
+ std::cout<<std::endl<<"Number of bits for U="<<pstats->ucomp_bits;
+ std::cout<<std::endl<<"Number of bits for V="<<pstats->vcomp_bits;
+ if (m_encparams.FieldCoding())
+ std::cout<<std::endl<<"Total field bits="<<pstats->pic_bits;
+ else
+ std::cout<<std::endl<<"Total frame bits="<<pstats->pic_bits;
+ }
+}
+
+int DiracEncoder::GetEncodedData (dirac_encoder_t *encoder)
+{
+ int size = 0;
+ dirac_enc_data_t *encdata = &encoder->enc_buf;
+
+ string output = m_dirac_byte_stream.GetBytes();
+ size = output.size();
+ //std::cout << std::endl << "ParseUnit size=" << size << std::endl;
+ if (size > 0)
+ {
+ if (encdata->size < size )
+ {
+ return -1;
+ }
+ memmove (encdata->buffer, output.c_str(), output.size());
+ if (m_enc_picture)
+ {
+ // picture data
+ encoder->enc_pparams.pnum = m_enc_picture->GetPparams().PictureNum();
+ encoder->enc_pparams.ptype = m_enc_picture->GetPparams().PicSort().IsIntra() ? INTRA_PICTURE : INTER_PICTURE;
+ encoder->enc_pparams.rtype = m_enc_picture->GetPparams().PicSort().IsRef() ? REFERENCE_PICTURE : NON_REFERENCE_PICTURE;
+
+ // Get frame statistics
+ GetPictureStats (encoder);
+ if(m_encparams.Verbose() && encoder->enc_ctx.enc_params.picture_coding_mode==1)
+ {
+ if (encoder->enc_pparams.pnum%2 == 0)
+ m_field1_stats = encoder->enc_pstats;
+ else
+ {
+ std::cout<<std::endl<<std::endl
+ <<"Frame "<<encoder->enc_pparams.pnum/2;
+ std::cout<< " stats";
+ std::cout<<std::endl<< "Number of MV bits=";
+ std::cout<< m_field1_stats.mv_bits + encoder->enc_pstats.mv_bits;
+ std::cout<< std::endl << "Number of bits for Y=";
+ std::cout<< m_field1_stats.ycomp_bits + encoder->enc_pstats.ycomp_bits;
+ std::cout<< std::endl << "Number of bits for U=";
+ std::cout<< m_field1_stats.ucomp_bits + encoder->enc_pstats.ucomp_bits;
+ std::cout<< std::endl << "Number of bits for V=";
+ std::cout<< m_field1_stats.vcomp_bits + encoder->enc_pstats.vcomp_bits;
+ std::cout << std::endl << "Total frame bits=";
+ std::cout<< m_field1_stats.pic_bits + encoder->enc_pstats.pic_bits;
+ }
+ }
+ }
+ else
+ {
+ // Not picture data
+ encoder->enc_pparams.pnum = -1;
+ }
+ encdata->size = size;
+
+ GetInstrumentationData(encoder);
+ encoder->encoded_picture_avail = 1;
+ }
+ else
+ {
+ encdata->size = 0;
+ }
+
+ if (m_enc_picture)
+ {
+ //Rate Control - work out bit rate to date and for current GOP
+ // and keep track of frame numbers
+ int interlace_factor = m_encparams.FieldCoding() ? 2 : 1;
+ int num_L1 = encoder->enc_ctx.enc_params.num_L1;
+ int L1_sep = encoder->enc_ctx.enc_params.L1_sep;
+
+ // Length of the GOP in pictures - twice as many if fields
+ int GOP_pic_length = (num_L1+1)*L1_sep*interlace_factor;
+
+ int offset;
+ if (num_L1 == 0)
+ {
+ GOP_pic_length = 10;
+ offset = 0;
+ }
+ else
+ offset = std::max(L1_sep-1,0)*interlace_factor;
+
+ m_gop_bits += encoder->enc_pstats.pic_bits;
+ m_picture_count++;
+
+ if ( (m_gop_count==0 && m_picture_count == GOP_pic_length-offset) ||
+ (m_gop_count>0 && m_picture_count == GOP_pic_length))
+ {
+ int denominator = encoder->enc_ctx.src_params.frame_rate.denominator;
+ int numerator = encoder->enc_ctx.src_params.frame_rate.numerator;
+ double frame_rate = (double)numerator/(double)denominator;
+
+ double gop_duration = double(m_picture_count)/interlace_factor/frame_rate;
+ double bit_rate = double(m_gop_bits)/gop_duration;
+
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+ if (compressor->GetEncParams().Verbose())
+ {
+ std::cout<<std::endl<<std::endl<<"Bit Rate for GOP number ";
+ std::cout<<m_gop_count<<" is "<<bit_rate/1000.0<<" kbps"<<std::endl;
+ }
+
+ m_gop_count++;
+ m_gop_bits = 0;
+ m_picture_count = 0;
+ }
+ //End of Rate Control
+ }
+
+ m_dirac_byte_stream.Clear();
+
+ return size;
+}
+
+int DiracEncoder::GetDecodedData (dirac_encoder_t *encoder)
+{
+ dirac_picparams_t *pp = &encoder->dec_pparams;
+
+ int ret_stat = (m_decpnum != -1);
+ if (m_return_decoded_pictures && m_decpnum != -1)
+ {
+ pp->ptype = m_decpsort.IsIntra() ? INTRA_PICTURE : INTER_PICTURE;
+ pp->rtype = m_decpsort.IsRef() ? REFERENCE_PICTURE : NON_REFERENCE_PICTURE;
+ pp->pnum = m_decpnum;
+ encoder->decoded_frame_avail = 1;
+ m_decpnum = -1;
+ }
+ return ret_stat;
+}
+
+void DiracEncoder::GetSequenceStats(dirac_encoder_t *encoder,
+ const DiracByteStats& dirac_seq_stats)
+{
+ dirac_enc_seqstats_t *sstats = &encoder->enc_seqstats;
+
+ sstats->seq_bits = dirac_seq_stats.GetBitCount(STAT_TOTAL_BYTE_COUNT);
+ sstats->mv_bits = dirac_seq_stats.GetBitCount(STAT_MV_BYTE_COUNT);
+ sstats->ycomp_bits = dirac_seq_stats.GetBitCount(STAT_YCOMP_BYTE_COUNT);
+ sstats->ucomp_bits = dirac_seq_stats.GetBitCount(STAT_UCOMP_BYTE_COUNT);
+ sstats->vcomp_bits = dirac_seq_stats.GetBitCount(STAT_VCOMP_BYTE_COUNT);
+
+ sstats->bit_rate = int64_t((sstats->seq_bits *
+ (double)m_srcparams.FrameRate().m_num)/
+ (m_srcparams.FrameRate().m_denom * m_num_coded_pictures));
+ if (encoder->enc_ctx.enc_params.picture_coding_mode==1)
+ sstats->bit_rate *= 2;
+
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+ if (compressor->GetEncParams().Verbose())
+ {
+ std::cout<<std::endl<<std::endl<<"Total bits for sequence="<<sstats->seq_bits;
+ std::cout<<std::endl<<"Of these: "<<std::endl;
+ std::cout<<std::endl<<sstats->ycomp_bits <<" were Y, ";
+ std::cout<<std::endl<<sstats->ucomp_bits <<" were U, ";
+ std::cout<<std::endl<<sstats->vcomp_bits<<" were V, and ";
+ std::cout<<std::endl<<sstats->mv_bits<<" were motion vector data.";
+ }
+}
+
+int DiracEncoder::GetSequenceEnd (dirac_encoder_t *encoder)
+{
+ dirac_enc_data_t *encdata = &encoder->enc_buf;
+ DiracByteStats dirac_seq_stats=m_seqcomp->EndSequence();
+ string output = m_dirac_byte_stream.GetBytes();
+ int size = output.size();
+ if (size > 0)
+ {
+ if (encdata->size < size )
+ {
+ return -1;
+ }
+ memmove (encdata->buffer, output.c_str(), size);
+ GetSequenceStats(encoder,
+ dirac_seq_stats);
+ encdata->size = size;
+ }
+ else
+ {
+ encdata->size = 0;
+ }
+ m_dirac_byte_stream.Clear();
+ return size;
+}
+
+static bool InitialiseEncoder (const dirac_encoder_context_t *enc_ctx, bool verbose, dirac_encoder_t *encoder)
+{
+ TEST (enc_ctx != NULL);
+ TEST (encoder != NULL);
+
+ if (enc_ctx->src_params.width == 0 || enc_ctx->src_params.height == 0)
+ return false;
+
+ if (enc_ctx->src_params.chroma < format444 ||
+ enc_ctx->src_params.chroma >= formatNK)
+ return false;
+
+ if (!enc_ctx->src_params.frame_rate.numerator ||
+ !enc_ctx->src_params.frame_rate.denominator)
+ return false;
+
+ memmove (&encoder->enc_ctx, enc_ctx, sizeof(dirac_encoder_context_t));
+
+ encoder->dec_buf.id = 0;
+
+ switch ( enc_ctx->src_params.chroma )
+ {
+ case format420:
+ encoder->enc_ctx.src_params.chroma_width = enc_ctx->src_params.width/2;
+ encoder->enc_ctx.src_params.chroma_height = enc_ctx->src_params.height/2;
+ break;
+ case format422:
+ encoder->enc_ctx.src_params.chroma_width = enc_ctx->src_params.width/2;
+ encoder->enc_ctx.src_params.chroma_height = enc_ctx->src_params.height;
+ break;
+ case format444:
+ default:
+ encoder->enc_ctx.src_params.chroma_width = enc_ctx->src_params.width;
+ encoder->enc_ctx.src_params.chroma_height = enc_ctx->src_params.height;
+ break;
+ }
+
+ try
+ {
+ DiracEncoder *comp = new DiracEncoder (&encoder->enc_ctx, verbose);
+
+ encoder->compressor = comp;
+ if (encoder->enc_ctx.decode_flag)
+ {
+ int bufsize = (encoder->enc_ctx.src_params.width * encoder->enc_ctx.src_params.height)+ 2*(encoder->enc_ctx.src_params.chroma_width*encoder->enc_ctx.src_params.chroma_height);
+ encoder->dec_buf.buf[0] = new unsigned char [bufsize];
+ encoder->dec_buf.buf[1] = encoder->dec_buf.buf[0] +
+ (encoder->enc_ctx.src_params.width * encoder->enc_ctx.src_params.height);
+ encoder->dec_buf.buf[2] = encoder->dec_buf.buf[1] +
+ (encoder->enc_ctx.src_params.chroma_width*encoder->enc_ctx.src_params.chroma_height);
+
+ comp->SetDecodeBuffer (encoder->dec_buf.buf[0], bufsize);
+ }
+ }
+ catch (...)
+ {
+ return false;
+ }
+ return true;
+}
+
+static void SetSourceParameters(dirac_encoder_context_t *enc_ctx,
+ const VideoFormat& video_format)
+{
+ TEST (enc_ctx != NULL);
+ dirac_sourceparams_t &src_params = enc_ctx->src_params;
+
+ // create object containing sequence params
+ SourceParams default_src_params(video_format);
+
+ src_params.height = default_src_params.Yl();
+ src_params.width = default_src_params.Xl();
+ src_params.chroma_height = default_src_params.ChromaHeight();
+ src_params.chroma_width = default_src_params.ChromaWidth();
+ src_params.chroma = default_src_params.CFormat();
+ src_params.frame_rate.numerator = default_src_params.FrameRate().m_num;
+ src_params.frame_rate.denominator = default_src_params.FrameRate().m_denom;
+ src_params.pix_asr.numerator = default_src_params.PixelAspectRatio().m_num;
+ src_params.pix_asr.denominator = default_src_params.PixelAspectRatio().m_denom;
+ src_params.source_sampling = default_src_params.SourceSampling();
+ src_params.topfieldfirst = default_src_params.TopFieldFirst();
+
+ //TODO - Need to accept these params from command line
+ //Set clean area
+ //Set signal range
+ //Set colour specification
+}
+
+static void SetEncoderParameters(dirac_encoder_context_t *enc_ctx,
+ const VideoFormat& video_format)
+{
+ TEST (enc_ctx != NULL);
+ dirac_encparams_t &encparams = enc_ctx->enc_params;
+
+ encparams.video_format = static_cast<int>(video_format);
+ // set encoder defaults
+ EncoderParams default_enc_params(video_format);
+
+ encparams.qf = default_enc_params.Qf();
+ encparams.cpd = default_enc_params.CPD();
+ encparams.prefilter = default_enc_params.Prefilter();
+ encparams.prefilter_strength = default_enc_params.PrefilterStrength();
+ encparams.L1_sep = default_enc_params.L1Sep();
+ encparams.lossless = default_enc_params.Lossless();
+ encparams.using_ac = default_enc_params.UsingAC();
+ encparams.num_L1 = default_enc_params.NumL1();
+
+ // Set rate to zero by default, meaning no rate control
+ encparams.trate = 0;
+
+ // set default block params
+ OLBParams default_block_params;
+ SetDefaultBlockParameters(default_block_params, video_format);
+ encparams.xblen = default_block_params.Xblen();
+ encparams.yblen = default_block_params.Yblen();
+ encparams.xbsep = default_block_params.Xbsep();
+ encparams.ybsep = default_block_params.Ybsep();
+
+ // set default MV parameters
+ encparams.mv_precision = default_enc_params.GetPicPredParams().MVPrecision();
+
+ // by default, use hierarchical, not full search
+ encparams.full_search = 0;
+ encparams.x_range_me = 32;
+ encparams.y_range_me = 32;
+
+ // by default, don't use combined component motion estimation
+ encparams.combined_me = 0;
+
+ // set default transform parameters
+ WltFilter wf;
+ SetDefaultTransformFilter(INTRA_PICTURE, video_format, wf);
+ encparams.intra_wlt_filter = wf;
+ SetDefaultTransformFilter(INTER_PICTURE, video_format, wf);
+ encparams.inter_wlt_filter = wf;
+ encparams.wlt_depth = default_enc_params.TransformDepth();
+ encparams.spatial_partition = default_enc_params.SpatialPartition();
+ encparams.multi_quants = default_enc_params.GetCodeBlockMode() == QUANT_MULTIPLE;
+
+ encparams.picture_coding_mode = default_enc_params.FieldCoding() ? 1 : 0;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern DllExport void dirac_encoder_context_init ( dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
+{
+ TEST (enc_ctx != NULL);
+ memset (enc_ctx, 0, sizeof(dirac_encoder_context_t));
+
+ // preset is the video format
+ int ps = static_cast<int>(preset);
+ VideoFormat video_format(static_cast<VideoFormat>(ps));
+ SetSourceParameters (enc_ctx, video_format);
+ SetEncoderParameters (enc_ctx, video_format);
+}
+
+extern DllExport dirac_encoder_t *dirac_encoder_init (const dirac_encoder_context_t *enc_ctx, int verbose)
+{
+ /* Allocate for encoder */
+ dirac_encoder_t *encoder = new dirac_encoder_t;
+
+ memset (encoder, 0, sizeof(dirac_encoder_t));
+ /* initialse the encoder context */
+ if (!InitialiseEncoder(enc_ctx, verbose>0, encoder))
+ {
+ delete encoder;
+ return NULL;
+ }
+
+ encoder->encoded_picture_avail = encoder->decoded_frame_avail = 0;
+ encoder->instr_data_avail = 0;
+
+ return encoder;
+}
+
+#if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,2)
+extern DllExport int dirac_encoder_pts_offset (const dirac_encoder_t *encoder)
+{
+ TEST (encoder != NULL);
+ TEST (encoder->compressor != NULL);
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+ int ret;
+ try
+ {
+ ret = compressor->GetPTSOffset();
+ }
+ catch (...)
+ {
+ ret = -1;
+ }
+
+ return ret;
+}
+#endif
+
+extern DllExport int dirac_encoder_load (dirac_encoder_t *encoder, unsigned char *uncdata, int uncdata_size)
+{
+ TEST (encoder != NULL);
+ TEST (encoder->compressor != NULL);
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+ int ret_stat = 0;
+ try
+ {
+ if ( compressor->LoadNextFrame (uncdata, uncdata_size))
+ {
+ ret_stat = uncdata_size;
+ }
+ }
+ catch (...)
+ {
+ if (compressor->GetEncParams().Verbose())
+ std::cerr << "dirac_encoder_load failed" << std::endl;
+ ret_stat = -1;
+ }
+ return ret_stat;
+}
+
+extern DllExport dirac_encoder_state_t
+ dirac_encoder_output (dirac_encoder_t *encoder)
+{
+ TEST (encoder != NULL);
+ TEST (encoder->compressor != NULL);
+ TEST (encoder->enc_buf.size != 0);
+ TEST (encoder->enc_buf.buffer != NULL);
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+ dirac_encoder_state_t ret_stat = ENC_STATE_BUFFER;
+
+ encoder->encoded_picture_avail = 0;
+ encoder->decoded_frame_avail = 0;
+ encoder->instr_data_avail = 0;
+
+ try
+ {
+ // Get the next compressed picture
+ if (compressor->CompressNextPicture() != 0)
+ {
+ if (compressor->GetEncodedData (encoder) < 0)
+ ret_stat = ENC_STATE_INVALID;
+ else
+ {
+ if (encoder->enc_buf.size > 0)
+ {
+ ret_stat = ENC_STATE_AVAIL;
+ }
+
+ }
+ }
+ else
+ {
+ // check if EOS has been signalled by the user app
+ if (compressor->EOS())
+ {
+ compressor->GetSequenceEnd (encoder);
+ encoder->end_of_sequence = 1;
+ encoder->enc_pparams.pnum = -1;
+ ret_stat = ENC_STATE_EOS;
+ }
+ }
+ if (encoder->enc_ctx.decode_flag)
+ compressor->GetDecodedData(encoder);
+ }
+ catch (...)
+ {
+ if (compressor->GetEncParams().Verbose())
+ std::cerr << "GetEncodedData failed..." << std::endl;
+
+ ret_stat = ENC_STATE_INVALID;
+ }
+ return ret_stat;
+}
+
+extern DllExport void dirac_encoder_end_sequence (dirac_encoder_t *encoder)
+{
+ TEST (encoder != NULL);
+ TEST (encoder->compressor != NULL);
+ DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
+
+ encoder->encoded_picture_avail = 0;
+ encoder->decoded_frame_avail = 0;
+ encoder->instr_data_avail = 0;
+
+ compressor->SignalEOS();
+
+}
+
+extern DllExport void dirac_encoder_close (dirac_encoder_t *encoder)
+{
+ TEST (encoder != NULL);
+ TEST (encoder->compressor != NULL);
+
+ delete (DiracEncoder *)(encoder->compressor);
+
+ if (encoder->enc_ctx.instr_flag)
+ {
+ dealloc_instr_data(&encoder->instr);
+ }
+
+ if (encoder->enc_ctx.decode_flag)
+ {
+ delete [] encoder->dec_buf.buf[0];
+ }
+ delete encoder;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.h
new file mode 100644
index 000000000..750c6a51a
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/dirac_encoder.h
@@ -0,0 +1,481 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: dirac_encoder.h,v 1.28 2008/11/18 23:25:54 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+* Andrew Kennedy,
+* Thomas Davies
+* Myo Tun (Brunel University, myo.tun@brunel.ac.uk)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef DIRAC_ENCODER_H
+#define DIRAC_ENCODER_H
+
+#include <libdirac_common/dirac_inttypes.h>
+#include <libdirac_common/dirac_types.h>
+
+/*! \file
+\brief C interface to Dirac Encoder.
+
+ A set of 'C' functions that define the public interface to the Dirac encoder.
+ Refer to the the reference encoder source code, encoder/encmain.cpp for
+ an example of how to use the "C" interface. The pseudocode below gives
+ a brief description of the "C" interface usage.
+
+\verbatim
+ #include <libdirac_decoder/dirac_encoder.h>
+
+ #define ENCBUF_SIZE 1024*1024;
+ unsigned char *buffer, enc_buf[ENC_BUFSIZE];
+ int buffer_size;
+ dirac_encoder_t *encoder;
+ dirac_encoder_context_t enc_ctx;
+
+ // Initialse the encoder context with the presets for SD576 - Standard
+ // Definition Digital
+ dirac_encoder_context_init (&enc_ctx, VIDEO_FORMAT_SD576I50);
+
+ // Override parameters if required
+ // interlace : 1 - interlaced; 0 - progressive
+ enc_ctx.seq_params.interlace = 0;
+ enc_ctx.seq_params.topfieldfirst = 0;
+ enc_ctx.enc_params.qf = 7.5;
+ // disable instrumentation flag
+ enc_ctx.instr_flag = 0;
+ // return locally decoded output
+ enc_ctx.decode_flag = 1;
+
+ // Initialise the encoder with the encoder context.
+ // Setting verbose output to false
+ encoder= dirac_encoder_init(&enc_ctx, false);
+
+ // Set the buffer size. For SD576 4:2:0 chroma
+ buffer_size = (720*576*3)/2;
+ buffer = (unsigned char *)malloc (buffer_size);
+
+ // Output buffer
+
+ dirac_encoder_state_t state;
+ int go = 1;
+ do
+ {
+ read uncompressed frame data into buffer
+ if (end of file)
+ {
+ // push end of sequence
+ dirac_encoder_end_sequence(encoder);
+ }
+ // load one frame of data into encoder
+ if (dirac_encoder_load(encoder, buffer, buffer_size) == 0)
+ {
+ // Retrieve encoded frames from encoder
+ do
+ {
+ encoder->enc_buf.buffer = enc_buf;
+ encoder->enc_buf.size = ENCBUF_SIZE;
+ state = dirac_encoder_output (encoder);
+ switch (state)
+ {
+ case ENC_STATE_AVAIL:
+ // Encoded frame available in encoder->enc_buf
+ // Encoded frame params available in enccoder->enc_fparams
+ // Encoded frame stats available in enccoder->enc_fstats
+ break;
+ case ENC_STATE_BUFFER:
+ break;
+ case ENC_STATE_EOS:
+ // Reached end of sequence
+ // End of sequence information is available in encoder->enc_buf
+ // Sequence statistics available in encoder->enc_seqstats;
+ go = 0; // exit from the encoding loop
+ break;
+ case ENC_STATE_INVALID:
+ default:
+ // Unrecoverable error encountered. Exit;
+ exit (exit code);
+ }
+ if (encoder->decoded_frame_avail)
+ {
+ //locally decoded frame is available in
+ //encoder->dec_buf
+ //locally decoded frame parameters available
+ //in encoder->dec_fparams
+ }
+ if (encoder->instr_data_avail)
+ {
+ //Instrumentation data (motion vectors etc.)
+ //available in encoder->instr
+ }
+ } while (state == ENC_STATE_AVAIL)
+ }
+ } while (go == 1);
+
+ // Free the encoder resources
+ dirac_encoder_close(encoder)
+ // Free the uncompressed data buffer
+ free (buffer);
+
+ \endverbatim
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! Enumerated type that defines encoder state */
+typedef enum
+{
+ ENC_STATE_INVALID = -1,
+ ENC_STATE_BUFFER,
+ ENC_STATE_AVAIL,
+ ENC_STATE_EOS
+} dirac_encoder_state_t ;
+
+/*! Enumerated type that defines prefiltering types supported by the
+ encoder. */
+typedef PrefilterType dirac_prefilter_t;
+
+/*! Enumerated type that defines encoder presets that set the encoder and
+ sequence paramters. More presets may be added in future*/
+typedef VideoFormat dirac_encoder_presets_t;
+
+/*! Enumerated type that defines motion vector precisions supported by the
+ encoder.*/
+typedef MVPrecisionType dirac_mvprecision_t;
+/*! Structure that holds the encoder specific parameters */
+typedef struct
+{
+ /*! Lossless coding */
+ int lossless;
+ /*! Quality factor */
+ float qf;
+ /*! Full-search motion estimation */
+ int full_search;
+ /*! Combined component motion estimation */
+ int combined_me;
+ /*! x-range for full search ME */
+ int x_range_me;
+ /*! y-range for full search ME */
+ int y_range_me;
+ /*! The separation between L1 frames */
+ int L1_sep;
+ /*! The number of L1 frames before the next intra frame. Together
+ with L1_sep determines the GOP structure.
+ */
+ int num_L1;
+ /*! Normalised viewing distance parameter, in cycles per degree */
+ float cpd;
+ /*! The width of blocks used for motion compensation */
+ int xblen;
+ /*! The height of blocks used for motion compensation */
+ int yblen;
+ /*! The horizontal separation between blocks. Always <xblen */
+ int xbsep;
+ /*! The vertical separation between blocks. Always <yblen */
+ int ybsep;
+ /*! Video format preset */
+ int video_format;
+ /*! Transform filter for intra frames*/
+ dirac_wlt_filter_t intra_wlt_filter;
+ /*! Transform filter for inter frames*/
+ dirac_wlt_filter_t inter_wlt_filter;
+ /*! Transform depth */
+ unsigned int wlt_depth;
+ /*! Spatial partitioning flag */
+ unsigned int spatial_partition;
+ /*! prefilter indicator */
+ dirac_prefilter_t prefilter;
+ /*! prefilter strength*/
+ unsigned int prefilter_strength;
+ /*! Multiple quantisers flag */
+ unsigned int multi_quants;
+ /*! motion-vector pixel precision */
+ dirac_mvprecision_t mv_precision;
+ /*! target bit rate in kbps */
+ int trate;
+ /*! picture coding mode: 0 - frame coding; 1 - field coding */
+ unsigned int picture_coding_mode;
+ /*! arithmetic coding flag: 0 - vlc coding; 1 - arithmetic coding */
+ int using_ac;
+} dirac_encparams_t;
+
+/*! Structure that holds the parameters that set up the encoder context */
+typedef struct
+{
+ /*! Source parameters */
+ dirac_sourceparams_t src_params;
+ /*! Encoder parameters */
+ dirac_encparams_t enc_params;
+ /*! Return diagnostics info 1-return mv data, 0-no diagnostics returned */
+ int instr_flag;
+ /*! Return locally decoded frames 1-return locally decoded frames,
+ 0-no decoded frames returned */
+ int decode_flag;
+} dirac_encoder_context_t;
+
+/*! Function that creates an encoder context based on a preset value. The
+ values can then be overridden by the user by setting each field separately
+ \param enc_ctx pointer to Encoder context tp be initialised.
+ \param preset Preset to be used to initialise the encoder context
+ \verbatim
+
+ For a full list of video formats presets supported and the default values
+ of the source and encoder parameters. refer to Annex C of the Dirac
+ ByteStream Specification.
+
+ \endverbatim
+*/
+extern DllExport void dirac_encoder_context_init (dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset);
+
+
+/*! Structure that holds the encoded data*/
+typedef struct
+{
+ /*! Buffer to hold encoded. Allocated and managed by library user. */
+ unsigned char *buffer;
+ /*! Buffer size */
+ int size;
+} dirac_enc_data_t;
+
+/*! Structure that holds the statistics about the encoded picture */
+typedef struct
+{
+ /*! Number of motion vector bits */
+ unsigned int mv_bits;
+ /*! Number of used to encode y component */
+ unsigned int ycomp_bits;
+ /*! Number of used to encode u component */
+ unsigned int ucomp_bits;
+ /*! Number of used to encode v component */
+ unsigned int vcomp_bits;
+ /*! Total number of bits used to encode picture */
+ unsigned int pic_bits;
+} dirac_enc_picstats_t;
+
+/*! Structure that holds the statistics about the encoded sequence */
+typedef struct
+{
+ /*! Number of motion vector bits */
+ int64_t mv_bits;
+ /*! Total number of bits used to encode sequence */
+ int64_t seq_bits;
+ /*! Number of used to encode y component */
+ int64_t ycomp_bits;
+ /*! Number of used to encode u component */
+ int64_t ucomp_bits;
+ /*! Number of used to encode v component */
+ int64_t vcomp_bits;
+ /*! Average bit rate for the sequence */
+ int64_t bit_rate;
+} dirac_enc_seqstats_t;
+
+/*! Structure that holds the motion vector information */
+typedef struct
+{
+ /*! X component */
+ int x;
+ /*! Y component */
+ int y;
+} dirac_mv_t;
+
+/*! Structure that holds the motion vector cost information*/
+typedef struct
+{
+ /*! The Sum of Absolute Differences */
+ float SAD;
+ /*! The (Lagrangian-weighted) motion vector cost */
+ float mvcost;
+} dirac_mv_cost_t;
+
+/*! Structure that diagnostics data returned by the encoder */
+typedef struct
+{
+ /*! Frame type */
+ dirac_picture_type_t ptype;
+ /*! Reference type */
+ dirac_reference_type_t rtype;
+ /*! Picture number */
+ int pnum;
+ /*! Number of reference pictures */
+ int num_refs;
+ /*! Array of Reference picture numbers */
+ int refs[2];
+ /*! Block separation in X direction */
+ int xbsep;
+ /*! Block separation in Y direction */
+ int ybsep;
+ /*! MacroBlock length in X direction */
+ int sb_xlen;
+ /*! MacroBlock length in Y direction */
+ int sb_ylen;
+ /*! Motion Vector array length in X direction */
+ int mv_xlen;
+ /*! Motion Vector array length in Y direction */
+ int mv_ylen;
+ /*! Macro-block split mode array - sb_ylen*sb_xlen*/
+ int *sb_split_mode;
+ /*! Macro-block costs array - sb_ylen*sb_xlen*/
+ float *sb_costs;
+ /*! Block prediction mode - mv_xlen*mv_ylen */
+ int *pred_mode;
+ /*! Block intrac costs - mv_xlen*mv_ylen */
+ float *intra_costs;
+ /*! Bi prediction costs - mv_xlen*mv_ylen*2 */
+ dirac_mv_cost_t *bipred_costs;
+ /*! DC values of y_comp */
+ short *dc_ycomp;
+ /*! DC values of u_comp */
+ short *dc_ucomp;
+ /*! DC values of v_comp */
+ short *dc_vcomp;
+ /*! Motion vectors for Reference frames mv_ylen*mv_xlen */
+ dirac_mv_t *mv[2];
+ /*! Predictions costs for Reference frames mv_ylen*mv_xlen */
+ dirac_mv_cost_t *pred_costs[2];
+} dirac_instr_t;
+
+/*! Structure that holds the information returned by the encoder */
+typedef struct
+{
+ /*! Encoder context */
+ dirac_encoder_context_t enc_ctx;
+
+ /*! encoded picture available flag */
+ int encoded_picture_avail;
+
+ /*!
+ encoded output. This buffer must be initialised by the user of the
+ library
+ */
+ dirac_enc_data_t enc_buf;
+
+ /*! encoded picture params */
+ dirac_picparams_t enc_pparams;
+
+ /*! encoded picture stats */
+ dirac_enc_picstats_t enc_pstats;
+
+ /*! encoded sequence stats */
+ dirac_enc_seqstats_t enc_seqstats;
+
+ /*! end of sequence */
+ int end_of_sequence;
+
+ /* locally decoded frame (NB: not picture) available flag.
+ 1 - locally decoded frame available in dec_buf.
+ 0 - locally decoded frame not available.
+ */
+ int decoded_frame_avail;
+
+ /*!
+ locally decoded output buffer. This buffer is allocated and managed by
+ the encoder library
+ */
+ dirac_framebuf_t dec_buf;
+
+ /*! locally decoded picture params */
+ dirac_picparams_t dec_pparams;
+
+ /*!
+ instrumentation data buffer. This buffer is allocated and managed by
+ the encoder library. */
+ dirac_instr_t instr;
+
+ /*! instrumentation data available flag
+ 1 - instrumentation data available in instr
+ 0 - linstrumentation data not available.
+ */
+ int instr_data_avail;
+
+ /*! void pointer to internal sequence compressor */
+ const void *compressor;
+} dirac_encoder_t;
+
+/*!
+ Initialise encoder. Makes a copy of the enc_ctx passed to it.
+ \param enc_ctx Parameters to initialise encoder context
+ \param verbose boolean flag to set verbose output
+ \return encoder Handle to encoder if successful or NULL on failure
+*/
+extern DllExport dirac_encoder_t *dirac_encoder_init (const dirac_encoder_context_t *enc_ctx, int verbose);
+
+#if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,2)
+/*!
+ Query the encoder for the reordering depth.
+ \param encoder Encoder Handle
+ \return encoder The number of pictures a realtime decoder must wait
+ before outputting the first picture in display order;
+ or -1 for failure.
+*/
+extern DllExport int dirac_encoder_pts_offset (const dirac_encoder_t *encoder);
+#endif
+
+/*!
+ Load uncompressed data into the encoder. Expects one full frame of data
+ \param encoder Encoder Handle
+ \param uncdata Uncompressed data buffer
+ \param uncdata_size boolean flag to set verbose output
+ \return return status. >0 - successful; -1 failed
+ Failure may be due to input data size not matching
+ the required frame size.
+*/
+extern DllExport int dirac_encoder_load (dirac_encoder_t *encoder, unsigned char *uncdata, int uncdata_size);
+
+/*!
+ Retrieve an encoded frame from the encoder. Returns the state of the
+ encoder. The encoder buffer enc_buf in the encodermust be
+ set up with the buffer and buffer_size that will hold the encoded frame
+ \param encoder Encoder Handle
+ \return ENC_STATE_INVALID - unrecoverable error
+ ENC_STATE_BUFFER - load data into encoder
+ ENC_STATE_AVAIL - Encoded frame available
+ ENC_STATE_EOS - End of Sequence info available
+*/
+extern DllExport dirac_encoder_state_t dirac_encoder_output (dirac_encoder_t *encoder);
+
+/*!
+ Request the encoder to end the sequence.
+ \param encoder Encoder Handle
+*/
+extern DllExport void dirac_encoder_end_sequence (dirac_encoder_t *encoder);
+
+/*!
+ Free resources held by encoder
+ \param encoder Encoder Handle
+*/
+extern DllExport void dirac_encoder_close (dirac_encoder_t *encoder);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.cpp
new file mode 100644
index 000000000..5ad01bbe3
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.cpp
@@ -0,0 +1,383 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: enc_picture.cpp,v 1.6 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2008.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_encoder/enc_picture.h>
+#include <libdirac_common/upconvert.h>
+
+using namespace dirac;
+
+EncPicture::EncPicture( const PictureParams& pp):
+ Picture( pp ),
+ m_me_data( NULL ),
+ m_status( NO_ENC ),
+ m_complexity( 0.0 ),
+ m_norm_complexity( 1.0 ),
+ m_pred_bias(0.5)
+{
+ for (int c=0; c<3; ++c ){
+ m_orig_data[c] = new PicArray( m_pic_data[c]->LengthY(), m_pic_data[c]->LengthX() );
+ m_orig_up_data[c] = NULL;
+ m_filt_data[c] = NULL;
+ m_filt_up_data[c] = NULL;
+ }
+}
+
+void EncPicture::ClearData(){
+
+ Picture::ClearData();
+
+ for (int c=0;c<3;++c){
+ if (m_orig_data[c] != NULL){
+ delete m_orig_data[c];
+ m_orig_data[c] = NULL;
+ }
+
+ if (m_orig_up_data[c] != NULL){
+ delete m_orig_up_data[c];
+ m_orig_up_data[c] = NULL;
+ }
+
+ if (m_filt_data[c] != NULL){
+ delete m_filt_data[c];
+ m_filt_data[c] = NULL;
+ }
+
+ if (m_filt_up_data[c] != NULL){
+ delete m_filt_up_data[c];
+ m_filt_up_data[c] = NULL;
+ }
+ }
+
+ if ( m_me_data != NULL )
+ delete m_me_data;
+}
+
+EncPicture::~EncPicture()
+{
+ ClearData();
+}
+
+void EncPicture::SetOrigData()
+{
+ for ( int c=0; c<3 ; ++c )
+ SetOrigData(c);
+}
+
+void EncPicture::SetOrigData( const int c )
+{
+ if ( m_pic_data[c] != NULL )
+ *(m_orig_data[c]) = *(m_pic_data[c]);
+}
+
+void EncPicture::InitMEData( const PicturePredParams& predparams , const int num_refs)
+{
+ if (m_me_data != NULL)
+ delete m_me_data;
+
+ m_me_data=new MEData( predparams, num_refs );
+}
+
+const PicArray& EncPicture::DataForME( bool combined_me ) const{
+
+ if (combined_me)
+ return CombinedData();
+ else
+ return OrigData( Y_COMP );
+}
+
+const PicArray& EncPicture::UpDataForME( bool combined_me ) const{
+
+ if (combined_me)
+ return UpCombinedData();
+ else
+ return UpOrigData( Y_COMP );
+}
+
+
+const PicArray& EncPicture::UpOrigData(CompSort cs) const
+{
+ const int c = (int) cs;
+
+ if (m_orig_up_data[c] != NULL)
+ return *m_orig_up_data[c];
+ else
+ {//we have to do the upconversion
+
+ m_orig_up_data[c] = new PicArray( 2*m_orig_data[c]->LengthY(),
+ 2*m_orig_data[c]->LengthX() );
+ UpConverter* myupconv;
+ if (c>0)
+ myupconv = new UpConverter(-(1 << (m_pparams.ChromaDepth()-1)),
+ (1 << (m_pparams.ChromaDepth()-1))-1,
+ m_pparams.ChromaXl(), m_pparams.ChromaYl());
+ else
+ myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
+ (1 << (m_pparams.LumaDepth()-1))-1,
+ m_pparams.Xl(), m_pparams.Yl());
+
+ myupconv->DoUpConverter( *(m_orig_data[c]) , *(m_orig_up_data[c]) );
+
+ delete myupconv;
+
+ return *(m_orig_up_data[c]);
+
+ }
+}
+
+const PicArray& EncPicture::FiltData(CompSort cs) const
+{
+ const int c = (int) cs;
+
+ if (m_filt_data[c] != NULL)
+ return *m_filt_data[c];
+ else
+ {//we have to do the filtering
+
+ if (m_orig_data[c] != NULL )
+ m_filt_data[c] = new PicArray( m_orig_data[c]->LengthY(),
+ m_orig_data[c]->LengthX() );
+
+ AntiAliasFilter( *(m_filt_data[c]), *(m_orig_data[c]));
+
+ return *(m_filt_data[c]);
+
+ }
+}
+
+const PicArray& EncPicture::UpFiltData(CompSort cs) const
+{
+ const int c = (int) cs;
+
+ if (m_filt_up_data[c] != NULL)
+ return *m_filt_up_data[c];
+ else
+ {//we have to do the upconversion
+
+ const PicArray& filt_data = FiltData( cs );
+
+ m_filt_up_data[c] = new PicArray( 2*filt_data.LengthY(),
+ 2*filt_data.LengthX() );
+ UpConverter* myupconv;
+ if (c>0)
+ myupconv = new UpConverter(-(1 << (m_pparams.ChromaDepth()-1)),
+ (1 << (m_pparams.ChromaDepth()-1))-1,
+ m_pparams.ChromaXl(), m_pparams.ChromaYl());
+ else
+ myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
+ (1 << (m_pparams.LumaDepth()-1))-1,
+ m_pparams.Xl(), m_pparams.Yl());
+
+ myupconv->DoUpConverter( filt_data , *(m_filt_up_data[c]) );
+
+ delete myupconv;
+
+ return *(m_filt_up_data[c]);
+
+ }
+}
+
+void EncPicture::AntiAliasFilter( PicArray& out_data, const PicArray& in_data ) const{
+
+ //Special case for first row
+ for (int i = in_data.FirstX(); i <= in_data.LastX(); ++i)
+ {
+ out_data[in_data.FirstY()][i] = (3*in_data[in_data.FirstY()][i] +
+ in_data[in_data.FirstY()+1][i] +2 )>>2;
+ }
+ //Middle section
+ for (int j = in_data.FirstY()+1; j < in_data.LastY(); ++j)
+ {
+ for (int i = in_data.FirstX(); i <= in_data.LastX(); ++i)
+ {
+ out_data[j][i] = (in_data[j-1][i] + 2*in_data[j][i] + in_data[j+1][i] + 2)>>2;
+ }
+ }
+ //Special case for last row
+ for (int i = in_data.FirstX(); i <= in_data.LastX(); ++i)
+ {
+ out_data[in_data.LastY()][i] = (in_data[in_data.LastY()-1][i] +
+ 3*in_data[in_data.LastY()][i] + 2)>>2;
+ }
+}
+
+const PicArray& EncPicture::CombinedData() const
+{
+
+ if (m_filt_data[Y_COMP] != NULL)
+ return *m_filt_data[Y_COMP];
+ else
+ {//we have to do the combining
+
+ if (m_orig_data[Y_COMP] != NULL )
+ m_filt_data[Y_COMP] = new PicArray( m_orig_data[Y_COMP]->LengthY(),
+ m_orig_data[Y_COMP]->LengthX() );
+
+ Combine( *(m_filt_data[Y_COMP]), *(m_orig_data[Y_COMP]),
+ *(m_orig_data[U_COMP]), *(m_orig_data[V_COMP])
+ );
+
+ return *(m_filt_data[Y_COMP]);
+
+ }
+}
+
+const PicArray& EncPicture::UpCombinedData() const
+{
+ if (m_filt_up_data[Y_COMP] != NULL)
+ return *m_filt_up_data[Y_COMP];
+ else
+ {//we have to do the upconversion
+
+ const PicArray& filt_data = CombinedData();
+
+ m_filt_up_data[Y_COMP] = new PicArray( 2*filt_data.LengthY(),
+ 2*filt_data.LengthX() );
+ UpConverter* myupconv;
+ myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
+ (1 << (m_pparams.LumaDepth()-1))-1,
+ m_pparams.Xl(), m_pparams.Yl());
+
+ myupconv->DoUpConverter( filt_data , *(m_filt_up_data[Y_COMP]) );
+
+ delete myupconv;
+
+ return *(m_filt_up_data[Y_COMP]);
+
+ }
+}
+
+
+
+void EncPicture::Combine( PicArray& comb_data, const PicArray& y_data,
+ const PicArray& u_data, const PicArray& v_data ) const
+{
+ int hcr = y_data.LengthX()/u_data.LengthX();
+ int vcr = y_data.LengthY()/u_data.LengthY();
+
+ float val, valc, valy;
+
+ if (vcr==1){
+ for (int j=0; j<comb_data.LengthY(); ++j) {
+ if (hcr==1){// 444 format
+ for (int i=0; i<comb_data.LengthX(); ++i ){
+ val = float(u_data[j][i]);
+ val *= val;
+ valc = val;
+
+ val = float(v_data[j][i]);
+ val *= val;
+ valc += val;
+
+ valy = float(y_data[j][i]) + 128.0;
+ valy *= valy;
+ comb_data[j][i] = ValueType( std::sqrt(valc+valy)-128.0 );
+ }// i
+ }
+ else{ // 422 format
+ for (int i=0; i<comb_data.LengthX(); i+=2 ){
+
+ val = float(u_data[j][i>>1]);
+ val *= val;
+ valc = val;
+
+ val = float(v_data[j][i>>1]);
+ val *= val;
+ valc += val;
+
+ valy = float(y_data[j][i]) + 128.0;
+ valy *= valy;
+ comb_data[j][i] = ValueType( std::sqrt(valc+valy)-128.0 );
+
+ valy = float(y_data[j][i+1]) + 128.0;
+ valy *= valy;
+
+ comb_data[j][i+1] = ValueType( std::sqrt(valc+valy)-128.0 );
+
+ }// i
+ }
+ }// j
+ }
+ else{ // 420 format
+ for (int j=0; j<comb_data.LengthY(); j+=2 ) {
+
+ for (int i=0; i<comb_data.LengthX(); i+=2 ){
+
+ val = float(u_data[j>>1][i>>1]);
+ val *= val;
+ valc = val;
+
+ val = float(v_data[j>>1][i>>1]);
+ val *= val;
+ valc += val;
+
+ valy = float(y_data[j][i]) + 128.0;
+ valy *= valy;
+ comb_data[j][i] = ValueType( std::sqrt(valc+valy)-128.0 );
+
+ valy = float(y_data[j][i+1]) + 128.0;
+ valy *= valy;
+ comb_data[j][i+1] = ValueType( std::sqrt(valc+valy)-128.0 );
+
+ valy = float(y_data[j+1][i]) + 128.0;
+ valy *= valy;
+ comb_data[j+1][i] = ValueType( std::sqrt(valc+valy)-128.0 );
+
+ valy = float(y_data[j+1][i+1]) + 128.0;
+ valy *= valy;
+ comb_data[j+1][i+1] = ValueType( std::sqrt(valc+valy)-128.0 );
+
+ }// i
+ }// j
+
+ }
+
+
+}
+
+
+void EncPicture::DropRef( int rindex ){
+
+ std::vector<int>& refs = m_pparams.Refs();
+
+ if (rindex==1 || rindex==2 )
+ refs.erase( refs.begin()+rindex-1 );
+
+ // Now reconfigure the motion data
+ if ( m_me_data!=NULL )
+ m_me_data->DropRef( rindex );
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.h
new file mode 100644
index 000000000..cbef4f5ce
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_picture.h
@@ -0,0 +1,163 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: enc_picture.h,v 1.6 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2008.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ENC_PICTURE_H_
+#define _ENC_PICTURE_H_
+
+#include <libdirac_common/picture.h>
+#include <libdirac_common/motion.h>
+
+
+namespace dirac
+{
+static const unsigned int DONE_ME_INIT = 0x1;
+static const unsigned int DONE_PEL_ME = 0x2;
+static const unsigned int DONE_SUBPEL_ME = 0x4;
+static const unsigned int DONE_ME_MODE_DECN = 0x8;
+static const unsigned int DONE_MV_CODING = 0x10;
+static const unsigned int DONE_MC = 0x20;
+static const unsigned int DONE_DWT = 0x40;
+static const unsigned int DONE_QUANT_SEL = 0x80;
+static const unsigned int DONE_RES_CODING = 0x100;
+static const unsigned int DONE_IDWT = 0x200;
+static const unsigned int DONE_MC_BACK = 0x400;
+static const unsigned int DONE_SET_PTYPE = 0x800;
+static const unsigned int DONE_PIC_COMPLEXITY = 0x1000;
+
+static const unsigned int ALL_ENC = 0xFFFFFFFF;
+static const unsigned int NO_ENC = 0;
+
+class EncPicture : public Picture
+{
+public:
+ EncPicture( const PictureParams& pp );
+
+ virtual ~EncPicture();
+
+ //! Initialise the motion estimation data arrays
+ void InitMEData( const PicturePredParams& predparams, const int num_refs);
+
+ //! Returns the motion data
+ MEData& GetMEData(){ return *m_me_data;}
+
+ //! Returns the motion data
+ const MEData& GetMEData() const { return *m_me_data;}
+
+ //! Drops a reference from the motion vector data
+ void DropRef( int rindex );
+
+
+ //! Returns a given component of the original data
+ const PicArray& OrigData(CompSort c) const { return *m_orig_data[(int) c];}
+
+ //! Returns a given upconverted component of the original data
+ const PicArray& UpOrigData(CompSort cs) const;
+
+ //! Initialises a copy of the data arrays into the original data
+ void SetOrigData();
+
+ //! Returns a version of the picture data suitable for motion estimation
+ const PicArray& DataForME(bool combined_me) const;
+
+ //! Returns a version of the picture data suitable for subpel motion estimation
+ const PicArray& UpDataForME(bool combined_me) const;
+
+
+ void UpdateStatus( const unsigned int mask ){ m_status |= mask; }
+
+ void FlipStatus( const unsigned int mask){ m_status ^= mask; }
+
+ void SetStatus( const int status ){ m_status = status; }
+
+ unsigned int GetStatus() const{ return m_status; }
+
+
+ double GetComplexity() const {return m_complexity; }
+
+ void SetComplexity(double c){ m_complexity = c; }
+
+ double GetNormComplexity() const { return m_norm_complexity; }
+
+ void SetNormComplexity( double c ){ m_norm_complexity = c; }
+
+ double GetPredBias() const { return m_pred_bias; }
+
+ void SetPredBias( double b ){ m_pred_bias = b; }
+
+
+private:
+
+ virtual void ClearData();
+
+ //! Filters a (field) picture vertically to reduce aliasing for motion estimation purposes
+ void AntiAliasFilter( PicArray& out_data, const PicArray& in_data ) const;
+
+ //! Returns an anti-aliased version of the original data
+ const PicArray& FiltData(CompSort c) const;
+
+ const PicArray& CombinedData() const;
+ const PicArray& UpCombinedData() const;
+ void Combine( PicArray& comb_data, const PicArray& y_data,
+ const PicArray& u_data, const PicArray& v_data ) const;
+
+ //! Returns an upconverted anti-aliased version of the original data
+ const PicArray& UpFiltData(CompSort c) const;
+
+
+ void SetOrigData(const int c);
+
+private:
+
+ PicArray* m_orig_data[3];
+ mutable PicArray* m_orig_up_data[3];
+ mutable PicArray* m_filt_data[3];
+ mutable PicArray* m_filt_up_data[3];
+
+ MEData* m_me_data;
+
+ unsigned int m_status;
+
+ double m_complexity;
+ double m_norm_complexity;
+
+ double m_pred_bias;
+};
+
+
+}
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.cpp
new file mode 100644
index 000000000..f64da8a0b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.cpp
@@ -0,0 +1,292 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: enc_queue.cpp,v 1.3 2008/08/14 01:58:39 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2008.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_encoder/enc_queue.h>
+#include <algorithm>
+using namespace dirac;
+
+//Simple constructor for decoder operation
+EncQueue::EncQueue(){}
+
+//Copy constructor. Why anyone would need this I don't know.
+EncQueue::EncQueue(const EncQueue& cpy)
+ {
+ // first delete all frames in the current buffer
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ delete m_pic_data[i];
+ }//i
+
+ // next create new arrays, copying from the initialising buffer
+ m_pic_data.resize(cpy.m_pic_data.size());
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i){
+ m_pic_data[i] = new EncPicture( *(cpy.m_pic_data[i]) );
+ }//i
+
+ // now copy the map
+ m_pnum_map = cpy.m_pnum_map;
+
+}
+
+//Assignment=. Not sure why this would be used either.
+EncQueue& EncQueue::operator=(const EncQueue& rhs){
+ if (&rhs!=this)
+ {
+ // delete all the frames in the lhs buffer
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ delete m_pic_data[i];
+ }//i
+
+ // next create new arrays, copying from the rhs
+ m_pic_data.resize(rhs.m_pic_data.size());
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ m_pic_data[i] = new EncPicture( *(rhs.m_pic_data[i]) );
+ }//i
+
+ // now copy the map
+ m_pnum_map = rhs.m_pnum_map;
+
+ }
+ return *this;
+}
+
+//Destructor
+EncQueue::~EncQueue()
+{
+ for (size_t i=0 ; i<m_pic_data.size() ;++i)
+ delete m_pic_data[i];
+}
+
+EncPicture& EncQueue::GetPicture( const unsigned int pnum )
+{//get picture with a given picture number, NOT with a given position in the buffer.
+ //If the picture number does not occur, the first picture in the buffer is returned.
+
+ std::map<unsigned int,unsigned int>::iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos = 0;
+ if (it != m_pnum_map.end())
+ pos = it->second;
+
+ return *(m_pic_data[pos]);
+}
+
+const EncPicture& EncQueue::GetPicture( const unsigned int pnum ) const
+{ //as above, but const version
+
+ std::map<unsigned int,unsigned int>::const_iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos=0;
+ if (it != m_pnum_map.end())
+ pos = it->second;
+
+ return *(m_pic_data[pos]);
+}
+
+EncPicture& EncQueue::GetPicture( const unsigned int pnum, bool& is_present )
+{//get picture with a given picture number, NOT with a given position in the buffer.
+ //If the picture number does not occur, the first picture in the buffer is returned.
+
+ std::map<unsigned int,unsigned int>::iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos = 0;
+ if (it != m_pnum_map.end())
+ {
+ is_present = true;
+ pos = it->second;
+ }
+ else
+ is_present=false;
+
+ return *(m_pic_data[pos]);
+}
+
+const EncPicture& EncQueue::GetPicture( const unsigned int pnum, bool& is_present ) const
+{ //as above, but const version
+
+ std::map<unsigned int,unsigned int>::const_iterator it = m_pnum_map.find(pnum);
+
+ unsigned int pos=0;
+ if (it != m_pnum_map.end())
+ {
+ is_present = true;
+ pos = it->second;
+ }
+ else
+ is_present=false;
+
+ return *(m_pic_data[pos]);
+}
+
+bool EncQueue::IsPictureAvail( const unsigned int pnum ) const
+{
+
+ std::map<unsigned int,unsigned int>::const_iterator it = m_pnum_map.find(pnum);
+
+ if (it != m_pnum_map.end())
+ return true;
+ else
+ return false;
+}
+
+std::vector<int> EncQueue::Members() const
+{
+ std::vector<int> members( 0 );
+ for (unsigned int i=0; i<m_pic_data.size(); ++i )
+ {
+ const PictureParams& pparams = m_pic_data[i]->GetPparams();
+ members.push_back( pparams.PictureNum() );
+ }// i
+
+ return members;
+}
+
+void EncQueue::PushPicture( const PictureParams& pp )
+{// Put a new picture onto the top of the stack
+
+ // if picture is present - return
+ if (IsPictureAvail(pp.PictureNum()))
+ return;
+
+// if ( pp.PicSort().IsRef() )
+// m_ref_count++;
+
+ EncPicture* pptr = new EncPicture(pp);
+ // add the picture to the buffer
+ m_pic_data.push_back(pptr);
+
+ // put the picture number into the index table
+ std::pair<unsigned int,unsigned int> temp_pair(pp.PictureNum() , m_pic_data.size()-1);
+ m_pnum_map.insert(temp_pair);
+}
+
+void EncQueue::CopyPicture( const EncPicture& picture )
+{
+ PushPicture(picture.GetPparams());
+
+ bool is_present;
+
+ EncPicture & p= GetPicture(picture.GetPparams().PictureNum(), is_present);
+ if(is_present)
+ p = picture;
+}
+
+void EncQueue::ClearSlot(const unsigned int pos)
+{
+ // Clear a slot corresponding to position pos to take more data
+
+ std::pair<unsigned int,unsigned int>* tmp_pair;
+
+ if (pos<m_pic_data.size())
+ {
+ delete m_pic_data[pos];
+
+ m_pic_data.erase(m_pic_data.begin() + pos);
+
+ //make a new map
+ m_pnum_map.clear();
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ tmp_pair = new std::pair<unsigned int,unsigned int>( m_pic_data[i]->GetPparams().PictureNum() , i);
+ m_pnum_map.insert(*tmp_pair);
+ delete tmp_pair;
+ }//i
+ }
+}
+
+
+void EncQueue::SetRetiredPictureNum(const int show_pnum, const int current_coded_pnum)
+{
+
+ if ( IsPictureAvail(current_coded_pnum))
+ {
+ PictureParams &pparams = GetPicture(current_coded_pnum).GetPparams();
+ pparams.SetRetiredPictureNum(-1);
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ if (m_pic_data[i]->GetPparams().PicSort().IsRef() )
+ {
+ if ( (m_pic_data[i]->GetPparams().PictureNum() + m_pic_data[i]->GetPparams().ExpiryTime() ) <= show_pnum)
+ {
+ pparams.SetRetiredPictureNum(m_pic_data[i]->GetPparams().PictureNum());
+ break;
+ }
+ }
+ }//i
+ }
+}
+
+void EncQueue::CleanAll(const int show_pnum, const int current_coded_pnum)
+{// clean out all frames that have expired
+ if (IsPictureAvail(current_coded_pnum))
+ {
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i)
+ {
+ if ( (m_pic_data[i]->GetPparams().PictureNum() + m_pic_data[i]->GetPparams().ExpiryTime() ) <= show_pnum)
+ ClearSlot(i);
+ }//i
+ }
+}
+
+void EncQueue::CleanRetired(const int show_pnum, const int current_coded_pnum)
+{// clean out all frames that have expired
+ if ( IsPictureAvail(current_coded_pnum) )
+ {
+ PictureParams &pparams = GetPicture(current_coded_pnum).GetPparams();
+ // Remove Reference picture specified in retired picture number.
+ if (pparams.PicSort().IsRef() && pparams.RetiredPictureNum()>= 0)
+ Remove(pparams.RetiredPictureNum());
+ pparams.SetRetiredPictureNum(-1);
+ // Remove non-reference frames that have expired
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i){
+ if ( (m_pic_data[i]->GetPparams().PictureNum()+
+ m_pic_data[i]->GetPparams().ExpiryTime() )<=show_pnum
+ && m_pic_data[i]->GetPparams().PicSort().IsNonRef() )
+ ClearSlot(i);
+ }//i
+ }
+}
+
+void EncQueue::Remove(const int pnum)
+{
+ for (size_t i=0 ; i<m_pic_data.size() ; ++i){
+ if ( m_pic_data[i]->GetPparams().PictureNum() == pnum)
+ ClearSlot(i);
+ }//i
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.h
new file mode 100644
index 000000000..2d282ebce
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/enc_queue.h
@@ -0,0 +1,222 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: enc_queue.h,v 1.3 2008/08/14 02:30:50 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ENC_QUEUE_H_
+#define _ENC_QUEUE_H_
+
+#include <vector>
+#include <map>
+#include <libdirac_encoder/enc_picture.h>
+#include <libdirac_common/common.h>
+
+namespace dirac
+{
+ //! Holds pictures both for reference and to overcome reordering delay
+ /*!
+ The buffer holds pictures in a stack to overcome both reordering due to
+ bi-directional prediction and use as references for subsequence motion
+ estimation. Pictures, and components of pictures, can be accessed by their
+ picture numbers. GOP parameters can be included in the constructors so
+ that pictures can be given types (I picture, L1 picture or L2 picture) on
+ being pushed onto the stack; alternatively, these parameters can be
+ overridden.
+ */
+ class EncQueue{
+ public:
+ //! Default Constructor
+ EncQueue();
+
+ //! Constructor
+ /*!
+ Creates a EncQueue using the chroma format. Suitable for
+ compressing when there are no L2 pictures, or when the temporal
+ prediction structure is to be determined on the fly.
+
+ \param cf the Chroma format of pictures in the buffer
+ \param xlen the luma width of pictures in the buffer
+ \param ylen the luma height of pictures in the buffer
+ \param luma_depth the video depth of the luma comp in the buffer
+ \param chroma_depth the video depth of the chroma comp in the buffer
+ \param using_ac True if using Arithmetic coding to code coefficient data
+
+ */
+ EncQueue(ChromaFormat cf,
+ const int xlen,
+ const int ylen,
+ const unsigned int luma_depth,
+ const unsigned int chroma_depth,
+ bool using_ac);
+
+ //! Constructor
+ /*!
+ Creates a EncQueue using the chroma format, the number of L1
+ pictures between I pictures and the separation in pictures between L1
+ pictures. Suitable for compressing when there is a full GOP structure
+ or when the temporal prediction structure is to be determined on
+ the fly.
+
+ \param cf the Chroma format of pictures in the buffer
+ \param numL1 the number of Layer 1 pictures before the next I picture. 0 means that there is only one I picture.
+ \param L1sep the number of Layer 2 pictures between Layer 1 pictures
+ \param xlen the luma width of pictures in the buffer
+ \param ylen the luma height of pictures in the buffer
+ \param luma_depth the video depth of the luma comp in the buffer
+ \param chroma_depth the video depth of the chroma comp in the buffer
+ \param interlace Set true if material is being coded in interlaced mode
+ \param using_ac True if using Arithmetic coding to code coefficient data
+ */
+ EncQueue(ChromaFormat cf,
+ const int numL1,
+ const int L1sep,
+ const int xlen,
+ const int ylen,
+ const unsigned int luma_depth,
+ const unsigned int chroma_depth,
+ bool interlace,
+ bool using_ac);
+
+ //! Copy constructor
+ /*!
+ Copy constructor. Removes the current contents of the pictureture buffer
+ and copies in the contents of the initialising buffer.
+ */
+ EncQueue(const EncQueue& cpy);
+
+ //! Operator=.
+ /*!
+ Operator=. Assigns all elements of the rhs to the lhs.
+ */
+ EncQueue& operator=(const EncQueue& rhs);
+
+ //! Destructor
+ ~EncQueue();
+
+ //! Get picture with a given picture number (NOT with a given position in the buffer)
+ EncPicture& GetPicture(const unsigned int pnum );
+
+ //! Get picture with a given picture number (NOT with a given position in the buffer)
+ const EncPicture& GetPicture(const unsigned int pnum) const;
+
+ //! Get picture with a given picture number, setting a flag to true if it's there
+ EncPicture& GetPicture(const unsigned int pnum, bool& is_present);
+
+ //! Get picture with a given picture number, setting a flag to true if it's there
+ const EncPicture& GetPicture(const unsigned int pnum, bool& is_present) const;
+
+ //! Return true if picture with the particular picture number is available else return false
+ bool IsPictureAvail(const unsigned int pnum) const;
+
+ //! Returns a list of member pictures
+ std::vector<int> Members() const;
+
+ //! Returns the size of the queue
+ int Size() const { return m_pic_data.size(); }
+
+ //! Put a new picture into the top of the buffer
+ /*!
+ Put a new picture into the top of the buffer. EncPicture parameters
+ associated with the picture will be as given by the picture parameter
+ object.
+ */
+ void PushPicture(const PictureParams& pp);
+
+ //! Put a copy of a new picture into the buffer
+ /*!
+ Put a copy of a new picture into the buffer.
+ */
+ void CopyPicture( const EncPicture& picture );
+
+ //! Sets the reference picture number that will be cleaned
+ /*!
+ Indicate which picture which has been output and which is no longer
+ required for reference. Expiry times are set in each picture's
+ picture parameters.
+ \param show_pnum picture number in display order that can be output
+ \param current_coded_pnum picture number in display order of picture currently being coded
+ */
+ void SetRetiredPictureNum(const int show_pnum, const int current_coded_pnum);
+
+ //! Delete all expired pictures
+ /*!
+ Delete pictures which have been output and which are no longer
+ required for reference. Expiry times are set in each picture's
+ picture parameters.
+ \param show_pnum picture number in display order that can be output
+ \param current_coded_pnum picture number in display order of picture currently being coded
+ */
+ void CleanAll(const int show_pnum, const int current_coded_pnum);
+
+ //! Delete retired reference pictures and expired non-ref pictures
+ /*!
+ Delete pictures which have been output and retired reference pictures.
+ Expiry times are set in each picture's picture parameters.
+ \param show_pnum picture number in display order that can be output
+ \param current_coded_pnum picture number in display order of picture currently being coded
+ */
+ void CleanRetired(const int show_pnum, const int current_coded_pnum);
+
+ //! Delete picture
+ /*!
+ Delete picture.
+ \param pnum picture number in display order to be deleted from picture buffer
+ */
+ void Remove(int pnum);
+
+ private:
+ //! Clear internal data slot number pos
+ /*!
+ Clear internal data slot number pos
+ */
+ void ClearSlot(const unsigned int pos);
+
+ private:
+
+// //! the count of the number of reference pictures in the buffer
+// int m_ref_count;
+
+ //! the buffer storing all the values
+ std::vector<EncPicture*> m_pic_data;
+
+ //!the map from picture numbers to position in the buffer
+ std::map<unsigned int,unsigned int> m_pnum_map;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.cpp
new file mode 100644
index 000000000..93c6be9b4
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.cpp
@@ -0,0 +1,710 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_compress.cpp,v 1.28 2009/01/21 05:20:57 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Chris Bowley,
+* Anuradha Suraparaju,
+* Tim Borer,
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+//Compression of pictures//
+/////////////////////////
+
+#include <libdirac_encoder/picture_compress.h>
+#include <libdirac_encoder/comp_compress.h>
+#include <libdirac_encoder/prefilter.h>
+#include <libdirac_common/mot_comp.h>
+#include <libdirac_motionest/pixel_match.h>
+#include <libdirac_motionest/me_subpel.h>
+#include <libdirac_motionest/me_mode_decn.h>
+#include <libdirac_common/mv_codec.h>
+#include <libdirac_encoder/quant_chooser.h>
+#include <libdirac_common/dirac_assertions.h>
+using namespace dirac;
+
+#include <iostream>
+#include <sstream>
+
+PictureCompressor::PictureCompressor( EncoderParams& encp ) :
+ m_encparams(encp),
+ m_skipped(false),
+ m_use_global(false),
+ m_use_block_mv(true),
+ m_global_pred_mode(REF1_ONLY),
+ m_me_data(NULL),
+ m_medata_avail(false),
+ m_is_a_cut(false)
+{}
+
+PictureCompressor::~PictureCompressor()
+{}
+
+
+void PictureCompressor::PixelME( EncQueue& my_buffer , int pnum )
+{
+ PixelMatcher pix_match( m_encparams );
+ pix_match.DoSearch( my_buffer , pnum );
+}
+
+void PictureCompressor::CalcComplexity( EncQueue& my_buffer, int pnum , const OLBParams& olbparams )
+{
+ EncPicture& my_picture = my_buffer.GetPicture( pnum );
+ PictureParams& pparams = my_picture.GetPparams();
+
+ if ( (my_picture.GetStatus()&DONE_PEL_ME) != 0 ){
+ MEData& me_data = my_picture.GetMEData();
+
+ TwoDArray<MvCostData>* pcosts1;
+ TwoDArray<MvCostData>* pcosts2;
+
+ pcosts1 = &me_data.PredCosts(1);
+ if (pparams.NumRefs()>1)
+ pcosts2 = &me_data.PredCosts(2);
+ else
+ pcosts2 = pcosts1;
+
+ float cost1, cost2, cost;
+ double total_cost1 = 0.0;
+ double total_cost2 = 0.0;
+ double total_cost = 0.0;
+
+ int count1=0;int count=0;
+
+ float cost_threshold = float(olbparams.Xblen()*olbparams.Yblen()*10);
+
+ for (int j=4; j<pcosts1->LengthY()-4; ++j){
+ for (int i=4; i<pcosts1->LengthX()-4; ++i){
+ cost1 = (*pcosts1)[j][i].SAD;
+ cost2 = (*pcosts2)[j][i].SAD;
+ cost = std::min(cost1, cost2);
+ total_cost1 += cost1;
+ total_cost2 += cost2;
+ total_cost += cost;
+ if (pparams.NumRefs()>1 && cost<=cost_threshold){
+ ++count;
+ if (cost1<=cost2)
+ ++count1;
+ }
+ }
+
+ }
+ total_cost1 *= olbparams.Xbsep()*olbparams.Ybsep();
+ total_cost1 /= olbparams.Xblen()*olbparams.Yblen();
+
+ total_cost2 *= olbparams.Xbsep()*olbparams.Ybsep();
+ total_cost2 /= olbparams.Xblen()*olbparams.Yblen();
+
+ if (pparams.NumRefs()>1){
+ my_picture.SetPredBias(float(count1)/float(count));
+ }
+ else
+ my_picture.SetPredBias(0.5);
+
+ total_cost *= olbparams.Xbsep()*olbparams.Ybsep();
+ total_cost /= olbparams.Xblen()*olbparams.Yblen();
+
+// my_picture.SetComplexity( total_cost );
+ my_picture.SetComplexity( total_cost*total_cost );
+
+ }
+
+}
+
+void PictureCompressor::CalcComplexity2( EncQueue& my_buffer, int pnum )
+{
+ // to be used after doing motion compensation
+ EncPicture& my_picture = my_buffer.GetPicture( pnum );
+ const PicArray& pic_data = my_picture.Data( Y_COMP );
+
+ if ( (my_picture.GetStatus()&DONE_MC) != 0 ){
+
+ float cost;
+ double total_sq_cost = 0.0;
+ double total_cost = 0.0;
+
+ for (int j=0; j<pic_data.LengthY(); ++j){
+ for (int i=0; i<pic_data.LengthX(); ++i){
+ cost = float( pic_data[j][i] );
+ total_cost += cost;
+ total_sq_cost += cost*cost;
+ }
+
+ }
+
+ total_cost /= ( pic_data.LengthX()*pic_data.LengthY() );
+ total_sq_cost /= ( pic_data.LengthX()*pic_data.LengthY() );
+
+ my_picture.SetComplexity( total_sq_cost - total_cost*total_cost );
+
+ }
+
+}
+
+
+
+void PictureCompressor::NormaliseComplexity( EncQueue& my_buffer, int pnum )
+{
+ EncPicture& my_picture = my_buffer.GetPicture( pnum );
+
+ if ( (my_picture.GetStatus()&DONE_PIC_COMPLEXITY) != 0 ){
+
+ std::vector<int> queue_members = my_buffer.Members();
+
+ double mean_complexity = 0.0;
+ int count = 0;
+ for (size_t i=0; i<queue_members.size(); ++ i){
+ int n = queue_members[i];
+ EncPicture& enc_pic = my_buffer.GetPicture( n );
+
+ if ( (enc_pic.GetStatus()&DONE_PIC_COMPLEXITY) != 0
+ && enc_pic.GetPparams().PicSort().IsInter()
+ && n >= pnum - 10
+ && n <= pnum + 10){
+ mean_complexity += enc_pic.GetComplexity();
+ count++;
+ }
+
+ }
+ mean_complexity /= count;
+ my_picture.SetNormComplexity( my_picture.GetComplexity() / mean_complexity );
+
+ }
+
+}
+
+void PictureCompressor::SubPixelME( EncQueue& my_buffer , int pnum )
+{
+ const std::vector<int>& refs = my_buffer.GetPicture(pnum).GetPparams().Refs();
+ const int num_refs = refs.size();
+
+ PictureParams& pparams = my_buffer.GetPicture(pnum).GetPparams();
+ MEData& me_data = my_buffer.GetPicture(pnum).GetMEData();
+ PicturePredParams& predparams = me_data.GetPicPredParams();
+
+ float lambda;
+ if ( pparams.IsBPicture())
+ lambda = m_encparams.L2MELambda();
+ else
+ lambda = m_encparams.L1MELambda();
+
+//lambda *= my_buffer.GetPicture(pnum).GetNormComplexity();
+
+ // Set up the lambda to be used
+ me_data.SetLambdaMap( num_refs , lambda );
+
+ m_orig_prec = predparams.MVPrecision();
+
+ // Step 2.
+ // Pixel accurate vectors are then refined to sub-pixel accuracy
+
+ if (m_orig_prec != MV_PRECISION_PIXEL)
+ {
+ SubpelRefine pelrefine( m_encparams );
+ pelrefine.DoSubpel( my_buffer , pnum );
+ }
+ else
+ {
+ // FIXME: HACK HACK
+ // Mutiplying the motion vectors by 2 and setting MV precision to
+ // HALF_PIXEL to implement pixel accurate motion estimate
+ MvArray &mv_arr1 = me_data.Vectors(1);
+ for (int j = 0; j < mv_arr1.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr1.LengthX(); ++i)
+ mv_arr1[j][i] = mv_arr1[j][i] << 1;
+ }
+ if (num_refs > 1)
+ {
+ MvArray &mv_arr2 = me_data.Vectors(2);
+ for (int j = 0; j < mv_arr2.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr2.LengthX(); ++i)
+ mv_arr2[j][i] = mv_arr2[j][i] << 1;
+ }
+ }
+ predparams.SetMVPrecision(MV_PRECISION_HALF_PIXEL);
+ }
+
+}
+
+void PictureCompressor::ModeDecisionME( EncQueue& my_buffer, int pnum )
+{
+ MEData& me_data = my_buffer.GetPicture(pnum).GetMEData();
+ PictureParams& pparams = my_buffer.GetPicture(pnum).GetPparams();
+ PicturePredParams& predparams = me_data.GetPicPredParams();
+
+ ModeDecider my_mode_dec( m_encparams );
+ my_mode_dec.DoModeDecn( my_buffer , pnum );
+
+ const int num_refs = pparams.NumRefs();
+
+ if (m_orig_prec == MV_PRECISION_PIXEL)
+ {
+ // FIXME: HACK HACK
+ // Divide the motion vectors by 2 to convert back to pixel
+ // accurate motion vectors and reset MV precision to
+ // PIXEL accuracy
+ MvArray &mv_arr1 = me_data.Vectors(1);
+ for (int j = 0; j < mv_arr1.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr1.LengthX(); ++i)
+ mv_arr1[j][i] = mv_arr1[j][i] >> 1;
+ }
+ if (num_refs > 1)
+ {
+ MvArray &mv_arr2 = me_data.Vectors(2);
+ for (int j = 0; j < mv_arr2.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr2.LengthX(); ++i)
+ mv_arr2[j][i] = mv_arr2[j][i]>>1;
+ }
+ }
+ predparams.SetMVPrecision(MV_PRECISION_PIXEL);
+ }
+
+}
+
+void PictureCompressor::IntraModeAnalyse( EncQueue& my_buffer, int pnum )
+{
+ MEData& me_data = my_buffer.GetPicture(pnum).GetMEData();
+
+ // Count the number of intra blocks
+ const TwoDArray<PredMode>& modes = me_data.Mode();
+
+ int count_intra = 0;
+ for ( int j=0 ; j<modes.LengthY() ; ++j )
+ {
+ for ( int i=0 ; i<modes.LengthX() ; ++i )
+ {
+ if ( modes[j][i] == INTRA )
+ count_intra++;
+ }
+ }// j
+
+ me_data.SetIntraBlockRatio(static_cast<double>( count_intra ) /
+ static_cast<double>( modes.LengthX() * modes.LengthY() ) );
+
+}
+
+void PictureCompressor::MotionCompensate( EncQueue& my_buffer, int pnum,
+ AddOrSub dirn )
+{
+ EncPicture* my_pic = &my_buffer.GetPicture(pnum);
+ std::vector<int>& my_refs = my_pic->GetPparams().Refs();
+ Picture* ref_pics[2];
+
+ ref_pics[0]=&my_buffer.GetPicture(my_refs[0]);
+ if (my_refs.size()>1)
+ ref_pics[1]=&my_buffer.GetPicture(my_refs[1]);
+ else
+ ref_pics[1]=&my_buffer.GetPicture(my_refs[0]);
+
+ PicturePredParams& predparams = my_pic->GetMEData().GetPicPredParams();
+ MotionCompensator::CompensatePicture( predparams , dirn ,
+ my_pic->GetMEData() , my_pic, ref_pics );
+}
+
+void PictureCompressor::Prefilter( EncQueue& my_buffer, int pnum )
+{
+ Picture& my_picture = my_buffer.GetPicture( pnum );
+
+ for (int c=0; c<3; ++c ){
+ if ( m_encparams.Prefilter() == RECTLP )
+ LPFilter( my_picture.Data( (CompSort) c) , m_encparams.Qf(),
+ m_encparams.PrefilterStrength() );
+
+ if ( m_encparams.Prefilter() == DIAGLP )
+// DiagFilter( my_picture.Data( (CompSort) c), 3.0, 5 );
+ DiagFilter( my_picture.Data( (CompSort) c) , m_encparams.Qf(),
+ m_encparams.PrefilterStrength() );
+ }
+
+}
+
+void PictureCompressor::DoDWT( EncQueue& my_buffer , int pnum, Direction dirn )
+{
+ Picture& my_picture = my_buffer.GetPicture( pnum );
+ PictureParams& pparams = my_picture.GetPparams();
+ const PictureSort& psort = pparams.PicSort();
+
+ // Set the wavelet filter
+ if ( psort.IsIntra() ){
+ m_encparams.SetTransformFilter( m_encparams.IntraTransformFilter() );
+ m_encparams.SetUsualCodeBlocks( INTRA_PICTURE );
+ }
+ else{
+ m_encparams.SetTransformFilter( m_encparams.InterTransformFilter() );
+ m_encparams.SetUsualCodeBlocks( INTER_PICTURE );
+ }
+
+ const int depth=m_encparams.TransformDepth();
+ const WltFilter filter = m_encparams.TransformFilter();
+ WaveletTransform wtransform( depth, filter );
+
+ if ( dirn==FORWARD )
+ my_picture.InitWltData( depth );
+
+ for (int c=0; c<3; ++c){
+
+ PicArray& comp_data = my_buffer.GetPicture( pnum ).Data((CompSort) c );
+ CoeffArray& coeff_data = my_buffer.GetPicture( pnum ).WltData((CompSort) c );
+
+ wtransform.Transform( dirn , comp_data, coeff_data );
+
+ }
+
+}
+
+void PictureCompressor::CodeResidue( EncQueue& my_buffer ,
+ int pnum, PictureByteIO* p_picture_byteio )
+{
+ EncPicture& my_picture = my_buffer.GetPicture( pnum );
+
+ PictureParams& pparams = my_picture.GetPparams();
+
+ if ( !m_skipped ){
+ // If not skipped we continue with the coding ...
+ if (m_encparams.Verbose() )
+ std::cout<<std::endl<<"Using QF: "<<m_encparams.Qf();
+
+ //Write Transform Header
+ TransformByteIO *p_transform_byteio = new TransformByteIO(pparams,
+ static_cast<CodecParams&>(m_encparams));
+ p_picture_byteio->SetTransformData(p_transform_byteio);
+ p_transform_byteio->Output();
+
+ /* Code component data */
+ /////////////////////////
+
+ CompCompressor my_compcoder(m_encparams , pparams );
+
+ const int depth=m_encparams.TransformDepth();
+
+ PicArray* comp_data[3];
+ CoeffArray* coeff_data[3];
+ OneDArray<unsigned int>* est_bits[3];
+ float lambda[3];
+
+ // Construction and definition of objects
+ for (int c=0;c<3;++c){
+ comp_data[c] = &my_picture.Data((CompSort) c );
+ coeff_data[c] = &my_picture.WltData((CompSort) c );
+ est_bits[c] = new OneDArray<unsigned int>( Range( 1, 3*depth+1 ) );
+ }// c
+
+ /* Do the wavelet transforms and select the component
+ * quantisers using perceptual weighting
+ */
+ double cpd_scale;
+ if (pparams.PicSort().IsIntra() ){
+ cpd_scale = 1.0;
+ }
+ else{
+ float intra_ratio = my_picture.GetMEData().IntraBlockRatio();
+
+ cpd_scale = 5.0*intra_ratio*1.0 + (1.0-5.0*intra_ratio)*0.125;
+ cpd_scale = std::max( 0.125, std::min( 1.2, cpd_scale ) );
+ }
+ for (int c=0; c<3; ++c){
+ lambda[c] = GetCompLambda( my_picture, (CompSort) c );
+
+ coeff_data[c]->SetBandWeights( m_encparams , pparams, (CompSort) c, cpd_scale);
+
+ SubbandList& bands = coeff_data[c]->BandList();
+ SetupCodeBlocks( bands );
+ SelectQuantisers( *(coeff_data[c]) , bands , lambda[c],
+ *est_bits[c] , m_encparams.GetCodeBlockMode(), pparams, (CompSort) c );
+
+ p_transform_byteio->AddComponent( my_compcoder.Compress(
+ *(coeff_data[c]), bands, (CompSort) c, *est_bits[c] ) );
+ }
+
+ // Destruction of objects
+ for (int c=0; c<3; ++c)
+ delete est_bits[c];
+
+ }//?m_skipped
+
+}
+
+void PictureCompressor::CodeMVData(EncQueue& my_buffer, int pnum, PictureByteIO* pic_byteio)
+{
+
+ // Code the MV data
+
+ EncPicture& my_picture = my_buffer.GetPicture(pnum);
+ PictureParams& pparams = my_picture.GetPparams();
+ MvData& mv_data = static_cast<MvData&> (my_picture.GetMEData());
+
+ // If we're using global motion parameters, code them
+ if (m_use_global){
+ /*
+ Code the global motion parameters
+ TBC ....
+ */
+ }
+
+ // If we're using block motion vectors, code them
+ if ( m_use_block_mv ){
+ MvDataByteIO *mv_byteio = new MvDataByteIO(pparams, mv_data.GetPicPredParams());
+ pic_byteio->SetMvData(mv_byteio);
+
+ SplitModeCodec smode_coder( mv_byteio->SplitModeData()->DataBlock(), TOTAL_MV_CTXS);
+ smode_coder.Compress( mv_data );
+ mv_byteio->SplitModeData()->Output();
+
+ PredModeCodec pmode_coder( mv_byteio->PredModeData()->DataBlock(), TOTAL_MV_CTXS, pparams.NumRefs() );
+ pmode_coder.Compress( mv_data );
+ mv_byteio->PredModeData()->Output();
+
+ VectorElementCodec vcoder1h( mv_byteio->MV1HorizData()->DataBlock(), 1,
+ HORIZONTAL, TOTAL_MV_CTXS);
+ vcoder1h.Compress( mv_data );
+ mv_byteio->MV1HorizData()->Output();
+
+ VectorElementCodec vcoder1v( mv_byteio->MV1VertData()->DataBlock(), 1,
+ VERTICAL, TOTAL_MV_CTXS);
+ vcoder1v.Compress( mv_data );
+ mv_byteio->MV1VertData()->Output();
+
+ if ( pparams.NumRefs()>1 )
+ {
+ VectorElementCodec vcoder2h( mv_byteio->MV2HorizData()->DataBlock(), 2,
+ HORIZONTAL, TOTAL_MV_CTXS);
+ vcoder2h.Compress( mv_data );
+ mv_byteio->MV2HorizData()->Output();
+
+ VectorElementCodec vcoder2v( mv_byteio->MV2VertData()->DataBlock(), 2,
+ VERTICAL, TOTAL_MV_CTXS);
+ vcoder2v.Compress( mv_data );
+ mv_byteio->MV2VertData()->Output();
+ }
+
+ DCCodec ydc_coder( mv_byteio->YDCData()->DataBlock(), Y_COMP, TOTAL_MV_CTXS);
+ ydc_coder.Compress( mv_data );
+ mv_byteio->YDCData()->Output();
+
+ DCCodec udc_coder( mv_byteio->UDCData()->DataBlock(), U_COMP, TOTAL_MV_CTXS);
+ udc_coder.Compress( mv_data );
+ mv_byteio->UDCData()->Output();
+
+ DCCodec vdc_coder( mv_byteio->VDCData()->DataBlock(), V_COMP, TOTAL_MV_CTXS);
+ vdc_coder.Compress( mv_data );
+ mv_byteio->VDCData()->Output();
+
+ mv_byteio->Output();
+ }
+}
+
+float PictureCompressor::GetCompLambda( const EncPicture& my_picture,
+ const CompSort csort )
+{
+ const PictureParams& pparams = my_picture.GetPparams();
+
+ const PictureSort psort = pparams.PicSort();
+
+ float lambda;
+
+ if ( psort.IsIntra() ){
+ if ( m_is_a_cut )
+ lambda = m_encparams.L1Lambda()/8;
+ else
+ lambda = m_encparams.ILambda();
+
+ }
+ else{
+ double log_intra_lambda = std::log10( m_encparams.ILambda() );
+/*
+double picture_lambda = m_encparams.L1Lambda() / my_picture.GetNormComplexity();
+if (pparams.IsBPicture() )
+ picture_lambda *= 1.2;
+
+ double log_picture_lambda = std::log10( picture_lambda );
+*/
+///*
+ double log_picture_lambda;
+ if (pparams.IsBPicture() )
+ log_picture_lambda= std::log10( m_encparams.L2Lambda() );
+ else
+ log_picture_lambda= std::log10( m_encparams.L1Lambda() );
+
+//*/
+ float intra_ratio = my_picture.GetMEData().IntraBlockRatio();
+
+ lambda= std::pow(10.0, 3.0*intra_ratio*log_intra_lambda+
+ (1.0-3.0*intra_ratio)*log_picture_lambda );
+
+//lambda /= my_picture.GetNormComplexity();
+
+ }
+
+ if (csort == U_COMP)
+ lambda*= m_encparams.UFactor();
+ if (csort == V_COMP)
+ lambda*= m_encparams.VFactor();
+
+ return lambda;
+}
+
+void PictureCompressor::SetupCodeBlocks( SubbandList& bands )
+{
+ int xregions;
+ int yregions;
+
+ for (int band_num = 1; band_num<=bands.Length() ; ++band_num){
+ if (m_encparams.SpatialPartition()){
+ int level = m_encparams.TransformDepth() - (band_num-1)/3;
+ const CodeBlocks &cb = m_encparams.GetCodeBlocks(level);
+ xregions = cb.HorizontalCodeBlocks();
+ yregions = cb.VerticalCodeBlocks();
+ }
+ else{
+ xregions = 1;
+ yregions = 1;
+ }
+
+ bands( band_num ).SetNumBlocks( yregions , xregions );
+ }// band_num
+}
+
+void PictureCompressor::SelectQuantisers( CoeffArray& coeff_data ,
+ SubbandList& bands ,
+ const float lambda,
+ OneDArray<unsigned int>& est_bits,
+ const CodeBlockMode cb_mode,
+ const PictureParams& pp,
+ const CompSort csort )
+{
+
+ // Set up the multiquantiser mode
+ for ( int b=bands.Length() ; b>=1 ; --b ){
+ // Set multiquants flag in the subband only if
+ // a. Global m_cb_mode flag is set to QUANT_MULTIPLE in encparams
+ // and
+ // b. Current subband has more than one block
+ if (
+ cb_mode == QUANT_MULTIPLE &&
+ (bands(b).GetCodeBlocks().LengthX() > 1 ||
+ bands(b).GetCodeBlocks().LengthY() > 1)
+ )
+ bands(b).SetUsingMultiQuants( true );
+ else
+ bands(b).SetUsingMultiQuants( false );
+ }// b
+
+ // Select all the quantizers
+ if ( !m_encparams.Lossless() ){
+ // Set quantizers for all bands.
+ for ( int b=bands.Length() ; b>=1 ; --b )
+ est_bits[b] = SelectMultiQuants( coeff_data , bands , b, lambda,
+ pp, csort );
+ }
+ else{
+ for ( int b=bands.Length() ; b>=1 ; --b ){
+ bands(b).SetQuantIndex( 0 );
+ est_bits[b] = 0;
+ TwoDArray<CodeBlock>& blocks = bands(b).GetCodeBlocks();
+ for (int j=0; j<blocks.LengthY() ;++j)
+ for (int i=0; i<blocks.LengthX() ;++i)
+ blocks[j][i].SetQuantIndex( 0 );
+ }// b
+ }
+}
+
+int PictureCompressor::SelectMultiQuants( CoeffArray& coeff_data , SubbandList& bands ,
+ const int band_num , const float lambda, const PictureParams& pp, const CompSort csort)
+{
+ Subband& node( bands( band_num ) );
+
+ // Now select the quantisers //
+ ///////////////////////////////
+
+ QuantChooser qchooser( coeff_data , lambda );
+
+ // For the DC band in I pictures, remove the average
+ if ( band_num == bands.Length() && pp.PicSort().IsIntra() )
+ AddSubAverage( coeff_data , node.Xl() , node.Yl() , SUBTRACT);
+
+ // The total estimated bits for the subband
+ int band_bits( 0 );
+ qchooser.SetEntropyCorrection( m_encparams.EntropyFactors().Factor( band_num, pp, csort ) );
+ band_bits = qchooser.GetBestQuant( node );
+
+ // Put the DC band average back in if necessary
+ if ( band_num == bands.Length() && pp.PicSort().IsIntra() )
+ AddSubAverage( coeff_data , node.Xl() , node.Yl() , ADD);
+
+ if ( band_bits == 0 )
+ node.SetSkip( true );
+ else
+ node.SetSkip( false );
+
+ return band_bits;
+}
+
+
+void PictureCompressor::AddSubAverage( CoeffArray& coeff_data, int xl, int yl ,
+ AddOrSub dirn)
+{
+
+ ValueType last_val=0;
+ ValueType last_val2;
+
+ if ( dirn == SUBTRACT )
+ {
+ for ( int j=0 ; j<yl ; j++)
+ {
+ for ( int i=0 ; i<xl ; i++)
+ {
+ last_val2 = coeff_data[j][i];
+ coeff_data[j][i] -= last_val;
+ last_val = last_val2;
+ }// i
+ }// j
+ }
+ else
+ {
+ for ( int j=0 ; j<yl ; j++)
+ {
+ for ( int i=0 ; i<xl; i++ )
+ {
+ coeff_data[j][i] += last_val;
+ last_val = coeff_data[j][i];
+ }// i
+ }// j
+
+ }
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.h
new file mode 100644
index 000000000..84f2d983b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/picture_compress.h
@@ -0,0 +1,201 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: picture_compress.h,v 1.7 2008/08/14 02:30:50 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _PICTURE_COMPRESS_H_
+#define _PICTURE_COMPRESS_H_
+
+#include <libdirac_encoder/enc_queue.h>
+#include <libdirac_common/common.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_byteio/picture_byteio.h>
+
+namespace dirac
+{
+
+ class MvData;
+
+ //! Compress a single image picture
+ /*!
+ This class compresses a single picture at a time, using parameters
+ supplied at its construction. PictureCompressor is used by
+ SequenceCompressor.
+ */
+ class PictureCompressor
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a FrameEncoder with specific set of parameters the control
+ the compression process. It encodes motion data before encoding
+ each component of the picture.
+ \param encp encoder parameters
+ */
+ PictureCompressor( EncoderParams& encp );
+
+ //! Destructor
+ ~PictureCompressor( );
+
+ //! Do pixel accurate motion estimate
+ void PixelME( EncQueue& my_buffer , int pnum );
+
+ //! Calculate the complexity of a picture
+ void CalcComplexity( EncQueue& my_buffer, int pnum , const OLBParams& olbparams );
+ void CalcComplexity2( EncQueue& my_buffer, int pnum );
+
+ //! Normalise picture complexity with respect to others in the queue
+ void NormaliseComplexity( EncQueue& my_buffer, int pnum );
+
+ //! Do subpixel accurate motion vector refinement
+ void SubPixelME( EncQueue& my_buffer , int pnum );
+
+ //! Do mode decision based on sub-pel vectors
+ void ModeDecisionME( EncQueue& my_buffer, int pnum );
+
+ //! Detect cuts in the current picture
+ void IntraModeAnalyse( EncQueue& my_buffer, int pnum );
+
+ //! Does motion compensation on picture pnum (forward or backward)
+ void MotionCompensate( EncQueue& my_buffer, int pnum, AddOrSub dirn );
+
+ //! Prefilter if required
+ void Prefilter( EncQueue& my_buffer, int pnum );
+
+ //! Do the DWT on a given picture
+ void DoDWT( EncQueue& my_buffer , int pnum, Direction dirn );
+
+ //! Compress a specific picture within a group of pictures (GOP)
+ /*!
+ Compresses a specified picture within a group of pictures.
+ \param my_pbuffer picture buffer in which the reference frames resides
+ \param pnum picture number to compress
+ \param pic_byteio compressed picture in Dirac bytestream format
+ */
+ void CodeResidue( EncQueue& my_pbuffer , int pnum , PictureByteIO* pic_byteio);
+
+ //! Compresses the motion vector data
+ void CodeMVData( EncQueue& my_buffer, int pnum, PictureByteIO* pic_byteio);
+
+ //! Returns true if the picture has been skipped rather than coded normally
+ bool IsSkipped(){ return m_skipped; }
+
+ //! Returns true if Motion estimation data is available
+ bool IsMEDataAvail() const { return m_medata_avail; }
+
+ //! Returns the motion estimation data
+ const MEData* GetMEData() const;
+
+ private:
+ //! Copy constructor is private and body-less
+ /*!
+ Copy constructor is private and body-less. This class should not
+ be copied.
+ */
+ PictureCompressor( const PictureCompressor& cpy );
+
+ //! Assignment = is private and body-less
+ /*!
+ Assignment = is private and body-less. This class should not be
+ assigned.
+ */
+ PictureCompressor& operator=(const PictureCompressor& rhs);
+
+ //! Initialise the coefficient data array for holding wavelet coefficients
+ void InitCoeffData( CoeffArray& coeff_data, const int xl, const int yl );
+
+ //! Returns the value lambda according to picture and component type
+ float GetCompLambda( const EncPicture& my_picture,
+ const CompSort csort );
+
+ void SelectQuantisers( CoeffArray& coeff_data ,
+ SubbandList& bands ,
+ const float lambda,
+ OneDArray<unsigned int>& est_counts,
+ const CodeBlockMode cb_mode,
+ const PictureParams& pp,
+ const CompSort csort );
+
+ int SelectMultiQuants( CoeffArray& coeff_data ,
+ SubbandList& bands ,
+ const int band_num,
+ const float lambda,
+ const PictureParams& pp,
+ const CompSort csort );
+
+ void SetupCodeBlocks( SubbandList& bands );
+
+
+ void AddSubAverage(CoeffArray& coeff_data,int xl,int yl,AddOrSub dirn);
+
+ private:
+
+ //member variables
+ // a local copy of the encoder params
+ EncoderParams& m_encparams;
+
+ // True if the picture has been skipped, false otherwise
+ bool m_skipped;
+
+ // True if we use global motion vectors, false otherwise
+ bool m_use_global;
+
+ // True if we use block motion vectors, false otherwise
+ bool m_use_block_mv;
+
+ // Prediction mode to use if we only have global motion vectors
+ PredMode m_global_pred_mode;
+
+ // A pointer to the current picture motion vector data
+ MEData* m_me_data;
+
+ // True if motion estimation data is available
+ bool m_medata_avail;
+
+ // True if we have detected a cut
+ bool m_is_a_cut;
+
+ // The original MV precision type
+ MVPrecisionType m_orig_prec;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.cpp
new file mode 100644
index 000000000..7920ed0d1
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.cpp
@@ -0,0 +1,588 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: prefilter.cpp,v 1.9 2008/10/29 02:42:06 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2008.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include<libdirac_encoder/prefilter.h>
+#include<libdirac_common/arrays.h>
+
+using namespace dirac;
+
+void dirac::CWMFilter( Picture& picture, const int strength )
+{
+ CWMFilterComponent( picture.Data(Y_COMP), strength );
+ CWMFilterComponent( picture.Data(U_COMP), strength );
+ CWMFilterComponent( picture.Data(V_COMP), strength );
+}
+
+void dirac::CWMFilterComponent( PicArray& pic_data, const int strength )
+{
+ // Do centre-weighted median denoising
+
+ PicArray pic_copy( pic_data );
+
+ const int width( 3 );
+ const int offset( (width-1)/2 );
+ const int centre_weight = std::max(1, (width*width+1)-strength );
+ const int list_length = centre_weight+(width*width)-1;
+
+ ValueType* val_list = new ValueType[list_length];
+
+ for (int j=offset; j<pic_data.LengthY()-offset; ++j){
+ for (int i=offset; i<pic_data.LastX()-offset; ++i){
+ // Make the value list
+ int pos=0;
+ for (; pos<centre_weight-1; ++pos)
+ val_list[pos] = pic_copy[j][i];
+
+ for (int s=-offset; s<=offset; ++s){
+ for (int r=-offset; r<=offset; ++r){
+ val_list[pos]=pic_copy[j+s][i+r];
+ pos++;
+ }// r
+ }// s
+
+ pic_data[j][i] = Median( val_list, list_length );
+ }// i
+ }// j
+
+ delete[] val_list;
+}
+
+ValueType dirac::Median( const ValueType* val_list, const int length)
+{
+
+
+ OneDArray<ValueType> ordered_vals( length );
+
+ // Place the values in order
+ int pos=0;
+ ordered_vals[0] = val_list[0];
+ for (int i=1 ; i<length ; ++i )
+ {
+ for (int k=0 ; k<i ; ++k)
+ {
+ if (val_list[i]<ordered_vals[k])
+ {
+ pos=k;
+ break;
+ }
+ else
+ pos=k+1;
+ }// k
+
+ if ( pos==i)
+ ordered_vals[i] = val_list[i];
+ else
+ {
+ for (int k=i-1 ; k>=pos ; --k )
+ {
+ ordered_vals[k+1] = ordered_vals[k];
+ }// k
+ ordered_vals[pos] = val_list[i];
+ }
+ }// i
+
+ // return the middle value
+ if ( length%2!=0 )
+ return ordered_vals[(length-1)/2];
+ else
+ return (ordered_vals[(length/2)-1]+ordered_vals[length/2]+1)>>1;
+
+}
+
+/*************************************************************/
+
+
+void VFilter( PicArray& pic_data, const OneDArray<int>& filter, const int bits );
+void HFilter( PicArray& pic_data, const OneDArray<int>& filter, const int bits );
+
+double sinxoverx( const double val )
+{
+ if ( 0.0f == val )
+ return 1.0;
+ else
+ return sin(val)/val;
+
+}
+
+OneDArray<int> MakeLPRectFilter( const float bw, const int bits )
+{
+ const int tl = 8;
+ const float pi = 3.1415926535;
+
+ OneDArray<double> double_filter( Range( -tl, tl ) );
+ OneDArray<int> int_filter( Range( -tl, tl) );
+
+ // Use the Hanning window
+ for (int i=double_filter.First(); i<=double_filter.Last(); ++i)
+ {
+ double_filter[i] = cos( (pi*i)/
+ (double_filter.Length()+1) );
+ }
+
+ // Apply sinc function
+ for (int i=double_filter.First(); i<=double_filter.Last(); ++i)
+ {
+ double_filter[i] *= sinxoverx( pi*1.0*bw*i );
+ }
+
+ // Get DC gain = 1<<bits
+ double sum = 0.0;
+ for (int i=double_filter.First(); i<=double_filter.Last(); ++i)
+ sum += double_filter[i];
+
+ for (int i=double_filter.First(); i<=double_filter.Last(); ++i)
+ {
+ double_filter[i] *= double(1<<(bits+4));
+ double_filter[i] /= sum;
+ }
+
+ // Turn the float filter into an integer filter
+ for (int i=double_filter.First(); i<=double_filter.Last(); ++i)
+ {
+ int_filter[i] = double_filter[i]>0 ? int( double_filter[i]+0.5 ) : -int( -double_filter[i]+0.5 );
+ int_filter[i] = (int_filter[i]+8)>>4;
+ }
+
+ return int_filter;
+}
+
+void dirac::LPFilter( PicArray& pic_data, const float qf, const int strength )
+{
+ float bw = (std::min( std::max( qf+3.0f-float(strength), 1.0f ), 10.0f ))/10.0;
+
+ // filter with 14-bit accuracy
+ OneDArray<int> filter=MakeLPRectFilter(bw, 14);
+
+ HFilter( pic_data, filter, 14 );
+ VFilter( pic_data, filter, 14 );
+
+}
+
+void HFilter( PicArray& pic_data, const OneDArray<int>& filter, const int bits )
+{
+ ValueType* line_data = new ValueType[pic_data.LengthX()];
+ const int offset = (1<<(bits-1));
+
+ int sum;
+
+ for (int j=0; j<pic_data.LengthY(); ++j)
+ {
+ // Do the first bit
+ for (int i=0; i<filter.Last(); ++i)
+ {
+ sum = offset;
+ for (int k=filter.Last(); k>=filter.First(); --k)
+ sum += filter[k]*pic_data[j][std::max(i-k,0)];
+ sum >>= bits;
+ sum = std::min( 127, std::max( -128, sum) );
+ line_data[i] = ValueType( sum );
+ }// i
+ // Do the middle bit
+ for (int i=filter.Last(); i<=pic_data.LastX()+filter.First(); ++i)
+ {
+ sum = offset;
+ for (int k=filter.Last(); k>=filter.First(); --k)
+ sum += filter[k]*pic_data[j][i-k];
+ sum >>= bits;
+ sum = std::min( 127, std::max( -128, sum) );
+ line_data[i] = ValueType( sum );
+ }// i
+ // Do the last bit
+ for (int i=pic_data.LastX()+filter.First()+1; i<pic_data.LengthX(); ++i)
+ {
+ sum = offset;
+ for (int k=filter.Last(); k>=filter.First(); --k)
+ sum += filter[k]*pic_data[j][std::min(i-k,pic_data.LastX())];
+ sum >>= bits;
+ sum = std::min( 127, std::max( -128, sum) );
+ line_data[i] = ValueType( sum );
+ }// i
+
+ // Copy data back
+
+ for (int i=0; i<pic_data.LengthX(); ++i )
+ pic_data[j][i] = line_data[i];
+
+ }// j
+
+ delete[] line_data;
+}
+
+void VFilter( PicArray& pic_data, const OneDArray<int>& filter, const int bits )
+{
+ PicArray tmp_data( pic_data );
+ const int offset = (1<<(bits-1));
+
+ int sum;
+
+ // Do the first bit
+ for (int j=0; j<filter.Last(); ++j)
+ {
+
+ for (int i=0; i<pic_data.LengthX(); ++i)
+ {
+ sum = offset;
+ for (int k=filter.Last(); k>=filter.First(); --k)
+ sum += filter[k]*pic_data[std::max(j-k,0)][i];
+ sum >>= bits;
+ sum = std::min( 127, std::max( -128, sum) );
+ tmp_data[j][i] = ValueType( sum );
+ }// i
+
+ }// j
+
+ // Do the middle bit
+ for (int j=filter.Last(); j<=pic_data.LastY()+filter.First(); ++j)
+ {
+
+ for (int i=0; i<pic_data.LengthX(); ++i)
+ {
+ sum = offset;
+ for (int k=filter.Last(); k>=filter.First(); --k)
+ sum += filter[k]*pic_data[j-k][i];
+ sum >>= bits;
+ sum = std::min( 127, std::max( -128, sum) );
+ tmp_data[j][i] = ValueType( sum );
+ }// i
+
+ }// j
+
+ // Do the last bit
+ for (int j=pic_data.LastY()+filter.First()+1; j<pic_data.LengthY(); ++j)
+ {
+
+ for (int i=0; i<pic_data.LengthX(); ++i)
+ {
+ sum = offset;
+ for (int k=filter.Last(); k>=filter.First(); --k)
+ sum += filter[k]*pic_data[std::min(j-k,pic_data.LastY())][i];
+ sum >>= bits;
+ sum = std::min( 127, std::max( -128, sum) );
+ tmp_data[j][i] = ValueType( sum );
+ }// i
+
+ }// j
+
+ // Copy data across
+ pic_data = tmp_data;
+
+}
+
+/***************************************************************************/
+
+ValueType DiagFilterBchkD( const PicArray& pic,
+ const int xpos, const int ypos,
+ const TwoDArray<int>& filter,
+ const int shift)
+{
+ // Half the filter length
+ const int len2 = 6;
+
+ const int height = pic.LengthY();
+ const int width = pic.LengthX();
+
+ int uplus, uneg, vplus, vneg;
+ int val = (1<<(shift-1));
+
+ // Do 0 position horizontally
+ val += filter[0][0]*pic[ypos][xpos];
+
+ for (int i=1; i<=len2;++i){
+ uplus = xpos + i;
+ uplus = (uplus>=width ? width-1 : uplus);
+ uneg = xpos - i;
+ uneg = (uneg<0 ? 0 : uneg );
+ val += filter[0][i]*(pic[ypos][uplus]+pic[ypos][uneg] );
+ }
+
+ // Do other positions vertically//
+ //////////////////////////////////
+
+ for (int j=1; j<=len2;++j){
+ vplus = ypos + j;
+ vplus = ( vplus>=height ? height-1 : vplus);
+ vneg = ypos - j;
+ vneg = (vneg<0 ? 0 : vneg );
+
+ // Do 0 position horizontally
+ val += filter[j][0]*(pic[vneg][xpos]+pic[vplus][xpos]);
+ for (int i=1; i<=len2;++i){
+ uplus = xpos + i;
+ uplus = (uplus>=width ? width-1 : uplus);
+ uneg = xpos - i;
+ uneg = (uneg<0 ? 0 : uneg );
+ val += filter[j][i]*(pic[vneg][uplus]+pic[vneg][uneg]+
+ pic[vplus][uplus]+pic[vplus][uneg] );
+ }
+ }
+
+ val >>= shift;
+
+ return ValueType(val);
+}
+
+ValueType DiagFilterD( const PicArray& pic,
+ const int xpos, const int ypos,
+ const TwoDArray<int>& filter,
+ const int shift)
+{
+ // Half the filter length
+ const int len2 = 6;
+
+ int uplus, uneg, vplus, vneg;
+ int val = (1<<(shift-1));
+
+ // Do 0 position horizontally
+ val += filter[0][0]*pic[ypos][xpos];
+
+ for (int i=1; i<=len2;++i){
+ uplus = xpos + i;
+ uneg = xpos - i;
+ val += filter[0][i]*(pic[ypos][uplus]+pic[ypos][uneg] );
+ }
+
+ // Do other positions vertically//
+ //////////////////////////////////
+
+ for (int j=1; j<=len2;++j){
+ vplus = ypos + j;
+ vneg = ypos - j;
+
+ // Do 0 position horizontally
+ val += filter[j][0]*(pic[vneg][xpos]+pic[vplus][xpos]);
+ for (int i=1; i<=len2;++i){
+ uplus = xpos + i;
+ uneg = xpos - i;
+ val += filter[j][i]*(pic[vneg][uplus]+pic[vneg][uneg]+
+ pic[vplus][uplus]+pic[vplus][uneg] );
+ }
+ }
+
+ val >>= shift;
+
+ return ValueType(val);
+}
+
+
+TwoDArray<int> GetDiagLPFilter( const float bw )
+{
+ TwoDArray<int> f( 7, 7 );
+
+ // Bandwidth quantised to range 0.2-1
+ int qbf = int( bw*10.0 + 0.5 );
+ qbf = std::min( std::max( qbf, 2 ) , 10 );
+
+ switch (qbf){
+
+ case 1 :
+ f[0][0]=1651; f[0][1]=1544; f[0][2]=1259; f[0][3]=887; f[0][4]=530; f[0][5]=260; f[0][6]=99;
+ f[1][0]=1544; f[1][1]=1442; f[1][2]=1170; f[1][3]=817; f[1][4]=480; f[1][5]=229; f[1][6]=83;
+ f[2][0]=1259; f[2][1]=1170; f[2][2]=935; f[2][3]=634; f[2][4]=354; f[2][5]=153; f[2][6]=45;
+ f[3][0]=887; f[3][1]=817; f[3][2]=634; f[3][3]=405; f[3][4]=202; f[3][5]=70; f[3][6]=11;
+ f[4][0]=530; f[4][1]=480; f[4][2]=354; f[4][3]=202; f[4][4]=80; f[4][5]=15; f[4][6]=0;
+ f[5][0]=260; f[5][1]=229; f[5][2]=153; f[5][3]=70; f[5][4]=15; f[5][5]=0; f[5][6]=0;
+ f[6][0]=99; f[6][1]=83; f[6][2]=45; f[6][3]=11; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 2:
+
+ f[0][0]=2855; f[0][1]=2540; f[0][2]=1775; f[0][3]=947; f[0][4]=364; f[0][5]=89; f[0][6]=10;
+ f[1][0]=2540; f[1][1]=2251; f[1][2]=1551; f[1][3]=804; f[1][4]=290; f[1][5]=59; f[1][6]=1;
+ f[2][0]=1775; f[2][1]=1551; f[2][2]=1020; f[2][3]=475; f[2][4]=130; f[2][5]=3; f[2][6]=-10;
+ f[3][0]=947; f[3][1]=804; f[3][2]=475; f[3][3]=165; f[3][4]=5; f[3][5]=-22; f[3][6]=-6;
+ f[4][0]=364; f[4][1]=290; f[4][2]=130; f[4][3]=5; f[4][4]=-28; f[4][5]=-10; f[4][6]=0;
+ f[5][0]=89; f[5][1]=59; f[5][2]=3; f[5][3]=-22; f[5][4]=-10; f[5][5]=0; f[5][6]=0;
+ f[6][0]=10; f[6][1]=1; f[6][2]=-10; f[6][3]=-6; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 3:
+
+ f[0][0]=5767; f[0][1]=4718; f[0][2]=2498; f[0][3]=745; f[0][4]=72; f[0][5]=5; f[0][6]=23;
+ f[1][0]=4718; f[1][1]=3796; f[1][2]=1875; f[1][3]=423; f[1][4]=-58; f[1][5]=-41; f[1][6]=7;
+ f[2][0]=2498; f[2][1]=1875; f[2][2]=643; f[2][3]=-146; f[2][4]=-241; f[2][5]=-88; f[2][6]=-9;
+ f[3][0]=745; f[3][1]=423; f[3][2]=-146; f[3][3]=-367; f[3][4]=-220; f[3][5]=-51; f[3][6]=-2;
+ f[4][0]=72; f[4][1]=-58; f[4][2]=-241; f[4][3]=-220; f[4][4]=-78; f[4][5]=-5; f[4][6]=0;
+ f[5][0]=5; f[5][1]=-41; f[5][2]=-88; f[5][3]=-51; f[5][4]=-5; f[5][5]=0; f[5][6]=0;
+ f[6][0]=23; f[6][1]=7; f[6][2]=-9; f[6][3]=-2; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 4:
+
+ f[0][0]=10534; f[0][1]=7642; f[0][2]=2603; f[0][3]=194; f[0][4]=56; f[0][5]=120; f[0][6]=28;
+ f[1][0]=7642; f[1][1]=5237; f[1][2]=1218; f[1][3]=-383; f[1][4]=-153; f[1][5]=40; f[1][6]=2;
+ f[2][0]=2603; f[2][1]=1218; f[2][2]=-771; f[2][3]=-958; f[2][4]=-269; f[2][5]=-3; f[2][6]=-7;
+ f[3][0]=194; f[3][1]=-383; f[3][2]=-958; f[3][3]=-541; f[3][4]=-18; f[3][5]=48; f[3][6]=4;
+ f[4][0]=56; f[4][1]=-153; f[4][2]=-269; f[4][3]=-18; f[4][4]=96; f[4][5]=22; f[4][6]=0;
+ f[5][0]=120; f[5][1]=40; f[5][2]=-3; f[5][3]=48; f[5][4]=22; f[5][5]=0; f[5][6]=0;
+ f[6][0]=28; f[6][1]=2; f[6][2]=-7; f[6][3]=4; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 5 :
+
+ f[0][0]=16421; f[0][1]=10159; f[0][2]=1716; f[0][3]=33; f[0][4]=325; f[0][5]=57; f[0][6]=6;
+ f[1][0]=10159; f[1][1]=5309; f[1][2]=-580; f[1][3]=-747; f[1][4]=44; f[1][5]=-43; f[1][6]=-25;
+ f[2][0]=1716; f[2][1]=-580; f[2][2]=-2310; f[2][3]=-763; f[2][4]=100; f[2][5]=-19; f[2][6]=-12;
+ f[3][0]=33; f[3][1]=-747; f[3][2]=-763; f[3][3]=308; f[3][4]=326; f[3][5]=27; f[3][6]=1;
+ f[4][0]=325; f[4][1]=44; f[4][2]=100; f[4][3]=326; f[4][4]=84; f[4][5]=-14; f[4][6]=0;
+ f[5][0]=57; f[5][1]=-43; f[5][2]=-19; f[5][3]=27; f[5][4]=-14; f[5][5]=0; f[5][6]=0;
+ f[6][0]=6; f[6][1]=-25; f[6][2]=-12; f[6][3]=1; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 6 :
+
+ f[0][0]=23511; f[0][1]=11883; f[0][2]=566; f[0][3]=524; f[0][4]=231; f[0][5]=18; f[0][6]=41;
+ f[1][0]= 11883; f[1][1]=3647; f[1][2]=-2496; f[1][3]=-361; f[1][4]=-96; f[1][5]=-97; f[1][6]=1;
+ f[2][0]=566; f[2][1]=-2496; f[2][2]=-2329; f[2][3]=459; f[2][4]=152; f[2][5]=-7; f[2][6]=18;
+ f[3][0]=524; f[3][1]=-361; f[3][2]=459; f[3][3]=979; f[3][4]=33; f[3][5]=-28; f[3][6]=3;
+ f[4][0]=231; f[4][1]=-96; f[4][2]=152; f[4][3]=33; f[4][4]=-184; f[4][5]=-15; f[4][6]=0;
+ f[5][0]=18; f[5][1]=-97; f[5][2]=-7; f[5][3]=-28; f[5][4]=-15; f[5][5]=0; f[5][6]=0;
+ f[6][0]=41; f[6][1]=1; f[6][2]=18; f[6][3]=3; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 7 :
+
+ f[0][0]=32188; f[0][1]=12652; f[0][2]=3; f[0][3]=921; f[0][4]=1; f[0][5]=128; f[0][6]=0;
+ f[1][0]=12652; f[1][1]=295; f[1][2]=-3414; f[1][3]=-2; f[1][4]=-343; f[1][5]=-1; f[1][6]=-37;
+ f[2][0]=3; f[2][1]=-3414; f[2][2]=-212; f[2][3]=1273; f[2][4]=1; f[2][5]=98; f[2][6]=0;
+ f[3][0]=921; f[3][1]=-2; f[3][2]=1273; f[3][3]=110; f[3][4]=-363; f[3][5]=0; f[3][6]=-8;
+ f[4][0]=1; f[4][1]=-343; f[4][2]=1; f[4][3]=-363; f[4][4]=-29; f[4][5]=29; f[4][6]=0;
+ f[5][0]=128; f[5][1]=-1; f[5][2]=98; f[5][3]=0; f[5][4]=29; f[5][5]=0; f[5][6]=0;
+ f[6][0]=0; f[6][1]=-37; f[6][2]=0; f[6][3]=-8; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 8 :
+
+ f[0][0]=41902; f[0][1]=12084; f[0][2]=435; f[0][3]=610; f[0][4]=188; f[0][5]=34; f[0][6]=37;
+ f[1][0]=12084; f[1][1]=-4268; f[1][2]=-2715; f[1][3]=-286; f[1][4]=-144; f[1][5]=-84; f[1][6]=-2;
+ f[2][0]=435; f[2][1]=-2715; f[2][2]=2809; f[2][3]=640; f[2][4]=127; f[2][5]=10; f[2][6]=17;
+ f[3][0]=610; f[3][1]=-286; f[3][2]=640; f[3][3]=-1250; f[3][4]=-45; f[3][5]=-26; f[3][6]=2;
+ f[4][0]=188; f[4][1]=-144; f[4][2]=127; f[4][3]=-45; f[4][4]=259; f[4][5]=-8; f[4][6]=0;
+ f[5][0]=34; f[5][1]=-84; f[5][2]=10; f[5][3]=-26; f[5][4]=-8; f[5][5]=0; f[5][6]=0;
+ f[6][0]=37; f[6][1]=-2; f[6][2]=17; f[6][3]=2; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ case 9 :
+
+ f[0][0]=53098; f[0][1]=10449; f[0][2]=1546; f[0][3]=73; f[0][4]=342; f[0][5]=38; f[0][6]=12;
+ f[1][0]=10449; f[1][1]=-9060; f[1][2]=-873; f[1][3]=-727; f[1][4]=52; f[1][5]=-65; f[1][6]=-20;
+ f[2][0]=1546; f[2][1]=-873; f[2][2]=4261; f[2][3]=-627; f[2][4]=137; f[2][5]=-27; f[2][6]=-7;
+ f[3][0]=73; f[3][1]=-727; f[3][2]=-627; f[3][3]=-804; f[3][4]=328; f[3][5]=14; f[3][6]=2;
+ f[4][0]=342; f[4][1]=52; f[4][2]=137; f[4][3]=328; f[4][4]=-83; f[4][5]=-20; f[4][6]=0;
+ f[5][0]=38; f[5][1]=-65; f[5][2]=-27; f[5][3]=14; f[5][4]=-20; f[5][5]=0; f[5][6]=0;
+ f[6][0]=12; f[6][1]=-20; f[6][2]=-7; f[6][3]=2; f[6][4]=0; f[6][5]=0; f[6][6]=0;
+
+ break;
+
+ default:// case 10
+
+ for (int j=0; j<f.LengthY(); ++j ){
+ for (int i=0; i<f.LengthX(); ++i ){
+ f[j][i] = 0;
+ }
+ }
+ f[0][0] = 65536;
+
+ }
+
+ return f;
+
+}
+
+
+// Does a diagnonal prefilter
+void dirac::DiagFilter( PicArray& pic_data, const float qf, const int strength ){
+ // One quadrant of the filter taps
+
+
+ float ffactor = (8.0+strength-4.0 - qf )/5.0;
+ int factor = std::max(0, std::min( 256, int( ffactor*256.0 ) ) ) ;
+
+ float bw = (1.0-ffactor)*0.6+0.4;
+
+ //std::cout<<std::endl<<"Diagonal prefiltering with bandwidth = "<<bw;
+
+ if (bw>0.9)
+ return;
+
+ TwoDArray<int> filter = GetDiagLPFilter( bw );
+
+ filter[0][0] = ( factor*filter[0][0] + ( (1<<8)-factor )*(1<<16) + (1<<7) ) >> 8;
+
+ for (int i=1;i<7; ++i )
+ filter[0][i] = ( factor*filter[0][i] + (1<<7) ) >> 8;
+
+ for (int j=1;j<7; ++j )
+ for (int i=0;i<7; ++i )
+ filter[j][i] = ( factor*filter[j][i] + (1<<7) ) >> 8;
+
+
+ PicArray tmp_data( pic_data.LengthY(), pic_data.LengthX(), pic_data.CSort() );
+
+ const int shift = 16;
+
+ for (int j=0; j<7;++j)
+ for (int i=0; i<pic_data.LengthX();++i)
+ tmp_data[j][i] = DiagFilterBchkD( pic_data, i, j, filter, shift);
+
+ for (int j=7; j<pic_data.LengthY()-7;++j){
+ for (int i=0; i<7;++i)
+ tmp_data[j][i] = DiagFilterBchkD( pic_data, i, j, filter, shift );
+
+ for (int i=7; i<pic_data.LengthX()-7;++i)
+ tmp_data[j][i] = DiagFilterD( pic_data, i, j, filter, shift );
+
+ for (int i=pic_data.LengthX()-7; i<pic_data.LengthX();++i)
+ tmp_data[j][i] = DiagFilterBchkD( pic_data, i, j, filter, shift );
+
+ }
+
+ for (int j=pic_data.LengthY()-7; j<pic_data.LengthY();++j)
+ for (int i=0; i<pic_data.LengthX();++i)
+ tmp_data[j][i] = DiagFilterBchkD( pic_data, i, j, filter, shift );
+
+ pic_data = tmp_data;
+
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.h
new file mode 100644
index 000000000..2a37c4aaf
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/prefilter.h
@@ -0,0 +1,68 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: prefilter.h,v 1.1 2008/04/29 14:09:35 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2008.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _PREFILTER_H_
+#define _PREFILTER_H_
+
+
+#include<libdirac_common/picture.h>
+
+namespace dirac
+{
+
+/*************************************************************/
+
+//! Denoises an input frame
+void CWMFilter( Picture& picture, const int strength );
+
+void CWMFilterComponent( PicArray& pic_data, const int strength );
+
+ValueType Median( const ValueType* val_list, const int length);
+
+
+/*************************************************************/
+
+//! Denoises a component
+void LPFilter( PicArray& pic_data, const float qf, const int strength );
+
+//! Diagonally filters an input component
+void DiagFilter( PicArray& pic_data, const float qf , const int strength );
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.cpp
new file mode 100644
index 000000000..93934f372
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.cpp
@@ -0,0 +1,184 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: quality_monitor.cpp,v 1.33 2008/08/14 01:04:26 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_encoder/quality_monitor.h>
+#include <libdirac_common/wavelet_utils.h>
+using namespace dirac;
+
+using std::log10;
+
+QualityMonitor::QualityMonitor(EncoderParams& encp) :
+ m_encparams(encp),
+ m_mse_averageY(3),
+ m_mse_averageU(3),
+ m_mse_averageV(3),
+ m_picture_total(3)
+{
+ ResetAll();
+}
+
+QualityMonitor::~QualityMonitor()
+{}
+
+void QualityMonitor::ResetAll()
+{
+
+ for (int i=0; i<3 ; ++i )
+ {
+ m_mse_averageY[i] = 0.0;
+ m_mse_averageU[i] = 0.0;
+ m_mse_averageV[i] = 0.0;
+ m_picture_total[i] = 0;
+ }// i
+ m_totalmse_averageY = 0.0;
+ m_totalmse_averageU = 0.0;
+ m_totalmse_averageV = 0.0;
+ m_allpicture_total = 0;
+}
+
+void QualityMonitor::WriteLog()
+{
+ const double Ymax = double( (1<<m_encparams.LumaDepth())-1 );
+ const double UVmax = double( (1<<m_encparams.ChromaDepth())-1 );
+
+ std::cout<<std::endl<<"Overall mean PSNR values";
+ std::cout<<std::endl<<"------------------------";
+ std::cout<<std::endl<<"Y: ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(Ymax*Ymax/(m_totalmse_averageY/m_allpicture_total))<<std::endl;
+ std::cout<<std::endl<<"U: ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_totalmse_averageU/m_allpicture_total))<<std::endl;
+ std::cout<<std::endl<<"V: ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_totalmse_averageV/m_allpicture_total))<<std::endl;
+
+
+ std::cout<<std::endl<<"Mean PSNR values by picture type and component";
+ std::cout<<std::endl<<"--------------------------------------------";
+ std::cout<<std::endl;
+
+ std::cout<<std::endl<<" || Y || U || V ||";
+ std::cout<<std::endl<<"=================||===================================================";
+ std::cout<<std::endl<<" Intra || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(Ymax*Ymax/(m_mse_averageY[0]/m_picture_total[0]))<<" || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageU[0]/m_picture_total[0]))<<" || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageV[0]/m_picture_total[0]))<<" || ";
+ std::cout<<std::endl<<"-----------------||---------------------------------------------------";
+ std::cout<<std::endl<<" Inter Ref || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(Ymax*Ymax/(m_mse_averageY[1]/m_picture_total[1]))<<" || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageU[1]/m_picture_total[1]))<<" || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageV[1]/m_picture_total[1]))<<" || ";
+ std::cout<<std::endl<<"-----------------||---------------------------------------------------";
+ std::cout<<std::endl<<" Inter Non Ref || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(Ymax*Ymax/(m_mse_averageY[2]/m_picture_total[2]))<<" || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageU[2]/m_picture_total[2]))<<" || ";
+ std::cout.width(5);std::cout.precision(4);
+ std::cout<<10*std::log10(UVmax*UVmax/(m_mse_averageV[2]/m_picture_total[2]))<<" || ";
+ std::cout<<std::endl<<"-----------------||---------------------------------------------------";
+}
+
+void QualityMonitor::UpdateModel(const EncPicture& enc_picture )
+{
+ const double Ymax = double( (1<<m_encparams.LumaDepth())-1 );
+ const double UVmax = double( (1<<m_encparams.ChromaDepth())-1 );
+
+ const PictureSort& psort = enc_picture.GetPparams().PicSort();
+ int idx = psort.IsIntra() ? 0 : (psort.IsRef() ? 1 : 2);
+
+ double fmseY, fmseU, fmseV;
+
+ fmseY = QualityVal( enc_picture.Data(Y_COMP) , enc_picture.OrigData(Y_COMP),
+ m_encparams.Xl(), m_encparams.Yl());
+ m_mse_averageY[idx] += fmseY;
+ m_totalmse_averageY += fmseY;
+
+ fmseU = QualityVal( enc_picture.Data(U_COMP) , enc_picture.OrigData(U_COMP),
+ m_encparams.ChromaXl(),
+ m_encparams.ChromaYl());
+ m_mse_averageU[idx] += fmseU;
+ m_totalmse_averageU += fmseU;
+
+ fmseV = QualityVal( enc_picture.Data(V_COMP) , enc_picture.OrigData(V_COMP),
+ m_encparams.ChromaXl(),
+ m_encparams.ChromaYl());
+ m_mse_averageV[idx] += fmseV;
+ m_totalmse_averageV += fmseV;
+
+ m_picture_total[idx]++;
+ m_allpicture_total++;
+
+ if (m_encparams.Verbose() )
+ {
+ std::cout<<std::endl<< (!m_encparams.FieldCoding() ? "Frame" : "Field");
+ std::cout << " PSNR: Y="<<10.0 * std::log10( Ymax*Ymax / fmseY );
+ std::cout<<", U="<<10.0 * std::log10( UVmax*UVmax / fmseU );
+ std::cout<<", V="<<10.0 * std::log10( UVmax*UVmax / fmseV );
+ }
+
+}
+
+
+double QualityMonitor::QualityVal(const PicArray& coded_data,
+ const PicArray& orig_data,
+ const int xlen, const int ylen)
+{
+ long double sum_sq_diff = 0.0;
+ double diff;
+ for ( int j=0;j<ylen; ++j )
+ {
+ for ( int i=0;i<xlen; ++i )
+ {
+ diff = orig_data[j][i] - coded_data[j][i];
+ sum_sq_diff += diff*diff;
+
+ }// i
+ }// j
+
+
+ sum_sq_diff /= xlen*ylen;
+
+ return (double) sum_sq_diff;
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.h
new file mode 100644
index 000000000..7f21a944d
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quality_monitor.h
@@ -0,0 +1,124 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: quality_monitor.h,v 1.19 2008/08/14 02:30:50 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _QUALITY_MONITOR_H_
+#define _QUALITY_MONITOR_H_
+
+#include <libdirac_common/common.h>
+#include <libdirac_encoder/enc_picture.h>
+#include <libdirac_common/wavelet_utils.h>
+namespace dirac
+{
+
+ //! Class to monitor the quality of pictures and adjust coding parameters appropriately
+ class QualityMonitor
+ {
+ public:
+
+ //! Constructor. Sets up initial Lagrangian values
+ /*
+ Constructor sets up initial Lagrangian values.
+ */
+ QualityMonitor(EncoderParams& ep);
+
+
+ //! Destructor
+ ~QualityMonitor();
+
+ ////////////////////////////////////////////////////////////
+ // //
+ // Assumes default copy constructor, assignment = //
+ // and destructor //
+ ////////////////////////////////////////////////////////////
+
+ //! Update the mse factors, returning true if we need to recode
+ /*!
+ Update the mse factors, returning true if we need to recode
+ \param enc_picture the picture being encoded
+ */
+ void UpdateModel(const EncPicture& enc_picture );
+
+ //! Reset the quality factors (say if there's been a cut)
+ void ResetAll();
+
+ //! Write a log of the quality to date
+ void WriteLog();
+
+ private:
+ //functions
+
+
+ //! Calculate the quality of coded wrt original picture
+ double QualityVal( const PicArray& coded_data ,
+ const PicArray& orig_data,
+ const int xlen,
+ const int ylen);
+
+ //member variables//
+ ////////////////////
+
+ //! A reference to the encoder parameters
+ EncoderParams& m_encparams;
+
+ //! The overall average Y mse
+ long double m_totalmse_averageY;
+
+ //! The overall average U mse
+ long double m_totalmse_averageU;
+
+ //! The overall average V mse
+ long double m_totalmse_averageV;
+
+ //! The total number of pictures coded
+ int m_allpicture_total;
+
+ //! The average Y mse for the picture types
+ OneDArray<long double> m_mse_averageY;
+
+ //! The average U mse for the picture types
+ OneDArray<long double> m_mse_averageU;
+
+ //! The average V mse for the picture types
+ OneDArray<long double> m_mse_averageV;
+
+ //! The number of pictures of each type
+ OneDArray<int> m_picture_total;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.cpp
new file mode 100644
index 000000000..9f369ffe8
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.cpp
@@ -0,0 +1,363 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: quant_chooser.cpp,v 1.20 2009/01/21 05:22:05 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+//Compression of an individual component,
+//after motion compensation if appropriate
+//////////////////////////////////////////
+
+#include <libdirac_encoder/quant_chooser.h>
+
+using namespace dirac;
+
+// Custom 4th power, to speed things up
+static inline double pow4 (double x)
+{
+ return x * x * x* x;
+}
+
+// Constructor
+QuantChooser::QuantChooser( const CoeffArray& coeff_data,
+ const float lambda ):
+ m_coeff_data( coeff_data ),
+ m_lambda( lambda ),
+ m_entropy_correctionfactor( 1.0 )
+{}
+
+
+int QuantChooser::GetBestQuant( Subband& node )
+{
+ // NB : quantiser selection only supports a single quantiser per subband
+ // Setting MultiQuants=true and using this function will get the same
+ // quantiser for each codeblock
+
+ m_subband_wt = node.Wt();
+
+ // The largest value in the block or band
+ CoeffType max_val;
+
+ // The index of the maximum bit of the largest value
+ int max_bit( 0 );
+
+ max_val = BlockAbsMax( node );
+
+ if ( max_val>=1 )
+ max_bit = int( std::floor( std::log( float( max_val ) )/std::log( 2.0 ) ) );
+ else
+ {
+ // Exit saying 'Skip this subband' if there's no data in it
+ node.SetSkip( true );
+ return 0;
+ }
+
+ // The number of quantisers to be tested
+ int num_quants( 4 * max_bit + 5 );
+
+ // Set the array sizes
+ m_costs.Resize( num_quants );
+ m_count0.Resize( num_quants );
+ m_count1=node.Xl()*node.Yl();
+ m_countPOS.Resize( num_quants );
+ m_countNEG.Resize( num_quants );
+ m_error_total.Resize( num_quants );
+
+ // Total estimated bits for the subband
+ double bit_sum( 0.0 );
+
+ // Step 1. Do integral bits first
+ m_bottom_idx = 0;
+ m_top_idx = num_quants-1;
+ m_index_step = 4;
+
+ IntegralErrorCalc( node, 2 , 2);
+ LagrangianCalc( );
+ SelectBestQuant();
+
+ // Step 2. Do 1/2-bit accuracy next
+ m_bottom_idx = std::max( m_min_idx - 2 , 0 );
+ m_top_idx = std::min( m_min_idx + 2 , num_quants-1 );
+ m_index_step = 2;
+
+ NonIntegralErrorCalc( node, 2 , 2);
+ LagrangianCalc( );
+ SelectBestQuant();
+
+ // Step 3. Finally, do 1/4-bit accuracy next
+ m_bottom_idx = std::max( m_min_idx - 1 , 0 );
+ m_top_idx = std::min( m_min_idx + 1 , num_quants-1 );
+ m_index_step = 1;
+
+ NonIntegralErrorCalc( node, 1 , 2);
+ LagrangianCalc( );
+ SelectBestQuant();
+
+ bit_sum = m_costs[m_min_idx].ENTROPY * node.Xl() * node.Yl();
+
+ node.SetQuantIndex( m_min_idx );
+
+ TwoDArray<CodeBlock>& block_list( node.GetCodeBlocks() );
+
+ // Set the codeblock quantisers
+ for (int j=0 ; j<block_list.LengthY() ; ++j )
+ for (int i=0 ; i<block_list.LengthX() ; ++i )
+ block_list[j][i].SetQuantIndex( m_min_idx );
+
+ // Set the codeblock skip flags
+ for (int j=0 ; j<block_list.LengthY() ; ++j )
+ for (int i=0 ; i<block_list.LengthX() ; ++i )
+ SetSkip( block_list[j][i], m_min_idx );
+
+
+ return static_cast<int>( bit_sum );
+
+}
+
+void QuantChooser::IntegralErrorCalc( Subband& node, const int xratio , const int yratio )
+{
+
+ CoeffType val, quant_val , abs_val;
+
+ CalcValueType error;
+
+ m_count1 = ( (node.Xl()/xratio)*(node.Yl()/yratio) );
+ for (int q = m_bottom_idx ; q<=m_top_idx ; q+=4 )
+ {
+ m_error_total[q] = 0.0;
+ m_count0[q] =0;
+ m_countPOS[q] = 0;
+ m_countNEG[q] = 0;
+ }
+
+ // Work out the error totals and counts for each quantiser
+ for ( int j=node.Yp(); j<node.Yp()+node.Yl() ; j+=yratio )
+ {
+ for ( int i=node.Xp(); i<node.Xp()+node.Xl() ; i+=xratio )
+ {
+ val = m_coeff_data[j][i];
+ abs_val = quant_val = abs(val);
+
+ int q = m_bottom_idx;
+ for ( ; q<=m_top_idx ; q+=4 )
+ {
+ // Quantiser is 2^(q/4), so we divide by this
+ quant_val >>= (q>>2);
+ if (!quant_val)
+ break;
+
+ m_count0[q] += quant_val;
+ // Multiply back up so that we can quantise again in the next loop step
+ quant_val <<= (q>>2)+2;
+ quant_val += dirac_quantiser_lists.InterQuantOffset4( q )+2;
+ quant_val >>= 2;
+ if (val>0)
+ m_countPOS[q]++;
+ else
+ m_countNEG[q]++;
+
+ error = abs_val-quant_val;
+
+ // Using the fourth power to measure the error
+ m_error_total[q] += pow4( static_cast<double>( error ) );
+
+ }// q
+ double derror = pow4 ( static_cast<double>( abs_val ) );
+ for (; q <= m_top_idx; q+= 4)
+ {
+ m_error_total[q] += derror;
+ }
+ }// i
+ }// j
+
+}
+
+void QuantChooser::NonIntegralErrorCalc( Subband& node , const int xratio , const int yratio )
+{
+
+ CoeffType val, abs_val;
+
+ CalcValueType quant_val;
+ CalcValueType error;
+
+ m_count1 = ( (node.Xl()/xratio)*(node.Yl()/yratio) );
+ for (int q = m_bottom_idx ; q<=m_top_idx ; q+=m_index_step )
+ {
+ m_error_total[q] = 0.0;
+ m_count0[q] =0;
+ m_countPOS[q] = 0;
+ m_countNEG[q] = 0;
+ }
+
+ // Work out the error totals and counts for each quantiser
+ for ( int j=node.Yp(); j<node.Yp()+node.Yl() ; j+=yratio )
+ {
+ for ( int i=node.Xp(); i<node.Xp()+node.Xl() ; i+=xratio )
+ {
+
+ val = m_coeff_data[j][i];
+ abs_val = abs( val );
+
+ int q=m_bottom_idx;
+ for ( ; q<=m_top_idx ; q+=m_index_step )
+ {
+ // Since the quantiser isn't a power of 2 we have to divide each time
+ quant_val = static_cast<CalcValueType>( abs_val );
+ quant_val <<= 2;
+ quant_val /= dirac_quantiser_lists.QuantFactor4( q );
+
+ if ( !quant_val )
+ break;
+
+ m_count0[q] += quant_val;
+ quant_val *= dirac_quantiser_lists.QuantFactor4( q );
+ quant_val += dirac_quantiser_lists.InterQuantOffset4( q )+2;
+ quant_val >>= 2;
+
+ if ( val>0 )
+ m_countPOS[q]++;
+ else
+ m_countNEG[q]++;
+
+ error = abs_val-quant_val;
+ m_error_total[q] += pow4( error );
+ }// q
+ double derror = pow4( abs_val );
+ for ( ; q <= m_top_idx; q += m_index_step)
+ m_error_total[q] += derror;
+ }// i
+ }// j
+
+}
+
+
+void QuantChooser::LagrangianCalc()
+{
+
+ // probabilities
+ double p0,p1;
+
+ double sign_entropy;
+
+ // Do Lagrangian costs calculation
+ for ( int q=m_bottom_idx ; q<=m_top_idx ; q += m_index_step )
+ {
+
+ m_costs[q].Error = m_error_total[q]/double(m_count1);
+ m_costs[q].Error = std::sqrt( m_costs[q].Error )/( m_subband_wt*m_subband_wt );
+
+ // Calculate probabilities and entropy
+ p0 = double( m_count0[q] )/ double( m_count0[q]+m_count1 );
+ p1 = 1.0 - p0;
+
+ if ( p0 != 0.0 && p1 != 0.0)
+ m_costs[q].ENTROPY = -( p0*std::log(p0)+p1*std::log(p1) ) / std::log(2.0);
+ else
+ m_costs[q].ENTROPY = 0.0;
+
+ // We want the entropy *per symbol*, not per bit ...
+ m_costs[q].ENTROPY *= double(m_count0[q]+m_count1);
+ m_costs[q].ENTROPY /= double(m_count1);
+
+ // Now add in the sign entropy
+ if ( m_countPOS[q] + m_countNEG[q] != 0 )
+ {
+ p0 = double( m_countNEG[q] )/double( m_countPOS[q]+m_countNEG[q] );
+ p1 = 1.0-p0;
+ if ( p0 != 0.0 && p1 != 0.0)
+ sign_entropy = -( (p0*std::log(p0)+p1*std::log(p1) ) / std::log(2.0));
+ else
+ sign_entropy = 0.0;
+ }
+ else
+ sign_entropy = 0.0;
+
+ // We want the entropy *per symbol*, not per bit ...
+ sign_entropy *= double( m_countNEG[q] + m_countPOS[q] );
+ sign_entropy /= double(m_count1);
+
+ m_costs[q].ENTROPY += sign_entropy;
+
+ // Sort out correction factors
+ m_costs[q].ENTROPY *= m_entropy_correctionfactor;
+ m_costs[q].TOTAL = m_costs[q].Error+m_lambda*m_costs[q].ENTROPY;
+
+ }// q
+}
+
+void QuantChooser::SelectBestQuant()
+{
+ // Selects the best quantiser to use for a subband block
+
+ m_min_idx = m_bottom_idx;
+ for ( int q=m_bottom_idx + m_index_step; q<=m_top_idx ; q +=m_index_step )
+ {
+ if ( m_costs[q].TOTAL < m_costs[m_min_idx].TOTAL)
+ m_min_idx = q;
+ }// q
+
+}
+
+void QuantChooser::SetSkip( CodeBlock& cblock , const int qidx)
+{
+ const int u_threshold = dirac_quantiser_lists.QuantFactor4( qidx );
+
+ // Sets the skip flag for a codeblock
+ bool can_skip = true;
+ for (int j=cblock.Ystart(); j<cblock.Yend(); ++j )
+ {
+ for (int i=cblock.Xstart(); i<cblock.Xend(); ++i )
+ {
+ if ( (std::abs(m_coeff_data[j][i])<<2) >= u_threshold )
+ can_skip = false;
+ }
+ }
+ cblock.SetSkip( can_skip );
+}
+
+CoeffType QuantChooser::BlockAbsMax( const Subband& node )
+{
+ int val( 0 );
+
+ for (int j=node.Yp() ; j<node.Yp()+node.Yl(); ++j)
+ {
+ for (int i=node.Xp() ; i<node.Xp()+node.Xl(); ++i)
+ {
+ val = std::max( val , std::abs(m_coeff_data[j][i]) );
+ }// i
+ }// j
+
+ return val;
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.h
new file mode 100644
index 000000000..c1d28302c
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/quant_chooser.h
@@ -0,0 +1,130 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: quant_chooser.h,v 1.7 2008/05/27 01:29:54 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _QUANT_CHOOSER_H_
+#define _QUANT_CHOOSER_H_
+
+#include <libdirac_common/arrays.h>
+#include <libdirac_common/wavelet_utils.h>
+#include <libdirac_common/common.h>
+
+namespace dirac
+{
+ //! Choose a quantiser
+ /*!
+ This class chooses a quantiser or quantisers for a subband
+ */
+ class QuantChooser
+ {
+ public:
+
+ //! Constructor
+ QuantChooser( const CoeffArray& pic_data , const float lambda );
+
+ //! Finds the best quantisers for the subband, returning the predicted number of bits needed
+ int GetBestQuant( Subband& node );
+
+ //! Sets the factor used for correcting the entropy calculation
+ void SetEntropyCorrection( const float ecfac ){ m_entropy_correctionfactor = ecfac; }
+ private:
+ //! Copy constructor is private and body-less. This class should not be copied.
+ QuantChooser(const QuantChooser& cpy);
+
+ //! Assignment = is private and body-less. This class should not be assigned.
+ QuantChooser& operator=(const QuantChooser& rhs);
+
+ //! Calculate errors and entropies for integral-bit quantisers
+ void IntegralErrorCalc( Subband& node , const int xratio , const int yratio );
+
+ //! Calculate errors and entropies for non-integral-bit quantisers
+ void NonIntegralErrorCalc( Subband& node, const int xratio, const int yratio );
+
+ //! Having got statistics, calculate the Lagrangian costs
+ void LagrangianCalc();
+
+ //! Select the best quantisation index on the basis of the Lagrangian calculations
+ void SelectBestQuant();
+
+ CoeffType BlockAbsMax( const Subband& node );
+
+ //! Set the skip flag for a codeblock
+ void SetSkip( CodeBlock& cblock , const int qidx);
+
+ private:
+ //! The perceptual weighting factor of the subband being tested
+ float m_subband_wt;
+
+ //! The smallest quantisation index being tested
+ int m_bottom_idx;
+ //! The largest quantisation index being tested
+ int m_top_idx;
+ //! The step we use in jumping through the list of quantisers
+ int m_index_step;
+
+ //! The index of the quantiser with the lowest cost
+ int m_min_idx;
+
+ //! A local reference to the data under consideration
+ const CoeffArray& m_coeff_data;
+
+ //! The lambda value to be used in the Lagrangian calculation
+ const float m_lambda;
+
+ //! A value for correcting the crude calculation of the entropy
+ float m_entropy_correctionfactor;
+
+ //! An array used to count the number of zeroes
+ OneDArray<int> m_count0;
+ //! The number of ones (equal to the number of coefficients)
+ int m_count1;
+ //! An array used to count the number of positive values
+ OneDArray<int> m_countPOS;
+ //! An array used to count the number of negative values
+ OneDArray<int> m_countNEG;
+ //! An array used to collate the sum of the perceptually-weighted errors
+ OneDArray<double> m_error_total;
+ //! An array used to collate the computed costs
+ OneDArray<CostType> m_costs;
+
+ };
+
+} // namespace dirac
+
+
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp
new file mode 100644
index 000000000..bd5b62346
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.cpp
@@ -0,0 +1,530 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: rate_control.cpp,v 1.33 2008/12/16 01:21:02 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Myo Tun (Original Author, myo.tun@brunel.ac.uk)
+* Jonathan Loo (Jonathan.Loo@brunel.ac.uk)
+* School of Engineering and Design, Brunel University, UK
+* Thomas Davies (bugfixes to improve stability and a major
+ refactor to introduce a buffer model)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+//////////////Rate Control Algorithm//////////////////
+/*
+The algorithm controls the bitrate by adaptively changing the Quality
+Factor, QF of each frame before encoding by the
+m_fcoder.Compress( , , , ) function in CompressNextPicture() (seq_compress.cpp).
+The first sub-group which is I, L1, L2, L2 frames are encoded
+by using the initial QF which is set to 7. The corresponding bitrate R is then
+calculated. Adaption for the next subgroup is carried out by determining a model
+ parameter K, whose relationship to QF and bit rate is:
+
+QF = 10-5/2log(K/R^(-2))
+
+K is determined from the first subgroup data (QF and rate), and used to
+calculate a new QF from the target rates for the next subgroup.
+
+The same procedure applies for the calculation of the QF for the remaining
+sub-groups until it reaches to the end of a GOP.
+
+For the next GOP, the initial QF of the first sub-group is the average value of
+the QF of the first sub-group and last sub-group from the previous GOP. The
+calculation of the QF of each and every sub-group is carried out in the
+CalcNextQualFactor( , ) function at the rate_control.cpp.
+
+The target bitrate is varied according to a decoder buffer model, consisting of
+the average bitrate over a GOP plus an adjustment to steer the buffer towards a
+target occupancy. A target bit rate corresponding to
+ the different sub-groups still neeeds to be calculated from this overall target.
+
+In order to do this, the modified version of test model version 5, TM5 bit
+allocation procedure is employed and target bit rates for each sub-group are
+calculated by using the allocated bits to each frame types. The modified version
+of TM5 bit allocation procedure is implemented in Allocate ( , ) function at the
+rate_control.cpp.
+*/
+
+
+#include <math.h>
+#include <libdirac_encoder/rate_control.h>
+using namespace dirac;
+
+//Default constructor
+FrameComplexity::FrameComplexity():
+ m_XI(169784),
+ m_XL1(36016),
+ m_XL2(4824)
+{}
+
+//Default constructor
+RateController::RateController(int trate, SourceParams& srcp, EncoderParams& encp):
+ m_qf (encp.Qf()),
+ m_I_qf (encp.Qf()),
+ m_I_qf_long_term(encp.Qf()),
+ m_target_rate(trate),
+ m_buffer_size(5000*trate),// for the moment, set buffer size to 5 seconds
+ m_buffer_bits((m_buffer_size*9)/10),// initial occupancy of 90%
+ m_encparams(encp),
+ m_fcount(encp.L1Sep() ),
+ m_intra_only(false),
+ m_L2_complexity_sum(0)
+{
+ SetFrameDistribution();
+ CalcTotalBits(srcp);
+
+ if (m_intra_only)
+ m_Iframe_bits = m_total_GOP_bits;
+ else
+ {
+ m_Iframe_bits = m_total_GOP_bits/10;
+ m_L1frame_bits = (m_Iframe_bits*3)/m_num_L1frame;
+ if (m_encparams.L1Sep()>1)
+ m_L2frame_bits = ( m_total_GOP_bits - m_Iframe_bits -
+ m_L1frame_bits*m_num_L1frame )/
+ (m_encparams.GOPLength()-1-m_num_L1frame);
+ else
+ m_L2frame_bits = 0;
+
+ }
+}
+
+void RateController::SetFrameDistribution()
+{
+ m_num_L1frame = m_encparams.NumL1();
+ m_num_Iframe = 1;
+
+ if (m_num_L1frame == 0)
+ {
+ m_num_Iframe = m_encparams.GOPLength();
+ m_intra_only = true;
+ }
+
+ m_num_L2frame = m_encparams.GOPLength() - m_num_Iframe - m_num_L1frame;
+}
+
+void RateController::CalcTotalBits(const SourceParams& sourceparams)
+{
+ const Rational& frame_rate = sourceparams.FrameRate();
+ double f_rate = double(frame_rate.m_num)/double(frame_rate.m_denom);
+ int GOP_length = m_encparams.GOPLength();
+
+ m_GOP_duration = GOP_length/f_rate;
+ m_total_GOP_bits = (long int)(m_GOP_duration*1000.0)*m_target_rate; //Unit in bits
+
+ m_GOP_target = m_total_GOP_bits;
+
+ m_picture_bits = m_total_GOP_bits/GOP_length;
+
+ if (m_encparams.Verbose())
+ {
+ std::cout<<"\nRate Control Encoding with target bit rate = ";
+ std::cout<<m_target_rate<<" kbps"<< std::endl;
+
+ std::cout<<"GOP Length = "<<GOP_length<< std::endl;
+
+ std::cout<<"Frame Rate = "<<f_rate<< std::endl;
+
+ std::cout<<"GOP Duration = "<<m_GOP_duration<< std::endl;
+
+ std::cout<<"Total Allocated Num. of bits for each GOP = ";
+ std::cout<<m_total_GOP_bits<<" ("<<m_picture_bits<<" per frame)";
+ std::cout<<std::endl;
+ }
+}
+
+void RateController::Report()
+{
+
+ std::cout<<std::endl;
+ std::cout<<std::endl<<"GOP target is "<<m_GOP_target;
+ std::cout<<std::endl<<"Allocated frame bits by type: ";
+ std::cout<<"I frames - "<<m_Iframe_bits;
+ std::cout<<"; L1/P frames - "<<m_L1frame_bits;
+ std::cout<<"; L2/B frames - "<<m_L2frame_bits;
+ std::cout<<std::endl;
+}
+
+
+double RateController::TargetSubgroupRate()
+{
+ long int bits = (m_encparams.L1Sep()-1)*m_L2frame_bits+
+ m_L1frame_bits;
+ return (double)(bits)/(1000.0*m_GOP_duration);
+
+}
+
+double RateController::ProjectedSubgroupRate()
+{
+ int bits = (m_encparams.L1Sep()-1)*m_frame_complexity.L2Complexity()+
+ m_frame_complexity.L1Complexity();
+
+ return (double)(bits)/(1000.0*m_GOP_duration);
+}
+void RateController::CalcNextQualFactor(const PictureParams& pparams, int num_bits)
+{
+
+ // Decrement the subgroup frame counter. This is zero just after the last
+ // L2 frame before the next L1 frame i.e. before the start of an L1L2L2
+ // subgroup
+ m_fcount--;
+ UpdateBuffer( num_bits );
+
+ // filter tap for adjusting the QF
+ double target_ratio = 0.9;
+
+ int field_factor = m_encparams.FieldCoding() ? 2 : 1;
+
+ double top_size = (1.0 - target_ratio)-0.5;
+ double bottom_size = target_ratio-0.1;
+ double actual_ratio = double(m_buffer_bits)/double(m_buffer_size);
+ double tap;
+
+ if ((pparams.PictureNum()/field_factor)<=3*m_encparams.L1Sep() )
+ tap = 1.0;
+ else{
+ if (actual_ratio>target_ratio)
+ tap = (actual_ratio-target_ratio)/top_size;
+ else
+ tap = (target_ratio-actual_ratio)/bottom_size;
+
+ tap = std::min( 1.0, std::max(tap, 0.25 ));
+ }
+
+
+ if (!m_intra_only)
+ {
+ bool emergency_realloc = false;
+ int target;
+
+ // First, do normal coding
+
+ if ( pparams.PicSort().IsIntra() == true )
+ {
+ target = m_Iframe_bits;
+
+ if (num_bits < target/2 )
+ emergency_realloc = true;
+
+ // Update the statistics
+ m_frame_complexity.SetIComplexity( num_bits );
+
+ // We've just coded an intra frame so we need to set qf for
+ // the next group of L2(B) frames
+ m_qf = std::max(tap*m_qf+(1.0-tap)*m_encparams.Qf(), m_encparams.Qf()-1.0);
+ m_encparams.SetQf( m_qf );
+
+ if (pparams.PictureNum()/field_factor==0)
+ {
+ // We've just coded the very first frame, which is a special
+ // case as the two L2 frames which normally follow are missing
+ m_fcount = m_encparams.L1Sep();
+ }
+
+ }
+
+ //Update complexities
+ if ( (pparams.PictureNum()/field_factor) % m_encparams.L1Sep() !=0 )
+ {
+ // Scheduled B/L2 picture
+
+ target = m_L2frame_bits;
+
+ if (num_bits < target/2 ){
+ emergency_realloc = true;
+ }
+
+ m_L2_complexity_sum += num_bits;
+ }
+ else if ( pparams.PicSort().IsIntra() == false )
+ {
+ // Scheduled P/L1 picture (if inserted I picture, don't change the complexity)
+
+ target = m_L1frame_bits;
+
+ if (num_bits < target/2 || num_bits > target*3 ){
+ emergency_realloc = true;
+ }
+
+ m_frame_complexity.SetL1Complexity(num_bits);
+ }
+
+ if ( m_fcount==0 || emergency_realloc==true)
+ {
+ if (emergency_realloc==true && m_encparams.Verbose()==true )
+ std::cout<<std::endl<<"Major mis-prediction of frame bit rate: re-allocating";
+
+
+ /* We recompute allocations for the next subgroup */
+
+ if ( m_encparams.L1Sep()>1 && m_fcount<m_encparams.L1Sep()-1)
+ {
+ m_frame_complexity.SetL2Complexity(m_L2_complexity_sum/
+ (m_encparams.L1Sep()-1-m_fcount));
+ }
+ Allocate( (pparams.PictureNum()/field_factor) );
+
+ /* We work out what this means for the quality factor and set it*/
+
+ // Get the target number of bits for the coming subgroup
+ // calculated from allocations
+ double trate = TargetSubgroupRate();
+
+ // Get the projected rate for the coming subgroup, calculated
+ // from measured values (complexities)
+ double prate = ProjectedSubgroupRate();
+
+ if (m_encparams.Verbose()==true )
+ {
+ std::cout<<std::endl<<"Target subgroup rate = "<<trate;
+ std::cout<<", projected subgroup rate = "<<prate;
+ }
+ // Determine K value
+ double K = std::pow(prate, 2)*std::pow(10.0, ((double)2/5*(10-m_qf)))/16;
+
+ // Determine a new QF
+ double new_qf = 10 - (double)5/2*log10(16*K/std::pow(trate, 2));
+ if ( ( std::abs(m_qf-new_qf)<0.25 && new_qf > 4.0 ) || new_qf>8.0)
+ m_qf = new_qf;
+ else
+ m_qf = tap*new_qf+(1.0-tap)*m_qf;
+
+ m_qf = ReviewQualityFactor( m_qf , num_bits );
+
+ if ( m_qf<8.0 ){
+ if (prate<2*trate)
+ m_qf = std::max(m_qf,m_encparams.Qf()-1.0);
+ else
+ m_qf = std::max(m_qf,m_encparams.Qf()-2.0);
+ }
+
+ m_encparams.SetQf(m_qf);
+
+
+ /* Resetting */
+
+ // Reset the frame counter
+ if (m_fcount==0)
+ m_fcount = m_encparams.L1Sep();
+
+ // Reset the count of L2 bits
+ m_L2_complexity_sum = 0;
+ }
+
+ }
+ else
+ {
+ // We're doing intra-only coding
+
+
+ // Target rate
+ double trate = double(m_total_GOP_bits)/(1000.0*m_num_Iframe);
+
+ // Projected rate with current QF
+ double prate = double(num_bits)/1000.0;
+
+
+ // Determine K value
+ double K = std::pow(prate, 2)*std::pow(10.0, ((double)2/5*(10-m_qf)))/16;
+
+ // Determine a new QF
+ double new_qf = 10 - (double)5/2*log10(16*K/std::pow(trate, 2));
+
+ // Adjust the QF to meet the target
+
+ double abs_delta = std::abs( new_qf - m_qf );
+ if ( abs_delta>0.01)
+ {
+ // Rate of convergence to new QF
+ double r;
+
+ /* Use an S-shaped curve to compute r
+ Where the qf difference is less than 1/2, r decreases to zero
+ exponentially, so for small differences in QF we jump straight
+ to the target value. For large differences in QF, r converges
+ exponentially to 0.75, so we converge to the target value at
+ a fixed rate.
+
+ Overall behaviour is to converge steadily for 2 or 3 frames until
+ close and then lock to the correct value. This avoids very rapid
+ changes in quality.
+
+ Actual parameters may be adjusted later. Some applications may
+ require instant lock.
+ */
+ double lg_diff = std::log( abs_delta/2.0 );
+ if ( lg_diff< 0.0 )
+ r = 0.5*std::exp(-lg_diff*lg_diff/2.0);
+ else
+ r = 1.0-0.5*std::exp(-lg_diff*lg_diff/2.0);
+
+ r *= 0.75;
+
+ m_qf = r*m_qf + (1.0-r)*new_qf;
+ m_qf = ReviewQualityFactor( m_qf , num_bits );
+
+ m_encparams.SetQf(m_qf);
+ }
+
+
+ }
+
+}
+
+
+void RateController::UpdateBuffer( const long int num_bits )
+{
+ m_buffer_bits -= num_bits;
+ m_buffer_bits += m_picture_bits;
+
+ if (m_encparams.Verbose())
+ {
+ std::cout<<std::endl<<"Buffer occupancy = "<<((double)m_buffer_bits*100.0)
+ /((double)m_buffer_size)<<"%";
+ }
+
+ if (m_buffer_bits<0)
+ {
+ if (m_encparams.Verbose())
+ {
+ std::cout<<std::endl<<"WARNING: decoder buffer is out of bits - bit rate is too high";
+ }
+// m_buffer_bits = 0;
+ }
+
+ if (m_buffer_bits>m_buffer_size)
+ {
+ if (m_encparams.Verbose())
+ {
+ std::cout<<std::endl<<"WARNING: decoder buffer has overflowed - bit rate is too low. Assuming bit-stuffing.";
+ }
+ m_buffer_bits = m_buffer_size;
+ }
+
+
+}
+
+void RateController::Allocate (const int fnum)
+{
+ const int XI = m_frame_complexity.IComplexity();
+ const int XL1 = m_frame_complexity.L1Complexity();
+ const int XL2 = m_frame_complexity.L2Complexity();
+
+ double buffer_occ = ( (double)m_buffer_bits)/((double)m_buffer_size);
+
+ if ( !m_intra_only)
+ {
+ double correction;
+ if (buffer_occ<0.9 && ( (fnum+1) % 4*m_encparams.L1Sep())==0 )
+ {
+ // If we're undershooting buffer target, correct slowly
+ correction = std::min( 0.25, 0.25*(0.9 - buffer_occ )/0.9 );
+ m_GOP_target = ( long int)(double(m_total_GOP_bits)*( 1.0-correction) );
+ }
+ else if (buffer_occ>0.9 && ((fnum+1) % m_encparams.L1Sep())==0)
+ {
+ // If we're overshooting buffer target, correct quickly
+ correction = std::min( 0.5, 0.5*( buffer_occ - 0.9 )/0.9 );
+ m_GOP_target = ( long int)(double(m_total_GOP_bits)*( 1.0+correction) );
+ }
+ }
+
+
+ const long int min_bits = m_total_GOP_bits/(100*m_encparams.GOPLength());
+
+ // Allocate intra bits
+ m_Iframe_bits = (long int) (m_GOP_target
+ / (m_num_Iframe
+ +(double)(m_num_L1frame*XL1)/XI
+ +(double)(m_num_L2frame*XL2)/XI));
+
+ m_Iframe_bits = std::max( min_bits, m_Iframe_bits );
+
+ // Allocate L1 bits
+ m_L1frame_bits = (long int) (m_GOP_target
+ / (m_num_L1frame
+ +(double)(m_num_Iframe*XI)/XL1
+ +(double)(m_num_L2frame*XL2)/XL1));
+
+ m_L1frame_bits = std::max( min_bits, m_L1frame_bits );
+
+ // Allocate L2 bits
+ m_L2frame_bits = (long int) (m_GOP_target
+ / (m_num_L2frame
+ +(double)(m_num_Iframe*XI)/XL2
+ +(double)(m_num_L1frame*XL1)/XL2));
+
+ m_L2frame_bits = std::max( min_bits, m_L2frame_bits );
+}
+
+
+
+float RateController::ReviewQualityFactor( const float qfac, const long int num_bits )
+{
+ if (num_bits>m_total_GOP_bits/2)
+ {
+ // The frame is too big, so reset to a smaller quality factor
+ return ClipQualityFactor(qfac-2);
+ }
+ else
+ {
+ // Keep the quality factor in a sensible range
+ return ClipQualityFactor( qfac );
+ }
+}
+
+float RateController::ClipQualityFactor( const float qfac )
+{
+ // Keep the quality factor in a sensible range
+ if ( !m_intra_only )
+ return std::min( std::max(qfac, 0.0f), 16.0f);
+ else
+ return std::max(qfac, 0.0f);
+}
+
+void RateController::CalcNextIntraQualFactor()
+{
+ m_I_qf = (m_I_qf + m_qf)/2.0;
+ m_I_qf = ClipQualityFactor( m_I_qf );
+ m_encparams.SetQf(m_I_qf);
+
+ const double ff = 0.95;
+ m_I_qf_long_term *= ff;
+ m_I_qf_long_term += ( 1.0 - ff )*m_I_qf;
+}
+
+void RateController::SetCutPictureQualFactor()
+{
+ m_qf = std::min( m_qf , m_I_qf_long_term );
+ m_encparams.SetQf( m_qf );
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.h
new file mode 100644
index 000000000..a54bb5d95
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/rate_control.h
@@ -0,0 +1,221 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: rate_control.h,v 1.7 2008/01/31 11:25:18 tjdwave Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Myo Tun (Original Author, myo.tun@brunel.ac.uk)
+* Jonathan Loo (Jonathan.Loo@brunel.ac.uk)
+* School of Engineering and Design, Brunel University, UK
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+//Compression of an individual component,
+//after motion compensation if appropriate
+//////////////////////////////////////////
+
+#ifndef _RATE_CONTROL_H_
+#define _RATE_CONTROL_H_
+
+#include <libdirac_common/common.h>
+
+namespace dirac
+{
+ class FrameComplexity
+ {
+ public:
+ //! Default constructor
+ FrameComplexity();
+
+ //! Return the complexity of I frame
+ int IComplexity() {return m_XI;}
+
+ //! Return the complexity of L1 frame
+ int L1Complexity() {return m_XL1;}
+
+ //! Return the complexity of L2 frame
+ int L2Complexity() {return m_XL2;}
+
+ //! Set the complexity of I frame
+ void SetIComplexity(int cpx) {m_XI = cpx;}
+
+ //! Set the complexity of L1 frame
+ void SetL1Complexity(int cpx) {m_XL1 = cpx;}
+
+ //! Set the complexity of L2 frame
+ void SetL2Complexity(int cpx) {m_XL2 = cpx;}
+
+
+ private:
+
+ //! Complexity of I frame
+ int m_XI;
+
+ //! Complexity of L1 frame
+ int m_XL1;
+
+ //! Complexity of L2 frame
+ int m_XL2;
+ };
+
+
+ //! A clas for allocation the bits to each and every types of frames in a GOP
+ class RateController
+ {
+ public:
+
+ //! Default constructor
+ RateController(int trate, SourceParams& srcp, EncoderParams& encp);
+
+
+ //! Calculate the Quality factor of the next frame to encode
+ void CalcNextQualFactor(const PictureParams& fparams, int num_bits);
+
+ //! Calculate the Quality factor of the next I frame to encode
+ void CalcNextIntraQualFactor();
+
+ //! Use the long-term average intra quality factor
+ void SetCutPictureQualFactor();
+
+ //! Return I frame qf
+ double IntraQualFactor() {return m_I_qf;}
+
+ //! Return qf
+ double QualFactor() {return m_qf;}
+
+ //! Report the allocation to picture types
+ void Report();
+
+
+ private:
+
+ double TargetSubgroupRate();
+
+ double ProjectedSubgroupRate();
+
+ //! Allocate the bits to each type of frame in a GOP
+ void Allocate(const int fnum);
+
+ //! Calculate the total number of bits in a GOP
+ void CalcTotalBits(const SourceParams& sourceparams);
+
+ //! Set the value of Current IQF
+ void SetIntraQualFactor(double value){m_I_qf = value;}
+
+ //! Set the number of I, L1 and L2 frames in the GOP
+ void SetFrameDistribution();
+
+ //! Review the quality factor to make sure it's being set sensibly
+ float ReviewQualityFactor( const float qfac, const long int num_bits );
+
+ //! Clip the quality factor to something sensible
+ float ClipQualityFactor( const float qfac );
+
+ //! Update the internal decoder buffer model
+ void UpdateBuffer( const long int num_bits );
+
+
+ private:
+
+ //! Current Quality Factor
+ double m_qf;
+
+ //! I frame Quality Factor
+ double m_I_qf;
+
+ //! Long-term average of I frame Quality Factor
+ double m_I_qf_long_term;
+
+ //! Target bit rate in kbps
+ const int m_target_rate;
+
+ //! Number of bits for I frame
+ long int m_Iframe_bits;
+
+ //! Number of bits for L1 frame
+ long int m_L1frame_bits;
+
+ //! Number of bits for L2 frame
+ long int m_L2frame_bits;
+
+ //! Number of I frames
+ int m_num_Iframe;
+
+ //! Number of L1 frames
+ int m_num_L1frame;
+
+ //! Number of L2 frames
+ int m_num_L2frame;
+
+ //! Total Number of bits in a GOP
+ long int m_total_GOP_bits;
+
+ //! Mean number of bits in a picture
+ long int m_picture_bits;
+
+ //! Size of the decoded bit buffer
+ const long int m_buffer_size;
+
+ //! Number of bits in the buffer
+ long int m_buffer_bits;
+
+ //! The old buffer occupancy
+ long int m_old_buffer_bits;
+
+ //! The rate of change of buffer occupancy
+ double m_buffer_rate_of_change;
+
+ //! The target number of bits for the current GOP
+ long int m_GOP_target;
+
+ //! The duration of a GOP
+ double m_GOP_duration;
+
+ //! A reference to the encoder parameters
+ EncoderParams& m_encparams;
+
+ //! A class to hold the frame complexity object
+ FrameComplexity m_frame_complexity;
+
+ //! A frame counter, giving the position within a subgroup
+ int m_fcount;
+
+ // Indicated whether a sequence is being coded intra only or not
+ bool m_intra_only;
+
+ // Sum of complexity of L2 frames
+ int m_L2_complexity_sum;
+
+ };
+
+
+}// namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.cpp
new file mode 100644
index 000000000..da4f73b2b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.cpp
@@ -0,0 +1,892 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: seq_compress.cpp,v 1.87 2008/10/29 02:42:06 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju,
+* Andrew Kennedy
+* Myo Tun (Brunel University, myo.tun@brunel.ac.uk)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_encoder/seq_compress.h>
+#include <libdirac_encoder/prefilter.h>
+
+using namespace dirac;
+
+SequenceCompressor::SequenceCompressor( StreamPicInput* pin ,
+ EncoderParams& encp,
+ DiracByteStream& dirac_byte_stream):
+ m_all_done(false),
+ m_just_finished(true),
+ m_srcparams(pin->GetSourceParams()),
+ m_encparams(encp),
+ m_predparams(encp.GetPicPredParams()),
+ m_L1_sep(encp.L1Sep()),
+ m_pparams(m_srcparams.CFormat(),
+ m_encparams.Xl(),
+ m_encparams.Yl(),
+ m_encparams.LumaDepth(),
+ m_encparams.ChromaDepth() ),
+ m_pic_in(pin),
+ m_current_display_pnum(-1),
+ m_current_code_pnum(0),
+ m_show_pnum(-1),m_last_picture_read(-1),
+ m_gop_start_num(0),
+ m_delay(1),
+ m_qmonitor( m_encparams ),
+ m_pcoder( m_encparams ),
+ m_dirac_byte_stream(dirac_byte_stream),
+ m_eos_signalled(false)
+{
+ // Set up the compression of the sequence
+
+ //TBD: put into the constructor for EncoderParams
+ m_encparams.SetEntropyFactors( new EntropyCorrector(m_encparams.TransformDepth()) );
+
+ // Set up generic picture parameters
+ m_pparams.SetUsingAC(m_encparams.UsingAC() );
+
+ // Set up a rate controller if rate control being used
+ if (m_encparams.TargetRate() != 0)
+ m_ratecontrol = new RateController(m_encparams.TargetRate(),
+ m_pic_in->GetSourceParams(), encp);
+
+ // Copy in the block parameters in case we want to change them dynamically
+ m_basic_olb_params2 = &m_predparams.LumaBParams(2);
+ m_basic_olb_params1 = new OLBParams( 2*m_predparams.LumaBParams(2).Xblen(),
+ 2*m_predparams.LumaBParams(2).Yblen(),
+ 2*m_predparams.LumaBParams(2).Xbsep(),
+ 2*m_predparams.LumaBParams(2).Ybsep() );
+
+ m_basic_olb_params0 = new OLBParams( 4*m_predparams.LumaBParams(2).Xblen(),
+ 4*m_predparams.LumaBParams(2).Yblen(),
+ 4*m_predparams.LumaBParams(2).Xbsep(),
+ 4*m_predparams.LumaBParams(2).Ybsep() );
+
+
+ m_intra_olbp = new OLBParams( 2*m_basic_olb_params2->Xbsep() ,
+ 2*m_basic_olb_params2->Ybsep() ,
+ m_basic_olb_params2->Xbsep() ,
+ m_basic_olb_params2->Ybsep() );
+
+ SetMotionParameters();
+
+}
+
+void SequenceCompressor::SetMotionParameters(){
+
+ if ( m_encparams.TargetRate() != 0 ){
+ OLBParams new_olb_params = *m_basic_olb_params2;
+
+ if (m_encparams.Qf()<2.5)
+ new_olb_params = *m_basic_olb_params1;
+ else if (m_encparams.Qf()<1.5)
+ new_olb_params = *m_basic_olb_params0;
+
+ m_predparams.SetBlockSizes( new_olb_params , m_srcparams.CFormat() );
+
+ }
+
+ int xl = m_encparams.Xl();
+ int yl = m_encparams.Yl();
+
+ // Make sure we have enough macroblocks to cover the pictures
+ m_predparams.SetXNumSB( (xl+m_predparams.LumaBParams(0).Xbsep()-1)/
+ m_predparams.LumaBParams(0).Xbsep() );
+ m_predparams.SetYNumSB( (yl+m_predparams.LumaBParams(0).Ybsep()-1)/
+ m_predparams.LumaBParams(0).Ybsep() );
+
+ m_predparams.SetXNumBlocks( 4 * m_predparams.XNumSB() );
+ m_predparams.SetYNumBlocks( 4 * m_predparams.YNumSB() );
+}
+
+
+SequenceCompressor::~SequenceCompressor()
+{
+ delete m_intra_olbp;
+ delete m_basic_olb_params1;
+ delete m_basic_olb_params0;
+
+ if ( m_encparams.Verbose())
+ MakeSequenceReport();
+
+ //TBD: put into the destructor for EncoderParams
+ delete &m_encparams.EntropyFactors();
+
+ if (m_encparams.TargetRate()!=0)
+ delete m_ratecontrol;
+}
+
+bool SequenceCompressor::CanEncode()
+{
+ const int queue_size = std::max( 4 , 2*m_encparams.L1Sep() );
+
+ if (m_eos_signalled)
+ {
+ if (m_encparams.NumL1() > 0)
+ {
+ /*
+ * Long-GOP sequence
+ */
+ int field_factor = m_encparams.PictureCodingMode() ? 2 : 1;
+ int last_frame_read = m_last_picture_read/field_factor;
+ int current_code_fnum = m_current_code_pnum/field_factor;
+
+ if ((last_frame_read >= (current_code_fnum + (last_frame_read%m_encparams.L1Sep()))))
+ return true;
+
+ /*
+ * Encode the remaining picture in the frame buffer. We check if
+ * the reference pictures are available and modify the picture sort
+ * accordingly.
+ */
+ if (current_code_fnum <= last_frame_read)
+ {
+ m_current_display_pnum = m_current_code_pnum;
+ return true;
+ }
+ }
+ else
+ {
+ if (m_last_picture_read >= m_current_display_pnum)
+ return true;
+ }
+ }
+ else
+ {
+ if (m_last_picture_read >= m_current_display_pnum + queue_size)
+ return true;
+ }
+ return false;
+}
+
+const EncPicture* SequenceCompressor::CompressNextPicture()
+{
+
+ // This function codes the next picture in coding order and returns the next picture in display order
+ // In general these will differ, and because of re-ordering there is a m_delay which needs to be imposed.
+ // This creates problems at the start and at the end of the sequence which must be dealt with.
+ // At the start we just keep outputting picture 0. At the end you will need to loop for longer to get all
+ // the pictures out. It's up to the calling function to do something with the decoded pictures as they
+ // come out - write them to screen or to file, or whatever.
+
+ // current_pnum is the number of the current picture being coded in display order
+ // m_current_code_pnum is the number of the current picture in coding order. This function increments
+ // m_current_code_pnum by 1 each time and works out what the number is in display order.
+ // m_show_pnum is the index of the picture number that can be shown when current_pnum has been coded.
+ // Var m_delay is the m_delay caused by reordering (as distinct from buffering)
+
+ TESTM (m_last_picture_read >= 0, "Data loaded before calling CompressNextPicture");
+
+ const int field_factor = m_encparams.FieldCoding() ? 2 : 1;
+
+ // If we have a scheduled P picture, reset the P separation to normal
+ if ( m_encparams.L1Sep()!=m_L1_sep ){
+ if ( (m_current_code_pnum-field_factor) % (m_encparams.L1Sep()*field_factor)==0 )
+ m_L1_sep = m_encparams.L1Sep();
+ }
+
+ m_current_display_pnum = CodedToDisplay( m_current_code_pnum );
+ m_show_pnum = std::max( m_current_code_pnum - m_delay , 0 );
+
+ if ( CanEncode() )
+ {
+
+ // Compress the picture//
+ ///////////////////////
+
+ const std::vector<int>& queue_members = m_enc_pbuffer.Members();
+
+ EncPicture* current_pic = &m_enc_pbuffer.GetPicture( m_current_display_pnum );
+ PictureParams* current_pp = &current_pic->GetPparams();
+
+ // 1. Set the picture type and refs for all the pictures in the queue not already encoded
+ for (size_t i=0; i<queue_members.size(); ++i){
+ int pnum = queue_members[i];
+ EncPicture& enc_pic = m_enc_pbuffer.GetPicture(pnum);
+
+ if ( (enc_pic.GetStatus() & DONE_SET_PTYPE) == 0 ){
+ PictureParams& pparams = enc_pic.GetPparams();
+ // only look one subgroup ahead
+ if ((m_encparams.NumL1() == 0) || pparams.PictureNum() < m_current_display_pnum + m_encparams.L1Sep() ){
+ SetPicTypeAndRefs( pparams );
+ enc_pic.UpdateStatus( DONE_SET_PTYPE );
+ }
+ }
+ }
+
+ /* Do motion estimation and compensation if inter*/
+ bool is_a_cut( false );
+
+ //2. Set up block sizes etc
+ SetMotionParameters();
+
+ // Loop over the whole queue and ...
+ for (size_t i=0; i<queue_members.size(); ++i){
+ int pnum = queue_members[i];
+ EncPicture& enc_pic = m_enc_pbuffer.GetPicture(pnum);
+
+ if ( ( enc_pic.GetStatus() & DONE_SET_PTYPE) != 0 ){
+ PictureParams& pparams = enc_pic.GetPparams();
+
+ if ( pparams.PicSort().IsInter() ){
+ // 3.Initialise motion data
+ if ( ( enc_pic.GetStatus() & DONE_ME_INIT) == 0 ){
+ enc_pic.InitMEData( m_predparams , pparams.NumRefs() );
+ enc_pic.UpdateStatus( DONE_ME_INIT );
+ }
+
+ // 4. Do pixel-accurate motion estimation
+ if ( ( enc_pic.GetStatus() & DONE_PEL_ME) == 0 ){
+ m_pcoder.PixelME( m_enc_pbuffer, pnum );
+ enc_pic.UpdateStatus( DONE_PEL_ME );
+ }
+
+// // 5. Set picture complexity
+// if ( (enc_pic.GetStatus() & DONE_PIC_COMPLEXITY ) == 0 ){
+// m_pcoder.CalcComplexity( m_enc_pbuffer, pnum, m_predparams.LumaBParams(2) );
+// enc_pic.UpdateStatus( DONE_PIC_COMPLEXITY );
+// }
+
+ //6. Revise the number of references if one ref is a bad predictor
+// if ( (enc_pic.GetStatus() & DONE_PIC_COMPLEXITY)!=0 &&
+// pparams.NumRefs()==2){
+// if (enc_pic.GetPredBias()>0.8)
+// enc_pic.DropRef(2);
+// else if(enc_pic.GetPredBias()<0.2)
+// enc_pic.DropRef(1);
+// }
+ }
+ }
+
+ }
+ if ( current_pp->PicSort().IsInter() ){
+// // 7. Normalise complexity for the current picture
+// m_pcoder.NormaliseComplexity( m_enc_pbuffer, m_current_display_pnum );
+
+ bool subgroup_reconfig;
+
+ do{
+ subgroup_reconfig = false;
+
+ //8. Do subpel refinement
+ m_pcoder.SubPixelME( m_enc_pbuffer, m_current_display_pnum );
+
+ //9. Do mode decision
+ m_pcoder.ModeDecisionME( m_enc_pbuffer, m_current_display_pnum );
+
+ //10. Work out how many blocks are intra
+ m_pcoder.IntraModeAnalyse( m_enc_pbuffer, m_current_display_pnum );
+
+ //11. Change the GOP structure to PPP if there are too many intras
+ if ( m_L1_sep>1 && current_pic->GetMEData().IntraBlockRatio()>0.25
+ && (m_current_display_pnum % (m_encparams.L1Sep()*field_factor))==0){
+
+ subgroup_reconfig = true;
+
+ m_L1_sep = 1;
+ for (int i = 0; i<field_factor*m_encparams.L1Sep(); ++i){
+
+ int pnum = m_current_display_pnum-i+(field_factor-1);
+
+ EncPicture& enc_pic = m_enc_pbuffer.GetPicture(pnum);
+ PictureParams& pparams = enc_pic.GetPparams();
+
+ SetPicTypeAndRefs( pparams );
+ enc_pic.UpdateStatus( DONE_SET_PTYPE );
+ }
+ current_pic->SetStatus( DONE_SET_PTYPE );
+
+ // Current picture to code has now changed: recalculate
+ m_current_display_pnum = CodedToDisplay( m_current_code_pnum );
+ current_pic = &m_enc_pbuffer.GetPicture(m_current_display_pnum );
+ current_pp = &current_pic->GetPparams();
+
+ }
+
+ }while(subgroup_reconfig==true);
+
+ //11. Do cut detection and insert intra pictures
+ if ( current_pic->GetMEData().IntraBlockRatio()>0.3333 ){
+ is_a_cut = true;
+ if ( m_encparams.L1Sep()>1 &&
+ (m_current_display_pnum % (field_factor*m_encparams.L1Sep())) == 0){
+ m_gop_start_num = current_pp->PictureNum();//restart the GOP
+ }
+
+ if ( current_pp->PicSort().IsRef() ) // Set the picture type to intra
+ current_pic->SetPictureSort (PictureSort::IntraRefPictureSort());
+ else
+ current_pic->SetPictureSort (PictureSort::IntraNonRefPictureSort());
+
+ if ( m_encparams.Verbose() )
+ std::cout<<std::endl<<"Cut detected and I-picture inserted!";
+
+ }
+ else{
+ //12. Do motion compensation if not a cut
+// MEData& me_data = current_pic->GetMEData();
+//
+// if (me_data.IntraBlockRatio()>0.1)//FIXME: this is broken with adaptive block sizes
+// m_predparams.SetBlockSizes(*m_intra_olbp, m_srcparams.CFormat() );
+
+ m_pcoder.MotionCompensate(m_enc_pbuffer, m_current_display_pnum, SUBTRACT );
+ current_pic->UpdateStatus( DONE_MC );
+ }
+
+ }
+
+ if ( current_pp->PicSort().IsRef()==true )
+ m_enc_pbuffer.SetRetiredPictureNum( m_show_pnum, m_current_display_pnum );
+
+ // 12. Now code the residual data and motion data
+ if (m_encparams.TargetRate() != 0)
+ UpdateIntraPicCBRModel( *current_pp, is_a_cut );
+
+ // 13. Write a sequence header if necessary
+ if( (m_encparams.NumL1() > 0 && current_pp->PicSort().IsRef()==true &&
+ current_pp->PicSort().IsIntra()==true && (m_current_display_pnum % m_encparams.L1Sep() == 0)) ||
+ (m_encparams.NumL1() == 0 && (m_current_display_pnum % m_encparams.GOPLength())==0))
+ {
+ if (m_encparams.Verbose())
+ {
+ std::cout<<std::endl<<std::endl<<"GOP start: writing sequence header before picture ";
+ std::cout<<m_current_display_pnum;
+ }
+ SequenceHeaderByteIO *p_seqheader_byteio = new SequenceHeaderByteIO
+ ( m_pic_in->GetSourceParams(),
+ m_encparams);
+ p_seqheader_byteio->Output();
+
+ m_dirac_byte_stream.AddSequenceHeader(p_seqheader_byteio);
+ }
+
+ // 13. Write the picture header.
+ PictureByteIO* p_picture_byteio = new PictureByteIO(*current_pp, m_current_display_pnum );
+ p_picture_byteio->Output();
+
+ if ( m_encparams.Verbose() ){
+ if (m_encparams.TargetRate()!=0 )
+ m_ratecontrol->Report();
+
+ if (m_encparams.FieldCoding())
+ std::cout<<std::endl<<std::endl<<"Compressing field "<<m_current_code_pnum<<", ";
+ else
+ std::cout<<std::endl<<std::endl<<"Compressing frame "<<m_current_code_pnum<<", ";
+ std::cout<<m_current_display_pnum<<" in display order";
+
+ if (is_a_cut==true || current_pp->PicSort().IsIntra()==false )
+ std::cout<<std::endl<<current_pic->GetMEData().IntraBlockRatio()*100.0<<"% of blocks are intra ";
+ if (is_a_cut==true)
+ std::cout<<std::endl<<"Cut detected and intra picture inserted.";
+
+ std::cout<<std::endl<<"Picture type is ";
+ if (current_pp->PicSort().IsRef() )
+ std::cout<<"REF";
+ else std::cout<<"NON-REF";
+
+ std::cout<<" , ";
+ if (current_pp->PicSort().IsIntra())
+ std::cout<<"INTRA";
+ else std::cout<<"INTER";
+
+ if ( current_pp->PicSort().IsInter() ){
+ std::cout<<std::endl<<"References "
+ << (m_encparams.FieldCoding() ? "field " : "frame ")
+ << current_pp->Refs()[0];
+ if (current_pp->Refs().size() > 1)
+ std::cout<<" and "<< current_pp->Refs()[1];
+ }
+ }
+
+ // 14. Code the motion vectors
+ if ( current_pp->PicSort().IsInter() )
+ m_pcoder.CodeMVData(m_enc_pbuffer , m_current_display_pnum, p_picture_byteio);
+
+ // 15. Do prefiltering on the residue if necessary
+ if (m_encparams.Prefilter() != NO_PF )
+ m_pcoder.Prefilter( m_enc_pbuffer, m_current_display_pnum );
+
+ // 16. Do the transform on the 3 components
+ m_pcoder.DoDWT( m_enc_pbuffer, m_current_display_pnum , FORWARD);
+
+ // 17. Select the quantisers
+
+ // 18. Code the residue
+ m_pcoder.CodeResidue(m_enc_pbuffer , m_current_display_pnum, p_picture_byteio);
+
+ const PictureSort& psort = current_pp->PicSort();
+
+ /* All coding is done - so output and reconstruct */
+
+ m_dirac_byte_stream.AddPicture(p_picture_byteio);
+
+ // 19. Do the inverse DWT if necessary
+ m_pcoder.DoDWT( m_enc_pbuffer, m_current_display_pnum , BACKWARD);
+
+
+ // 20. Motion compensate back if necessary
+ if (psort.IsInter() && !is_a_cut )
+ m_pcoder.MotionCompensate(m_enc_pbuffer, m_current_display_pnum, ADD );
+
+ // Reset block sizes for next picture
+ m_predparams.SetBlockSizes(*m_basic_olb_params2, m_srcparams.CFormat() );
+
+ // 21. Clip the data to keep it in range
+ current_pic->Clip();
+
+ // Use the results of encoding to update the CBR model
+ if (m_encparams.TargetRate() != 0 )
+ UpdateCBRModel(*current_pic, p_picture_byteio);
+
+ // 22. Measure the encoded picture quality
+ if ( m_encparams.LocalDecode() )
+ m_qmonitor.UpdateModel( *current_pic );
+
+ // Increment our position
+ m_current_code_pnum++;
+
+ CleanBuffers();
+
+ current_pic->SetStatus( ALL_ENC );
+
+ }
+
+ // Return the latest picture that can be shown
+ if ( m_enc_pbuffer.GetPicture(m_show_pnum).GetStatus() == ALL_ENC ){
+ if ( m_encparams.Verbose() ){
+ std::cout<<std::endl<<"Return " <<
+ (m_encparams.FieldCoding() ? "field " : "frame ") <<
+ m_show_pnum << " in display order";
+ }
+ return &m_enc_pbuffer.GetPicture(m_show_pnum );
+ }
+ else
+ return NULL;
+}
+
+
+
+void SequenceCompressor::CleanBuffers()
+{
+ // If we're not at the beginning, clean the buffer
+ if ( m_current_code_pnum != 0 )
+ m_enc_pbuffer.CleanRetired( m_show_pnum, m_current_display_pnum );
+}
+
+const EncPicture *SequenceCompressor::GetPictureEncoded()
+{
+ if (m_current_display_pnum >= 0)
+ return &m_enc_pbuffer.GetPicture( m_current_display_pnum );
+
+ return 0;
+}
+
+DiracByteStats SequenceCompressor::EndSequence()
+{
+ DiracByteStats seq_stats;
+
+ if (m_just_finished)
+ {
+ seq_stats=m_dirac_byte_stream.EndSequence();
+ m_just_finished = false;
+ m_all_done = true;
+ }
+
+ return seq_stats;
+}
+
+
+
+void SequenceCompressor::MakeSequenceReport()
+{
+ if ( m_encparams.LocalDecode() )
+ m_qmonitor.WriteLog();
+
+ std::cout<<std::endl;
+
+}
+
+void SequenceCompressor::UpdateIntraPicCBRModel( const PictureParams& pparams, const bool is_a_cut ){
+ // For intra pictures we want to update before coding
+ // especially if they're inserted
+
+ if ( pparams.PicSort().IsIntra() && m_current_display_pnum > 0 &&
+ m_encparams.NumL1() != 0){
+ // Calculate the new QF for encoding the following I picture
+ if ( is_a_cut )
+ m_ratecontrol->SetCutPictureQualFactor();
+ else
+ m_ratecontrol->CalcNextIntraQualFactor();
+ }
+}
+
+FrameSequenceCompressor::FrameSequenceCompressor(
+ StreamPicInput* pin ,
+ EncoderParams& encp,
+ DiracByteStream& dirac_byte_stream):
+ SequenceCompressor(pin, encp, dirac_byte_stream)
+{
+}
+
+void FrameSequenceCompressor::SetPicTypeAndRefs( PictureParams& pparams )
+{
+ // Set the temporal prediction parameters for frame coding
+
+ const int pnum = pparams.PictureNum();
+ const int rel_pnum = pnum - m_gop_start_num;
+ const int gop_len = m_encparams.GOPLength();
+ const int num_L1 = m_encparams.NumL1();
+
+ pparams.SetRetiredPictureNum( -1 );
+ pparams.Refs().clear();
+
+ if ( num_L1>0 ){
+
+ if ( rel_pnum % gop_len == 0){
+ if (gop_len > 1)
+ pparams.SetPicSort( PictureSort::IntraRefPictureSort());
+ else // I-picture only coding
+ pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
+
+ // I picture expires after we've coded the next I picture
+ pparams.SetExpiryTime( 2*m_L1_sep );
+ }
+ else if (rel_pnum % m_L1_sep == 0){
+ pparams.SetPicSort( PictureSort::InterRefPictureSort());
+
+ // Ref the previous I or L1 picture
+ pparams.Refs().push_back( pnum - m_L1_sep );
+
+ // if we don't have the first L1 picture ...
+ if ( ((rel_pnum-m_L1_sep) % gop_len>0) && m_L1_sep>1)
+ // ... other ref is the prior I/L1 picture but one
+ pparams.Refs().push_back( pnum - 2*m_L1_sep );
+
+ // Expires after the next L1 or I picture
+ pparams.SetExpiryTime( 2*m_L1_sep );
+ if (rel_pnum % m_encparams.L1Sep() == 0 )
+ pparams.SetExpiryTime(2*m_encparams.L1Sep());
+ }
+ else if ((rel_pnum+1) % m_L1_sep == 0){
+ pparams.SetPicSort( PictureSort::InterNonRefPictureSort());
+
+ // .. and the previous picture
+ pparams.Refs().push_back(pnum-1);
+ // Refs are the next I or L1 picture ...
+ if (m_enc_pbuffer.IsPictureAvail(pnum+1))
+ pparams.Refs().push_back(pnum+1);
+
+ pparams.SetExpiryTime( 1 );
+ }
+ else{
+ pparams.SetPicSort( PictureSort::InterRefPictureSort());
+
+ // .. and the previous picture
+ pparams.Refs().push_back(pnum-1);
+ // Refs are the next I or L1 picture ...
+ int next_ref = ((pnum/m_L1_sep)+1)*m_L1_sep;
+ if (m_enc_pbuffer.IsPictureAvail(next_ref))
+ pparams.Refs().push_back(next_ref);
+
+ pparams.SetExpiryTime( 2 );
+ }
+
+ }
+ else{
+ pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
+ pparams.SetExpiryTime( 1 );
+ }
+
+}
+
+bool FrameSequenceCompressor::LoadNextFrame()
+{
+ PictureParams pp( m_pparams );
+ pp.SetPictureNum( m_last_picture_read+1 );
+
+ // Set an initially huge expiry time as we don't know when it will expire yet
+ pp.SetExpiryTime(1<<30);
+
+ m_enc_pbuffer.PushPicture( pp );
+
+ m_pic_in->ReadNextPicture( m_enc_pbuffer.GetPicture(m_last_picture_read+1) );
+
+ // Copy into the original data
+ m_enc_pbuffer.GetPicture(m_last_picture_read+1).SetOrigData();
+
+ if ( m_encparams.Prefilter()==CWM )
+ CWMFilter(m_enc_pbuffer.GetPicture( m_last_picture_read+1 ) ,
+ m_encparams.PrefilterStrength() );
+
+ if ( m_pic_in->End() )
+ {
+ m_all_done = true;
+ return false;
+ }
+
+ m_last_picture_read++;
+
+ return true;
+}
+
+int FrameSequenceCompressor::CodedToDisplay( const int cnum )
+{
+ int div;
+
+ if (m_L1_sep>0)
+ {
+ // We have L1 and L2 pictures
+ if (cnum==0)
+ return 0;
+ else if ((cnum-1)% m_L1_sep==0)
+ {//we have L1 or subsequent I pictures
+ div=(cnum-1)/m_L1_sep;
+ return cnum+m_L1_sep-1;
+ }
+ else//we have L2 pictures
+ return cnum-1;
+ }
+ else
+ {//we just have I-pictures, so no re-ordering
+
+ return cnum;
+ }
+}
+
+void FrameSequenceCompressor::UpdateCBRModel(EncPicture& my_frame,
+ const PictureByteIO* p_picture_byteio)
+{
+ // Update the quality factor
+ m_ratecontrol->CalcNextQualFactor(my_frame.GetPparams(), p_picture_byteio->GetSize()*8);
+
+}
+
+
+FieldSequenceCompressor::FieldSequenceCompressor(
+ StreamPicInput* pin ,
+ EncoderParams& encp,
+ DiracByteStream& dirac_byte_stream):
+ SequenceCompressor(pin, encp, dirac_byte_stream)
+{
+ m_delay = 2;
+}
+
+bool FieldSequenceCompressor::LoadNextFrame()
+{
+ PictureParams pp( m_pparams );
+ pp.SetExpiryTime( 1<<30 );
+
+ int pnum = m_last_picture_read+1;
+
+ for (int j=pnum; j<=pnum+1; ++j){
+ pp.SetPictureNum( j );
+ m_enc_pbuffer.PushPicture( pp );
+ }
+
+ StreamFieldInput* field_input = (StreamFieldInput*) m_pic_in;
+ field_input->ReadNextFrame( m_enc_pbuffer.GetPicture( pnum ), m_enc_pbuffer.GetPicture(pnum+1) );
+
+ // Copy data across
+ for (int j=pnum; j<=pnum+1; ++j){
+ m_enc_pbuffer.GetPicture( j ).SetOrigData();
+
+ if ( m_encparams.Prefilter()==CWM )
+ CWMFilter(m_enc_pbuffer.GetPicture( j ), m_encparams.PrefilterStrength() );
+
+ }
+
+ if ( m_pic_in->End() ){
+ m_all_done = true;
+ return false;
+ }
+
+ m_last_picture_read +=2;
+
+ return true;
+}
+
+void FieldSequenceCompressor::PreMotionEstmationFilter(PicArray& comp)
+{
+ //Special case for first row
+ for (int i = comp.FirstX(); i <= comp.LastX(); ++i)
+ {
+ comp[comp.FirstY()][i] = (3*comp[comp.FirstY()][i] +
+ comp[comp.FirstY()+1][i] +2 )>>2;
+ }
+ //Middle section
+ for (int j = comp.FirstY()+1; j < comp.LastY(); ++j)
+ {
+ for (int i = comp.FirstX(); i <= comp.LastX(); ++i)
+ {
+ comp[j][i] = (comp[j-1][i] + 2*comp[j][i] + comp[j+1][i] + 2)>>2;
+ }
+ }
+ //Special case for last row
+ for (int i = comp.FirstX(); i <= comp.LastX(); ++i)
+ {
+ comp[comp.LastY()][i] = (comp[comp.LastY()-1][i] +
+ 3*comp[comp.LastY()][i] + 2)>>2;
+ }
+}
+
+void FieldSequenceCompressor::SetPicTypeAndRefs( PictureParams& pparams )
+{
+// FIXME: won't work with adaptive GOP properly
+ // Set the temporal prediction parameters for field coding
+
+ const int pnum = pparams.PictureNum();
+ const int rel_pnum = pparams.PictureNum()-m_gop_start_num;
+ const int gop_len = m_encparams.GOPLength();
+ const int num_L1 = m_encparams.NumL1();
+
+ pparams.SetRetiredPictureNum( -1 );
+ pparams.Refs().clear();
+
+ if ( num_L1>0 ){
+
+ if ( (rel_pnum/2) % gop_len == 0){
+ // Field 1 is Intra Field
+ if (gop_len > 1){
+ pparams.SetPicSort( PictureSort::IntraRefPictureSort());
+ // I picture expires after we've coded the next L1 picture
+ pparams.SetExpiryTime( gop_len * 2);
+ pparams.SetExpiryTime( 2*m_L1_sep );
+ if ( pnum%2){
+ pparams.SetPicSort( PictureSort::InterRefPictureSort());
+ // Ref the previous I field
+ pparams.Refs().push_back( pnum-1 );
+ }
+ }
+ else{
+ // I-picture only coding
+ pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
+ pparams.SetExpiryTime( gop_len );
+ }
+ }
+ else if ((rel_pnum/2) % m_L1_sep == 0){
+
+ pparams.SetPicSort( PictureSort::InterRefPictureSort());
+
+ if (pnum%2){
+ // Field 2
+ // Ref the first field of same picture
+ pparams.Refs().push_back( pnum - 1);
+ // Ref the previous field 2 of I or L1 picture
+ pparams.Refs().push_back( pnum - m_L1_sep*2 );
+ }
+ else{
+ // Field 1
+ // Ref the field 1 of previous I or L1 picture
+ pparams.Refs().push_back( pnum - m_L1_sep*2 );
+ // Ref the field 2 of previous I or L1 picture
+ pparams.Refs().push_back( pnum - m_L1_sep*2 + 1 );
+ }
+
+ // Expires after the next L1 or I picture
+ pparams.SetExpiryTime( (m_L1_sep+1)*2-1 );
+ if ((rel_pnum/2) % m_encparams.L1Sep() == 0 )
+ pparams.SetExpiryTime((2*m_encparams.L1Sep())+1*2-1);
+ }
+ else if ((rel_pnum/2+1) % m_L1_sep == 0){
+ // Bi-directional non-reference fields.
+ if (pnum%2)
+ pparams.SetPicSort( PictureSort::InterNonRefPictureSort());
+ else
+ pparams.SetPicSort( PictureSort::InterRefPictureSort());
+
+ pparams.Refs().push_back(pnum-1);
+ if (m_enc_pbuffer.IsPictureAvail(pnum+2))
+ pparams.Refs().push_back(pnum+2);
+
+ pparams.SetExpiryTime( 1 );
+ }
+ else{
+ // Bi-directional reference fields.
+ pparams.SetPicSort( PictureSort::InterRefPictureSort());
+
+ pparams.Refs().push_back(pnum-1);
+ int next_ref = (((pnum/2)/m_L1_sep+1)*m_L1_sep)*2+(pnum%2);
+ if (m_enc_pbuffer.IsPictureAvail(next_ref))
+ pparams.Refs().push_back(next_ref);
+ pparams.SetExpiryTime( 4 );
+ }
+
+ }
+ else{
+ pparams.SetPicSort( PictureSort::IntraNonRefPictureSort());
+ pparams.SetExpiryTime( 2 );
+ }
+}
+
+FieldSequenceCompressor::~FieldSequenceCompressor()
+{
+}
+
+int FieldSequenceCompressor::CodedToDisplay( const int pnum )
+{
+ // Frame the field pnum belongs to
+ int fnum = pnum>>1;
+ if (m_L1_sep>0)
+ {
+ // We have L1 and L2 frames
+ if (fnum==0)
+ return pnum;
+ else if ((fnum-1)% m_L1_sep==0)
+ {//we have L1 or subsequent I frames
+ return (pnum+(m_L1_sep-1)*2);
+ }
+ else//we have L2 frames
+ return (pnum - 2);
+ }
+ else
+ {//we just have I-frames, so no re-ordering
+ return (pnum);
+ }
+}
+
+void FieldSequenceCompressor::UpdateCBRModel(EncPicture& my_picture,
+ const PictureByteIO* p_picture_byteio)
+{
+ if (m_current_display_pnum%2 == 0)
+ m_field1_bytes = p_picture_byteio->GetSize();
+ else
+ m_field2_bytes = p_picture_byteio->GetSize();
+
+ // Update the quality factor
+ if (my_picture.GetPparams().PictureNum()%2)
+ m_ratecontrol->CalcNextQualFactor(my_picture.GetPparams(), (m_field1_bytes+m_field2_bytes)*8);
+
+}
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.h
new file mode 100644
index 000000000..37f5496be
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_encoder/seq_compress.h
@@ -0,0 +1,387 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: seq_compress.h,v 1.33 2008/10/20 04:20:12 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Scott R Ladd,
+* Anuradha Suraparaju
+* Andrew Kennedy
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _SEQ_COMPRESS_H_
+#define _SEQ_COMPRESS_H_
+
+/////////////////////////////////////////
+//-------------------------------------//
+//Class to manage compressing sequences//
+//-------------------------------------//
+/////////////////////////////////////////
+
+#include <libdirac_byteio/dirac_byte_stream.h>
+#include <libdirac_common/common.h>
+#include <libdirac_encoder/enc_queue.h>
+#include <libdirac_common/pic_io.h>
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_encoder/quality_monitor.h>
+#include <libdirac_encoder/picture_compress.h>
+#include <libdirac_encoder/rate_control.h>
+
+#include <fstream>
+
+namespace dirac
+{
+
+ //! Compresses a sequence of frames/fields from a stream.
+ /*!
+ This class compresses a sequence of frames/fields, frame by frame.
+ or field by field. It currently uses GOP parameters set in the encoder
+ parameters in order to define the temporal prediction structure.
+ A version to incorporate non-GOP structures is TBC.
+
+ This is an abstract class.
+ */
+ class SequenceCompressor{
+ public:
+ //! Constructor
+ /*!
+ Creates a sequence compressor, and prepares to begin compressing
+ with the first picture.Sets up picture padding in the picture input if
+ necesary
+ \param pin an input stream containing a sequence of frames
+ \param encp parameters for the encoding process
+ \param dirac_byte_stream Output destination for compressed data
+ */
+ SequenceCompressor(StreamPicInput* pin,
+ EncoderParams& encp,
+ DiracByteStream& dirac_byte_stream);
+
+ //! Destructor
+ /*!
+ Destructor. Must delete IO objects created by constructor.
+ */
+ virtual ~SequenceCompressor();
+
+ //! Load data
+ /*!
+ Load one picture of data into the Sequence Compressor. Sets
+ m_all_done to true if no more data is available to be loaded.
+ Input can be frame or field. So the child class will have to
+ implement this function.
+ \return true - if frame load succeeded.
+ false - otherwise
+ */
+ virtual bool LoadNextFrame() = 0;
+
+ //! Compress the next picture in sequence
+ /*!
+ This function codes the next picture in coding order and returns the
+ next picture in display order. In general these will differ, and
+ because of re-ordering there is a delay which needs to be imposed.
+ This creates problems at the start and at the end of the sequence
+ which must be dealt with. At the start we just keep outputting
+ picture 0. At the end you will need to loop for longer to get all
+ the pictures out. It's up to the calling function to do something
+ with the decoded pictures as they come out -- write them to screen
+ or to file, for example. .
+ If coding is fast enough the compressed version could be watched
+ real-time (with suitable buffering in the calling function to
+ account for encode-time variations).
+
+ NOTE: LoadNextFrame must be called atleast once before invoking this
+ method.
+
+ \return pointer to the next locally decoded picture available for display
+ */
+ const EncPicture *CompressNextPicture();
+
+ //! Set up the appropriate prediction parameters for a picture
+ virtual void SetPicTypeAndRefs( PictureParams& pparams ) = 0;
+
+ //! Return a pointer to the most recent picture encoded
+ const EncPicture *GetPictureEncoded();
+
+ DiracByteStats EndSequence();
+
+ //! Determine if compression is complete.
+ /*!
+ Indicates whether or not the last picture in the sequence has been
+ compressed.
+ \return true if last picture has been compressed; false if not
+ */
+ bool Finished(){return m_all_done;}
+
+ //! Signal end of sequence
+ void SignalEOS() { m_eos_signalled = true; }
+
+ //! The delay required for correct timestamps
+ int PTSOffset(){return m_delay;}
+
+ protected:
+
+ //! Set up the motion block parameters
+ void SetMotionParameters();
+
+ //! Uses the GOP parameters to convert picture numbers in coded order to display order.
+ /*!
+ Uses the GOP parameters to convert picture numbers in coded order
+ to display order. Pure virtual function. The child class will
+ have to define it.
+ \param pnum the picture number in coded order
+ */
+ virtual int CodedToDisplay(const int pnum) = 0;
+
+ //! Make a report to screen on the coding results for the whole sequence
+ void MakeSequenceReport();
+
+ //! Remove unwanted pictures from picture buffers
+ virtual void CleanBuffers();
+
+ //! Update the CBR model based on the data we've compressed.
+ //Purely virtual. The child class will have to define it.
+ virtual void UpdateCBRModel(EncPicture& my_picture, const PictureByteIO* picture_byteio) = 0;
+
+ //! Update the parameters to be used in advance of coding an intra frame
+ void UpdateIntraPicCBRModel( const PictureParams& , const bool is_a_cut );
+
+ //! Returns true if the encoder can encode a picture
+ bool CanEncode();
+
+ //! Completion flag, returned via the Finished method.
+ bool m_all_done;
+
+ //! Flag indicating whether we've just finished.
+ /*!
+ Flag which is false if we've been all-done for more than one
+ picture, true otherwise (so that we can take actions on finishing
+ once only).
+ */
+ bool m_just_finished;
+
+ //! A class to hold the basic block parameters
+ OLBParams* m_basic_olb_params0;
+
+ //! A class to hold the basic block parameters
+ OLBParams* m_basic_olb_params1;
+
+ //! A class to hold the basic block parameters
+ const OLBParams* m_basic_olb_params2;
+
+ //! A class to hold block parameters to use when there are lots of intra blocks
+ OLBParams* m_intra_olbp;
+
+ //! The parameters of the input source
+ SourceParams& m_srcparams;
+
+ //! The parameters used for encoding.
+ EncoderParams& m_encparams;
+
+ //! The parameters used for ME/MC
+ PicturePredParams& m_predparams;
+
+ //! The L1 separation currently in use
+ int m_L1_sep;
+
+ //! Generic picture parameters for initialising pictures
+ PictureParams m_pparams;
+
+ //! Pointer pointing at the picture input.
+ StreamPicInput* m_pic_in;
+
+ //! A picture buffer used for local storage of pictures whilst pending re-ordering or being used for reference.
+ EncQueue m_enc_pbuffer;
+
+ //state variables for CompressNextPicture
+
+ //! The number of the current picture to be coded, in display order
+ int m_current_display_pnum;
+
+ //! The number of the current picture to be coded, in coded order
+ int m_current_code_pnum;
+
+ //! The number of the picture which should be output for concurrent display or storage
+ int m_show_pnum;
+
+ //! The index, in display order, of the last picture read
+ int m_last_picture_read;
+
+ //! The picture number of the last GOP start
+ int m_gop_start_num;
+
+ //! A delay so that we don't display what we haven't coded
+ int m_delay;
+
+ //! A class for monitoring the quality of pictures and adjusting parameters appropriately
+ QualityMonitor m_qmonitor;
+
+ //! A class for monitoring and controlling bit rate
+ RateController* m_ratecontrol;
+
+ //! A class to hold the picture compressor object
+ PictureCompressor m_pcoder;
+
+ //! Output destination for compressed data in bitstream format
+ DiracByteStream& m_dirac_byte_stream;
+
+ //! Flag to check if End of Sequence has been signalled by the end user
+ bool m_eos_signalled;
+
+ private:
+ //! Copy constructor is private and body-less
+ /*!
+ Copy constructor is private and body-less. This class should not
+ be copied.
+ */
+ SequenceCompressor(const SequenceCompressor& cpy);
+
+ //! Assignment = is private and body-less
+ /*!
+ Assignment = is private and body-less. This class should not be
+ assigned..
+ */
+ SequenceCompressor& operator=(const SequenceCompressor& rhs);
+
+
+ };
+
+ //! Compresses a sequence of frames from a stream.
+ /*!
+ This class compresses a sequence of frames, frame by frame. It
+ currently uses GOP parameters set in the encoder parameters in order
+ to define the temporal prediction structure. A version to incorporate
+ non-GOP structures is TBC.
+ */
+ class FrameSequenceCompressor : public SequenceCompressor
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a sequence compressor that compresses frames i.e.
+ progressive data, and prepares to begin compressing
+ with the first frame.Sets up frame padding in the picture input if
+ necesary
+ \param pin an input stream containing a sequence of frames
+ \param encp parameters for the encoding process
+ \param dirac_byte_stream Output destination for compressed data
+ */
+ FrameSequenceCompressor(StreamPicInput* pin,
+ EncoderParams& encp,
+ DiracByteStream& dirac_byte_stream);
+
+ //! Destructor
+ /*!
+ Destructor. Must delete IO objects created by constructor.
+ */
+ virtual ~FrameSequenceCompressor(){};
+
+ //! Load data
+ /*!
+ Load one frame of data into the Sequence Compressor. Sets
+ m_all_done to true if no more data is available to be loaded.
+ \return true - if frame load succeeded.
+ false - otherwise
+ */
+ virtual bool LoadNextFrame();
+
+ //! Set up the appropriate prediction parameters for a picture
+ virtual void SetPicTypeAndRefs( PictureParams& pparams );
+
+protected:
+ virtual int CodedToDisplay(const int pnum);
+ virtual void UpdateCBRModel(EncPicture& my_picture, const PictureByteIO* picture_byteio);
+
+ };
+
+ //! Compresses a sequence of fields from a stream.
+ /*!
+ This class compresses a sequence of fields, field by field. It
+ currently uses GOP parameters set in the encoder parameters in order
+ to define the temporal prediction structure. A version to incorporate
+ non-GOP structures is TBC.
+ */
+ class FieldSequenceCompressor : public SequenceCompressor
+ {
+ public:
+ //! Constructor
+ /*!
+ Creates a sequence compressor that compresses fields i.e.
+ interlaced data, and prepares to begin compressing
+ with the first field.
+ \param pin an input stream containing a sequence of frames
+ \param encp parameters for the encoding process
+ \param dirac_byte_stream Output destination for compressed data
+ */
+ FieldSequenceCompressor(StreamPicInput* pin,
+ EncoderParams& encp,
+ DiracByteStream& dirac_byte_stream);
+
+ //! Destructor
+ /*!
+ Destructor. Must delete IO objects created by constructor.
+ */
+ virtual ~FieldSequenceCompressor();
+
+ //! Load data
+ /*!
+ Load one frame i.e. two fields of data into the Sequence
+ Compressor. Sets m_all_done to true if no more data is available
+ to be loaded.
+ \return true - if both fields load succeeded.
+ false - otherwise
+ */
+ virtual bool LoadNextFrame();
+
+
+ //! Set up the appropriate prediction parameters for a picture
+ virtual void SetPicTypeAndRefs( PictureParams& pparams );
+
+ protected:
+
+ virtual int CodedToDisplay(const int pnum);
+
+ virtual void UpdateCBRModel(EncPicture& my_picture, const PictureByteIO* picture_byteio);
+ private:
+ //! Filter fields
+ /*!
+ Low pass filter the components in the fields used in Motion
+ Estimation so that ME works better. Using a 1/4 1/2 1/4 filter
+ */
+ void PreMotionEstmationFilter (PicArray& comp);
+
+ // Field1 bytes
+ int m_field1_bytes;
+ // Field2 bytes
+ int m_field2_bytes;
+ };
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.cpp
new file mode 100644
index 000000000..bf5725c6e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.cpp
@@ -0,0 +1,469 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: block_match.cpp,v 1.21 2008/10/29 02:46:22 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_motionest/block_match.h>
+#include <libdirac_motionest/me_utils.h>
+using namespace dirac;
+
+#include <cmath>
+using std::vector;
+
+namespace dirac
+{
+
+void AddNewVlist( CandidateList& vect_list, const MVector& mv,
+ const int xr , const int yr , const int step )
+{
+ //Creates a new motion vector list in a square region around mv
+
+ vector<MVector> tmp_list;
+ vect_list.push_back(tmp_list);
+ int list_num=vect_list.size()-1;
+
+ MVector tmp_mv( mv );
+ AddVect(vect_list , tmp_mv , list_num );
+
+ for ( int i=1 ; i<=xr ; ++i )
+ {
+ tmp_mv.x = mv.x + i*step;
+ AddVect( vect_list , tmp_mv , list_num );
+
+ tmp_mv.x = mv.x - i*step;
+ AddVect( vect_list , tmp_mv , list_num );
+ }
+
+ for ( int j=1 ; j<=yr ; ++j)
+ {
+ for ( int i=-xr ; i<=xr ; ++i)
+ {
+ tmp_mv.x = mv.x + i*step;
+ tmp_mv.y = mv.y + j*step;
+ AddVect(vect_list,tmp_mv,list_num);
+
+ tmp_mv.y = mv.y -j*step;
+ AddVect(vect_list,tmp_mv,list_num);
+
+ }// i
+ }// j
+
+ // If we've not managed to add any element to the list
+ // remove the list so we don't ever have to check its size
+ if ( vect_list[list_num].size() == 0 )
+ vect_list.erase( vect_list.begin() + list_num );
+}
+
+void AddNewVlist( CandidateList& vect_list , const MVector& mv , const int xr , const int yr)
+{
+ // Creates a new motion vector list in a square region around mv
+
+ vector<MVector> tmp_list;
+ vect_list.push_back(tmp_list);
+ int list_num=vect_list.size()-1;
+
+ MVector tmp_mv(mv);
+ AddVect(vect_list,tmp_mv,list_num);
+
+ for ( int i=1 ; i<=xr ; ++i)
+ {
+ tmp_mv.x = mv.x + i;
+ AddVect( vect_list , tmp_mv , list_num );
+
+ tmp_mv.x = mv.x - i;
+ AddVect( vect_list , tmp_mv , list_num );
+ }
+
+ for ( int j=1 ; j<=yr ; ++j)
+ {
+ for ( int i=-xr ; i<=xr ; ++i)
+ {
+ tmp_mv.x = mv.x + i;
+ tmp_mv.y = mv.y + j;
+ AddVect( vect_list , tmp_mv , list_num );
+
+ tmp_mv.y = mv.y-j;
+ AddVect( vect_list , tmp_mv , list_num );
+ }
+ }
+
+ // If we've not managed to add any element to the list
+ // remove the list so we don't ever have to check its size
+ if ( vect_list[list_num].size() == 0 )
+ vect_list.erase( vect_list.begin() + list_num );
+}
+
+void AddNewVlistD( CandidateList& vect_list , const MVector& mv , const int xr , const int yr )
+{
+ //As above, but using a diamond pattern
+
+ vector<MVector> tmp_list;
+ vect_list.push_back( tmp_list );
+
+ int list_num=vect_list.size()-1;
+ int xlim;
+
+ MVector tmp_mv( mv );
+ AddVect( vect_list , tmp_mv , list_num );
+
+ for ( int i=1 ; i<=xr ; ++i)
+ {
+ tmp_mv.x = mv.x + i;
+ AddVect( vect_list , tmp_mv , list_num );
+
+ tmp_mv.x = mv.x - i;
+ AddVect( vect_list , tmp_mv , list_num );
+ }
+
+ for ( int j=1 ; j<=yr ; ++j)
+ {
+ xlim = xr * (yr-std::abs(j)) / yr;
+ for ( int i=-xlim ; i<=xlim ; ++i)
+ {
+ tmp_mv.x = mv.x + i;
+ tmp_mv.y = mv.y + j;
+ AddVect( vect_list , tmp_mv , list_num );
+
+ tmp_mv.y = mv.y - j;
+ AddVect( vect_list , tmp_mv , list_num );
+ }
+ }
+
+ // If we've not managed to add any element to the list
+ // remove the list so we don't ever have to check its size
+ if ( vect_list[list_num].size() == 0 )
+ vect_list.erase( vect_list.begin() + list_num );
+}
+
+void AddVect(CandidateList& vect_list,const MVector& mv,int list_num)
+{
+
+ bool is_in_list=false;
+
+ size_t lnum=0;
+ size_t i;
+
+ while( !is_in_list && lnum<vect_list.size() )
+ {
+ i=0;
+ while( !is_in_list && i<vect_list[lnum].size())
+ {
+ if ( vect_list[lnum][i].x == mv.x && vect_list[lnum][i].y == mv.y )
+ is_in_list=true;
+ ++i;
+ }
+ ++lnum;
+ }
+
+ if ( !is_in_list )
+ vect_list[list_num].push_back(mv);
+
+}
+
+BlockMatcher::BlockMatcher( const PicArray& pic_data ,
+ const PicArray& ref_data ,
+ const OLBParams& bparams ,
+ const int precision ,
+ const MvArray& mv_array ,
+ const TwoDArray< MvCostData >& cost_array):
+ m_pic_data(pic_data),
+ m_ref_data(ref_data),
+ m_mv_array(mv_array),
+ m_cost_array(cost_array),
+ m_peldiff( ref_data , pic_data ), //NB: ORDER!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ m_subpeldiff( 3 ),
+ m_bparams( bparams ),
+ m_var_max( (pic_data.LengthX()+pic_data.LengthY() )/216 ),
+ m_var_max_up( (pic_data.LengthX()+pic_data.LengthY() )/27 ),
+ m_precision( precision )
+{
+ m_subpeldiff[0] = new BlockDiffHalfPel( ref_data, pic_data );
+ m_subpeldiff[1] = new BlockDiffQuarterPel( ref_data, pic_data );
+ m_subpeldiff[2] = new BlockDiffEighthPel( ref_data, pic_data );
+}
+
+BlockMatcher::~BlockMatcher()
+{
+ for (int i=0; i<3; ++i )
+ delete m_subpeldiff[i];
+}
+
+
+ValueType BlockMatcher::GetVar( const MVector& predmv , const MVector& mv ) const
+{
+ MVector diff;
+ diff.x = mv.x-predmv.x;
+ diff.y = mv.y-predmv.y;
+
+ return Norm1( diff );
+}
+
+ValueType BlockMatcher::GetVarUp( const MVector& predmv , const MVector& mv ) const
+{
+ MVector diff;
+ diff.x = mv.x-predmv.x;
+ diff.y = mv.y-predmv.y;
+
+ return std::min( Norm1( diff ) , Norm1( mv ) );
+}
+
+void BlockMatcher::FindBestMatchPel(const int xpos , const int ypos ,
+ const CandidateList& cand_list,
+ const MVector& mv_prediction,
+ const int list_start)
+{
+ BlockDiffParams dparams;
+ dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos);
+
+ //now test against the offsets in the MV list to get the lowest cost//
+ //////////////////////////////////////////////////////////////////////
+
+ float best_cost = m_cost_array[ypos][xpos].total;
+
+ MVector best_mv = m_mv_array[ypos][xpos];
+
+ for ( size_t lnum=list_start ; lnum<cand_list.size() ; ++lnum)
+ {
+ for (size_t i=0 ; i<cand_list[lnum].size() ; ++i)
+ {
+ m_peldiff.Diff( dparams ,
+ cand_list[lnum][i] ,
+ best_cost ,
+ best_mv);
+ }// i
+ }// num
+
+ // Write the results in the arrays //
+ /////////////////////////////////////
+
+ m_mv_array[ypos][xpos] = best_mv;
+ m_cost_array[ypos][xpos].SAD = best_cost;
+ m_cost_array[ypos][xpos].mvcost = GetVar( mv_prediction , best_mv);
+ m_cost_array[ypos][xpos].SetTotal( 0.0 );
+}
+
+void BlockMatcher::FindBestMatchSubp( const int xpos, const int ypos,
+ const CandidateList& cand_list,
+ const MVector& mv_prediction,
+ const float lambda)
+{
+
+ BlockDiffParams dparams;
+ dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos);
+
+ //now test against the offsets in the MV list to get the lowest cost//
+ //////////////////////////////////////////////////////////////////////
+
+ // Numbers of the lists to do more searching in
+ vector<int> list_nums;
+
+ // Costs of the initial vectors in each list
+ OneDArray<float> list_costs( cand_list.size() );
+
+ // First test the first in each of the lists to choose which lists to pursue
+ MvCostData best_costs( m_cost_array[ypos][xpos] );
+ best_costs.total = 100000000.0f;
+ MVector best_mv( m_mv_array[ypos][xpos] );
+
+ MvCostData cand_costs;
+ MVector cand_mv;
+
+ for (size_t list_num=0 ; list_num<cand_list.size() ; ++list_num )
+ {
+ for (size_t i=0 ; i<cand_list[list_num].size() ; ++i )
+ {
+ cand_mv = cand_list[list_num][i];
+ cand_costs.mvcost = GetVarUp( mv_prediction , cand_mv );
+
+ m_subpeldiff[m_precision-1]->Diff( dparams,
+ cand_mv ,
+ cand_costs.mvcost,
+ lambda,
+ best_costs ,
+ best_mv);
+ }//
+ }// list_num
+
+
+ // Write the results in the arrays //
+ /////////////////////////////////////
+
+ m_mv_array[ypos][xpos] = best_mv;
+ m_cost_array[ypos][xpos] = best_costs;
+
+}
+void BlockMatcher::RefineMatchSubp(const int xpos, const int ypos,
+ const MVector& mv_prediction,
+ const float lambda)
+{
+
+ BlockDiffParams dparams;
+ dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos);
+
+ m_cost_array[ypos][xpos].mvcost = GetVarUp( mv_prediction,
+ m_mv_array[ypos][xpos]<<m_precision );
+ m_cost_array[ypos][xpos].SetTotal( lambda );
+
+ // Initialise to the best pixel value
+ MvCostData best_costs( m_cost_array[ypos][xpos] );
+ MVector pel_mv( m_mv_array[ypos][xpos] );
+ MVector best_mv( pel_mv );
+
+ // If the integer value is good enough, bail out
+ if ( best_costs.SAD < 2*dparams.Xl()*dparams.Yl() )
+ {
+ m_mv_array[ypos][xpos] = m_mv_array[ypos][xpos]<<m_precision;
+ return;
+ }
+
+ // Next, test the predictor. If that's good enough, bail out
+ MvCostData pred_costs;
+ pred_costs.mvcost = 0;
+ pred_costs.SAD = m_subpeldiff[m_precision-1]->Diff( dparams, mv_prediction);
+ pred_costs.total = pred_costs.SAD;
+
+ if (pred_costs.SAD<2*dparams.Xl()*dparams.Yl() )
+ {
+ m_mv_array[ypos][xpos] = mv_prediction;
+ m_cost_array[ypos][xpos] = pred_costs;
+ return;
+ }
+
+ // Now, let's see if we can do better than this
+
+ MvCostData cand_costs;
+ MVector cand_mv, old_best_mv;
+
+ for (int i=1; i<=m_precision; ++i )
+ {
+ best_mv = best_mv<<1;
+ MVector temp_best_mv = best_mv;
+
+ // Do a neighbourhood of best_mv
+
+ // Stage 1 - look at the 4 nearest points
+ cand_mv.x = best_mv.x - 1;
+ cand_mv.y = best_mv.y;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+ cand_mv.x = best_mv.x + 1;
+ cand_mv.y = best_mv.y;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+ cand_mv.x = best_mv.x;
+ cand_mv.y = best_mv.y - 1;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+ cand_mv.x = best_mv.x;
+ cand_mv.y = best_mv.y + 1;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+
+ // Stage 2. If we've done better than the original value,
+ // look at the other two neighbours
+ if ( temp_best_mv.x != best_mv.x )
+ {
+ MVector new_best_mv = temp_best_mv;
+ cand_mv.x = new_best_mv.x;
+ cand_mv.y = new_best_mv.y - 1;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+
+ cand_mv.x = new_best_mv.x;
+ cand_mv.y = new_best_mv.y + 1;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+ }
+ else if ( temp_best_mv.y != best_mv.y )
+ {
+ MVector new_best_mv = temp_best_mv;
+ cand_mv.x = new_best_mv.x - 1;
+ cand_mv.y = new_best_mv.y;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+
+ cand_mv.x = new_best_mv.x + 1;
+ cand_mv.y = new_best_mv.y;
+ m_subpeldiff[i-1]->Diff( dparams, cand_mv ,
+ GetVarUp( mv_prediction,
+ cand_mv<<(m_precision-i) ) ,
+ lambda , best_costs ,
+ temp_best_mv);
+ }
+
+ best_mv = temp_best_mv;
+
+ // Bail out if we can't do better than 10% worse than the predictor at
+ // each stage
+ if ( best_costs.total>1.1*pred_costs.total )
+ {
+ m_mv_array[ypos][xpos] = mv_prediction;
+ m_cost_array[ypos][xpos] = pred_costs;
+ return;
+ }
+
+ }//i
+
+
+ // Write the results in the arrays //
+ /////////////////////////////////////
+
+ m_mv_array[ypos][xpos] = best_mv;
+ m_cost_array[ypos][xpos] = best_costs;
+
+}
+
+} // namespace dirac
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.h
new file mode 100644
index 000000000..2bcb5e2b3
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/block_match.h
@@ -0,0 +1,207 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: block_match.h,v 1.10 2007/09/03 14:52:40 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _BLOCK_MATCH_H_
+#define _BLOCK_MATCH_H_
+
+#include <libdirac_motionest/me_utils.h>
+#include <vector>
+//handles the business of finding the best block match
+
+namespace dirac
+{
+
+ typedef std::vector< std::vector< MVector > > CandidateList;
+
+ //! Add a new motion vector list of neighbours of a vector to the set of lists
+ /*
+ Add a new motion vector list to the set of lists consisting of the
+ square neighbourhood [mv.x-xr,mv.x+xr] by
+ [mv.y-yr,mv.y+yr]. Vectors that already occur in previous lists are
+ not added.
+ */
+ void AddNewVlist( CandidateList& vect_list , const MVector& mv , const int xr , const int yr );
+
+ //! Add a new motion vector list to the set of lists for sub-pixel matching
+ /*
+ Add a new motion vector list to the set of lists consisting of the
+ vectors of the form (mv.x+m*step,mv.y+n*step) where m lies between
+ -xr and xr and n lies between -yr and yr. Vectors that already occur
+ in previous lists are not added.
+ */
+ void AddNewVlist( CandidateList& vect_list , const MVector& mv , const int xr , const int yr , const int step );
+
+ //! Add a new motion vector list of diagnonal neighbours of a vector to the set of lists
+ /*
+ Add a new motion vector list to the set of lists consisting of the
+ diagonal neighbourhood of height 2yr+1 pixels and width 2xr+1 centred
+ on \param mv.
+ Vectors that already occur in previous lists are not added.
+ */
+ void AddNewVlistD( CandidateList& vect_list , const MVector& mv , const int xr, const int yr);
+
+ //! Add a motion vector to the set of motion vector lists
+ /*!
+ Add a motion vector to the set of motion vector lists, making sure
+ it's not a duplicate.
+ */
+ void AddVect( CandidateList& vect_list , const MVector& mv , const int list_num);
+
+ //! Get the (absolute) variation between two motion vectors
+ /*!
+ Return the variation between two motion vectors, computed as the sum
+ of absolute differences of their components.
+ */
+ ValueType GetVar(const MVector& mv1,const MVector& mv2);
+
+ //! Get the (absolute) variation between a motion vector and a list of motion vectors
+ /*!
+ Return the variation between a motion vector and a list of motion
+ vectos, computed as the sum of absolute differences between the
+ components of the vector and the median vector produced by the list of
+ vectors
+ */
+ ValueType GetVar(const std::vector<MVector>& pred_list,const MVector& mv);
+
+
+ //! Class to do block matching
+
+ // Subsumes FindBestMatch and FindBestMatchSubpel
+ class BlockMatcher
+ {
+ public:
+ //! Constructor
+ /*!
+ Constructor
+ \param ref_data the reference picture component
+ \param pic_data the picture being matched
+ \param bparams the (overlapped) block parameters to be used for the matching
+ \param precision the number of bits of precision being used for estimation
+ \param mv_array the array of vectors we're going to write into
+ \param cost_array the array of costs we're going to write into
+
+ */
+ BlockMatcher( const PicArray& ref_data ,
+ const PicArray& pic_data ,
+ const OLBParams& bparams ,
+ const int precision ,
+ const MvArray& mv_array ,
+ const TwoDArray< MvCostData >& cost_array);
+
+ ~BlockMatcher();
+
+ //! Find the best matching vector from a list of candidates
+ /*!
+ Find the best matching vector from a list of candidates.
+ \param xpos the horizontal location of the block being matched
+ \param ypos the vertical location of the block being matched
+ \param cand_list the list of candidate vectors
+ \param mv_prediction Prediction used for each block used to control the variation in the motion vector field.
+ \param list_start index into the candidate vectors list
+ */
+ void FindBestMatchPel( const int xpos , const int ypos ,
+ const CandidateList& cand_list,
+ const MVector& mv_prediction,
+ const int list_start);
+
+ //! Find the best matching vector from a list of candidates, to sub-pixel accuracy (TBC: merge with FindBestMatch)
+ /*!
+ Find the best matching vector from a list of candidates.
+ \param xpos the horizontal location of the block being matched
+ \param ypos the vertical location of the block being matched
+ \param cand_list the list of candidate vectors
+ \param mv_prediction the prediction for the motion vector
+ \param lambda the Lagrangian parameter
+ */
+ void FindBestMatchSubp( const int xpos, const int ypos,
+ const CandidateList& cand_list,
+ const MVector& mv_prediction,
+ const float lambda);
+
+ void RefineMatchSubp(const int xpos, const int ypos,
+ const MVector& mv_prediction,
+ const float lambda);
+
+ //! Get a measure of the difference between a motion vector and a prediction
+ /*!
+ Get a measure of the difference between a motion vector and a prediction
+ \param predmv the predicting motion vector
+ \param mv the motion vector
+ */
+ ValueType GetVar( const MVector& predmv , const MVector& mv ) const;
+
+ //! Get a measure of the difference between a motion vector and a prediction, to 1/8pel accuracy
+ /*!
+ Get a measure of the difference between a motion vector and a prediction, to 1/8pel accuracy
+ \param predmv the predicting motion vector
+ \param mv the motion vector
+ */
+ ValueType GetVarUp( const MVector& predmv , const MVector& mv ) const;
+
+ void SetPrecision( const int n ){ m_precision = n; }
+
+ private:
+ // Local copies of the picture and reference
+ const PicArray& m_pic_data;
+ const PicArray& m_ref_data;
+
+ // Local copy of the motion vector array being populated
+ const MvArray& m_mv_array;
+
+ // Local copy of the costs being determined through the matching
+ const TwoDArray< MvCostData >& m_cost_array;
+
+ // Block difference elements. Will choose between them depending
+ // on whether we're at the edge of the picture
+ PelBlockDiff m_peldiff;
+
+ OneDArray<BlockDiffUp* > m_subpeldiff;
+
+ // The block parameters we're using
+ OLBParams m_bparams;
+
+ // The maximum variations allowed in calculating motion vector costs
+ const int m_var_max;
+ const int m_var_max_up;
+
+ // The motion vector precision
+ int m_precision;
+
+ };
+
+} // namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.cpp
new file mode 100644
index 000000000..75bd0739e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.cpp
@@ -0,0 +1,204 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: downconvert.cpp,v 1.10 2007/03/19 16:19:00 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author),
+* Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_motionest/downconvert.h>
+using namespace dirac;
+
+DownConverter::DownConverter()
+{}
+
+
+#if !defined(HAVE_MMX)
+//General function - does some admin and calls the correct function
+//NOTE: The mmx version of this function is defined in downconvert_mmx.cpp
+//Ensusre that changes made in this function are reflected in the mmx version
+//as well.
+void DownConverter::DoDownConvert(const PicArray& old_data, PicArray& new_data)
+{
+ //Down-convert by a factor of two.
+ m_row_buffer= new ValueType[old_data.LengthX()];
+ //Variables that will be used by the filter calculations
+ int sum;
+ int colpos;
+
+ // The area of the picture that will be downconverted
+ const int xlen = 2*new_data.LengthX();
+ const int ylen = 2*new_data.LengthY();
+
+
+ //There are three y loops to cope with the leading edge, middle
+ //and trailing edge of each column.
+ colpos=0;
+ for( int y=0; y<Stage_I_Size*2 ; y+=2 , colpos++ )
+ {
+ // We are filtering each column but doing it bit by bit.
+ // This means our main loop is in the x direction and
+ // there is a much greater chance the data we need will
+ // be in the cache.
+
+ for( int x=0 ; x<xlen ; x++ )
+ {
+ // In down conversion we interpolate every pixel
+ // so there is no copying.
+ // Excuse the complicated ternary stuff but it sorts out the edge
+ sum = (old_data[y][x] + old_data[y+1][x])*StageI_I;
+ sum += (old_data[((y-1)>=0)?(y-1):0][x] + old_data[y+2][x])*StageI_II;
+ sum += (old_data[((y-2)>=0)?(y-2):0][x] + old_data[y+3][x])*StageI_III;
+ sum += (old_data[((y-3)>=0)?(y-3):0][x] + old_data[y+4][x])*StageI_IV;
+ sum += (old_data[((y-4)>=0)?(y-4):0][x] + old_data[y+5][x])*StageI_V;
+ sum += (old_data[((y-5)>=0)?(y-5):0][x] + old_data[y+6][x])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+ m_row_buffer[x] = sum >> StageI_Shift;
+ }// x
+ //Speaking of which - the row loop.
+
+ RowLoop(colpos,new_data);
+ }// y
+
+ // This loop is like the last one but it deals with the center
+ // section of the image and so the ternary operations are dropped
+ // from the filter section.
+ for( int y=Stage_I_Size*2 ; y<ylen-Stage_I_Size*2 ; y+=2 , colpos++ )
+ {
+ for( int x=0 ; x<xlen ; x++ )
+ {
+
+ sum = (old_data[y][x] + old_data[y+1][x])*StageI_I;
+ sum += (old_data[y-1][x] + old_data[y+2][x])*StageI_II;
+ sum += (old_data[y-2][x] + old_data[y+3][x])*StageI_III;
+ sum += (old_data[y-3][x] + old_data[y+4][x])*StageI_IV;
+ sum += (old_data[y-4][x] + old_data[y+5][x])*StageI_V;
+ sum += (old_data[y-5][x] + old_data[y+6][x])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+ m_row_buffer[x] = sum >> StageI_Shift;
+ }// x
+
+ RowLoop( colpos , new_data );
+ }// y
+
+ // Another similar loop! - this time we are dealing with
+ // the trailing edge so the ternary stuff is back in the
+ // filter calcs but in the second parameter.
+
+ for( int y=ylen-(Stage_I_Size*2) ; y<ylen-1 ; y+=2 , colpos++ )
+ {
+ for( int x=0; x<xlen ; x++ )
+ {
+
+ sum = (old_data[y][x] + old_data[((y+1)<ylen)?(y+1):(ylen-1)][x])*StageI_I;
+ sum += (old_data[y-1][x] + old_data[((y+2)<ylen)?(y+2):(ylen-1)][x])*StageI_II;
+ sum += (old_data[y-2][x] + old_data[((y+3)<ylen)?(y+3):(ylen-1)][x])*StageI_III;
+ sum += (old_data[y-3][x] + old_data[((y+4)<ylen)?(y+4):(ylen-1)][x])*StageI_IV;
+ sum += (old_data[y-4][x] + old_data[((y+5)<ylen)?(y+5):(ylen-1)][x])*StageI_V;
+ sum += (old_data[y-5][x] + old_data[((y+6)<ylen)?(y+6):(ylen-1)][x])*StageI_VI;
+
+ // Do rounding right
+ sum += 1<<(StageI_Shift-1);
+ m_row_buffer[x] = sum >> StageI_Shift;
+
+ }// x
+
+ RowLoop( colpos , new_data );
+
+ }// y
+
+ // Tidy up the data
+ delete[] m_row_buffer;
+
+}
+#endif
+
+
+// The loop over the columns is the same every time so lends itself to isolation
+// as an individual function.
+void DownConverter::RowLoop( const int colpos , PicArray& new_data)
+{
+
+ //Calculation variables
+ int sum;
+ const int xlen = 2*new_data.LengthX();
+ int linepos=0;
+
+ // Leading Column Edge
+ // Similar loops to the x case in ByHalf_opto, for explanation look there.
+ // Note the factor of two difference as we only want to fill in every other
+ // line as the others have already been created by the line loops.
+
+ for( int x=0; x<(2*Stage_I_Size) ; x+=2 , linepos++ )
+ {
+ sum = (m_row_buffer[((x)>=0)?(x):0] + m_row_buffer[x+1])*StageI_I;
+ sum += (m_row_buffer[((x-1)>=0)?(x-1):0] + m_row_buffer[x+2])*StageI_II;
+ sum += (m_row_buffer[((x-2)>=0)?(x-2):0] + m_row_buffer[x+3])*StageI_III;
+ sum += (m_row_buffer[((x-3)>=0)?(x-3):0] + m_row_buffer[x+4])*StageI_IV;
+ sum += (m_row_buffer[((x-4)>=0)?(x-4):0] + m_row_buffer[x+5])*StageI_V;
+ sum += (m_row_buffer[((x-5)>=0)?(x-5):0] + m_row_buffer[x+6])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+
+ new_data[colpos][linepos] = sum >> StageI_Shift;
+
+ }
+ //Middle of column
+ for( int x=(2*Stage_I_Size) ; x<xlen-(2*Stage_I_Size) ; x+=2 , linepos++)
+ {
+ sum = (m_row_buffer[x] + m_row_buffer[x+1])*StageI_I;
+ sum += (m_row_buffer[x-1] + m_row_buffer[x+2])*StageI_II;
+ sum += (m_row_buffer[x-2] + m_row_buffer[x+3])*StageI_III;
+ sum += (m_row_buffer[x-3] + m_row_buffer[x+4])*StageI_IV;
+ sum += (m_row_buffer[x-4] + m_row_buffer[x+5])*StageI_V;
+ sum += (m_row_buffer[x-5] + m_row_buffer[x+6])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+
+ new_data[colpos][linepos] = sum >> StageI_Shift;
+
+ }
+ //Trailing column edge
+ for( int x=xlen-(2*Stage_I_Size) ; x< xlen-1 ; x+=2 , linepos++ )
+ {
+ sum = (m_row_buffer[x] + m_row_buffer[((x+1)<xlen)?(x+1):(xlen-1)])*StageI_I;
+ sum += (m_row_buffer[x-1] + m_row_buffer[((x+2)<xlen)?(x+2):(xlen-1)])*StageI_II;
+ sum += (m_row_buffer[x-2] + m_row_buffer[((x+3)<xlen)?(x+3):(xlen-1)])*StageI_III;
+ sum += (m_row_buffer[x-3] + m_row_buffer[((x+4)<xlen)?(x+4):(xlen-1)])*StageI_IV;
+ sum += (m_row_buffer[x-4] + m_row_buffer[((x+5)<xlen)?(x+5):(xlen-1)])*StageI_V;
+ sum += (m_row_buffer[x-5] + m_row_buffer[((x+6)<xlen)?(x+6):(xlen-1)])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+
+ new_data[colpos][linepos] = sum >> StageI_Shift;
+
+ }
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.h
new file mode 100644
index 000000000..bb2bdcf1e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert.h
@@ -0,0 +1,94 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: downconvert.h,v 1.11 2007/03/19 16:19:00 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Richard Felton (Original Author),
+* Thomas Davies
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _DOWNCONVERT_H_
+#define _DOWNCONVERT_H_
+
+#include <libdirac_common/common.h>
+namespace dirac
+{
+
+ //! A class for fast downconversion of picture data
+ /*!
+ A class for fast down-conversion of picture data. The picture data is
+ downconverted by a factor of two in each dimension, using fast
+ filtering techniques. The filter is a half-band filter designed to
+ trade off frequency response, ringiness, and aliasing
+ */
+ class DownConverter{
+
+ public:
+
+ //! Constructor
+ DownConverter();
+ //! Destructor
+ ~DownConverter(){};
+
+ //! A function to do the actual down-conversion
+ /*!
+ A function to do the actual downconversion.
+ \param old_data the picture data to be downconverted
+ \param new_data the resulting down-converted data. The array must be of the correct size.
+ */
+ void DoDownConvert(const PicArray& old_data, PicArray& new_data);
+
+ private:
+ //Copy constructor
+ DownConverter(const DownConverter& cpy);//private, body-less: class should not be copied
+ //Assignment=
+ DownConverter& operator=(const DownConverter& rhs);//private, body-less: class should not be assigned
+
+ //Applies the filter to a single column
+ void RowLoop(const int colpos , PicArray& new_data );
+
+ ValueType* m_row_buffer;
+
+ //Define filter parameters
+ static const int Stage_I_Size = 6;
+ static const int StageI_I = 86;
+ static const int StageI_II = 46;
+ static const int StageI_III = 4;
+ static const int StageI_IV = -8;
+ static const int StageI_V = -4;
+ static const int StageI_VI = 4;
+ static const int StageI_Shift = 8;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert_mmx.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert_mmx.cpp
new file mode 100644
index 000000000..efdc261e5
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/downconvert_mmx.cpp
@@ -0,0 +1,246 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: downconvert_mmx.cpp,v 1.2 2007/03/19 16:19:00 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Anuradha Suraparaju (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_motionest/downconvert.h>
+using namespace dirac;
+
+#if defined (HAVE_MMX)
+#include <mmintrin.h>
+
+typedef union
+{
+ __m64 m;
+ int i[2];
+} u_sum;
+
+
+#define mmx_add(pic1,pic2,tap,zero,sum1,sum2) \
+ tmp = _mm_add_pi16 (*(__m64 *)pic1, *(__m64 *)pic2); \
+ m1 = _mm_unpacklo_pi16 ( tmp, zero); \
+ m2 = _mm_unpackhi_pi16 ( tmp, zero); \
+ m1 = _mm_madd_pi16 (m1, tap); \
+ m2 = _mm_madd_pi16 (m2, tap); \
+ *sum1 = _mm_add_pi32 (*sum1, m1); \
+ *sum2 = _mm_add_pi32 (*sum2, m2); \
+
+//General function - does some admin and calls the correct function
+void DownConverter::DoDownConvert(const PicArray& old_data, PicArray& new_data)
+{
+ //Down-convert by a factor of two.
+ m_row_buffer= new ValueType[old_data.LengthX()];
+ //Variables that will be used by the filter calculations
+ int sum;
+ int colpos;
+
+ // The area of the picture that will be downconverted
+ const int xlen = 2*new_data.LengthX();
+ const int ylen = 2*new_data.LengthY();
+
+
+ //There are three y loops to cope with the leading edge, middle
+ //and trailing edge of each column.
+ colpos=0;
+
+ static __m64 zero = _mm_set_pi16(0, 0, 0, 0);
+ static __m64 tap0 = _mm_set_pi16 (0, StageI_I, 0, StageI_I);
+ static __m64 tap1 = _mm_set_pi16 (0, StageI_II, 0, StageI_II);
+ static __m64 tap2 = _mm_set_pi16 (0, StageI_III, 0, StageI_III);
+ static __m64 tap3 = _mm_set_pi16 (0, StageI_IV, 0, StageI_IV);
+ static __m64 tap4 = _mm_set_pi16 (0, StageI_V, 0, StageI_V);
+ static __m64 tap5 = _mm_set_pi16 (0, StageI_VI, 0, StageI_VI);
+ static __m64 round = _mm_set_pi32 ( 1<<(StageI_Shift-1), 1<<(StageI_Shift-1));
+
+ u_sum sum1, sum2;
+ __m64 tmp, m1, m2;
+
+ int stopX = (xlen >> 2)<<2;
+ for( int y=0; y<Stage_I_Size*2 ; y+=2 , colpos++ )
+ {
+ // We are filtering each column but doing it bit by bit.
+ // This means our main loop is in the x direction and
+ // there is a much greater chance the data we need will
+ // be in the cache.
+
+ for( int x=0 ; x<stopX ; x+=4 )
+ {
+ // In down conversion we interpolate every pixel
+ // so there is no copying.
+ // Excuse the complicated ternary stuff but it sorts out the edge
+ sum1.m = _mm_set_pi32 (0, 0);
+ sum2.m = _mm_set_pi32 (0, 0);
+
+ mmx_add (&old_data[y][x], &old_data[y+1][x], tap0, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[((y-1)>=0)?(y-1):0][x] , &old_data[y+2][x], tap1, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[((y-2)>=0)?(y-2):0][x] , &old_data[y+3][x], tap2, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[((y-3)>=0)?(y-3):0][x] , &old_data[y+4][x], tap3, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[((y-4)>=0)?(y-4):0][x] , &old_data[y+5][x], tap4, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[((y-5)>=0)?(y-5):0][x] , &old_data[y+6][x], tap5, zero, &sum1.m, &sum2.m);
+
+ sum1.m = _mm_add_pi32 (sum1.m, round);
+ sum2.m = _mm_add_pi32 (sum2.m, round);
+ sum1.m = _mm_srai_pi32 (sum1.m, StageI_Shift);
+ sum2.m = _mm_srai_pi32 (sum2.m, StageI_Shift);
+ m_row_buffer[x] = sum1.i[0];
+ m_row_buffer[x+1] = sum1.i[1];
+ m_row_buffer[x+2] = sum2.i[0];
+ m_row_buffer[x+3] = sum2.i[1];
+ }// x
+ _mm_empty();
+
+ for( int x=stopX ; x<xlen ; x++ )
+ {
+ // In down conversion we interpolate every pixel
+ // so there is no copying.
+ // Excuse the complicated ternary stuff but it sorts out the edge
+ sum = (old_data[y][x] + old_data[y+1][x])*StageI_I;
+ sum += (old_data[((y-1)>=0)?(y-1):0][x] + old_data[y+2][x])*StageI_II;
+ sum += (old_data[((y-2)>=0)?(y-2):0][x] + old_data[y+3][x])*StageI_III;
+ sum += (old_data[((y-3)>=0)?(y-3):0][x] + old_data[y+4][x])*StageI_IV;
+ sum += (old_data[((y-4)>=0)?(y-4):0][x] + old_data[y+5][x])*StageI_V;
+ sum += (old_data[((y-5)>=0)?(y-5):0][x] + old_data[y+6][x])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+ m_row_buffer[x] = sum >> StageI_Shift;
+ }// x
+ //Speaking of which - the row loop.
+
+ RowLoop(colpos,new_data);
+ }// y
+
+ // This loop is like the last one but it deals with the center
+ // section of the image and so the ternary operations are dropped
+ // from the filter section.
+ for( int y=Stage_I_Size*2 ; y<ylen-Stage_I_Size*2 ; y+=2 , colpos++ )
+ {
+ for( int x=0 ; x<stopX ; x+=4 )
+ {
+ // In down conversion we interpolate every pixel
+ // so there is no copying.
+ // Excuse the complicated ternary stuff but it sorts out the edge
+ sum1.m = _mm_set_pi32 (0, 0);
+ sum2.m = _mm_set_pi32 (0, 0);
+
+ mmx_add (&old_data[y][x], &old_data[y+1][x], tap0, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-1][x] , &old_data[y+2][x], tap1, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-2][x] , &old_data[y+3][x], tap2, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-3][x] , &old_data[y+4][x], tap3, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-4][x] , &old_data[y+5][x], tap4, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-5][x] , &old_data[y+6][x], tap5, zero, &sum1.m, &sum2.m);
+
+ sum1.m = _mm_add_pi32 (sum1.m, round);
+ sum2.m = _mm_add_pi32 (sum2.m, round);
+ sum1.m = _mm_srai_pi32 (sum1.m, StageI_Shift);
+ sum2.m = _mm_srai_pi32 (sum2.m, StageI_Shift);
+ m_row_buffer[x] = sum1.i[0];
+ m_row_buffer[x+1] = sum1.i[1];
+ m_row_buffer[x+2] = sum2.i[0];
+ m_row_buffer[x+3] = sum2.i[1];
+ }// x
+ _mm_empty();
+
+ for( int x=stopX ; x<xlen ; x++ )
+ {
+ sum = (old_data[y][x] + old_data[y+1][x])*StageI_I;
+ sum += (old_data[y-1][x] + old_data[y+2][x])*StageI_II;
+ sum += (old_data[y-2][x] + old_data[y+3][x])*StageI_III;
+ sum += (old_data[y-3][x] + old_data[y+4][x])*StageI_IV;
+ sum += (old_data[y-4][x] + old_data[y+5][x])*StageI_V;
+ sum += (old_data[y-5][x] + old_data[y+6][x])*StageI_VI;
+ sum += 1<<(StageI_Shift-1);//do rounding right
+ m_row_buffer[x] = sum >> StageI_Shift;
+ }// x
+
+ RowLoop( colpos , new_data );
+ }// y
+
+ // Another similar loop! - this time we are dealing with
+ // the trailing edge so the ternary stuff is back in the
+ // filter calcs but in the second parameter.
+
+ for( int y=ylen-(Stage_I_Size*2) ; y<ylen-1 ; y+=2 , colpos++ )
+ {
+ for( int x=0 ; x<stopX ; x+=4 )
+ {
+ // In down conversion we interpolate every pixel
+ // so there is no copying.
+ // Excuse the complicated ternary stuff but it sorts out the edge
+ sum1.m = _mm_set_pi32 (0, 0);
+ sum2.m = _mm_set_pi32 (0, 0);
+
+ mmx_add (&old_data[y][x], &old_data[((y+1)<ylen)?(y+1):(ylen-1)][x], tap0, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-1][x] , &old_data[((y+2)<ylen)?(y+2):(ylen-1)][x], tap1, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-2][x] , &old_data[((y+3)<ylen)?(y+3):(ylen-1)][x], tap2, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-3][x] , &old_data[((y+4)<ylen)?(y+4):(ylen-1)][x], tap3, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-4][x] , &old_data[((y+5)<ylen)?(y+5):(ylen-1)][x], tap4, zero, &sum1.m, &sum2.m);
+ mmx_add(&old_data[y-5][x] , &old_data[((y+6)<ylen)?(y+6):(ylen-1)][x], tap5, zero, &sum1.m, &sum2.m);
+
+ sum1.m = _mm_add_pi32 (sum1.m, round);
+ sum2.m = _mm_add_pi32 (sum2.m, round);
+ sum1.m = _mm_srai_pi32 (sum1.m, StageI_Shift);
+ sum2.m = _mm_srai_pi32 (sum2.m, StageI_Shift);
+
+ m_row_buffer[x] = sum1.i[0];
+ m_row_buffer[x+1] = sum1.i[1];
+ m_row_buffer[x+2] = sum2.i[0];
+ m_row_buffer[x+3] = sum2.i[1];
+ }// x
+ _mm_empty();
+
+ for( int x=stopX; x<xlen ; x++ )
+ {
+
+ sum = (old_data[y][x] + old_data[((y+1)<ylen)?(y+1):(ylen-1)][x])*StageI_I;
+ sum += (old_data[y-1][x] + old_data[((y+2)<ylen)?(y+2):(ylen-1)][x])*StageI_II;
+ sum += (old_data[y-2][x] + old_data[((y+3)<ylen)?(y+3):(ylen-1)][x])*StageI_III;
+ sum += (old_data[y-3][x] + old_data[((y+4)<ylen)?(y+4):(ylen-1)][x])*StageI_IV;
+ sum += (old_data[y-4][x] + old_data[((y+5)<ylen)?(y+5):(ylen-1)][x])*StageI_V;
+ sum += (old_data[y-5][x] + old_data[((y+6)<ylen)?(y+6):(ylen-1)][x])*StageI_VI;
+
+ // Do rounding right
+ sum += 1<<(StageI_Shift-1);
+ m_row_buffer[x] = sum >> StageI_Shift;
+
+ }// x
+
+ RowLoop( colpos , new_data );
+
+ }// y
+
+ // Tidy up the data
+ delete[] m_row_buffer;
+
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.cpp
new file mode 100644
index 000000000..a23e705de
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.cpp
@@ -0,0 +1,573 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_mode_decn.cpp,v 1.34 2008/10/20 04:19:32 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_motionest/me_mode_decn.h>
+#include <libdirac_encoder/enc_queue.h>
+using namespace dirac;
+
+#include <algorithm>
+
+using std::vector;
+
+ModeDecider::ModeDecider( const EncoderParams& encp):
+ m_encparams( encp ),
+ m_level_factor(3),
+ m_mode_factor(3),
+ m_me_data_set(3)
+{
+
+}
+
+
+ModeDecider::~ModeDecider()
+{
+ if (m_psort.IsInter())
+ {
+ delete m_me_data_set[0];
+ delete m_me_data_set[1];
+ }
+}
+
+void ModeDecider::DoModeDecn( EncQueue& my_buffer, int pic_num )
+{
+
+ m_predparams = &(my_buffer.GetPicture(pic_num).GetMEData().GetPicPredParams() );
+
+ // The following factors normalise costs for sub-SBs and SBs to those of
+ // blocks, so that the overlap is take into account (e.g. a sub-SB has
+ // length XBLEN+XBSEP and YBLEN+YBSEP). The SB costs for a 1x1
+ // decomposition are not directly comprable to those for other decompositions
+ // because of the block overlaps. These factors remove these effects, so that
+ // all SAD costs are normalised to the area corresponding to non-overlapping
+ // 16 blocks of size XBLEN*YBLEN.
+
+ m_level_factor[0] = float( 16 * m_predparams->LumaBParams(2).Xblen() * m_predparams->LumaBParams(2).Yblen() )/
+ float( m_predparams->LumaBParams(0).Xblen() * m_predparams->LumaBParams(0).Yblen() );
+
+ m_level_factor[1] = float( 4 * m_predparams->LumaBParams(2).Xblen() * m_predparams->LumaBParams(2).Yblen() )/
+ float( m_predparams->LumaBParams(1).Xblen() * m_predparams->LumaBParams(1).Yblen() );
+
+ m_level_factor[2] = 1.0f;
+
+ for (int i=0 ; i<=2 ; ++i)
+ m_mode_factor[i] = 80.0*std::pow(0.8 , 2-i);
+
+ // We've got 'raw' block motion vectors for up to two reference pictures. Now we want
+ // to make a decision as to mode. In this initial implementation, this is bottom-up
+ // i.e. find mvs for SBs and sub-SBs and see whether it's worthwhile merging.
+
+ int ref1,ref2;
+
+ // Initialise //
+ ////////////////
+
+ m_psort = my_buffer.GetPicture(pic_num).GetPparams().PicSort();
+ if (m_psort.IsInter())
+ {
+ // Extract the references
+ const vector<int>& refs = my_buffer.GetPicture(pic_num).GetPparams().Refs();
+ num_refs = refs.size();
+ ref1 = refs[0];
+
+ // The picture we're doing estimation from
+ m_pic_data = &(my_buffer.GetPicture( pic_num ).DataForME(m_encparams.CombinedME()) );
+
+ // Set up the hierarchy of motion vector data objects
+ PicturePredParams predparams0 = *m_predparams;
+ predparams0.SetXNumBlocks( m_predparams->XNumBlocks()/4 );
+ predparams0.SetYNumBlocks( m_predparams->YNumBlocks()/4 );
+
+ PicturePredParams predparams1 = *m_predparams;
+ predparams1.SetXNumBlocks( m_predparams->XNumBlocks()/2 );
+ predparams1.SetYNumBlocks( m_predparams->YNumBlocks()/2 );
+
+ m_me_data_set[0] = new MEData( predparams0, num_refs );
+ m_me_data_set[1] = new MEData( predparams1, num_refs );
+
+ m_me_data_set[2] = &my_buffer.GetPicture(pic_num).GetMEData();
+
+ // Set up the lambdas to use per block
+ m_me_data_set[0]->SetLambdaMap( 0 , m_me_data_set[2]->LambdaMap() , 1.0/m_level_factor[0] );
+ m_me_data_set[1]->SetLambdaMap( 1 , m_me_data_set[2]->LambdaMap() , 1.0/m_level_factor[1] );
+
+ // Set up the reference pictures
+ m_ref1_updata = &(my_buffer.GetPicture( ref1 ).UpDataForME(m_encparams.CombinedME()) );
+
+ if (num_refs>1)
+ {
+ ref2 = refs[1];
+ m_ref2_updata = &(my_buffer.GetPicture( ref2).UpDataForME(m_encparams.CombinedME()) );
+ // Create an object for computing bi-directional prediction calculations
+ if ( m_predparams->MVPrecision()==MV_PRECISION_EIGHTH_PIXEL )
+ m_bicheckdiff = new BiBlockEighthPel( *m_ref1_updata ,
+ *m_ref2_updata ,
+ *m_pic_data );
+ else if ( m_predparams->MVPrecision()==MV_PRECISION_QUARTER_PIXEL )
+ m_bicheckdiff = new BiBlockQuarterPel( *m_ref1_updata ,
+ *m_ref2_updata ,
+ *m_pic_data );
+ else
+ m_bicheckdiff = new BiBlockHalfPel( *m_ref1_updata ,
+ *m_ref2_updata ,
+ *m_pic_data );
+ }
+ else
+ {
+ ref2 = ref1;
+ }
+
+
+ // Create an object for doing intra calculations
+ m_intradiff = new IntraBlockDiff( *m_pic_data );
+
+ // Loop over all the superblocks, doing the work //
+ ///////////////////////////////////////////////////
+
+ for (m_ysb_loc=0 ; m_ysb_loc<m_predparams->YNumSB() ; ++m_ysb_loc ){
+ for (m_xsb_loc=0 ; m_xsb_loc<m_predparams->XNumSB(); ++m_xsb_loc ){
+ DoSBDecn();
+ }//m_xsb_loc
+ }//m_ysb_loc
+
+ delete m_intradiff;
+ if (num_refs>1)
+ delete m_bicheckdiff;
+ }
+
+ // Finally, although not strictly part of motion estimation,
+ // we have to assign DC values for
+ // blocks we're decided are intra.
+ SetDC( my_buffer , pic_num );
+
+}
+
+void ModeDecider::DoSBDecn()
+{
+ // Does the mode decision for the given SB, in three stages
+
+ // Start with 4x4 modes
+ DoLevelDecn(2);
+ float old_best_SB_cost = m_me_data_set[2]->SBCosts()[m_ysb_loc][m_xsb_loc];
+
+ // Next do 2x2 modes
+ DoLevelDecn(1);
+
+ // Do 1x1 mode if merging worked before
+ if ( m_me_data_set[2]->SBCosts()[m_ysb_loc][m_xsb_loc] <= old_best_SB_cost)
+ {
+ old_best_SB_cost = m_me_data_set[2]->SBCosts()[m_ysb_loc][m_xsb_loc];
+ DoLevelDecn(0);
+ }
+
+}
+
+void ModeDecider::DoLevelDecn( int level )
+{
+ // Computes the best costs if we were to
+ // stick to a decomposition at this level
+
+ // Looks at two cases: the prediction mode is
+ // constant across the SB; and the pred mode
+ // for each constituent is different.
+
+ // The limits of the prediction units
+ const int xstart = m_xsb_loc <<level;
+ const int ystart = m_ysb_loc <<level;
+
+ const int xend = xstart + (1<<level);
+ const int yend = ystart + (1<<level);
+
+ // Case 1: prediction modes are all different
+
+ float SB_cost = 0.0;
+ for ( int j=ystart ; j<yend ; ++j)
+ {
+ for (int i=xstart ; i<xend ; ++i)
+ {
+ if ( level<2 )
+ DoME( i , j , level);
+ SB_cost += DoUnitDecn( i , j ,level );
+
+ }// i
+ }// j
+
+ // if we've improved on the best cost, we should propagate data in
+ // the base level motion vector set
+ if (level == 2)
+ {
+ m_me_data_set[2]->SBSplit()[m_ysb_loc][m_xsb_loc] = 2;
+ m_me_data_set[2]->SBCosts()[m_ysb_loc][m_xsb_loc] = SB_cost;
+ }
+
+ if ( level<2 && SB_cost <= m_me_data_set[2]->SBCosts()[m_ysb_loc][m_xsb_loc] )
+ {
+ m_me_data_set[2]->SBCosts()[m_ysb_loc][m_xsb_loc] = SB_cost;
+ m_me_data_set[2]->SBSplit()[m_ysb_loc][m_xsb_loc] = level;
+
+ // Parameters of the base-level blocks corresponding to each
+ // prediction unit
+ int xblock_start;
+ int yblock_start;
+ int xblock_end;
+ int yblock_end;
+
+ for ( int j=ystart ; j<yend ; ++j )
+ {
+ yblock_start = j<<(2-level);
+ yblock_end = (j+1)<<(2-level);
+ for ( int i=xstart ; i<xend ; ++i )
+ {
+ xblock_start = i<<(2-level);
+ xblock_end = (i+1)<<(2-level);
+
+ for ( int v=yblock_start ; v<yblock_end ; ++v )
+ {
+ for ( int u=xblock_start ; u<xblock_end ; ++u )
+ {
+ m_me_data_set[2]->Mode()[v][u] = m_me_data_set[level]->Mode()[j][i];
+ m_me_data_set[2]->DC( Y_COMP )[v][u] = m_me_data_set[level]->DC( Y_COMP )[j][i];
+ m_me_data_set[2]->Vectors(1)[v][u] = m_me_data_set[level]->Vectors(1)[j][i];
+ if ( num_refs>1 )
+ m_me_data_set[2]->Vectors(2)[v][u] = m_me_data_set[level]->Vectors(2)[j][i];
+
+ }// u
+ }// v
+
+ }// i
+ }// j
+
+ }
+
+}
+
+
+void ModeDecider::DoME(const int xpos , const int ypos , const int level)
+{
+ // Do motion estimation for a prediction unit using the
+ // four vectors derived from the next level as a guide
+
+ MEData& me_data = *(m_me_data_set[level]);
+ const MEData& guide_data = *(m_me_data_set[level+1]);
+
+ // The corresponding location of the guide data
+ const int guide_xpos = xpos<<1;
+ const int guide_ypos = ypos<<1;
+
+ // The location of the lowest level vectors
+ const int xblock = xpos << ( 2 - level);
+ const int yblock = ypos << ( 2 - level);
+
+ // The list of potential candidate vectors
+ CandidateList cand_list;
+
+ // The lambda to use for motion estimation
+ const float lambda = me_data.LambdaMap()[ypos][xpos];
+
+ // The predicting motion vector
+ MVector mv_pred;
+
+ for ( int j=0 ; j<2 ; ++j )
+ for (int i=0 ; i<2 ; ++i )
+ AddNewVlist( cand_list , guide_data.Vectors(1)[guide_ypos+j][guide_xpos+i] , 0 , 0 );
+
+ if (xblock>0 && yblock>0)
+ mv_pred = MvMedian( m_me_data_set[2]->Vectors(1)[yblock][xblock-1] ,
+ m_me_data_set[2]->Vectors(1)[yblock-1][xblock-1],
+ m_me_data_set[2]->Vectors(1)[yblock-1][xblock]);
+ else if (xblock==0 && yblock>0)
+ mv_pred = MvMean( m_me_data_set[2]->Vectors(1)[yblock-1][xblock],
+ m_me_data_set[2]->Vectors(1)[yblock-1][xblock+1]);
+ else if (xblock>0 && yblock==0)
+ mv_pred = MvMean( m_me_data_set[2]->Vectors(1)[yblock][xblock-1],
+ m_me_data_set[2]->Vectors(1)[yblock+1][xblock-1]);
+ else{
+ mv_pred.x = 0;
+ mv_pred.y = 0;
+ }
+
+ BlockMatcher my_bmatch1( *m_pic_data ,
+ *m_ref1_updata ,
+ m_predparams->LumaBParams(level) ,
+ m_predparams->MVPrecision(),
+ me_data.Vectors(1) , me_data.PredCosts(1) );
+ me_data.PredCosts(1)[ypos][xpos].total = 100000000.0f;
+ my_bmatch1.FindBestMatchSubp( xpos , ypos , cand_list, mv_pred, lambda );
+
+ if (num_refs>1)
+ {//do the same for the other reference
+
+ cand_list.clear();
+
+ for ( int j=0 ; j<2 ; ++j )
+ for (int i=0 ; i<2 ; ++i )
+ AddNewVlist( cand_list , guide_data.Vectors(2)[guide_ypos+j][guide_xpos+i] , 0 , 0 );
+
+ if (xblock>0 && yblock>0)
+ mv_pred = MvMedian( m_me_data_set[2]->Vectors(2)[yblock][xblock-1] ,
+ m_me_data_set[2]->Vectors(2)[yblock-1][xblock-1],
+ m_me_data_set[2]->Vectors(2)[yblock-1][xblock]);
+ else if (xblock==0 && yblock>0)
+ mv_pred = MvMean( m_me_data_set[2]->Vectors(2)[yblock-1][xblock],
+ m_me_data_set[2]->Vectors(2)[yblock-1][xblock+1]);
+ else if (xblock>0 && yblock==0)
+ mv_pred = MvMean( m_me_data_set[2]->Vectors(2)[yblock][xblock-1],
+ m_me_data_set[2]->Vectors(2)[yblock+1][xblock-1]);
+ else{
+ mv_pred.x = 0;
+ mv_pred.y = 0;
+ }
+
+ BlockMatcher my_bmatch2( *m_pic_data ,
+ *m_ref2_updata ,
+ m_predparams->LumaBParams(level) ,
+ m_predparams->MVPrecision(),
+ me_data.Vectors(2) , me_data.PredCosts(2) );
+ me_data.PredCosts(2)[ypos][xpos].total = 100000000.0f;
+ my_bmatch2.FindBestMatchSubp( xpos , ypos , cand_list, mv_pred, lambda );
+
+ }
+}
+
+
+
+float ModeDecider::DoUnitDecn(const int xpos , const int ypos , const int level )
+{
+ // For a given prediction unit (SB, subSB or block) find the best
+ // mode, given that the REF1 and REF2 motion estimation has
+ // already been done.
+
+ MEData& me_data = *( m_me_data_set[level] );
+
+ // Coords of the top-leftmost block belonging to this unit
+// const int xblock = xpos<<(2-level);
+// const int yblock = ypos<<(2-level);
+
+ const float loc_lambda = me_data.LambdaMap()[ypos][xpos];
+
+ float unit_cost;
+ float mode_cost(0.0);
+ float min_unit_cost;
+ float best_SAD_value;
+
+ BlockDiffParams dparams;
+
+ dparams.SetBlockLimits( m_predparams->LumaBParams( level ) , *m_pic_data, xpos , ypos);
+
+ // First check REF1 costs //
+ /**************************/
+
+// mode_cost = ModeCost( xblock , yblock )*m_mode_factor[level];
+ me_data.Mode()[ypos][xpos] = REF1_ONLY;
+ me_data.PredCosts(1)[ypos][xpos].total *= m_level_factor[level];
+ min_unit_cost = me_data.PredCosts(1)[ypos][xpos].total + mode_cost;
+ best_SAD_value = me_data.PredCosts(1)[ypos][xpos].SAD;
+
+ if (num_refs>1)
+ {
+ // Next check REF2 costs //
+ /*************************/
+
+// mode_cost = ModeCost( xblock , yblock )*m_mode_factor[level];
+ me_data.PredCosts(2)[ypos][xpos].total *= m_level_factor[level];
+ unit_cost = me_data.PredCosts(2)[ypos][xpos].total + mode_cost;
+ if ( unit_cost<min_unit_cost )
+ {
+ me_data.Mode()[ypos][xpos] = REF2_ONLY;
+ min_unit_cost = unit_cost;
+ best_SAD_value = me_data.PredCosts(2)[ypos][xpos].SAD;
+ }
+
+ // Calculate the cost if we were to use bi-predictions //
+ /****************************************************************/
+// mode_cost = ModeCost( xpos , ypos )*m_mode_factor[level];
+
+ me_data.BiPredCosts()[ypos][xpos].mvcost =
+ me_data.PredCosts(1)[ypos][xpos].mvcost+
+ me_data.PredCosts(2)[ypos][xpos].mvcost;
+
+ me_data.BiPredCosts()[ypos][xpos].SAD = m_bicheckdiff->Diff(dparams ,
+ me_data.Vectors(1)[ypos][xpos] ,
+ me_data.Vectors(2)[ypos][xpos] );
+
+ me_data.BiPredCosts()[ypos][xpos].SetTotal( loc_lambda );
+
+ me_data.BiPredCosts()[ypos][xpos].total *= m_level_factor[level];
+ unit_cost = me_data.BiPredCosts()[ypos][xpos].total + mode_cost;
+
+ if ( unit_cost<min_unit_cost )
+ {
+ me_data.Mode()[ypos][xpos] = REF1AND2;
+ min_unit_cost = unit_cost;
+ best_SAD_value = me_data.BiPredCosts()[ypos][xpos].SAD;
+ }
+
+ }
+
+ // Calculate the cost if we were to code the block as intra //
+ /************************************************************/
+
+ if ( level==2 && best_SAD_value> 4.0*m_predparams->LumaBParams( level ).Xblen()*
+ m_predparams->LumaBParams( level ).Yblen() )
+ {
+// mode_cost = ModeCost( xblock , yblock ) * m_mode_factor[level];
+ me_data.IntraCosts()[ypos][xpos] = m_intradiff->Diff( dparams , me_data.DC( Y_COMP )[ypos][xpos] );
+// me_data.IntraCosts()[ypos][xpos] += loc_lambda *
+// GetDCVar( me_data.DC( Y_COMP )[ypos][xpos] , GetDCPred( xblock , yblock ) );
+ me_data.IntraCosts()[ypos][xpos] *= m_level_factor[level];
+ unit_cost = me_data.IntraCosts()[ypos][xpos] + mode_cost;
+
+ if ( unit_cost<min_unit_cost && me_data.IntraCosts()[ypos][xpos]<0.85*best_SAD_value)
+ {
+ me_data.Mode()[ypos][xpos] = INTRA;
+ min_unit_cost = unit_cost;
+ }
+ }
+
+ return min_unit_cost;
+}
+
+ValueType ModeDecider::GetDCPred( int xblock , int yblock )
+{
+ ValueType dc_pred = 0;
+
+ if ( xblock>0 && m_me_data_set[2]->Mode()[yblock][xblock-1] == INTRA )
+ {
+ dc_pred = m_me_data_set[2]->DC( Y_COMP )[yblock][xblock-1];
+ if ( yblock>0 && m_me_data_set[2]->Mode()[yblock-1][xblock] == INTRA )
+ {
+ dc_pred += m_me_data_set[2]->DC( Y_COMP )[yblock-1][xblock];
+ dc_pred >>= 1;
+ }
+ }
+
+ return dc_pred;
+}
+
+float ModeDecider::ModeCost(const int xindex , const int yindex)
+{
+ // Computes the variation of the given mode, predmode, from its immediate neighbours
+ // First, get a prediction for the mode
+
+ unsigned int mode_predictor = (unsigned int)(REF1_ONLY);
+ const TwoDArray<PredMode>& preddata( m_me_data_set[2]->Mode() );
+
+ unsigned int num_ref1_nbrs( 0 );
+ unsigned int num_ref2_nbrs( 0 );
+
+ if (xindex > 0 && yindex > 0)
+ {
+ num_ref1_nbrs += ((unsigned int)( preddata[yindex-1][xindex] ) ) & 1;
+ num_ref1_nbrs += ((unsigned int)( preddata[yindex-1][xindex-1] ) ) & 1;
+ num_ref1_nbrs += ((unsigned int)( preddata[yindex][xindex-1] ) ) & 1;
+
+ mode_predictor = num_ref1_nbrs>>1;
+
+ num_ref2_nbrs += ((unsigned int)( preddata[yindex-1][xindex] ) ) & 2;
+ num_ref2_nbrs += ((unsigned int)( preddata[yindex-1][xindex-1] ) ) & 2;
+ num_ref2_nbrs += ((unsigned int)( preddata[yindex][xindex-1] ) ) & 2;
+ num_ref2_nbrs >>= 1;
+
+ mode_predictor ^= ( (num_ref2_nbrs>>1)<<1 );
+ }
+ else if (xindex > 0 && yindex == 0)
+ mode_predictor = (unsigned int)( preddata[0][xindex-1] );
+ else if (xindex == 0 && yindex > 0)
+ mode_predictor = (unsigned int)( preddata[yindex-1][0] );
+
+ unsigned int var = (mode_predictor & 1)+((mode_predictor>>1) &1);
+
+ return var*m_me_data_set[2]->LambdaMap()[yindex][xindex];
+}
+
+
+float ModeDecider::GetDCVar( const ValueType dc_val , const ValueType dc_pred)
+{
+ return 4.0*std::abs( static_cast<float>( dc_val - dc_pred ) );
+}
+
+ValueType ModeDecider::GetBlockDC(const PicArray& pic_data,
+ int xunit , int yunit , int split, CompSort cs)
+{
+ BlockDiffParams dparams;
+
+ if ( cs!=Y_COMP )
+ dparams.SetBlockLimits( m_predparams->ChromaBParams( split ) ,
+ pic_data, xunit , yunit);
+ else
+ dparams.SetBlockLimits( m_predparams->LumaBParams( split ) ,
+ pic_data, xunit , yunit);
+
+ IntraBlockDiff intradiff( pic_data );
+
+ return intradiff.CalcDC( dparams );
+}
+
+void ModeDecider::SetDC( const PicArray& pic_data , MEData& me_data , CompSort cs )
+{
+
+ TwoDArray<ValueType>& dcarray = me_data.DC( cs );
+ TwoDArray<ValueType> temp_dcarray (dcarray.LengthY(), dcarray.LengthX() );
+
+ for ( int y=0 ; y<dcarray.LengthY() ; ++y ){
+ for ( int x=0 ; x<dcarray.LengthX() ; ++x ){
+ temp_dcarray[y][x] = GetBlockDC( pic_data , x , y , 2, cs );
+ }
+ }
+
+ for ( int x=0 ; x<dcarray.LengthX() ; ++x ){
+ dcarray[0][x] = temp_dcarray[0][x];
+ }
+ for ( int y=1 ; y<dcarray.LengthY()-1 ; ++y ){
+ dcarray[y][0] = temp_dcarray[y][0];
+ for ( int x=1 ; x<dcarray.LengthX()-1 ; ++x ){
+ dcarray[y][x] = (temp_dcarray[y-1][x-1]+3*temp_dcarray[y-1][x]+temp_dcarray[y-1][x+1]+
+ 3*temp_dcarray[y][x-1]+ 3*temp_dcarray[y][x+1]+
+ temp_dcarray[y+1][x-1]+3*temp_dcarray[y+1][x]+temp_dcarray[y+1][x+1]+8 )>>4;
+ }
+ dcarray[y][dcarray.LastX()] = temp_dcarray[y][dcarray.LastX()];
+ }
+}
+
+void ModeDecider::SetDC( EncQueue& my_buffer , int pic_num )
+{
+ MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData();
+ SetDC( my_buffer.GetPicture( pic_num ).OrigData(Y_COMP) , me_data , Y_COMP );
+ SetDC( my_buffer.GetPicture( pic_num ).OrigData(U_COMP) , me_data , U_COMP );
+ SetDC( my_buffer.GetPicture( pic_num ).OrigData(V_COMP) , me_data , V_COMP );
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.h
new file mode 100644
index 000000000..08f4b6e00
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_mode_decn.h
@@ -0,0 +1,167 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_mode_decn.h,v 1.18 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ME_MODE_DECN_H_
+#define _ME_MODE_DECN_H_
+
+#include <libdirac_common/motion.h>
+#include <libdirac_motionest/block_match.h>
+
+namespace dirac
+{
+ class EncQueue;
+
+ //! Decides between superblock and block prediction modes.
+ /*!
+ Loops over all the superblocks and decides on the best modes. A
+ superblock is a square of 16 blocks. There are three possible
+ splitting levels:
+ level 0 means the superblock is considered as a single block;
+ level 1 means the superblock is considered as 4 larger blocks,
+ termed sub-superblocks;
+ level 0 means the superblock is split right down to blocks.
+
+ In deciding which modes
+ to adopt, the ModeDecider object calculates costs for all
+ permutations, doing motion estimation for the level 1 and level 0
+ modes as these have not been calculated before.
+ The process of decision for each is as follows. For each SB, we loop
+ over the levels, and call DoLevelDecn. DoLevelDecn does motion
+ estimation if it's necessary. Then it assumes that we don't have a
+ common block mode and calls DoUnitDecn which finds the best mode for
+ each unit in the SB at that level, individually. When we've got a
+ best cost for that level we go up to the next one.
+ */
+ class ModeDecider
+ {
+
+ public:
+ //! Constructor
+ /*!
+ The constructor creates arrays for handling the motion vector data
+ at splitting levels 0 and 1, as motion
+ estimation must be performed for these levels.
+ */
+ ModeDecider(const EncoderParams& encp );
+
+ //! Destructor
+ /*!
+ The destructor destroys the classes created in the constructor
+ */
+ ~ModeDecider();
+
+ //! Does the actual mode decision
+ /*!
+ Does the mode decision
+ \param my_buffer the buffer of all the relevant frames
+ \param pic_num the picture number for which motion estimation is being done
+ */
+ void DoModeDecn( EncQueue& my_buffer , int pic_num );
+
+ private:
+ ModeDecider( const ModeDecider& cpy );//private, body-less copy constructor: this class should not be copied
+ ModeDecider& operator=( const ModeDecider& rhs );//private, body-less assignment=: this class should not be assigned
+
+ //functions
+ void DoSBDecn(); //called by do_mode_decn for each SB
+
+ //! Make a mode decision given a particular level of decomposition
+ void DoLevelDecn( int level );
+
+ //! Decide on a mode for a given prediction unit (block, sub-SB or SB)
+ float DoUnitDecn( const int xpos , const int ypos , const int level );
+
+ //! Do motion estimation for a prediction unit at a given level
+ void DoME( const int xpos , const int ypos , const int level );
+
+ //! Return a measure of the cost of coding a given mode
+ float ModeCost( const int xindex , const int yindex );
+
+ //! Get a prediction for the dc value of a block
+ ValueType GetDCPred( int xblock , int yblock );
+
+ //! Get a measure of DC value variance
+ float GetDCVar( const ValueType dc_val , const ValueType dc_pred);
+
+ //! Go through all the intra blocks and extract the chroma dc values to be coded
+ void SetDC( EncQueue& my_buffer, int pic_num);
+
+ //! Called by previous fn for each component
+ void SetDC(const PicArray& pic_data, MEData& me_data,CompSort cs);
+
+ //! Called by previous fn for each block
+ ValueType GetBlockDC(const PicArray& pic_data, int xloc,int yloc,int split, CompSort cs);
+
+
+ // Member data
+ PictureSort m_psort;
+
+ //! A local reference to the encoder parameters
+ const EncoderParams& m_encparams;
+
+ //! A local pointer to the picture prediction params
+ const PicturePredParams* m_predparams;
+
+ //! The Lagrangian parameter for motion estimation
+ float m_lambda;
+
+ //! Correction factor for comparing SAD costs for different SB splittings
+ OneDArray<float> m_level_factor;
+
+
+ //! Correction factor for comparing mode costs for different SB splittings
+ OneDArray<float> m_mode_factor;
+
+ //! Motion vector data for each level of splitting
+ OneDArray< MEData* > m_me_data_set;
+
+ const PicArray* m_pic_data;
+ const PicArray* m_ref1_updata;
+ const PicArray* m_ref2_updata;
+ int num_refs;
+
+ IntraBlockDiff* m_intradiff;
+ BiBlockDiff* m_bicheckdiff;
+
+ //position variables, used in all the mode decisions
+ int m_xsb_loc,m_ysb_loc; //coords of the current SB
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.cpp
new file mode 100644
index 000000000..51376808b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.cpp
@@ -0,0 +1,176 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_subpel.cpp,v 1.20 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_motionest/me_subpel.h>
+#include <libdirac_encoder/enc_queue.h>
+using namespace dirac;
+
+#include <iostream>
+
+using std::vector;
+
+SubpelRefine::SubpelRefine(const EncoderParams& encp):
+ m_encparams(encp),
+ m_nshift(4)
+{
+ //define the relative coordinates of the four neighbours
+ m_nshift[0].x = -1;
+ m_nshift[0].y = 0;
+
+ m_nshift[1].x = -1;
+ m_nshift[1].y = -1;
+
+ m_nshift[2].x = 0;
+ m_nshift[2].y = -1;
+
+ m_nshift[3].x = 1;
+ m_nshift[3].y = -1;
+
+}
+
+void SubpelRefine::DoSubpel( EncQueue& my_buffer,int pic_num )
+{
+ m_predparams = &(my_buffer.GetPicture(pic_num).GetMEData().GetPicPredParams() );
+
+ //main loop for the subpel refinement
+ int ref1,ref2;
+
+ const PictureSort psort = my_buffer.GetPicture(pic_num).GetPparams().PicSort();
+
+ if (psort.IsInter())
+ {
+ // Get the references
+ const vector<int>& refs = my_buffer.GetPicture(pic_num).GetPparams().Refs();
+
+ int num_refs = refs.size();
+ ref1 = refs[0];
+ if (num_refs>1)
+ ref2 = refs[1];
+ else
+ ref2 = ref1;
+
+ const PicArray& pic_data = my_buffer.GetPicture(pic_num).DataForME(m_encparams.CombinedME());
+ const PicArray& refup1_data = my_buffer.GetPicture(ref1).UpDataForME(m_encparams.CombinedME());
+ const PicArray& refup2_data = my_buffer.GetPicture(ref2).UpDataForME(m_encparams.CombinedME());
+
+ MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData();
+
+ // Now match the pictures
+ MatchPic( pic_data , refup1_data , me_data ,1 );
+
+ if (ref1 != ref2 )
+ MatchPic( pic_data , refup2_data , me_data ,2 );
+
+ }
+}
+
+void SubpelRefine::MatchPic(const PicArray& pic_data , const PicArray& refup_data , MEData& me_data ,
+ int ref_id)
+{
+ // Match a picture against a single reference. Loop over all the blocks
+ // doing the matching
+
+ // Initialisation //
+ ////////////////////
+
+ // Provide aliases for the appropriate motion vector data components
+ MvArray& mv_array = me_data.Vectors( ref_id );
+ TwoDArray<MvCostData>& pred_costs = me_data.PredCosts( ref_id );
+
+ // Provide a block matching object to do the work
+ BlockMatcher my_bmatch( pic_data , refup_data , m_predparams->LumaBParams(2) ,
+ m_predparams->MVPrecision() , mv_array , pred_costs );
+
+ // Do the work //
+ /////////////////
+
+ // Loop over all the blocks, doing the work
+
+ for (int yblock=0 ; yblock<m_predparams->YNumBlocks() ; ++yblock){
+ for (int xblock=0 ; xblock<m_predparams->XNumBlocks() ; ++xblock){
+ DoBlock(xblock , yblock , my_bmatch , me_data , ref_id );
+ }// xblock
+ }// yblock
+
+}
+
+void SubpelRefine::DoBlock(const int xblock , const int yblock ,
+ BlockMatcher& my_bmatch, MEData& me_data , const int ref_id )
+{
+ // For each block, home into the sub-pixel vector
+
+ // Provide aliases for the appropriate motion vector data components
+ MvArray& mv_array = me_data.Vectors( ref_id );
+
+ const MVector mv_pred = GetPred( xblock , yblock , mv_array );
+ const float loc_lambda = me_data.LambdaMap()[yblock][xblock];
+
+ my_bmatch.RefineMatchSubp( xblock , yblock , mv_pred, loc_lambda );
+}
+
+MVector SubpelRefine::GetPred(int xblock,int yblock,const MvArray& mvarray)
+{
+ MVector mv_pred;
+ ImageCoords n_coords;
+ vector<MVector> neighbours;
+
+ if (xblock>0 && yblock>0 && xblock<mvarray.LastX())
+ {
+
+ for (int i=0 ; i<m_nshift.Length() ; ++i)
+ {
+ n_coords.x = xblock+m_nshift[i].x;
+ n_coords.y = yblock+m_nshift[i].y;
+ neighbours.push_back(mvarray[n_coords.y][n_coords.x]);
+
+ }// i
+ }
+ else
+ {
+ for (int i=0 ; i<m_nshift.Length(); ++i )
+ {
+ n_coords.x = xblock+m_nshift[i].x;
+ n_coords.y = yblock+m_nshift[i].y;
+ if (n_coords.x>=0 && n_coords.y>=0 && n_coords.x<mvarray.LengthX() && n_coords.y<mvarray.LengthY())
+ neighbours.push_back(mvarray[n_coords.y][n_coords.x]);
+ }// i
+ }
+
+ mv_pred = MvMedian(neighbours);
+
+ return mv_pred;
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.h
new file mode 100644
index 000000000..bd5724928
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_subpel.h
@@ -0,0 +1,115 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_subpel.h,v 1.15 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ME_SUBPEL_H_
+#define _ME_SUBPEL_H_
+
+#include <libdirac_common/common.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_motionest/block_match.h>
+namespace dirac
+{
+
+ class EncQueue;
+ class MvData;
+ class PicArray;
+
+ //! The SubpelRefine class takes pixel-accurate motion vectors and refines them to 1/8-pixel accuracy
+ /*!
+ The SubpelRefine class takes pixel-accurate motion vectors and refines
+ them to 1/8-pixel accuracy. It uses references upconverted by a factor
+ of 2 in each dimension, with the remaining precision gained by doing
+ linear interpolation between values on-the-fly.
+ */
+ class SubpelRefine
+ {
+ public:
+ //! Constructor
+ /*!
+ The constructor initialises the encoder parameters.
+ \param encp the parameters used for controlling ME/MC
+ */
+ SubpelRefine(const EncoderParams& encp);
+
+ //! Destructor
+ ~SubpelRefine(){}
+
+ //! Does the actual sub-pixel refinement
+ /*!
+ Does the actual sub-pixel refinement.
+ \param my_buffer the buffer of pictures being used
+ \param pic_num the picture number on which motion estimation is being performed
+ */
+ void DoSubpel( EncQueue& my_buffer , int pic_num );
+
+ private:
+ //! Private, body-less copy constructor: this class should not be copied
+ SubpelRefine( const SubpelRefine& cpy );
+
+ //! Private, body-less assignment=: this class should not be assigned
+ SubpelRefine& operator=( const SubpelRefine& rhs );
+
+ //! Match a picture from its (upconverted) reference, and record the block mvs
+ void MatchPic(const PicArray& pic_data , const PicArray& refup_data , MEData& me_data ,
+ int ref_id);
+
+ //! Match an individual block
+ void DoBlock( const int xblock , const int yblock ,
+ BlockMatcher& my_bmatch, MEData& me_data , const int ref_id );
+
+ //! Get a prediction for a block MV from the neighbouring blocks
+ MVector GetPred( int xblock , int yblock , const MvArray& mvarray );
+
+ //member variables
+
+ //! Local reference to the encoder params
+ const EncoderParams& m_encparams;
+
+ //! A local pointer to the encoder params
+ const PicturePredParams* m_predparams;
+
+ //! The list of candidate vectors being tested
+ CandidateList m_cand_list;
+
+ //! The relative coords of the set of neighbours used to generate MV predictions
+ OneDArray<ImageCoords> m_nshift;
+
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.cpp
new file mode 100644
index 000000000..007334151
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.cpp
@@ -0,0 +1,1785 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_utils.cpp,v 1.23 2008/10/21 04:55:46 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Peter Meerwald (pmeerw@users.sourceforge.net)
+* Steve Bearcroft (bearcrsw@users.sourceforge.net)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+///////////////////////////////////
+//-------------------------------//
+//utilities for motion estimation//
+//-------------------------------//
+///////////////////////////////////
+
+#if defined(HAVE_MMX)
+#include <climits>
+#endif
+#include <libdirac_motionest/me_utils.h>
+#include <libdirac_motionest/me_utils_mmx.h>
+#include <libdirac_common/common.h>
+
+using namespace dirac;
+
+#include <algorithm>
+//#define INTRA_HAAR
+
+void BlockDiffParams::SetBlockLimits( const OLBParams& bparams ,
+ const PicArray& m_pic_data ,
+ const int xbpos , const int ybpos)
+{
+ const int loc_xp = xbpos * bparams.Xbsep() - bparams.Xoffset();
+ const int loc_yp = ybpos * bparams.Ybsep() - bparams.Yoffset();
+
+ m_xp=std::max( loc_xp , 0 );
+ m_yp=std::max( loc_yp , 0 );
+
+ m_xl = bparams.Xblen() - m_xp + loc_xp;
+ m_yl = bparams.Yblen() - m_yp + loc_yp;
+
+ //constrain block lengths to fall within the picture
+ m_xl = ( ( m_xp + m_xl - 1) > m_pic_data.LastX() ) ? ( m_pic_data.LastX() + 1 - m_xp ): m_xl;
+ m_yl = ( ( m_yp + m_yl - 1) > m_pic_data.LastY() ) ? ( m_pic_data.LastY() + 1 - m_yp ) : m_yl;
+
+ m_xend = m_xp+m_xl;
+ m_yend = m_yp+m_yl;
+
+}
+
+// Block difference class functions
+
+// Constructors ...
+
+BlockDiff::BlockDiff(const PicArray& ref,const PicArray& pic) :
+ m_pic_data( pic ),
+ m_ref_data( ref )
+{}
+
+PelBlockDiff::PelBlockDiff( const PicArray& ref , const PicArray& pic ) :
+ BlockDiff( ref , pic )
+{}
+
+IntraBlockDiff::IntraBlockDiff( const PicArray& pic ) :
+ m_pic_data( pic )
+{}
+
+BiBlockDiff::BiBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
+ const PicArray& pic) :
+ m_pic_data( pic ),
+ m_ref_data1( ref1 ),
+ m_ref_data2( ref2 )
+{}
+
+BlockDiffUp::BlockDiffUp( const PicArray& ref , const PicArray& pic ):
+ BlockDiff( ref , pic )
+{}
+
+BlockDiffHalfPel::BlockDiffHalfPel( const PicArray& ref , const PicArray& pic ) :
+ BlockDiffUp( ref , pic )
+{}
+
+BlockDiffQuarterPel::BlockDiffQuarterPel( const PicArray& ref , const PicArray& pic ) :
+ BlockDiffUp( ref , pic )
+{}
+
+BlockDiffEighthPel::BlockDiffEighthPel( const PicArray& ref , const PicArray& pic ) :
+ BlockDiffUp( ref , pic )
+{}
+
+BiBlockHalfPel::BiBlockHalfPel( const PicArray& ref1 , const PicArray& ref2 ,
+ const PicArray& pic ):
+ BiBlockDiff( ref1 , ref2 , pic)
+{}
+
+BiBlockQuarterPel::BiBlockQuarterPel( const PicArray& ref1 , const PicArray& ref2 ,
+ const PicArray& pic ):
+ BiBlockDiff( ref1 , ref2 , pic)
+{}
+
+BiBlockEighthPel::BiBlockEighthPel( const PicArray& ref1 , const PicArray& ref2 ,
+ const PicArray& pic ):
+ BiBlockDiff( ref1 , ref2 , pic)
+{}
+
+
+// Difference functions ...
+
+float PelBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+
+ CalcValueType sum( 0 );
+
+ const ImageCoords ref_start( dparams.Xp()+mv.x , dparams.Yp()+mv.y );
+ const ImageCoords ref_stop( dparams.Xend()+mv.x , dparams.Yend()+mv.y );
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ if ( !bounds_check )
+ {
+#if defined(HAVE_MMX)
+ return static_cast<float>(simple_block_diff_mmx_4(dparams, mv, m_pic_data, m_ref_data, INT_MAX));
+#else
+ ValueType diff;
+ for ( int j=dparams.Yp() ; j<dparams.Yp()+dparams.Yl() ; ++j )
+ {
+ for(int i=dparams.Xp() ; i< dparams.Xp()+dparams.Xl() ; ++i )
+ {
+ diff = m_pic_data[j][i]-m_ref_data[j+mv.y][i+mv.x];
+ sum += std::abs( diff );
+ }// i
+ }// j
+#endif /* HAVE_MMX */
+ }
+ else
+ {
+#if defined (HAVE_MMX)
+ return static_cast<float>(bchk_simple_block_diff_mmx_4(dparams, mv, m_pic_data, m_ref_data, INT_MAX));
+#else
+ ValueType diff;
+ for ( int j=dparams.Yp() ; j < dparams.Yp()+dparams.Yl() ; ++j )
+ {
+ for( int i=dparams.Xp() ; i < dparams.Xp()+dparams.Xl() ; ++i )
+ {
+ diff = m_pic_data[j][i] - m_ref_data[BChk(j+mv.y , m_ref_data.LengthY())][BChk(i+mv.x , m_ref_data.LengthX())];
+ sum += std::abs( diff );
+
+ }// i
+ }// j
+
+#endif /* HAVE_MMX */
+ }
+
+ return static_cast<float>( sum );
+}
+
+void PelBlockDiff::Diff( const BlockDiffParams& dparams,
+ const MVector& mv,
+ float& best_sum,
+ MVector& best_mv )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return;
+ }
+
+ CalcValueType sum( 0 );
+
+ const ImageCoords ref_start( dparams.Xp()+mv.x , dparams.Yp()+mv.y );
+ const ImageCoords ref_stop( dparams.Xend()+mv.x , dparams.Yend()+mv.y );
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ if ( !bounds_check )
+ {
+#if defined (HAVE_MMX)
+ sum = simple_block_diff_mmx_4(dparams, mv, m_pic_data, m_ref_data, static_cast<int>(best_sum));
+ if (sum < best_sum)
+ {
+ best_sum = sum;
+ best_mv = mv;
+ }
+ return;
+#else
+ ValueType diff;
+ ValueType *pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() ); // - go down a row and back along
+
+
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+
+ for( int y=dparams.Yl(); y>0; --y, pic_curr+=pic_next, ref_curr+=pic_next )
+ {
+ for( int x=dparams.Xl(); x>0; --x, ++pic_curr, ++ref_curr )
+ {
+ diff = (*pic_curr)-(*ref_curr);
+ sum += std::abs( diff );
+ }// x
+
+ if ( sum>=best_sum )
+ return;
+
+ }// y
+#endif /* HAVE_MMX */
+ }
+ else
+ {
+#if defined (HAVE_MMX)
+ sum = (bchk_simple_block_diff_mmx_4(dparams, mv, m_pic_data, m_ref_data, static_cast<int>(best_sum)));
+ if (sum < best_sum)
+ {
+ best_sum = sum;
+ best_mv = mv;
+ }
+ return;
+#else
+ ValueType diff;
+ for ( int j=dparams.Yp() ; j<dparams.Yend() ; ++j )
+ {
+ for( int i=dparams.Xp() ; i<dparams.Xend() ; ++i )
+ {
+ diff = m_pic_data[j][i] - m_ref_data[BChk(j+mv.y , m_ref_data.LengthY())][BChk(i+mv.x , m_ref_data.LengthX())];
+ sum += std::abs( diff );
+
+ }// i
+
+ if ( sum>=best_sum )
+ return;
+
+ }// j
+#endif /* HAVE_MMX */
+ }
+
+ best_sum = sum;
+ best_mv = mv;
+
+}
+
+ValueType IntraBlockDiff::CalcDC( const BlockDiffParams& dparams ){
+
+ CalcValueType int_dc( 0 );
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+
+ for ( int j=dparams.Yp() ; j<dparams.Yp()+dparams.Yl() ; ++j)
+ for(int i=dparams.Xp(); i<dparams.Xp()+dparams.Xl() ; ++i )
+ int_dc += static_cast<int>( m_pic_data[j][i] );
+
+ int_dc /= ( dparams.Xl() * dparams.Yl() );
+
+ return static_cast<ValueType>( int_dc );
+}
+
+#ifdef INTRA_HAAR
+float IntraBlockDiff::Diff( const BlockDiffParams& dparams , ValueType& dc_val )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ dc_val = 0;
+ return 0;
+ }
+
+ dc_val = CalcDC(dparams);
+
+ // Now compute the resulting SAD
+ ValueType dc( dc_val );
+ CalcValueType intra_cost( 0 );
+
+ for (int j=dparams.Yp(); j<dparams.Yend() ; j+=2){
+ for( int i=dparams.Xp() ; i<dparams.Xend() ;i+=2 ){
+ intra_cost += std::abs( m_pic_data[j][i]
+ + m_pic_data[j][i+1]
+ + m_pic_data[j+1][i]
+ + m_pic_data[j+1][i+1]
+ - 4*dc );
+ intra_cost += std::abs( m_pic_data[j][i]
+ + m_pic_data[j][i+1]
+ - m_pic_data[j+1][i]
+ - m_pic_data[j+1][i+1] );
+ intra_cost += std::abs( m_pic_data[j][i]
+ - m_pic_data[j][i+1]
+ + m_pic_data[j+1][i]
+ - m_pic_data[j+1][i+1] );
+ intra_cost += std::abs( m_pic_data[j][i]
+ - m_pic_data[j][i+1]
+ - m_pic_data[j+1][i]
+ + m_pic_data[j+1][i+1] );
+ }
+ }
+
+ return static_cast<float>( intra_cost );
+}
+
+#else
+
+float IntraBlockDiff::Diff( const BlockDiffParams& dparams , ValueType& dc_val )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ dc_val = 0;
+ return 0;
+ }
+
+ //computes the cost if block is predicted by its dc component
+#if defined(HAVE_MMX)
+ CalcValueType intra_cost =
+ simple_intra_block_diff_mmx_4 (dparams, m_pic_data, dc_val);
+
+#ifdef DIRAC_DEBUG
+ CalcValueType int_dc( 0 );
+ ValueType non_mmx_dc(0);
+
+ for ( int j=dparams.Yp() ; j<dparams.Yp()+dparams.Yl() ; ++j)
+ for(int i=dparams.Xp(); i<dparams.Xp()+dparams.Xl() ; ++i )
+ int_dc += static_cast<int>( m_pic_data[j][i] );
+
+ int_dc /= ( dparams.Xl() * dparams.Yl() );
+
+ non_mmx_dc = static_cast<ValueType>( int_dc );
+
+ // Now compute the resulting SAD
+ ValueType dc( non_mmx_dc );
+ CalcValueType non_mmx_intra_cost( 0 );
+
+ for (int j=dparams.Yp(); j<dparams.Yend() ; ++j)
+ for( int i=dparams.Xp() ; i<dparams.Xend() ;++i )
+ non_mmx_intra_cost += std::abs( m_pic_data[j][i] - dc );
+
+ if (non_mmx_dc != dc_val || non_mmx_intra_cost != intra_cost)
+ {
+ std::cerr << "MMX vals: dc=" << dc_val;
+ std::cerr << " cost=" << intra_cost << std::endl;
+ //print_arr (pic_data, width[i%5], height[i%5]);
+ std::cerr << "non-MMX vals: dc=" << non_mmx_dc;
+ std::cerr << " cost=" << non_mmx_intra_cost << std::endl;
+ }
+#endif
+ return static_cast<float>( intra_cost );
+#else
+ CalcValueType int_dc( 0 );
+
+ for ( int j=dparams.Yp() ; j<dparams.Yp()+dparams.Yl() ; ++j)
+ for(int i=dparams.Xp(); i<dparams.Xp()+dparams.Xl() ; ++i )
+ int_dc += static_cast<int>( m_pic_data[j][i] );
+
+ int_dc /= ( dparams.Xl() * dparams.Yl() );
+
+ dc_val = static_cast<ValueType>( int_dc );
+
+ // Now compute the resulting SAD
+ ValueType dc( dc_val );
+ CalcValueType intra_cost( 0 );
+
+ for (int j=dparams.Yp(); j<dparams.Yend() ; ++j)
+ for( int i=dparams.Xp() ; i<dparams.Xend() ;++i )
+ intra_cost += std::abs( m_pic_data[j][i] - dc );
+
+ return static_cast<float>( intra_cost );
+#endif //HAVE_MMX
+}
+#endif
+
+float BlockDiffHalfPel::Diff( const BlockDiffParams& dparams ,
+ const MVector& mv )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+ //Where to start in the upconverted image
+ const ImageCoords ref_start( ( dparams.Xp()<<1 ) + mv.x ,( dparams.Yp()<<1 ) + mv.y );
+ const ImageCoords ref_stop( ref_start.x+(dparams.Xl()<<1) , ref_start.y+(dparams.Yl()<<1));
+
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ float sum( 0 );
+
+ if ( !bounds_check )
+ {
+#if defined (HAVE_MMX)
+ MVector rmdr(0,0);
+ const ImageCoords start_pos(dparams.Xp(), dparams.Yp());
+ const ImageCoords end_pos(dparams.Xp() + dparams.Xl(), dparams.Yp() + dparams.Yl());
+ sum = simple_block_diff_up_mmx_4 (m_pic_data, m_ref_data,
+ start_pos, end_pos,
+ ref_start, ref_stop,
+ rmdr,
+ sum,
+ static_cast<float>(INT_MAX));
+#else
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += std::abs( *ref_curr - *pic_curr );
+ }// x
+ }// y
+#endif
+
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+ for( int y=dparams.Yl(), ry=ref_start.y, by=BChk(ry,m_ref_data.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data.LengthY()))
+ {
+ for( int x=dparams.Xl() , rx=ref_start.x , bx=BChk(rx,m_ref_data.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , bx=BChk(rx,m_ref_data.LengthX()))
+ {
+ sum += std::abs( m_ref_data[by][bx] -*pic_curr);
+ }// x
+ }// y
+
+ }
+
+ return sum;
+
+}
+
+void BlockDiffHalfPel::Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return;
+ }
+
+ //Where to start in the upconverted image
+ const ImageCoords ref_start( ( dparams.Xp()<<1 ) + mv.x ,( dparams.Yp()<<1 ) + mv.y );
+ const ImageCoords ref_stop( ref_start.x+(dparams.Xl()<<1) , ref_start.y+(dparams.Yl()<<1));
+
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ const float start_val( mvcost*lambda );
+ float sum( start_val );
+
+ if ( !bounds_check )
+ {
+#if defined (HAVE_MMX)
+
+ const ImageCoords start_pos(dparams.Xp(), dparams.Yp());
+ const ImageCoords end_pos(dparams.Xp() + dparams.Xl(), dparams.Yp() + dparams.Yl());
+ MVector rmdr(0,0);
+ sum = simple_block_diff_up_mmx_4 (m_pic_data, m_ref_data,
+ start_pos, end_pos,
+ ref_start, ref_stop,
+ rmdr,
+ sum,
+ best_costs.total);
+ if ( sum>=best_costs.total )
+ return;
+#else
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += std::abs( *ref_curr - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+#endif
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+ for( int y=dparams.Yl(), ry=ref_start.y, by=BChk(ry,m_ref_data.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data.LengthY()))
+ {
+ for( int x=dparams.Xl() , rx=ref_start.x , bx=BChk(rx,m_ref_data.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , bx=BChk(rx,m_ref_data.LengthX()))
+ {
+ sum += std::abs( m_ref_data[by][bx] -*pic_curr);
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+
+ }
+
+ best_mv = mv;
+ best_costs.total = sum;
+ best_costs.mvcost = mvcost;
+ best_costs.SAD = sum - start_val;
+}
+
+float BlockDiffQuarterPel::Diff( const BlockDiffParams& dparams , const MVector& mv )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+ // Set up the start point in the reference image by rounding the motion vector
+ // to 1/2 pel accuracy.NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>1 , mv.y>>1 );
+
+ //Get the remainder after rounding. NB rmdr values always 0 or 1
+ const MVector rmdr( mv.x & 1 , mv.y & 1 );
+
+ //Where to start in the upconverted image
+ const ImageCoords ref_start( ( dparams.Xp()<<1 ) + roundvec.x ,( dparams.Yp()<<1 ) + roundvec.y );
+ const ImageCoords ref_stop( ref_start.x+(dparams.Xl()<<1) , ref_start.y+(dparams.Yl()<<1));
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ float sum( 0.0f );
+ CalcValueType temp;
+
+
+ if ( !bounds_check )
+ {
+#if defined (HAVE_MMX)
+ const ImageCoords start_pos(dparams.Xp(), dparams.Yp());
+ const ImageCoords end_pos(dparams.Xp() + dparams.Xl(), dparams.Yp() + dparams.Yl());
+
+ sum = simple_block_diff_up_mmx_4 (m_pic_data, m_ref_data,
+ start_pos, end_pos,
+ ref_start, ref_stop,
+ rmdr,
+ sum,
+ static_cast<float>(INT_MAX));
+
+#else
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += std::abs( *ref_curr - *pic_curr );
+ }// x
+ }// y
+ }
+ else if( rmdr.y == 0 )
+ {
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+ }// y
+ }
+ else if( rmdr.x == 0 )
+ {
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[m_ref_data.LengthX()] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+ }// y
+ }
+ else
+ {
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[m_ref_data.LengthX()+0] ) +
+ CalcValueType( ref_curr[m_ref_data.LengthX()+1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+ }// y
+ }
+#endif // HAVE_MMX
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+
+ // weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (2 - rmdr.x) * (2 - rmdr.y), //tl
+ rmdr.x * (2 - rmdr.y), //tr
+ (2 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+ const int refXlen( m_ref_data.LengthX() );
+ const int refYlen( m_ref_data.LengthY() );
+
+ for(int y = dparams.Yp(), uY = ref_start.y,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen);
+ y < dparams.Yend(); ++y, uY += 2,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen))
+ {
+ for(int x = dparams.Xp(), uX = ref_start.x,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen);
+ x < dparams.Xend(); ++x, uX += 2,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen))
+ {
+
+ temp = ( linear_wts[0] * CalcValueType( m_ref_data[BuY][BuX] ) +
+ linear_wts[1] * CalcValueType( m_ref_data[BuY][BuX1] ) +
+ linear_wts[2] * CalcValueType( m_ref_data[BuY1][BuX] )+
+ linear_wts[3] * CalcValueType( m_ref_data[BuY1][BuX1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( temp - m_pic_data[y][x] );
+ }// x
+ }// y
+
+ }
+
+ return sum;
+
+}
+
+void BlockDiffQuarterPel::Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv)
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return;
+ }
+
+ // Set up the start point in the reference image by rounding the motion vector
+ // to 1/2 pel accuracy.NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>1 , mv.y>>1 );
+
+ //Get the remainder after rounding. NB rmdr values always 0 or 1
+ const MVector rmdr( mv.x & 1 , mv.y & 1 );
+
+ //Where to start in the upconverted image
+ const ImageCoords ref_start( ( dparams.Xp()<<1 ) + roundvec.x ,( dparams.Yp()<<1 ) + roundvec.y );
+ const ImageCoords ref_stop( ref_start.x+(dparams.Xl()<<1) , ref_start.y+(dparams.Yl()<<1));
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ const float start_val( mvcost*lambda );
+ float sum( start_val );
+
+ CalcValueType temp;
+
+ if ( !bounds_check )
+ {
+#if defined (HAVE_MMX)
+ const ImageCoords start_pos(dparams.Xp(), dparams.Yp());
+ const ImageCoords end_pos(dparams.Xp() + dparams.Xl(), dparams.Yp() + dparams.Yl());
+
+ sum = simple_block_diff_up_mmx_4 (m_pic_data, m_ref_data,
+ start_pos, end_pos,
+ ref_start, ref_stop,
+ rmdr,
+ sum,
+ best_costs.total);
+
+ if ( sum>=best_costs.total )
+ return;
+#else
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += std::abs( *ref_curr - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+ }// y
+ }
+ else if( rmdr.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+ }// y
+ }
+ else if( rmdr.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[m_ref_data.LengthX()] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[m_ref_data.LengthX()+0] ) +
+ CalcValueType( ref_curr[m_ref_data.LengthX()+1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+
+ }
+#endif // HAVE_MMX
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+
+ // weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (2 - rmdr.x) * (2 - rmdr.y), //tl
+ rmdr.x * (2 - rmdr.y), //tr
+ (2 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+ const int refXlen( m_ref_data.LengthX() );
+ const int refYlen( m_ref_data.LengthY() );
+
+ for(int y = dparams.Yp(), uY = ref_start.y,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen);
+ y < dparams.Yend(); ++y, uY += 2,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen))
+ {
+ for(int x = dparams.Xp(), uX = ref_start.x,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen);
+ x < dparams.Xend(); ++x, uX += 2,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen))
+ {
+
+ temp = ( linear_wts[0] * CalcValueType( m_ref_data[BuY][BuX] ) +
+ linear_wts[1] * CalcValueType( m_ref_data[BuY][BuX1] ) +
+ linear_wts[2] * CalcValueType( m_ref_data[BuY1][BuX] )+
+ linear_wts[3] * CalcValueType( m_ref_data[BuY1][BuX1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( temp - m_pic_data[y][x] );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+
+ }
+
+ // Since we've got here, we must have beaten the best cost to date
+
+ best_mv = mv;
+ best_costs.total = sum;
+ best_costs.mvcost = mvcost;
+ best_costs.SAD = sum - start_val;
+}
+
+float BlockDiffEighthPel::Diff( const BlockDiffParams& dparams , const MVector& mv )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+ //Set up the start point in the reference image by rounding the motion vector
+ //NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>2 , mv.y>>2 );
+
+ //Get the remainder after rounding. NB rmdr values always 0,1,2 or 3
+ const MVector rmdr( mv.x & 3 , mv.y & 3 );
+
+ //Where to start in the upconverted image
+ const ImageCoords ref_start( ( dparams.Xp()<<1 ) + roundvec.x ,( dparams.Yp()<<1 ) + roundvec.y );
+ const ImageCoords ref_stop( ref_start.x+(dparams.Xl()<<1) , ref_start.y+(dparams.Yl()<<1));
+
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+
+ //weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (4 - rmdr.x) * (4 - rmdr.y), //tl
+ rmdr.x * (4 - rmdr.y), //tr
+ (4 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ float sum( 0.0f );
+
+ CalcValueType temp;
+
+ if ( !bounds_check )
+ {
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += CalcValueType( std::abs( ref_curr[0] - *pic_curr ) );
+ }// x
+ }// y
+ }
+ else if( rmdr.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = (( linear_wts[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts[1] * CalcValueType( ref_curr[1] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( temp - *pic_curr );
+ }// x
+ }// y
+ }
+ else if( rmdr.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = (( linear_wts[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts[2] * CalcValueType( ref_curr[m_ref_data.LengthX()+0] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( temp - *pic_curr );
+ }// x
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = (( linear_wts[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts[1] * CalcValueType( ref_curr[1] ) +
+ linear_wts[2] * CalcValueType( ref_curr[m_ref_data.LengthX()+0] ) +
+ linear_wts[3] * CalcValueType( ref_curr[m_ref_data.LengthX()+1] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( temp - *pic_curr );
+ }// x
+ }// y
+ }
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ const int refXlen( m_ref_data.LengthX() );
+ const int refYlen( m_ref_data.LengthY() );
+
+ for(int y = dparams.Yp(), uY = ref_start.y,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen);
+ y < dparams.Yend(); ++y, uY += 2,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen))
+ {
+ for(int x = dparams.Xp(), uX = ref_start.x,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen);
+ x < dparams.Xend(); ++x, uX += 2,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen))
+ {
+
+ temp = ( linear_wts[0] * CalcValueType( m_ref_data[BuY][BuX] ) +
+ linear_wts[1] * CalcValueType( m_ref_data[BuY][BuX1] ) +
+ linear_wts[2] * CalcValueType( m_ref_data[BuY1][BuX] )+
+ linear_wts[3] * CalcValueType( m_ref_data[BuY1][BuX1] ) +
+ 8
+ ) >> 4;
+ sum += std::abs( temp - m_pic_data[y][x] );
+ }// x
+ }// y
+
+ }
+
+ return sum;
+}
+
+void BlockDiffEighthPel::Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv)
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return;
+ }
+ //Set up the start point in the reference image by rounding the motion vector
+ //NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec( mv.x>>2 , mv.y>>2 );
+
+ //Get the remainder after rounding. NB rmdr values always 0,1,2 or 3
+ const MVector rmdr( mv.x & 3 , mv.y & 3 );
+
+ //Where to start in the upconverted image
+ const ImageCoords ref_start( ( dparams.Xp()<<1 ) + roundvec.x ,( dparams.Yp()<<1 ) + roundvec.y );
+ const ImageCoords ref_stop( ref_start.x+(dparams.Xl()<<1) , ref_start.y+(dparams.Yl()<<1));
+
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+
+ //weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts[4] = { (4 - rmdr.x) * (4 - rmdr.y), //tl
+ rmdr.x * (4 - rmdr.y), //tr
+ (4 - rmdr.x) * rmdr.y, //bl
+ rmdr.x * rmdr.y }; //br
+
+ bool bounds_check( false );
+
+ if ( ref_start.x<0 ||
+ ref_stop.x >= m_ref_data.LengthX() ||
+ ref_start.y<0 ||
+ ref_stop.y >= m_ref_data.LengthY() )
+ bounds_check = true;
+
+ const float start_val( mvcost*lambda );
+ float sum( start_val );
+
+ CalcValueType temp;
+
+ if ( !bounds_check )
+ {
+ ValueType *ref_curr = &m_ref_data[ref_start.y][ref_start.x];
+ const int ref_next( (m_ref_data.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ if( rmdr.x == 0 && rmdr.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += CalcValueType( std::abs( ref_curr[0] - *pic_curr ) );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+ }
+ else if( rmdr.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = (( linear_wts[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts[1] * CalcValueType( ref_curr[1] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+ }
+ else if( rmdr.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = (( linear_wts[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts[2] * CalcValueType( ref_curr[m_ref_data.LengthX()+0] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2 )
+ {
+ temp = (( linear_wts[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts[1] * CalcValueType( ref_curr[1] ) +
+ linear_wts[2] * CalcValueType( ref_curr[m_ref_data.LengthX()+0] ) +
+ linear_wts[3] * CalcValueType( ref_curr[m_ref_data.LengthX()+1] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+ }
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ const int refXlen( m_ref_data.LengthX() );
+ const int refYlen( m_ref_data.LengthY() );
+
+ for(int y = dparams.Yp(), uY = ref_start.y,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen);
+ y < dparams.Yend(); ++y, uY += 2,BuY=BChk(uY,refYlen),BuY1=BChk(uY+1,refYlen))
+ {
+ for(int x = dparams.Xp(), uX = ref_start.x,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen);
+ x < dparams.Xend(); ++x, uX += 2,BuX=BChk(uX,refXlen),BuX1=BChk(uX+1,refXlen))
+ {
+
+ temp = ( linear_wts[0] * CalcValueType( m_ref_data[BuY][BuX] ) +
+ linear_wts[1] * CalcValueType( m_ref_data[BuY][BuX1] ) +
+ linear_wts[2] * CalcValueType( m_ref_data[BuY1][BuX] )+
+ linear_wts[3] * CalcValueType( m_ref_data[BuY1][BuX1] ) +
+ 8
+ ) >> 4;
+ sum += std::abs( temp - m_pic_data[y][x] );
+ }// x
+
+ if ( sum>=best_costs.total )
+ return;
+
+ }// y
+
+ }
+
+ // If we've got here we must have done better than the best costs so far
+ best_mv = mv;
+ best_costs.total = sum;
+ best_costs.mvcost = mvcost;
+ best_costs.SAD = sum - start_val;
+}
+
+float BiBlockHalfPel::Diff( const BlockDiffParams& dparams ,
+ const MVector& mv1 ,
+ const MVector& mv2 )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+ // First create a difference array, and subtract the reference 1 data into it
+ TwoDArray<ValueType> diff_array( dparams.Yl() , dparams.Xl() );
+
+ //Where to start in the upconverted images
+ const ImageCoords ref_start1( ( dparams.Xp()<<1 ) + mv1.x ,( dparams.Yp()<<1 ) + mv1.y );
+ const ImageCoords ref_stop1( ref_start1.x+(dparams.Xl()<<1) , ref_start1.y+(dparams.Yl()<<1));
+
+ const ImageCoords ref_start2( ( dparams.Xp()<<1 ) + mv2.x ,( dparams.Yp()<<1 ) + mv2.y );
+ const ImageCoords ref_stop2( ref_start2.x+(dparams.Xl()<<1) , ref_start2.y+(dparams.Yl()<<1));
+
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+
+ ValueType* diff_curr = &diff_array[0][0];
+
+ bool bounds_check( false );
+
+ if ( ref_start1.x<0 ||
+ ref_stop1.x >= m_ref_data1.LengthX() ||
+ ref_start1.y<0 ||
+ ref_stop1.y >= m_ref_data1.LengthY() )
+ bounds_check = true;
+
+ if ( !bounds_check )
+ {
+ ValueType *ref_curr = &m_ref_data1[ref_start1.y][ref_start1.x];
+ const int ref_next( (m_ref_data1.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next)
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ *diff_curr = ( (*pic_curr)<<1 ) - *ref_curr;
+
+ }// x
+ }// y
+
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=dparams.Yl(), ry=ref_start1.y, by=BChk(ry,m_ref_data1.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data1.LengthY()))
+ {
+ for( int x=dparams.Xl() , rx=ref_start1.x , bx=BChk(rx,m_ref_data1.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , ++diff_curr, bx=BChk(rx,m_ref_data1.LengthX()))
+ {
+ *diff_curr = ( (*pic_curr)<<1 ) - m_ref_data1[by][bx];
+ }// x
+ }// y
+
+ }
+
+ // Now do the other reference
+
+ bounds_check = false;
+
+ if ( ref_start2.x<0 ||
+ ref_stop2.x >= m_ref_data2.LengthX() ||
+ ref_start2.y<0 ||
+ ref_stop2.y >= m_ref_data2.LengthY() )
+ bounds_check = true;
+
+ float sum( 0 );
+
+ diff_curr = &diff_array[0][0];
+ ValueType temp;
+
+ if ( !bounds_check )
+ {
+ ValueType *ref_curr = &m_ref_data2[ref_start2.y][ref_start2.x];
+ const int ref_next( (m_ref_data2.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next)
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (*diff_curr - *ref_curr )>>1;
+ sum += std::abs( temp );
+
+ }// x
+ }// y
+
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=dparams.Yl(), ry=ref_start2.y, by=BChk(ry,m_ref_data2.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data2.LengthY()))
+ {
+ for( int x=dparams.Xl() , rx=ref_start2.x , bx=BChk(rx,m_ref_data2.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , ++diff_curr, bx=BChk(rx,m_ref_data2.LengthX()))
+ {
+ temp = (*diff_curr - m_ref_data2[by][bx] )>>1;
+ sum += std::abs( temp );
+ }// x
+ }// y
+
+ }
+
+ return sum;
+
+}
+
+float BiBlockQuarterPel::Diff( const BlockDiffParams& dparams ,
+ const MVector& mv1 ,
+ const MVector& mv2 )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+ // First create a difference array, and subtract the reference 1 data into it
+ TwoDArray<ValueType> diff_array( dparams.Yl() , dparams.Xl() );
+
+ // Set up the start point in the reference images by rounding the motion vectors
+ // to 1/2 pel accuracy.NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec1 ( mv1.x>>1 , mv1.y>>1 );
+ const MVector roundvec2 ( mv2.x>>1 , mv2.y>>1 );
+
+ //Get the remainders after rounding. NB rmdr values always 0 or 1
+ const MVector rmdr1( mv1.x & 1 , mv1.y & 1 );
+ const MVector rmdr2( mv2.x & 1 , mv2.y & 1 );
+
+ //Where to start in the upconverted images
+ const ImageCoords ref_start1( ( dparams.Xp()<<1 ) + roundvec1.x ,( dparams.Yp()<<1 ) + roundvec1.y );
+ const ImageCoords ref_stop1( ref_start1.x+(dparams.Xl()<<1) , ref_start1.y+(dparams.Yl()<<1));
+
+ const ImageCoords ref_start2( ( dparams.Xp()<<1 ) + roundvec2.x ,( dparams.Yp()<<1 ) + roundvec2.y );
+ const ImageCoords ref_stop2( ref_start2.x+(dparams.Xl()<<1) , ref_start2.y+(dparams.Yl()<<1));
+
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+
+ ValueType* diff_curr = &diff_array[0][0];
+
+ bool bounds_check( false );
+
+ if ( ref_start1.x<0 ||
+ ref_stop1.x >= m_ref_data1.LengthX() ||
+ ref_start1.y<0 ||
+ ref_stop1.y >= m_ref_data1.LengthY() )
+ bounds_check = true;
+
+ ValueType temp;
+
+ if ( !bounds_check )
+ {
+#if defined (HAVE_MMX)
+ const ImageCoords start_pos(dparams.Xp(), dparams.Yp());
+ const ImageCoords end_pos(dparams.Xp() + dparams.Xl(), dparams.Yp() + dparams.Yl());
+
+ simple_biblock_diff_pic_mmx_4 (m_pic_data, m_ref_data1, diff_array,
+ start_pos, end_pos,
+ ref_start1, ref_stop1,
+ rmdr1);
+#else
+ ValueType *ref_curr = &m_ref_data1[ref_start1.y][ref_start1.x];
+ const int ref_next( (m_ref_data1.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+
+
+ if( rmdr1.x == 0 && rmdr1.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ *diff_curr = ( (*pic_curr)<<1 ) - *ref_curr;
+ }// x
+ }// y
+ }
+ else if( rmdr1.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+ else if( rmdr1.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[m_ref_data1.LengthX()] ) +
+ 1
+ ) >> 1;
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[m_ref_data1.LengthX()+0] ) +
+ CalcValueType( ref_curr[m_ref_data1.LengthX()+1] ) +
+ 2
+ ) >> 2;
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+
+#endif
+ }
+ else
+ {
+ const ValueType linear_wts[4] = { (2 - rmdr1.x) * (2 - rmdr1.y), //tl
+ rmdr1.x * (2 - rmdr1.y), //tr
+ (2 - rmdr1.x) * rmdr1.y, //bl
+ rmdr1.x * rmdr1.y }; //br
+
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=dparams.Yl(), ry=ref_start1.y, by=BChk(ry,m_ref_data1.LengthY()), by1=BChk(ry+1,m_ref_data1.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data1.LengthY()), by1=BChk(ry+1,m_ref_data1.LengthY()) )
+ {
+ for( int x=dparams.Xl() , rx=ref_start1.x , bx=BChk(rx,m_ref_data1.LengthX()), bx1=BChk(rx+1,m_ref_data1.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , ++diff_curr, bx=BChk(rx,m_ref_data1.LengthX()), bx1=BChk(rx+1,m_ref_data1.LengthX()))
+ {
+ temp = ( linear_wts[0] * CalcValueType( m_ref_data1[by][bx] ) +
+ linear_wts[1] * CalcValueType( m_ref_data1[by][bx1] ) +
+ linear_wts[2] * CalcValueType( m_ref_data1[by1][bx] )+
+ linear_wts[3] * CalcValueType( m_ref_data1[by1][bx1] ) +
+ 2
+ ) >> 2;
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+
+ // Now do the other reference
+
+ bounds_check = false;
+
+ if ( ref_start2.x<0 ||
+ ref_stop2.x >= m_ref_data2.LengthX() ||
+ ref_start2.y<0 ||
+ ref_stop2.y >= m_ref_data2.LengthY() )
+ bounds_check = true;
+
+ float sum( 0 );
+
+ diff_curr = &diff_array[0][0];
+
+ if ( !bounds_check )
+ {
+
+
+#if defined (HAVE_MMX)
+ sum = static_cast<float>( simple_biblock_diff_up_mmx_4 (diff_array,
+ m_ref_data2,
+ ref_start2, ref_stop2,
+ rmdr2) );
+#else
+ ValueType *ref_curr = &m_ref_data2[ref_start2.y][ref_start2.x];
+ const int ref_next( (m_ref_data2.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+ if( rmdr2.x == 0 && rmdr2.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ sum += std::abs( (*diff_curr - *ref_curr)>>1 );
+ }// x
+ }// y
+ }
+ else if( rmdr2.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+ else if( rmdr2.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[m_ref_data2.LengthX()] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[m_ref_data2.LengthX()+0] ) +
+ CalcValueType( ref_curr[m_ref_data2.LengthX()+1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+#endif
+ }
+ else
+ {
+ const ValueType linear_wts[4] = { (2 - rmdr2.x) * (2 - rmdr2.y), //tl
+ rmdr2.x * (2 - rmdr2.y), //tr
+ (2 - rmdr2.x) * rmdr2.y, //bl
+ rmdr2.x * rmdr2.y }; //br
+
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=dparams.Yl(), ry=ref_start2.y, by=BChk(ry,m_ref_data2.LengthY()),by1=BChk(ry+1,m_ref_data2.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data2.LengthY()),by1=BChk(ry+1,m_ref_data2.LengthY()))
+ {
+ for( int x=dparams.Xl() , rx=ref_start2.x , bx=BChk(rx,m_ref_data2.LengthX()), bx1=BChk(rx+1,m_ref_data2.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , ++diff_curr, bx=BChk(rx,m_ref_data2.LengthX()), bx1=BChk(rx+1,m_ref_data2.LengthX()))
+ {
+ temp = ( linear_wts[0] * CalcValueType( m_ref_data2[by][bx] ) +
+ linear_wts[1] * CalcValueType( m_ref_data2[by][bx1] ) +
+ linear_wts[2] * CalcValueType( m_ref_data2[by1][bx] )+
+ linear_wts[3] * CalcValueType( m_ref_data2[by1][bx1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+
+ return sum;
+
+}
+
+float BiBlockEighthPel::Diff( const BlockDiffParams& dparams ,
+ const MVector& mv1 ,
+ const MVector& mv2 )
+{
+ if (dparams.Xl() <= 0 || dparams.Yl() <= 0)
+ {
+ return 0;
+ }
+
+ // First create a difference array, and subtract the reference 1 data into it
+ TwoDArray<ValueType> diff_array( dparams.Yl() , dparams.Xl() );
+
+ // Set up the start point in the reference images by rounding the motion vectors
+ // to 1/2 pel accuracy.NB: bit shift rounds negative values DOWN, as required
+ const MVector roundvec1 ( mv1.x>>2 , mv1.y>>2 );
+ const MVector roundvec2 ( mv2.x>>2 , mv2.y>>2 );
+
+ //Get the remainders after rounding. NB rmdr values always 0-3
+ const MVector rmdr1( mv1.x & 3 , mv1.y & 3 );
+ const MVector rmdr2( mv2.x & 3 , mv2.y & 3 );
+
+ //weights for doing linear interpolation, calculated from the remainder values
+ const ValueType linear_wts1[4] = { (4 - rmdr1.x) * (4 - rmdr1.y), //tl
+ rmdr1.x * (4 - rmdr1.y), //tr
+ (4 - rmdr1.x) * rmdr1.y, //bl
+ rmdr1.x * rmdr1.y }; //br
+ const ValueType linear_wts2[4] = { (4 - rmdr2.x) * (4 - rmdr2.y), //tl
+ rmdr2.x * (4 - rmdr2.y), //tr
+ (4 - rmdr2.x) * rmdr2.y, //bl
+ rmdr2.x * rmdr2.y }; //br
+
+ //Where to start in the upconverted images
+ const ImageCoords ref_start1( ( dparams.Xp()<<1 ) + roundvec1.x ,( dparams.Yp()<<1 ) + roundvec1.y );
+ const ImageCoords ref_stop1( ref_start1.x+(dparams.Xl()<<1) , ref_start1.y+(dparams.Yl()<<1));
+
+ const ImageCoords ref_start2( ( dparams.Xp()<<1 ) + roundvec2.x ,( dparams.Yp()<<1 ) + roundvec2.y );
+ const ImageCoords ref_stop2( ref_start2.x+(dparams.Xl()<<1) , ref_start2.y+(dparams.Yl()<<1));
+
+ ValueType* pic_curr = &m_pic_data[dparams.Yp()][dparams.Xp()];
+ const int pic_next( m_pic_data.LengthX() - dparams.Xl() );// go down a row and back up
+
+ ValueType* diff_curr = &diff_array[0][0];
+
+ bool bounds_check( false );
+
+ if ( ref_start1.x<0 ||
+ ref_stop1.x >= m_ref_data1.LengthX() ||
+ ref_start1.y<0 ||
+ ref_stop1.y >= m_ref_data1.LengthY() )
+ bounds_check = true;
+
+ ValueType temp;
+
+ if ( !bounds_check )
+ {
+ ValueType *ref_curr = &m_ref_data1[ref_start1.y][ref_start1.x];
+ const int ref_next( (m_ref_data1.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ if( rmdr1.x == 0 && rmdr1.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ *diff_curr = ( (*pic_curr)<<1 ) - *ref_curr;
+ }// x
+ }// y
+ }
+ else if( rmdr1.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (( linear_wts1[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts1[1] * CalcValueType( ref_curr[1] ) +
+ 8
+ ) >> 4);
+
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+ else if( rmdr1.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (( linear_wts1[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts1[2] * CalcValueType( ref_curr[m_ref_data1.LengthX()+0] ) +
+ 8
+ ) >> 4);
+
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (( linear_wts1[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts1[1] * CalcValueType( ref_curr[1] ) +
+ linear_wts1[2] * CalcValueType( ref_curr[m_ref_data1.LengthX()+0] ) +
+ linear_wts1[3] * CalcValueType( ref_curr[m_ref_data1.LengthX()+1] ) +
+ 8
+ ) >> 4);
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+
+
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=dparams.Yl(), ry=ref_start1.y, by=BChk(ry,m_ref_data1.LengthY()), by1=BChk(ry+1,m_ref_data1.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data1.LengthY()), by1=BChk(ry+1,m_ref_data1.LengthY()) )
+ {
+ for( int x=dparams.Xl() , rx=ref_start1.x , bx=BChk(rx,m_ref_data1.LengthX()), bx1=BChk(rx+1,m_ref_data1.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , ++diff_curr, bx=BChk(rx,m_ref_data1.LengthX()), bx1=BChk(rx+1,m_ref_data1.LengthX()))
+ {
+ temp = ( linear_wts1[0] * CalcValueType( m_ref_data1[by][bx] ) +
+ linear_wts1[1] * CalcValueType( m_ref_data1[by][bx1] ) +
+ linear_wts1[2] * CalcValueType( m_ref_data1[by1][bx] )+
+ linear_wts1[3] * CalcValueType( m_ref_data1[by1][bx1] ) +
+ 8
+ ) >> 4;
+ *diff_curr = ( (*pic_curr)<<1 ) - temp;
+ }// x
+ }// y
+ }
+
+ // Now do the other reference
+
+ bounds_check = false;
+
+ if ( ref_start2.x<0 ||
+ ref_stop2.x >= m_ref_data2.LengthX() ||
+ ref_start2.y<0 ||
+ ref_stop2.y >= m_ref_data2.LengthY() )
+ bounds_check = true;
+
+ float sum( 0 );
+
+ diff_curr = &diff_array[0][0];
+
+ if ( !bounds_check )
+ {
+ ValueType *ref_curr = &m_ref_data2[ref_start2.y][ref_start2.x];
+ const int ref_next( (m_ref_data2.LengthX() - dparams.Xl())*2 );// go down 2 rows and back up
+
+ if( rmdr2.x == 0 && rmdr2.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ sum += std::abs( (*diff_curr - *ref_curr)>>1 );
+ }// x
+ }// y
+ }
+ else if( rmdr2.y == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (( linear_wts2[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts2[1] * CalcValueType( ref_curr[1] ) +
+ 8
+ ) >> 4);
+
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+ else if( rmdr2.x == 0 )
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (( linear_wts2[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts2[2] * CalcValueType( ref_curr[m_ref_data2.LengthX()+0] ) +
+ 8
+ ) >> 4);
+
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+ else
+ {
+ for( int y=dparams.Yl(); y > 0; --y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=dparams.Xl(); x > 0; --x, ++pic_curr, ref_curr+=2, ++diff_curr )
+ {
+ temp = (( linear_wts2[0] * CalcValueType( ref_curr[0] ) +
+ linear_wts2[1] * CalcValueType( ref_curr[1] ) +
+ linear_wts2[2] * CalcValueType( ref_curr[m_ref_data2.LengthX()+0] ) +
+ linear_wts2[3] * CalcValueType( ref_curr[m_ref_data2.LengthX()+1] ) +
+ 8
+ ) >> 4);
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+
+ }
+ else
+ {
+ // We're doing bounds checking because we'll fall off the edge of the reference otherwise.
+ for( int y=dparams.Yl(), ry=ref_start1.y, by=BChk(ry,m_ref_data2.LengthY()),by1=BChk(ry+1,m_ref_data2.LengthY());
+ y>0;
+ --y, pic_curr+=pic_next, ry+=2 , by=BChk(ry,m_ref_data2.LengthY()),by1=BChk(ry+1,m_ref_data2.LengthY()))
+ {
+ for( int x=dparams.Xl() , rx=ref_start1.x , bx=BChk(rx,m_ref_data2.LengthX()), bx1=BChk(rx+1,m_ref_data2.LengthX());
+ x>0 ;
+ --x, ++pic_curr, rx+=2 , ++diff_curr, bx=BChk(rx,m_ref_data2.LengthX()), bx1=BChk(rx+1,m_ref_data2.LengthX()))
+ {
+ temp = ( linear_wts2[0] * CalcValueType( m_ref_data2[by][bx] ) +
+ linear_wts2[1] * CalcValueType( m_ref_data2[by][bx1] ) +
+ linear_wts2[2] * CalcValueType( m_ref_data2[by1][bx] )+
+ linear_wts2[3] * CalcValueType( m_ref_data2[by1][bx1] ) +
+ 8
+ ) >> 4;
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ }
+
+ return sum;
+
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.h
new file mode 100644
index 000000000..51c464b7b
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils.h
@@ -0,0 +1,557 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_utils.h,v 1.14 2008/08/14 00:58:24 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1-
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ME_UTILS_H_
+#define _ME_UTILS_H_
+
+#include <algorithm>
+#include <libdirac_common/motion.h>
+#include <libdirac_common/common.h>
+namespace dirac
+{
+
+ ///////////////////////////////////
+ //Utilities for motion estimation//
+ //-------------------------------//
+ ///////////////////////////////////
+
+ //! A class encapsulating parameters for calculating a block difference value (a single instance of matching)
+ class BlockDiffParams
+ {
+
+ public:
+ //! Constructor
+ BlockDiffParams(){}
+
+ //! Constructor
+ BlockDiffParams( const int x_p , const int y_p , const int x_l , const int y_l):
+ m_xp(x_p),
+ m_yp(y_p),
+ m_xl(x_l),
+ m_yl(y_l),
+ m_xend(x_l+x_p),
+ m_yend(y_l+y_p)
+ {}
+
+ ////////////////////////////////////////////////////////////////////
+ //NB: Assume default copy constructor, assignment = and destructor//
+ ////////////////////////////////////////////////////////////////////
+
+ // Sets ...
+
+
+ //! Set the limits of the block to fit in a picture
+
+ void SetBlockLimits( const OLBParams& bparams ,
+ const PicArray& pic_data ,
+ const int xbpos , const int ybpos);
+
+ // ... and gets
+
+ //! Return the x-position of the top-left block corner
+ int Xp() const {return m_xp;}
+
+ //! Return the y-position of the top-left block corner
+ int Yp() const {return m_yp;}
+
+ //! Return the block width
+ int Xl() const {return m_xl;}
+
+ //! Return the block height
+ int Yl() const {return m_yl;}
+
+ //! Return the block horizontal endpoint
+ int Xend() const {return m_xend;}
+
+ //! Return the block vertical endpoint
+ int Yend() const {return m_yend;}
+
+ private:
+
+ int m_xp;
+ int m_yp;
+ int m_xl;
+ int m_yl;
+ int m_xend;
+ int m_yend;
+ };
+
+ //////////////////////////////////////////////////
+ //----Different difference classes, so that-----//
+ //bounds-checking need only be done as necessary//
+ //////////////////////////////////////////////////
+
+ //! An abstract class for doing block difference calculations
+ class BlockDiff
+ {
+ public:
+ //! Constructor, initialising the reference and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref the reference picture
+ \param pic the picture being matched
+ */
+ BlockDiff( const PicArray& ref , const PicArray& pic );
+
+ //! Destructor
+ virtual ~BlockDiff(){}
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv the motion vector being used
+ */
+ virtual float Diff( const BlockDiffParams& dparams , const MVector& mv )=0;
+
+ protected:
+
+ const PicArray& m_pic_data;
+ const PicArray& m_ref_data;
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BlockDiff( const BlockDiff& cpy );
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BlockDiff& operator=( const BlockDiff& rhs );
+ };
+
+ //! A class for doing block differences to pixel accuracy, inherited from BlockDiff
+ class PelBlockDiff: public BlockDiff
+ {
+ public:
+ //! Constructor, initialising the reference and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref the reference picture
+ \param pic the picture being matched
+ */
+ PelBlockDiff( const PicArray& ref , const PicArray& pic );
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv the motion vector being used
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv );
+
+ //! Do the difference, overwriting the best MV so far if appropriate
+ /*!
+ Do the difference, overwriting the best MV so far if appropriate,
+ and bailing out if we do worse
+ \param dparams block parameters
+ \param mv the motion vector being used
+ \param best_sum the best SAD value obtain yet
+ \param best_mv the MV giving the best SAD value so far
+ */
+ void Diff( const BlockDiffParams& dparams ,
+ const MVector& mv ,
+ float& best_sum ,
+ MVector& best_mv );
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ PelBlockDiff(const PelBlockDiff& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ PelBlockDiff& operator=(const PelBlockDiff& rhs);
+ };
+
+
+ //! A class for calculating the difference between a block and its DC value (average)
+ class IntraBlockDiff
+ {
+ public:
+ //! Constructor, initialising the picture data
+ /*
+ Constructor, initialising the picture data
+ \param pic the picture being matched
+ */
+ IntraBlockDiff( const PicArray& pic );
+
+ //! Do the difference, calculating the DC value and returning SAD
+ /*!
+ Do the difference, calculating the DC value and returning SAD
+ \param dparams block parameters
+ \param dc_val DC value
+ */
+ float Diff( const BlockDiffParams& dparams , ValueType& dc_val );
+
+ //! Calculate a DC value
+ ValueType CalcDC( const BlockDiffParams& dparams);
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ IntraBlockDiff(const IntraBlockDiff& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ IntraBlockDiff& operator=(const IntraBlockDiff& rhs);
+
+ const PicArray& m_pic_data;
+ };
+
+ //! A virtual class for bi-directional differences
+ class BiBlockDiff
+ {
+ public:
+ //! Constructor, initialising the references and picture data
+ /*
+ Constructor, initialising the references and picture data
+ \param ref1 the first reference picture
+ \param ref2 the second reference picture
+ \param pic the picture being matched
+ */
+ BiBlockDiff( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic);
+
+ //! Virtual destructor
+ virtual ~BiBlockDiff( ) {}
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv1 the motion vector being used for reference 1
+ \param mv2 the motion vector being used for reference 2
+ */
+ virtual float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 )=0;
+
+ protected:
+ const PicArray& m_pic_data;
+ const PicArray& m_ref_data1;
+ const PicArray& m_ref_data2;
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BiBlockDiff(const BiBlockDiff& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BiBlockDiff& operator=(const BiBlockDiff& rhs);
+ };
+
+ // Classes where the reference is upconverted //
+ ////////////////////////////////////////////////
+ //! A virtual class for doing differences with sub-pixel vectors
+ class BlockDiffUp: public BlockDiff
+ {
+
+ public:
+
+ //! Constructor, initialising the reference and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref the reference picture
+ \param pic the picture being matched
+ */
+ BlockDiffUp( const PicArray& ref , const PicArray& pic );
+
+ //! Destructor
+ virtual ~BlockDiffUp(){}
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv the motion vector being used
+ */
+ virtual float Diff( const BlockDiffParams& dparams , const MVector& mv )=0;
+
+ //! Do the actual difference, overwriting the best MV so far if appropriate
+ /*!
+ Do the actual difference, overwriting the best MV so far if appropriate,
+ and bailing out if we do worse
+ \param dparams block parameters
+ \param mv the motion vector being used
+ \param mvcost the (prediction) cost of the motion vector mv
+ \param lambda the weighting to be given to mvcost
+ \param best_costs the best Lagrangian costs obtained yet
+ \param best_mv the MV giving the best Lagrangian costs so far
+ */
+ virtual void Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv)=0;
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BlockDiffUp(const BlockDiffUp& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BlockDiffUp& operator=(const BlockDiffUp& rhs);
+ };
+
+ //! A class for doing differences with half-pixel accurate vectors
+ class BlockDiffHalfPel: public BlockDiffUp
+ {
+
+ public:
+ //! Constructor, initialising the reference and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref the reference picture
+ \param pic the picture being matched
+ */
+ BlockDiffHalfPel( const PicArray& ref , const PicArray& pic );
+
+ //! Destructor
+ ~BlockDiffHalfPel(){}
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv the motion vector being used
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv );
+
+ //! Do the actual difference, overwriting the best MV so far if appropriate
+ /*!
+ Do the actual difference, overwriting the best MV so far if appropriate,
+ and bailing out if we do worse
+ \param dparams block parameters
+ \param mv the motion vector being used
+ \param mvcost the (prediction) cost of the motion vector mv
+ \param lambda the weighting to be given to mvcost
+ \param best_costs the best Lagrangian costs obtained yet
+ \param best_mv the MV giving the best Lagrangian costs so far
+ */
+ void Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv);
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BlockDiffHalfPel(const BlockDiffHalfPel& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BlockDiffHalfPel& operator=(const BlockDiffHalfPel& rhs);
+
+ };
+
+ //! A class for doing differences with quarter-pixel accurate vectors
+ class BlockDiffQuarterPel: public BlockDiffUp
+ {
+ public:
+ //! Constructor, initialising the reference and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref the reference picture
+ \param pic the picture being matched
+ */
+ BlockDiffQuarterPel( const PicArray& ref , const PicArray& pic );
+
+ //! Destructor
+ ~BlockDiffQuarterPel(){}
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv the motion vector being used
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv );
+
+ //! Do the actual difference, overwriting the best MV so far if appropriate
+ /*!
+ Do the actual difference, overwriting the best MV so far if appropriate,
+ and bailing out if we do worse
+ \param dparams block parameters
+ \param mv the motion vector being used
+ \param mvcost the (prediction) cost of the motion vector mv
+ \param lambda the weighting to be given to mvcost
+ \param best_costs the best Lagrangian costs obtained yet
+ \param best_mv the MV giving the best Lagrangian costs so far
+ */
+ void Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv);
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BlockDiffQuarterPel(const BlockDiffQuarterPel& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BlockDiffQuarterPel& operator=(const BlockDiffQuarterPel& rhs);
+ };
+
+ //! A class for doing differences with eighth-pixel accurate vectors
+ class BlockDiffEighthPel: public BlockDiffUp
+ {
+ public:
+ //! Constructor, initialising the reference and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref the reference picture
+ \param pic the picture being matched
+ */
+ BlockDiffEighthPel( const PicArray& ref , const PicArray& pic );
+
+ //! Destructor
+ ~BlockDiffEighthPel(){}
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv the motion vector being used
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv );
+
+ //! Do the actual difference, overwriting the best MV so far if appropriate
+ /*!
+ Do the actual difference, overwriting the best MV so far if appropriate,
+ and bailing out if we do worse
+ \param dparams block parameters
+ \param mv the motion vector being used
+ \param mvcost the (prediction) cost of the motion vector mv
+ \param lambda the weighting to be given to mvcost
+ \param best_costs the best Lagrangian costs obtained yet
+ \param best_mv the MV giving the best Lagrangian costs so far
+ */
+ void Diff( const BlockDiffParams& dparams,
+ const MVector& mv ,
+ const float mvcost,
+ const float lambda,
+ MvCostData& best_costs ,
+ MVector& best_mv);
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BlockDiffEighthPel(const BlockDiffEighthPel& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BlockDiffEighthPel& operator=(const BlockDiffEighthPel& rhs);
+ };
+
+ //! A class for computing a bidirection difference for half-pel vectors
+ class BiBlockHalfPel: public BiBlockDiff
+ {
+ public:
+ //! Constructor, initialising the references and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref1 the first reference picture
+ \param ref2 the second reference picture
+ \param pic the picture being matched
+ */
+ BiBlockHalfPel( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic );
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv1 the motion vector being used for reference 1
+ \param mv2 the motion vector being used for reference 2
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 );
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BiBlockHalfPel(const BiBlockHalfPel& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BiBlockHalfPel& operator=(const BiBlockHalfPel& rhs);
+ };
+
+ //! A class for computing a bidirection difference for quarter-pel vectors
+ class BiBlockQuarterPel: public BiBlockDiff
+ {
+ public:
+ //! Constructor, initialising the references and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref1 the first reference picture
+ \param ref2 the second reference picture
+ \param pic the picture being matched
+ */
+ BiBlockQuarterPel( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic );
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv1 the motion vector being used for reference 1
+ \param mv2 the motion vector being used for reference 2
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 );
+
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BiBlockQuarterPel(const BiBlockQuarterPel& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BiBlockQuarterPel& operator=(const BiBlockQuarterPel& rhs);
+ };
+
+ //! A class for computing a bidirection difference for eighth-pel vectors
+ class BiBlockEighthPel: public BiBlockDiff
+ {
+ public:
+ //! Constructor, initialising the references and picture data
+ /*
+ Constructor, initialising the reference and picture data
+ \param ref1 the first reference picture
+ \param ref2 the second reference picture
+ \param pic the picture being matched
+ */
+ BiBlockEighthPel( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic );
+
+ //! Do the difference, returning SAD
+ /*!
+ Do the difference, returning SAD
+ \param dparams block parameters
+ \param mv1 the motion vector being used for reference 1
+ \param mv2 the motion vector being used for reference 2
+ */
+ float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 );
+ private:
+ //! Private, bodyless copy-constructor: class should not be copied
+ BiBlockEighthPel(const BiBlockEighthPel& cpy);
+
+ //! Private, bodyless assignment=: class should not be assigned
+ BiBlockEighthPel& operator=(const BiBlockEighthPel& rhs);
+ };
+
+} // namespace dirac
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.cpp
new file mode 100644
index 000000000..692b9c148
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.cpp
@@ -0,0 +1,1134 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_utils_mmx.cpp,v 1.8 2007/08/24 16:13:38 asuraparaju Exp $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is contributed by Peter Meerwald.
+*
+* The Initial Developer of the Original Code is Peter Meerwald.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Peter Meerwald (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_common/dirac_assertions.h>
+#include <libdirac_motionest/me_utils_mmx.h>
+
+#if defined HAVE_MMX
+using namespace dirac;
+
+namespace dirac
+{
+ typedef union
+ {
+ int i[2];
+ short h[4];
+ __m64 m;
+ } u_mmx_val;
+
+ CalcValueType simple_block_diff_mmx_4 (
+ const BlockDiffParams& dparams, const MVector& mv,
+ const PicArray& pic_data, const PicArray& ref_data,
+ CalcValueType i_best_sum)
+ {
+ u_mmx_val u_sum;
+
+ u_sum.i[0] = u_sum.i[1] = 0;
+
+ ValueType *src = &(pic_data[dparams.Yp()][dparams.Xp()]);
+ ValueType *refd = &(ref_data[dparams.Yp()+mv.y][dparams.Xp()+mv.x]);
+
+ int height = dparams.Yl();
+ int width = dparams.Xl();
+ int stopX = (width>>2)<<2;
+ int pic_next = (pic_data.LengthX() - width);
+ int ref_next = (ref_data.LengthX() - width);
+ CalcValueType mop_sum = 0;
+ for (int j = 0; j < height; j++)
+ {
+ for (int i = 0; i < stopX; i+=4)
+ {
+ // pic - ref
+ __m64 pic = _mm_sub_pi16 (*(__m64 *)src, *(__m64 *)refd);
+ // abs (pic - ref)
+ __m64 ref = _mm_srai_pi16(pic, 15);
+ pic = _mm_xor_si64(pic, ref);
+ pic = _mm_sub_pi16 (pic, ref);
+ // sum += abs(pic -ref)
+ ref = _mm_xor_si64(ref, ref);
+ ref = _mm_unpackhi_pi16(pic, ref);
+ pic = _mm_unpacklo_pi16(pic, pic);
+ pic = _mm_srai_pi32 (pic, 16);
+ pic = _mm_add_pi32 (pic, ref);
+ u_sum.m = _mm_add_pi32 (u_sum.m, pic);
+ src += 4;
+ refd += 4;
+ }
+ for (int i = stopX; i < width; i++)
+ {
+ mop_sum += std::abs(*src - *refd);
+ src++;
+ refd++;
+ }
+ if ((u_sum.i[0] + u_sum.i[1] + mop_sum) >= i_best_sum)
+ {
+ _mm_empty();
+ return i_best_sum;
+ }
+ src += pic_next;
+ refd += ref_next;
+ }
+ _mm_empty();
+
+ return u_sum.i[0] + u_sum.i[1] + mop_sum;
+ }
+
+
+ CalcValueType simple_intra_block_diff_mmx_4 (
+ const BlockDiffParams& dparams,
+ const PicArray& pic_data, ValueType &dc_val)
+ {
+ __m64 tmp = _mm_set_pi16(0, 0, 0, 0);
+ u_mmx_val u_sum;
+ u_sum.i[0] = u_sum.i[1] = 0;
+
+ ValueType *src = &(pic_data[dparams.Yp()][dparams.Xp()]);
+
+ int height = dparams.Yl();
+ int width = dparams.Xl();
+ int stopX = (width>>2)<<2;
+ int pic_next = (pic_data.LengthX() - width);
+ CalcValueType mop_sum = 0;
+ for (int j = 0; j < height; j++)
+ {
+ for (int i = 0; i < stopX; i+=4)
+ {
+ __m64 pic = *(__m64 *)src;
+ // sum += (pic)
+ tmp = _mm_xor_si64(tmp, tmp);
+ tmp = _mm_unpackhi_pi16(pic, tmp);
+ tmp = _mm_slli_pi32 (tmp, 16);
+ tmp = _mm_srai_pi32 (tmp, 16);
+ pic = _mm_unpacklo_pi16(pic, pic);
+ pic = _mm_srai_pi32 (pic, 16);
+ pic = _mm_add_pi32 (pic, tmp);
+ u_sum.m = _mm_add_pi32 (u_sum.m, pic);
+ src += 4;
+ }
+ // Mop up
+ for (int i = stopX; i < width; ++i)
+ {
+ mop_sum += *src;
+ src++;
+ }
+ src += pic_next;
+ }
+
+ CalcValueType int_dc = (u_sum.i[0] + u_sum.i[1] + mop_sum)/(width*height);
+
+ dc_val = static_cast<ValueType>( int_dc );
+
+ // Now compute the resulting SAD
+ __m64 dc = _mm_set_pi16 ( dc_val, dc_val , dc_val , dc_val);
+ u_sum.m = _mm_xor_si64(u_sum.m, u_sum.m); // initialise sum to 0
+ mop_sum = 0;
+
+ src = &(pic_data[dparams.Yp()][dparams.Xp()]);
+ for (int j = 0; j < height; ++j)
+ {
+ for (int i = 0; i < stopX; i+=4)
+ {
+ __m64 pic = *(__m64 *)src;
+ // pic - dc
+ pic = _mm_sub_pi16 (pic, dc);
+ // abs (pic - dc)
+ tmp = _mm_srai_pi16(pic, 15);
+ pic = _mm_xor_si64(pic, tmp);
+ pic = _mm_sub_pi16 (pic, tmp);
+ // sum += abs(pic -dc)
+ tmp = _mm_xor_si64(tmp, tmp);
+ tmp = _mm_unpackhi_pi16(pic, tmp);
+ pic = _mm_unpacklo_pi16(pic, pic);
+ pic = _mm_srai_pi32 (pic, 16);
+ pic = _mm_add_pi32 (pic, tmp);
+ u_sum.m = _mm_add_pi32 (u_sum.m, pic);
+ src += 4;
+ }
+ // Mop up
+ for (int i = stopX; i < width; ++i)
+ {
+ mop_sum += std::abs(*src - dc_val);
+ src++;
+ }
+ src += pic_next;
+ }
+ CalcValueType intra_cost = u_sum.i[0] + u_sum.i[1] + mop_sum;
+ _mm_empty();
+
+ return intra_cost;
+
+ }
+
+ /*
+ * NOTE: we are not doing any bounds checks here. This function must
+ * be invoked only when the reference images start and stop fall
+ * withing bounds
+ */
+ float simple_block_diff_up_mmx_4(
+ const PicArray& pic_data, const PicArray& ref_data,
+ const ImageCoords& start_pos, const ImageCoords& end_pos,
+ const ImageCoords& ref_start, const ImageCoords& ref_stop,
+ const MVector& rmdr, float cost_so_far,
+ float best_total_cost_so_far)
+ {
+ ValueType *pic_curr = &pic_data[start_pos.y][start_pos.x];
+ ValueType *ref_curr = &ref_data[ref_start.y][ref_start.x];
+
+ const int width = end_pos.x - start_pos.x;
+ int height = end_pos.y - start_pos.y;
+ const int ref_stride = ref_data.LengthX();
+
+ // go down a row and back up
+ const int pic_next = pic_data.LengthX() - width;
+ // go down 2 rows and back up
+ const int ref_next = ref_data.LengthX()*2 - width*2;
+
+ REPORTM (ref_start.x>=0 && ref_stop.x < ref_data.LengthX() &&
+ ref_start.y>=0 && ref_stop.y < ref_data.LengthY(),
+ "Reference image coordinates within bounds");
+
+ CalcValueType sum = 0;
+ CalcValueType mop_sum(0);
+ int stopX = (width>>2)<<2;
+ __m64 m_sum = _mm_set_pi16(0, 0, 0, 0);
+ u_mmx_val u_sum;
+ if (rmdr.x == 0 && rmdr.y == 0 )
+ {
+ //std::cerr << "Inmmx routine rmdr.x = rmdr.y = 0" << std::endl;
+#if 1
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ m_sum = _mm_xor_si64 (m_sum, m_sum);
+ mop_sum= 0;
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, ref_curr+=8 )
+ {
+ __m64 pic = *(__m64 *)pic_curr;
+ __m64 ref = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 ref2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ ref = _mm_unpacklo_pi16 ( ref, ref2);
+ // ref - pic
+ pic = _mm_sub_pi16 (pic, ref);
+ // abs (ref - pic)
+ ref = _mm_srai_pi16(pic, 15);
+ pic = _mm_xor_si64(pic, ref);
+ pic = _mm_sub_pi16 (pic, ref);
+ // sum += abs(ref -pic)
+ /**
+ * Since we are re-initialising m_sum with every loop
+ * maybe we don't need the following since overflow may
+ * not occur
+ ref = _mm_xor_si64(ref, ref);
+ ref = _mm_unpackhi_pi16(pic, ref);
+ pic = _mm_unpacklo_pi16(pic, pic);
+ pic = _mm_srai_pi32 (pic, 16);
+ pic = _mm_add_pi32 (pic, ref);
+ m_sum = _mm_add_pi32 (m_sum, pic);
+ **/
+ m_sum = _mm_add_pi16 (m_sum, pic);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr,ref_curr+=2)
+ {
+ mop_sum += std::abs (*ref_curr - *pic_curr);
+ }
+ u_sum.m = m_sum;
+ //sum += (u_sum.i[0] + u_sum.i[1] + mop_sum);
+ sum += (u_sum.h[0] + u_sum.h[1] + u_sum.h[2] + u_sum.h[3] + mop_sum);
+ _mm_empty();
+ if ((sum + cost_so_far )>= best_total_cost_so_far)
+ {
+ return best_total_cost_so_far;
+ }
+ }
+ _mm_empty();
+ return sum + cost_so_far;
+#else
+ float sum = cost_so_far;
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ref_curr+=2 )
+ {
+ sum += std::abs( *ref_curr - *pic_curr );
+ }// x
+
+ if ( sum>= best_total_cost_so_far)
+ return best_total_cost_so_far;
+
+ }// y
+ return sum;
+#endif
+
+ }
+ else if( rmdr.y == 0 )
+ {
+#if 1
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ m_sum = _mm_xor_si64 (m_sum, m_sum);
+ mop_sum= 0;
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ // m3 = words 0 2 4 6 of ref_curr
+ __m64 m3 = _mm_unpacklo_pi16 ( m1, m2);
+ // m2 = words 1 3 5 7 of ref_curr
+ m2 = _mm_unpackhi_pi16 ( m1, m2);
+ // (ref_curr[0] + ref_curr[1] + 1)>>1
+ m3 = _mm_add_pi16 (m3, m2);
+ m3 = _mm_add_pi16 (m3, m_one);
+ m3 = _mm_srai_pi16 (m3, 1);
+ // ref - pic
+ m1 = _mm_sub_pi16 (*(__m64 *)pic_curr, m3);
+ // abs (ref - pic)
+ m3 = _mm_srai_pi16(m1, 15);
+ m1 = _mm_xor_si64(m1, m3);
+ m1 = _mm_sub_pi16 (m1, m3);
+ // sum += abs(ref -pic)
+ /**
+ * Since we are re-initialising m_sum with every loop
+ * maybe we don't need the following since overflow may
+ * not occur
+ ref = _mm_xor_si64(ref, ref);
+ ref = _mm_unpackhi_pi16(pic, ref);
+ pic = _mm_unpacklo_pi16(pic, pic);
+ pic = _mm_srai_pi32 (pic, 16);
+ pic = _mm_add_pi32 (pic, ref);
+ m_sum = _mm_add_pi32 (m_sum, pic);
+ **/
+ m_sum = _mm_add_pi16 (m_sum, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr,ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[1]+1)>>1;
+ mop_sum += std::abs (temp - *pic_curr);
+ }
+ u_sum.m = m_sum;
+ //sum += (u_sum.i[0] + u_sum.i[1] + mop_sum);
+ sum += (u_sum.h[0] + u_sum.h[1] + u_sum.h[2] + u_sum.h[3] + mop_sum);
+ _mm_empty();
+ if ((sum + cost_so_far )>= best_total_cost_so_far)
+ {
+ return best_total_cost_so_far;
+ }
+ }
+ _mm_empty();
+ return sum + cost_so_far;
+#else
+ //std::cerr << "Inmmx routine rmdr.y == 0" << std::endl;
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( (sum+cost_so_far)>=best_total_cost_so_far)
+ return best_total_cost_so_far;
+
+ }// y
+ return sum+cost_so_far;
+#endif
+ }
+ else if( rmdr.x == 0 )
+ {
+#if 1
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ m_sum = _mm_xor_si64 (m_sum, m_sum);
+ mop_sum= 0;
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ // m1 = words 0 2 4 6 of ref_curr
+ m1 = _mm_unpacklo_pi16 ( m1, m2);
+ // m2 = words 0 2 4 6 of ref_curr+ref_stride
+ m2 = _mm_unpacklo_pi16 (*(__m64 *)(ref_curr+ref_stride), *(__m64 *)(ref_curr+ref_stride+4));
+ __m64 m3 = _mm_unpackhi_pi16 (*(__m64 *)(ref_curr+ref_stride), *(__m64 *)(ref_curr+ref_stride+4));
+ m2 = _mm_unpacklo_pi16 (m2, m3);
+
+ // (ref_curr[0] + ref_curr[ref_stride] + 1)>>1
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_add_pi16 (m1, m_one);
+ m1 = _mm_srai_pi16 (m1, 1);
+ // ref - pic
+ m1 = _mm_sub_pi16 (*(__m64 *)pic_curr, m1);
+ // abs (ref - pic)
+ m3 = _mm_srai_pi16(m1, 15);
+ m1 = _mm_xor_si64(m1, m3);
+ m1 = _mm_sub_pi16 (m1, m3);
+ // sum += abs(ref -pic)
+ m_sum = _mm_add_pi16 (m_sum, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr,ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[ref_stride]+1)>>1;
+ mop_sum += std::abs (temp - *pic_curr);
+ }
+ u_sum.m = m_sum;
+ //sum += (u_sum.i[0] + u_sum.i[1] + mop_sum);
+ sum += (u_sum.h[0] + u_sum.h[1] + u_sum.h[2] + u_sum.h[3] + mop_sum);
+ _mm_empty();
+ if ((sum + cost_so_far )>= best_total_cost_so_far)
+ {
+ return best_total_cost_so_far;
+ }
+ }
+ _mm_empty();
+ return sum + cost_so_far;
+#else
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[ref_stride]+1)>>1;
+ sum += std::abs (temp - *pic_curr);
+ }// x
+
+ if ( (sum+cost_so_far)>=best_total_cost_so_far)
+ return best_total_cost_so_far;
+
+ }// y
+ return sum+cost_so_far;
+#endif
+ }
+ else
+ {
+#if 1
+ __m64 m_two = _mm_set_pi32(2, 2);
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ // processing four pic_data values at a time
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ m_sum = _mm_xor_si64 (m_sum, m_sum);
+ mop_sum= 0;
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ // m1 = words 0 1 2 3 of line 0 ref_curr
+ __m64 m1 = *(__m64 *)ref_curr;
+ // m1 = words 0 1 2 3 of line 1 of ref_curr
+ __m64 m2 = *(__m64 *)(ref_curr+ref_stride);
+ // (ref_curr[0] + ref_curr[1] +
+ // ref_curr[ref_stride] + ref_curr[ref_stride+1] + 2) >>2
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_madd_pi16 (m1, m_one);
+ m1 = _mm_add_pi32 (m1, m_two);
+ m1 = _mm_srai_pi32 (m1, 2);
+
+
+ // m2 = words 4 5 6 7 of line 0 ref_curr
+ __m64 m3 = *(__m64 *)(ref_curr+4);
+ // m1 = words 4 5 6 7 of line 1 of ref_curr
+ m2 = *(__m64 *)(ref_curr+4+ref_stride);
+ // (ref_curr[0] + ref_curr[1] +
+ // ref_curr[ref_stride] + ref_curr[ref_stride+1] + 2) >>2
+ m3 = _mm_add_pi16 (m3, m2);
+ m3 = _mm_madd_pi16 (m3, m_one);
+ m3 = _mm_add_pi32 (m3, m_two);
+ m3 = _mm_srai_pi32 (m3, 2);
+
+ m1 = _mm_packs_pi32 (m1, m3);
+
+ // load first four values pic_data
+ m2 = *(__m64 *)pic_curr;
+
+ // ref - pic
+ m1 = _mm_sub_pi16 (m1, m2);
+ // abs (ref - pic)
+ m2 = _mm_srai_pi16(m1, 15);
+ m1 = _mm_xor_si64(m1, m2);
+ m1 = _mm_sub_pi16(m1, m2);
+ // sum += abs(ref -pic)
+ m_sum = _mm_add_pi16 (m_sum, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr,ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[1] +
+ ref_curr[ref_stride] + ref_curr[ref_stride+1]+2)>>2;
+ mop_sum += std::abs (temp - *pic_curr);
+ }
+ u_sum.m = m_sum;
+ sum += (u_sum.h[0] + u_sum.h[1] + u_sum.h[2] + u_sum.h[3] + mop_sum);
+ _mm_empty();
+ if ((sum + cost_so_far )>= best_total_cost_so_far)
+ {
+ return best_total_cost_so_far;
+ }
+ }
+ _mm_empty();
+ return sum + cost_so_far;
+#else
+ //std::cerr << "Inmmx routine rmdr.y == 0" << std::endl;
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[ref_stride] ) +
+ CalcValueType( ref_curr[ref_stride+1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( temp - *pic_curr );
+ }// x
+
+ if ( (sum+cost_so_far)>=best_total_cost_so_far)
+ return best_total_cost_so_far;
+
+ }// y
+ return sum+cost_so_far;
+#endif
+ }
+ return cost_so_far;
+ }
+
+ /*
+ * NOTE: we are not doing any bounds checks here. This function must
+ * be invoked only when the reference images start and stop fall
+ * withing bounds
+ */
+ void simple_biblock_diff_pic_mmx_4(
+ const PicArray& pic_data, const PicArray& ref_data,
+ TwoDArray<ValueType>& diff,
+ const ImageCoords& start_pos, const ImageCoords& end_pos,
+ const ImageCoords& ref_start, const ImageCoords& ref_stop,
+ const MVector& rmdr)
+ {
+ ValueType *pic_curr = &pic_data[start_pos.y][start_pos.x];
+ ValueType *ref_curr = &ref_data[ref_start.y][ref_start.x];
+ ValueType *diff_curr = &diff[0][0];
+
+ const int width = end_pos.x - start_pos.x;
+ int height = end_pos.y - start_pos.y;
+ const int ref_stride = ref_data.LengthX();
+
+ // go down a row and back up
+ const int pic_next = pic_data.LengthX() - width;
+ // go down 2 rows and back up
+ const int ref_next = ref_data.LengthX()*2 - width*2;
+
+ REPORTM (ref_start.x>=0 && ref_stop.x < ref_data.LengthX() &&
+ ref_start.y>=0 && ref_stop.y < ref_data.LengthY(),
+ "Reference image coordinates withing bounds");
+
+ int stopX = (width>>2)<<2;
+ if (rmdr.x == 0 && rmdr.y == 0 )
+ {
+ //std::cerr << "Inmmx routine rmdr.x = rmdr.y = 0" << std::endl;
+#if 1
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next)
+ {
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, ref_curr+=8, diff_curr += 4 )
+ {
+ __m64 pic = *(__m64 *)pic_curr;
+ // pic << 1
+ pic = _mm_slli_pi16(pic, 1);
+ // load ref
+ __m64 ref = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 ref2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ ref = _mm_unpacklo_pi16 ( ref, ref2);
+ // pic<<1 - ref
+ *(__m64 *)diff_curr = _mm_sub_pi16 (pic, ref);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2)
+ {
+ *diff_curr = ((*pic_curr)<<1) - *ref_curr;
+ }
+ }
+#else
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2 )
+ {
+ *diff_curr = ((*pic_curr)<<1) - *ref_curr;
+ }// x
+ }// y
+#endif
+ }
+ else if( rmdr.y == 0 )
+ {
+#if 1
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, diff_curr += 4, ref_curr+=8 )
+ {
+ // Load ref
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ // m3 = words 0 2 4 6 of ref_curr
+ __m64 m3 = _mm_unpacklo_pi16 ( m1, m2);
+ // m2 = words 1 3 5 7 of ref_curr
+ m2 = _mm_unpackhi_pi16 ( m1, m2);
+ // (ref_curr[0] + ref_curr[1] + 1)>>1
+ m3 = _mm_add_pi16 (m3, m2);
+ m3 = _mm_add_pi16 (m3, m_one);
+ m3 = _mm_srai_pi16 (m3, 1);
+ // pic << 1
+ m1 = _mm_slli_pi16(*(__m64 *)pic_curr, 1);
+ // diff = pic - ref
+ *(__m64 *)diff_curr = _mm_sub_pi16 (m1, m3);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[1]+1)>>1;
+ *diff_curr = ((*pic_curr)<<1) - temp;
+ }
+ }
+#else
+ //std::cerr << "Inmmx routine rmdr.y == 0" << std::endl;
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+ *diff_curr = ((*pic_curr)<<1) - temp;
+ }// x
+
+ }// y
+#endif
+ }
+ else if( rmdr.x == 0 )
+ {
+#if 1
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, diff_curr +=4, ref_curr+=8 )
+ {
+ // Load ref
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ // m1 = words 0 2 4 6 of ref_curr
+ m1 = _mm_unpacklo_pi16 ( m1, m2);
+ // m2 = words 0 2 4 6 of ref_curr+ref_stride
+ m2 = _mm_unpacklo_pi16 (*(__m64 *)(ref_curr+ref_stride), *(__m64 *)(ref_curr+ref_stride+4));
+ __m64 m3 = _mm_unpackhi_pi16 (*(__m64 *)(ref_curr+ref_stride), *(__m64 *)(ref_curr+ref_stride+4));
+ m2 = _mm_unpacklo_pi16 (m2, m3);
+
+ // (ref_curr[0] + ref_curr[ref_stride] + 1)>>1
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_add_pi16 (m1, m_one);
+ m1 = _mm_srai_pi16 (m1, 1);
+ // pic << 1
+ m2 = _mm_slli_pi16 (*(__m64 *)pic_curr, 1);
+ // diff = pic<<1 - ref)
+ *(__m64 *)diff_curr = _mm_sub_pi16(m2, m1 );
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[ref_stride]+1)>>1;
+ *diff_curr = ((*pic_curr)<<1) - temp;
+ }
+ }
+#else
+ //std::cerr << "Inmmx routine rmdr.y == 0" << std::endl;
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+ *diff_curr = ((*pic_curr)<<1) - temp;
+ }// x
+ }// y
+#endif
+ }
+ else
+ {
+#if 1
+ __m64 m_two = _mm_set_pi32(2, 2);
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ // processing four pic_data values at a time
+ for( int y=0; y < height; y++, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, pic_curr+=4, diff_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ // m1 = words 0 1 2 3 of line 0 ref_curr
+ __m64 m1 = *(__m64 *)ref_curr;
+ // m1 = words 0 1 2 3 of line 1 of ref_curr
+ __m64 m2 = *(__m64 *)(ref_curr+ref_stride);
+ // (ref_curr[0] + ref_curr[1] +
+ // ref_curr[ref_stride] + ref_curr[ref_stride+1] + 2) >>2
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_madd_pi16 (m1, m_one);
+ m1 = _mm_add_pi32 (m1, m_two);
+ m1 = _mm_srai_pi32 (m1, 2);
+
+ // m2 = words 4 5 6 7 of line 0 ref_curr
+ __m64 m3 = *(__m64 *)(ref_curr+4);
+ // m1 = words 4 5 6 7 of line 1 of ref_curr
+ m2 = *(__m64 *)(ref_curr+4+ref_stride);
+ // (ref_curr[0] + ref_curr[1] +
+ // ref_curr[ref_stride] + ref_curr[ref_stride+1] + 2) >>2
+ m3 = _mm_add_pi16 (m3, m2);
+ m3 = _mm_madd_pi16 (m3, m_one);
+ m3 = _mm_add_pi32 (m3, m_two);
+ m3 = _mm_srai_pi32 (m3, 2);
+
+ m1 = _mm_packs_pi32 (m1, m3);
+
+ // load first four values pic_data and <<1
+ m2 = _mm_slli_pi16 (*(__m64 *)pic_curr, 1);
+
+ // pic<<1 - ref
+ *(__m64 *)diff_curr = _mm_sub_pi16 (m2, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++pic_curr,++diff_curr, ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[1] +
+ ref_curr[ref_stride] + ref_curr[ref_stride+1]+2)>>2;
+ *diff_curr = ((*pic_curr)<<1) - temp;
+ }
+ }
+#else
+ //std::cerr << "Inmmx routine rmdr.y == 0" << std::endl;
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, pic_curr+=pic_next, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++pic_curr, ++diff_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[ref_stride] ) +
+ CalcValueType( ref_curr[ref_stride+1] ) +
+ 2
+ ) >> 2;
+ *diff_curr = ((*pic_curr)<<1) - temp;
+ }// x
+
+ }// y
+#endif
+ }
+ _mm_empty();
+ return;
+ }
+
+ /*
+ * NOTE: we are not doing any bounds checks here. This function must
+ * be invoked only when the reference images start and stop fall
+ * withing bounds
+ */
+ CalcValueType simple_biblock_diff_up_mmx_4(
+ const TwoDArray<ValueType>& diff_data, const PicArray& ref_data,
+ const ImageCoords& ref_start, const ImageCoords& ref_stop,
+ const MVector& rmdr)
+ {
+ ValueType *diff_curr = &diff_data[0][0];
+ ValueType *ref_curr = &ref_data[ref_start.y][ref_start.x];
+
+ const int width = diff_data.LengthX();
+ int height = diff_data.LengthY();
+ const int ref_stride = ref_data.LengthX();
+
+ // go down 2 rows and back up
+ const int ref_next = ref_data.LengthX()*2 - width*2;
+
+ REPORTM (ref_start.x>=0 && ref_stop.x < ref_data.LengthX() &&
+ ref_start.y>=0 && ref_stop.y < ref_data.LengthY(),
+ "Reference image coordinates withing bounds");
+
+ CalcValueType mop_sum(0);
+ int stopX = (width>>2)<<2;
+ __m64 m_sum = _mm_set_pi16(0, 0, 0, 0);
+ u_mmx_val u_sum;
+ if (rmdr.x == 0 && rmdr.y == 0 )
+ {
+ //std::cerr << "Inmmx routine rmdr.x = rmdr.y = 0" << std::endl;
+#if 1
+ for( int y=0; y < height; y++, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, diff_curr+=4, ref_curr+=8 )
+ {
+ u_mmx_val diff = *(u_mmx_val *)diff_curr;
+ __m64 ref = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 ref2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ ref = _mm_unpacklo_pi16 ( ref, ref2);
+ // diff - ref
+ diff.m = _mm_sub_pi16 (diff.m, ref);
+ // (diff - ref)>>1
+ diff.m = _mm_srai_pi16 (diff.m, 1);
+ // abs (diff - ref)
+ ref = _mm_srai_pi16(diff.m, 15);
+ diff.m = _mm_xor_si64(diff.m, ref);
+ diff.m = _mm_sub_pi16 (diff.m, ref);
+ // sum += abs(ref -pic)
+ ref = _mm_xor_si64(ref, ref);
+ ref = _mm_unpackhi_pi16(diff.m, ref);
+ diff.m = _mm_unpacklo_pi16(diff.m, diff.m);
+ diff.m = _mm_srai_pi32 (diff.m, 16);
+ diff.m = _mm_add_pi32 (diff.m, ref);
+ m_sum = _mm_add_pi32 (m_sum, diff.m);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++diff_curr,ref_curr+=2)
+ {
+ mop_sum += std::abs ((*diff_curr - *ref_curr)>>1);
+ }
+ }
+ u_sum.m = m_sum;
+ _mm_empty();
+ return u_sum.i[0] + u_sum.i[1] + mop_sum;
+#else
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++diff_curr, ref_curr+=2 )
+ {
+ sum += std::abs( (*diff_curr - *ref_curr)>>1 );
+ }// x
+
+ }// y
+ return sum;
+#endif
+
+ }
+ else if( rmdr.y == 0 )
+ {
+#if 1
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ for( int y=0; y < height; y++, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, diff_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ __m64 m1 = _mm_unpacklo_pi16 (((u_mmx_val *)ref_curr)->m, ((u_mmx_val *)(ref_curr+4))->m);
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ // m3 = words 0 2 4 6 of ref_curr
+ __m64 m3 = _mm_unpacklo_pi16 ( m1, m2);
+ // m2 = words 1 3 5 7 of ref_curr
+ m2 = _mm_unpackhi_pi16 ( m1, m2);
+ // (ref_curr[0] + ref_curr[1] + 1)>>1
+ m3 = _mm_add_pi16 (m3, m2);
+ m3 = _mm_add_pi16 (m3, m_one);
+ m3 = _mm_srai_pi16 (m3, 1);
+ // diff - pic
+ m1 = _mm_sub_pi16 (*(__m64 *)diff_curr, m3);
+ // (diff - pic)>>1
+ m1 = _mm_srai_pi16 (m1, 1);
+ // abs (diff-ref)>>1
+ m3 = _mm_srai_pi16(m1, 15);
+ m1 = _mm_xor_si64(m1, m3);
+ m1 = _mm_sub_pi16 (m1, m3);
+ // sum += abs(diff-ref)>>1
+ m2 = _mm_xor_si64(m2, m2);
+ m2 = _mm_unpackhi_pi16(m1, m2);
+ m1 = _mm_unpacklo_pi16(m1, m1);
+ m1 = _mm_srai_pi32 (m1, 16);
+ m1 = _mm_add_pi32 (m1, m2);
+ m_sum = _mm_add_pi32 (m_sum, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++diff_curr,ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[1]+1)>>1;
+ mop_sum += std::abs ((*diff_curr - temp)>>1);
+ }
+ }
+ u_sum.m = m_sum;
+ _mm_empty();
+ return (u_sum.i[0] + u_sum.i[1] + mop_sum);
+#else
+ //std::cerr << "Inmmx routine rmdr.y == 0" << std::endl;
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++diff_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ 1
+ ) >> 1;
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ return sum;
+#endif
+ }
+ else if( rmdr.x == 0 )
+ {
+#if 1
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ for( int y=0; y < height; y++, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, diff_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ __m64 m1 = _mm_unpacklo_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ __m64 m2 = _mm_unpackhi_pi16 (*(__m64 *)ref_curr, *(__m64 *)(ref_curr+4));
+ // m1 = words 0 2 4 6 of ref_curr
+ m1 = _mm_unpacklo_pi16 ( m1, m2);
+ // m2 = words 0 2 4 6 of ref_curr+ref_stride
+ m2 = _mm_unpacklo_pi16 (*(__m64 *)(ref_curr+ref_stride), *(__m64 *)(ref_curr+ref_stride+4));
+ __m64 m3 = _mm_unpackhi_pi16 (*(__m64 *)(ref_curr+ref_stride), *(__m64 *)(ref_curr+ref_stride+4));
+ m2 = _mm_unpacklo_pi16 (m2, m3);
+
+ // (ref_curr[0] + ref_curr[ref_stride] + 1)>>1
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_add_pi16 (m1, m_one);
+ m1 = _mm_srai_pi16 (m1, 1);
+ // diff - ref
+ m1 = _mm_sub_pi16 (*(__m64 *)diff_curr, m1);
+ // (diff - ref)>>1
+ m1 = _mm_srai_pi16 (m1, 1);
+ // abs ((diff - pic)>>1)
+ m3 = _mm_srai_pi16(m1, 15);
+ m1 = _mm_xor_si64(m1, m3);
+ m1 = _mm_sub_pi16 (m1, m3);
+ // sum += abs(ref -pic)
+ m2 = _mm_xor_si64(m2, m2);
+ m2 = _mm_unpackhi_pi16(m1, m2);
+ m1 = _mm_unpacklo_pi16(m1, m1);
+ m1 = _mm_srai_pi32 (m1, 16);
+ m1 = _mm_add_pi32 (m1, m2);
+ m_sum = _mm_add_pi32 (m_sum, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++diff_curr,ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[ref_stride]+1)>>1;
+ mop_sum += std::abs ( (*diff_curr - temp)>>1 );
+ }
+ }
+ u_sum.m = m_sum;
+ _mm_empty();
+ return (u_sum.i[0] + u_sum.i[1] + mop_sum);
+#else
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++diff_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[ref_stride]+1)>>1;
+ sum += std::abs ( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ return sum;
+#endif
+ }
+ else
+ {
+#if 1
+ __m64 m_two = _mm_set_pi32(2, 2);
+ __m64 m_one = _mm_set_pi16(1, 1, 1, 1);
+ // processing four pic_data values at a time
+ for( int y=0; y < height; y++, ref_curr+=ref_next )
+ {
+ for( int x=0; x < stopX; x+=4, diff_curr+=4, ref_curr+=8 )
+ {
+ // Load ref
+ // m1 = words 0 1 2 3 of line 0 ref_curr
+ __m64 m1 = *(__m64 *)ref_curr;
+ // m1 = words 0 1 2 3 of line 1 of ref_curr
+ __m64 m2 = *(__m64 *)(ref_curr+ref_stride);
+ // (ref_curr[0] + ref_curr[1] +
+ // ref_curr[ref_stride] + ref_curr[ref_stride+1] + 2) >>2
+ m1 = _mm_add_pi16 (m1, m2);
+ m1 = _mm_madd_pi16 (m1, m_one);
+ m1 = _mm_add_pi32 (m1, m_two);
+ m1 = _mm_srai_pi32 (m1, 2);
+
+ // m2 = words 4 5 6 7 of line 0 ref_curr
+ __m64 m3 = *(__m64 *)(ref_curr+4);
+ // m1 = words 4 5 6 7 of line 1 of ref_curr
+ m2 = *(__m64 *)(ref_curr+4+ref_stride);
+ // (ref_curr[0] + ref_curr[1] +
+ // ref_curr[ref_stride] + ref_curr[ref_stride+1] + 2) >>2
+ m3 = _mm_add_pi16 (m3, m2);
+ m3 = _mm_madd_pi16 (m3, m_one);
+ m3 = _mm_add_pi32 (m3, m_two);
+ m3 = _mm_srai_pi32 (m3, 2);
+ m1 = _mm_packs_pi32 (m1, m3);
+
+ // load first four values pic_data
+ m2 = *(__m64 *)diff_curr;
+
+ // diff - ref
+ m1 = _mm_sub_pi16 (m2, m1);
+ // (diff - ref)>>1
+ m1 = _mm_srai_pi16 (m1, 1);
+ // abs (diff - ref)>>1
+ m2 = _mm_srai_pi16(m1, 15);
+ m1 = _mm_xor_si64(m1, m2);
+ m1 = _mm_sub_pi16(m1, m2);
+ // sum += abs(ref -pic)>>1
+ m1 = _mm_madd_pi16(m1, m_one);
+ m_sum = _mm_add_pi32 (m_sum, m1);
+ }
+ // mopup;
+ for (int x = stopX; x < width; ++x, ++diff_curr,ref_curr+=2)
+ {
+ CalcValueType temp = (ref_curr[0] + ref_curr[1] +
+ ref_curr[ref_stride] + ref_curr[ref_stride+1]+2)>>2;
+ mop_sum += std::abs ( (*diff_curr - temp)>>1 );
+ }
+ }
+ u_sum.m = m_sum;
+ _mm_empty();
+ return (u_sum.i[0] + u_sum.i[1] + mop_sum);
+#else
+ CalcValueType sum(0);
+ for( int y=0; y < height; ++y, ref_curr+=ref_next )
+ {
+ for( int x=0; x < width; ++x, ++diff_curr, ref_curr+=2 )
+ {
+ CalcValueType temp = ( CalcValueType( ref_curr[0] ) +
+ CalcValueType( ref_curr[1] ) +
+ CalcValueType( ref_curr[ref_stride] ) +
+ CalcValueType( ref_curr[ref_stride+1] ) +
+ 2
+ ) >> 2;
+ sum += std::abs( (*diff_curr - temp)>>1 );
+ }// x
+ }// y
+ return sum;
+#endif
+ }
+ return 0;
+ }
+
+ inline void check_active_columns(
+ int x, int xmax, ValueType act_cols1[4],ValueType *row1)
+ {
+ // check if we need any clipping
+ if (x >= 0 && (x+3) < xmax) {
+ // special case, nothing to do
+ memcpy(act_cols1, &row1[x], 4 * sizeof(ValueType));
+ }
+ else if (x < 0)
+ {
+ act_cols1[0] = row1[0];
+ //act_cols1[1] = (x + 1) < 0 ? row1[0] : row1[x+1];
+ //act_cols1[2] = (x + 2) < 0 ? row1[0] : row1[x+2];
+ //act_cols1[3] = (x + 3) < 0 ? row1[0] : row1[x+3];
+ for (int i = 1; i < 4; ++i)
+ {
+ act_cols1[i] = (x + i) < 0 ? row1[0] : row1[x+i];
+ }
+ }
+ else
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ act_cols1[i] = (x + i) < xmax ? row1[x+i] : row1[xmax-1];
+ }
+ act_cols1[3] = row1[xmax-1];
+ }
+ }
+
+ CalcValueType bchk_simple_block_diff_mmx_4 (
+ const BlockDiffParams& dparams, const MVector& mv,
+ const PicArray& pic_data, const PicArray& ref_data,
+ CalcValueType i_best_sum)
+ {
+ u_mmx_val u_sum;
+ u_mmx_val u_ref;
+ u_sum.i[0] = u_sum.i[1]= 0;
+
+ ValueType *src = &(pic_data[dparams.Yp()][dparams.Xp()]);
+ ImageCoords ref_start(dparams.Xp()+mv.x, dparams.Yp()+mv.y);
+
+ int height = dparams.Yl();
+ int width = dparams.Xl();
+ int stopX = (width>>2)<<2;
+ int pic_next = (pic_data.LengthX() - width);
+ CalcValueType mop_sum = 0;
+ for (int j = 0; j < height; j++)
+ {
+ for (int i = 0; i < stopX; i+=4)
+ {
+ check_active_columns(ref_start.x+i, ref_data.LengthX(), u_ref.h, ref_data[BChk(ref_start.y+j, ref_data.LengthY())]);
+ // pic - ref
+ __m64 pic = _mm_sub_pi16 (*(__m64 *)src, u_ref.m);
+ // abs (pic - ref)
+ u_ref.m = _mm_srai_pi16(pic, 15);
+ pic = _mm_xor_si64(pic, u_ref.m);
+ pic = _mm_sub_pi16 (pic, u_ref.m);
+ // sum += abs(pic -ref)
+ u_ref.m = _mm_xor_si64(u_ref.m, u_ref.m);
+ u_ref.m = _mm_unpackhi_pi16(pic, u_ref.m);
+ pic = _mm_unpacklo_pi16(pic, pic);
+ pic = _mm_srai_pi32 (pic, 16);
+ pic = _mm_add_pi32 (pic, u_ref.m);
+ u_sum.m = _mm_add_pi32 (u_sum.m, pic);
+ src += 4;
+ }
+ for (int i = stopX; i < width; i++)
+ {
+ mop_sum += std::abs(*src -
+ ref_data[BChk(j+ref_start.y , ref_data.LengthY())][BChk(i+ref_start.x , ref_data.LengthX())]);
+ src++;
+ }
+ if ((u_sum.i[0] + u_sum.i[1] + mop_sum) >= i_best_sum)
+ {
+ _mm_empty();
+ return i_best_sum;
+ }
+ src += pic_next;
+ }
+ _mm_empty();
+
+ return u_sum.i[0] + u_sum.i[1] + mop_sum;
+ }
+}
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.h
new file mode 100644
index 000000000..855fc4a75
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/me_utils_mmx.h
@@ -0,0 +1,81 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: me_utils_mmx.h,v 1.3 2008/05/27 01:29:55 asuraparaju Exp $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is contributed by Peter Meerwald.
+*
+* The Initial Developer of the Original Code is Peter Meerwald.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Peter Meerwald (Original Author)
+* Anuradha Suraparaju
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _ME_UTILS_MMX_H_
+#define _ME_UTILS_MMX_H_
+
+#if defined(HAVE_MMX)
+
+#include <mmintrin.h>
+
+#include <libdirac_motionest/me_utils.h>
+#include <libdirac_common/common.h>
+
+namespace dirac
+{
+
+ CalcValueType simple_block_diff_mmx_4(const BlockDiffParams& dparams, const MVector& mv, const PicArray& pic_data, const PicArray& ref_data, CalcValueType i_best_sum);
+ CalcValueType simple_intra_block_diff_mmx_4 ( const BlockDiffParams& dparams, const PicArray& pic_data, ValueType &dc_val);
+
+ CalcValueType bchk_simple_block_diff_mmx_4 (
+ const BlockDiffParams& dparams, const MVector& mv,
+ const PicArray& pic_data, const PicArray& ref_data,
+ CalcValueType i_best_sum);
+
+ float simple_block_diff_up_mmx_4(
+ const PicArray& pic_data, const PicArray& ref_data,
+ const ImageCoords& start_pos, const ImageCoords& end_pos,
+ const ImageCoords& ref_start, const ImageCoords& ref_stop,
+ const MVector& rmdr, float cost_so_far,
+ float best_cost_so_far);
+
+
+ void simple_biblock_diff_pic_mmx_4(
+ const PicArray& pic_data, const PicArray& ref_data,
+ TwoDArray<ValueType>& diff,
+ const ImageCoords& start_pos, const ImageCoords& end_pos,
+ const ImageCoords& ref_start, const ImageCoords& ref_stop,
+ const MVector& rmdr);
+
+ CalcValueType simple_biblock_diff_up_mmx_4(
+ const TwoDArray<ValueType>& diff_data, const PicArray& ref_data,
+ const ImageCoords& ref_start, const ImageCoords& ref_stop,
+ const MVector& rmdr);
+}
+
+#endif /* HAVE_MMX */
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.cpp
new file mode 100644
index 000000000..bdde41891
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.cpp
@@ -0,0 +1,247 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: motion_estimate.cpp,v 1.23 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#include <libdirac_encoder/enc_queue.h>
+#include <libdirac_motionest/motion_estimate.h>
+#include <libdirac_motionest/pixel_match.h>
+#include <libdirac_motionest/me_subpel.h>
+#include <libdirac_motionest/me_mode_decn.h>
+using namespace dirac;
+
+#include <cmath>
+#include <vector>
+
+MotionEstimator::MotionEstimator( const EncoderParams& encp ):
+ m_encparams( encp )
+{}
+
+void MotionEstimator::DoME( EncQueue& my_buffer, int pic_num )
+{
+ MEData& me_data = my_buffer.GetPicture( pic_num ).GetMEData();
+
+ const PictureParams& pparams = my_buffer.GetPicture(pic_num).GetPparams();
+
+ // Step 1.
+ //Initial search gives vectors for each reference accurate to 1 pixel
+
+ PixelMatcher pix_match( m_encparams );
+ pix_match.DoSearch( my_buffer , pic_num );
+
+ float lambda;
+ // Get the references
+ const std::vector<int>& refs = my_buffer.GetPicture(pic_num).GetPparams().Refs();
+
+ const int num_refs = refs.size();
+ if ( pparams.IsBPicture())
+ lambda = m_encparams.L2MELambda();
+ else
+ lambda = m_encparams.L1MELambda();
+
+ // Set up the lambda to be used
+ me_data.SetLambdaMap( num_refs , lambda );
+
+ MVPrecisionType orig_prec = m_encparams.GetPicPredParams().MVPrecision();
+
+ // Step 2.
+ // Pixel accurate vectors are then refined to sub-pixel accuracy
+
+ if (orig_prec != MV_PRECISION_PIXEL)
+ {
+ SubpelRefine pelrefine( m_encparams );
+ pelrefine.DoSubpel( my_buffer , pic_num );
+ }
+ else
+ {
+ // FIXME: HACK HACK
+ // Mutiplying the motion vectors by 2 and setting MV precision to
+ // HALF_PIXEL to implement pixel accurate motion estimate
+ MvArray &mv_arr1 = me_data.Vectors(1);
+ for (int j = 0; j < mv_arr1.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr1.LengthX(); ++i)
+ mv_arr1[j][i] = mv_arr1[j][i] << 1;
+ }
+ if (num_refs > 1)
+ {
+ MvArray &mv_arr2 = me_data.Vectors(2);
+ for (int j = 0; j < mv_arr2.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr2.LengthX(); ++i)
+ mv_arr2[j][i] = mv_arr2[j][i] << 1;
+ }
+ }
+ m_encparams.GetPicPredParams().SetMVPrecision(MV_PRECISION_HALF_PIXEL);
+ }
+
+ // Step3.
+ // We now have to decide how each superblock should be split
+ // and which references should be used, and so on.
+
+ ModeDecider my_mode_dec( m_encparams );
+ my_mode_dec.DoModeDecn( my_buffer , pic_num );
+
+ if (orig_prec == MV_PRECISION_PIXEL)
+ {
+ // FIXME: HACK HACK
+ // Divide the motion vectors by 2 to convert back to pixel
+ // accurate motion vectors and reset MV precision to
+ // PIXEL accuracy
+ MvArray &mv_arr1 = me_data.Vectors(1);
+ for (int j = 0; j < mv_arr1.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr1.LengthX(); ++i)
+ mv_arr1[j][i] = mv_arr1[j][i] >> 1;
+ }
+ if (num_refs > 1)
+ {
+ MvArray &mv_arr2 = me_data.Vectors(2);
+ for (int j = 0; j < mv_arr2.LengthY(); ++j)
+ {
+ for (int i = 0; i < mv_arr2.LengthX(); ++i)
+ mv_arr2[j][i] = mv_arr2[j][i]>>1;
+ }
+ }
+ m_encparams.GetPicPredParams().SetMVPrecision(MV_PRECISION_PIXEL);
+ }
+
+ // Finally, although not strictly part of motion estimation,
+ // we have to assign DC values for chroma components for
+ // blocks we're decided are intra.
+
+ SetChromaDC( my_buffer , pic_num );
+
+//return false;
+}
+
+ValueType MotionEstimator::GetChromaBlockDC(const PicArray& pic_data,
+ int xunit , int yunit , int split)
+{
+ BlockDiffParams dparams;
+ dparams.SetBlockLimits( m_encparams.GetPicPredParams().ChromaBParams( split ) ,
+ pic_data, xunit , yunit);
+
+ ValueType dc;
+
+ IntraBlockDiff intradiff( pic_data );
+
+ intradiff.Diff( dparams , dc );
+
+ return dc;
+}
+
+void MotionEstimator::SetChromaDC( const PicArray& pic_data , MEData& me_data , CompSort csort )
+{
+
+ // Lower limit of block coords in SB
+ int xtl,ytl;
+ // Upper limit of block coords in SB
+ int xbr,ybr;
+
+ // Ditto, for subSBs
+ int xsubSBtl,ysubSBtl;
+ int xsubSBbr,ysubSBbr;
+
+ TwoDArray<ValueType>& dcarray = me_data.DC( csort );
+
+ ValueType dc = 0;
+
+ // Coords of the prediction units (at appropriate level)
+ int xunit, yunit;
+
+ // The delimiters of the blocks contained in the prediction unit
+ int xstart, ystart;
+ int xend, yend;
+
+ int level;
+
+ for ( int ysb=0 ; ysb<me_data.SBSplit().LengthY() ; ++ysb )
+ {
+ for ( int xsb=0 ; xsb<me_data.SBSplit().LengthX() ; ++xsb )
+ {
+
+ level = me_data.SBSplit()[ysb][xsb];
+
+ xtl = xsb<<2;
+ ytl = ysb<<2;
+ xbr = xtl+4;
+ ybr = ytl+4;
+
+ xsubSBtl = xsb<<1;
+ ysubSBtl = ysb<<1;
+ xsubSBbr = xsubSBtl+2;
+ ysubSBbr = ysubSBtl+2;
+
+
+ for (int j = 0 ; j<(1<<level) ;++j)
+ {
+ for (int i = 0 ; i<(1<<level) ;++i)
+ {
+ xunit = ( xsb<<level ) + i;
+ yunit = ( ysb<<level ) + j;
+
+ xstart = xunit<<( 2-level );
+ ystart = yunit<<( 2-level );
+
+ xend = xstart + ( 1<<( 2-level ) );
+ yend = ystart + ( 1<<( 2-level ) );
+
+ if ( me_data.Mode()[ystart][xstart] == INTRA )
+ // Get the DC value for the unit
+ dc = GetChromaBlockDC( pic_data , xunit , yunit , level );
+
+ // Copy it into the corresponding blocks
+ for ( int q=ystart ; q< yend ; ++q )
+ for ( int p=xstart ; p< xend ; ++p )
+ dcarray[q][p] = dc;
+
+ }// i
+ }// j
+
+ }// xsb
+ }// ysb
+}
+
+void MotionEstimator::SetChromaDC( EncQueue& my_buffer , int pic_num )
+{
+ MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData();
+ SetChromaDC( my_buffer.GetPicture( pic_num ).OrigData(U_COMP) , me_data , U_COMP );
+ SetChromaDC( my_buffer.GetPicture( pic_num ).OrigData(V_COMP) , me_data , V_COMP );
+
+}
+
+
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.h
new file mode 100644
index 000000000..10129dd3e
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/motion_estimate.h
@@ -0,0 +1,105 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: motion_estimate.h,v 1.12 2008/08/14 00:51:09 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+
+#ifndef _MOTION_ESTIMATE_H_
+#define _MOTION_ESTIMATE_H_
+
+#include <libdirac_common/motion.h>
+namespace dirac
+{
+
+ class EncQueue;
+
+
+ //! Class to handle the whole motion estimation process.
+ /*!
+
+ Class to handle the whole motion estimation process, which works in
+ three stages.
+
+ First a pixel-accurate estimate is formed by looking at the current
+ picture data and the data from the reference picture(s). Motion vectors
+ are found for every block.
+
+ Second, these pixel-accurate motion vectors are refined to sub-pixel
+ accuracy. This means some sort of upconversion needs to be applied to
+ the reference. This can be done by actually upconverting the reference
+ to create a bigger picture or by doing some interpolation of values
+ on the fly.
+
+ Third, mode decisions have to be made. This means choosing which (if
+ any) reference to use for each block, and whether to use the same
+ motion vectors for groups of blocks together. A 2x2 group of blocks is
+ called a sub-MB and a 4x4 group of blocks is a MB (Macroblock). All
+ the MV data is organised by MB.
+ */
+ class MotionEstimator{
+ public:
+ //! Constructor
+ MotionEstimator( const EncoderParams& encp );
+ //! Destructor
+ ~MotionEstimator(){}
+
+ //! Do the motion estimation
+ void DoME( EncQueue& my_buffer , int pic_num );
+
+ private:
+ //! Copy constructor: private, body-less - class should not be copied
+ MotionEstimator( const MotionEstimator& cpy );
+
+ //! Assignment= : //private, body-less - class should not be assigned
+ MotionEstimator& operator=( const MotionEstimator& rhs );
+
+ //! Go through all the intra blocks and extract the chroma dc values to be coded
+ void SetChromaDC( EncQueue& my_buffer, int pic_num);
+
+ //! Called by previous fn for each component
+ void SetChromaDC(const PicArray& pic_data, MEData& me_data,CompSort csort);
+
+ //! Called by previous fn for each block
+ ValueType GetChromaBlockDC(const PicArray& pic_data, int xloc,int yloc,int split);
+
+ // Member variables
+
+ //! A local reference to the encoder parameters
+ const EncoderParams& m_encparams;
+ };
+
+} // namespace dirac
+
+#endif
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.cpp b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.cpp
new file mode 100644
index 000000000..7ac7f74ed
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.cpp
@@ -0,0 +1,380 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: pixel_match.cpp,v 1.20 2008/10/01 01:26:47 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copm_yright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author),
+* Tim Borer
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#include <libdirac_motionest/pixel_match.h>
+#include <libdirac_motionest/block_match.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_encoder/enc_queue.h>
+#include <libdirac_motionest/downconvert.h>
+#include <libdirac_motionest/me_mode_decn.h>
+#include <libdirac_motionest/me_subpel.h>
+using namespace dirac;
+
+#include <cmath>
+#include <vector>
+
+using std::vector;
+using std::log;
+
+PixelMatcher::PixelMatcher( const EncoderParams& encp):
+ m_encparams(encp)
+{}
+
+
+void PixelMatcher::DoSearch( EncQueue& my_buffer, int pic_num )
+{
+ m_predparams = &(my_buffer.GetPicture(pic_num).GetMEData().GetPicPredParams() );
+
+ //does an initial search using hierarchical matching to get guide vectors
+
+ // Picture numbers of references
+ int ref1,ref2;
+
+ // Use the luminance only for motion estimating
+ const PicArray& pic_data = my_buffer.GetPicture( pic_num ).DataForME(m_encparams.CombinedME());
+
+ const vector<int>& refs = my_buffer.GetPicture( pic_num ).GetPparams().Refs();
+ ref1 = refs[0];
+
+ if (refs.size()>1)
+ ref2 = refs[1];
+ else
+ ref2 = ref1;
+
+ // Record temporal distances
+ m_tdiff[0] = std::abs( ref1 - pic_num );
+ m_tdiff[1] = std::abs( ref2 - pic_num );
+
+ // Obtain C++ references to the reference picture luma components
+ const PicArray& ref1_data = my_buffer.GetPicture(ref1).DataForME(m_encparams.CombinedME());
+ const PicArray& ref2_data = my_buffer.GetPicture(ref2).DataForME(m_encparams.CombinedME());
+
+ // Determine the picture sort - this affects the motion estimation Lagrangian parameter
+ m_psort = my_buffer.GetPicture(pic_num).GetPparams().PicSort();
+
+
+ if ( m_encparams.FullSearch() == false )
+ {
+ // Set the number of downconversion levels - not too many or we run out of picture!
+ m_depth = ( int) std::min( log(((double) pic_data.LengthX())/12.0)/log(2.0) ,
+ log(((double) pic_data.LengthY())/12.0)/log(2.0) );
+
+ // These arrays will contain the downconverted picture and MvData hierarchy
+ OneDArray<PicArray*> ref1_down( Range( 1 , m_depth ) );
+ OneDArray<PicArray*> ref2_down( Range( 1 , m_depth ) );
+ OneDArray<PicArray*> pic_down( Range( 1 , m_depth ) );
+ OneDArray<MEData*> me_data_set( Range( 1 , m_depth ) );
+
+ // Populate the hierarchies
+ MakePicHierarchy( pic_data , pic_down );
+ MakePicHierarchy( ref1_data , ref1_down );
+ if (ref1 != ref2)
+ MakePicHierarchy( ref2_data , ref2_down );
+
+ MakeMEDataHierarchy( pic_down , me_data_set );
+
+ // Now do the work! //
+ //////////////////////
+
+ // Start with motion estimating at the very lowest level
+ m_level = m_depth;
+
+ MatchPic( *(pic_down[m_depth]) , *(ref1_down[m_depth]) , *(me_data_set[m_depth]) ,
+ *(me_data_set[m_depth]) , 1 );
+ if ( ref1 != ref2 )
+ MatchPic( *(pic_down[m_depth]) , *(ref2_down[m_depth]) , *(me_data_set[m_depth]) ,
+ *(me_data_set[m_depth]) , 2 );
+
+ // Do the intervening levels - here we can have a genuine set of guide vectors
+ for ( m_level=m_depth-1 ; m_level>=1 ; --m_level )
+ {
+ MatchPic( *(pic_down[m_level]) , *(ref1_down[m_level]) , *(me_data_set[m_level]) ,
+ *(me_data_set[m_level+1]) , 1 );
+ if (ref1!=ref2)
+ MatchPic( *(pic_down[m_level]) , *(ref2_down[m_level]) , *(me_data_set[m_level]) ,
+ *(me_data_set[m_level+1]) , 2 );
+ }// level
+
+ // Finally, do the top level, with the pictures themselves
+ m_level = 0;
+ MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData();
+ MatchPic( pic_data , ref1_data, me_data , *(me_data_set[1]) , 1 );
+ if ( ref1 != ref2 )
+ MatchPic( pic_data , ref2_data , me_data , *(me_data_set[1]) , 2 );
+
+ // Now we're finished, tidy everything up ...
+ TidyPics( pic_down );
+ TidyPics( ref1_down );
+ if (ref1 != ref2)
+ TidyPics( ref2_down );
+ TidyMEData( me_data_set );
+ }
+ else
+ {
+ m_depth = 0;
+ m_level = 0;
+ MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData();
+ MatchPic( pic_data , ref1_data, me_data , me_data , 1 );
+ if ( ref1 != ref2 )
+ MatchPic( pic_data , ref2_data , me_data , me_data , 2 );
+ }
+
+}
+
+void PixelMatcher::MakePicHierarchy(const PicArray& data ,
+ OneDArray< PicArray* >& down_data)
+{
+
+ DownConverter mydcon;
+
+ // Allocate
+ int scale_factor = 1;
+ for (int i=1 ; i<=m_depth;++i)
+ {
+ // Dimensions of pic_down[i] will be shrunk by a factor 2**i
+ scale_factor*=2;
+ down_data[i] = new PicArray( data.LengthY()/scale_factor , data.LengthX()/scale_factor);
+ }
+
+ //do all the downconversions
+ if (m_depth>0)
+ {
+ mydcon.DoDownConvert( data , *(down_data[1]) );
+
+ for (int i=1 ; i<m_depth ; ++i)
+ mydcon.DoDownConvert( *(down_data[i]) , *(down_data[i+1]) );
+
+ }
+}
+
+void PixelMatcher::MakeMEDataHierarchy(const OneDArray< PicArray*>& down_data,
+ OneDArray< MEData* >& me_data_set )
+{
+
+ int xnumblocks , ynumblocks;
+ const OLBParams bparams = m_predparams->LumaBParams(2);
+
+ // We might not have an integral number of Macroblocks and blocks in
+ // a picture. So we go start of with the number of macroblocks in the
+ // full size picture and calculate the number of in the downsized pics
+ // from this.
+ xnumblocks = m_predparams->XNumBlocks();
+ ynumblocks = m_predparams->YNumBlocks();
+
+ PicturePredParams predparams = *m_predparams;
+ predparams.SetXNumSB(0);
+ predparams.SetYNumSB(0);
+ for (int i=1 ; i<=m_depth;++i)
+ {
+
+ xnumblocks = xnumblocks>>1;
+ ynumblocks = ynumblocks>>1;
+
+ if (( down_data[i]->LengthX() )%bparams.Xbsep() != 0)
+ xnumblocks++;
+
+ if (( down_data[i]->LengthY() )%bparams.Ybsep() != 0)
+ ynumblocks++;
+
+ predparams.SetXNumBlocks( xnumblocks );
+ predparams.SetYNumBlocks( ynumblocks );
+
+ me_data_set[i] = new MEData( predparams, 2 );
+ }// i
+
+}
+
+void PixelMatcher::TidyPics( OneDArray< PicArray*>& down_data )
+{
+ for (int i=1 ; i <= m_depth ; ++i)
+ {
+ delete down_data[i];
+ }// i
+
+}
+
+void PixelMatcher::TidyMEData( OneDArray< MEData*>& me_data_set )
+{
+ for (int i=1 ; i <= m_depth ; ++i)
+ {
+ delete me_data_set[i];
+ }// i
+
+}
+
+
+
+void PixelMatcher::MatchPic(const PicArray& pic_data , const PicArray& ref_data , MEData& me_data ,
+ const MvData& guide_data, const int ref_id)
+{
+
+ // Initialisation //
+ ////////////////////
+
+ m_big_xr = std::min( m_tdiff[ref_id-1], 3 )*m_encparams.XRangeME();
+ m_big_yr = std::min( m_tdiff[ref_id-1], 3 )*m_encparams.YRangeME();
+
+ // Set the search ranges according to the level
+ if ( m_encparams.FullSearch() == false )
+ {
+ m_cost_mean = 0.0;
+ m_cost_mean_sq = 0.0;
+
+ m_xr = std::min( m_level+1, 5);
+ m_yr = std::min( m_level+1, 5);
+ }
+ else
+ {
+ m_xr = m_big_xr;
+ m_yr = m_big_yr;
+ }
+
+ // Provide aliases for the appropriate motion vector data components
+
+ MvArray& mv_array = me_data.Vectors( ref_id );
+ const MvArray& guide_array = guide_data.Vectors( ref_id );
+ TwoDArray<MvCostData>& pred_costs = me_data.PredCosts( ref_id );
+
+ // Initialise the arrays
+ for (int y=0; y<mv_array.LengthY(); ++y)
+ {
+ for (int x=0; x<mv_array.LengthX(); ++x)
+ {
+ mv_array[y][x].x = 0;
+ mv_array[y][x].y = 0;
+ pred_costs[y][x].total = 10000000.0f;
+ }// x
+ }// y
+
+ // Provide a block matching object to do the work
+ BlockMatcher my_bmatch( pic_data , ref_data ,
+ m_predparams->LumaBParams(2) , m_predparams->MVPrecision() ,
+ mv_array , pred_costs );
+
+ // Do the work - loop over all the blocks, finding the best match //
+ ////////////////////////////////////////////////////////////////////
+
+ /*
+ The idea is for each block construct a list of candidate vectors,which will
+ be tested. This list is actually a list of lists, implemented as a C++
+ vector of C++ vectors. This is so that FindBestMatch can shorten the
+ search process by looking at the beginning of each sublist and
+ discarding that sub-list if it's too far off.
+ */
+
+ // Make a zero-based list that is always used
+ m_cand_list.clear();
+ MVector zero_mv( 0 , 0 );
+
+ AddNewVlist( m_cand_list , zero_mv , m_xr , m_yr);
+
+ // Now loop over the blocks and find the best matches.
+ // The loop is unrolled because predictions are different at picture edges.
+ // The purpose of the loop is to create appropriate candidate lists, and then
+ // call the DoBlock() function which does the actual work.
+
+ // First do TL corner
+
+ // Set the prediction as the zero vector
+ m_mv_prediction = zero_mv;
+
+ DoBlock(0, 0 , guide_array , my_bmatch);
+
+ // The rest of the first row
+ for ( int xpos=1 ; xpos<mv_array.LengthX() ; ++xpos )
+ {
+ m_mv_prediction = mv_array[0][xpos-1];
+ DoBlock(xpos, 0 , guide_array , my_bmatch);
+ }// xpos
+
+ // All the remaining rows except the last
+ for ( int ypos=1 ; ypos<mv_array.LengthY() ; ++ypos )
+ {
+
+ // The first element of each row
+ m_mv_prediction = mv_array[ypos-1][0];
+ DoBlock(0, ypos , guide_array , my_bmatch );
+
+ // The middle elements of each row
+ for ( int xpos=1 ; xpos<mv_array.LastX() ; ++xpos )
+ {
+ m_mv_prediction = MvMedian( mv_array[ypos][xpos-1],
+ mv_array[ypos-1][xpos],
+ mv_array[ypos-1][xpos+1]);
+ DoBlock(xpos, ypos , guide_array , my_bmatch );
+
+ }// xpos
+
+ // The last element in each row
+ m_mv_prediction = MvMean( mv_array[ypos-1][ mv_array.LastX() ],
+ mv_array[ypos][ mv_array.LastX()-1 ]);
+ DoBlock(mv_array.LastX() , ypos , guide_array , my_bmatch );
+ }//ypos
+
+}
+
+void PixelMatcher::DoBlock(const int xpos, const int ypos ,
+ const MvArray& guide_array,
+ BlockMatcher& block_match)
+{
+ // Find the best match for each block ...
+
+ // Use guide from lower down if one exists
+ if ( m_level<m_depth )
+ {
+ int xdown = BChk(xpos>>1, guide_array.LengthX());
+ int ydown = BChk(ypos>>1, guide_array.LengthY());
+ AddNewVlist( m_cand_list , guide_array[ydown][xdown] * 2 , m_xr , m_yr );
+
+ }
+
+ // use the spatial prediction, also, as a guide
+ if (m_encparams.FullSearch()==false )
+ AddNewVlist( m_cand_list , m_mv_prediction , m_xr , m_yr );
+ else
+ AddNewVlist( m_cand_list , m_mv_prediction , 1 , 1);
+
+ // Find the best motion vector //
+ /////////////////////////////////
+
+ block_match.FindBestMatchPel( xpos , ypos , m_cand_list, m_mv_prediction, 0 );
+
+ // Reset the lists ready for the next block (don't erase the first sublist as
+ // this is a neighbourhood of zero, which we always look at)
+ m_cand_list.erase( m_cand_list.begin()+1 , m_cand_list.end() );
+}
diff --git a/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.h b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.h
new file mode 100644
index 000000000..f860882fb
--- /dev/null
+++ b/src/filters/parser/DiracSplitter/libdirac/libdirac_motionest/pixel_match.h
@@ -0,0 +1,157 @@
+/* ***** BEGIN LICENSE BLOCK *****
+*
+* $Id: pixel_match.h,v 1.11 2008/08/27 00:20:52 asuraparaju Exp $ $Name: $
+*
+* Version: MPL 1.1/GPL 2.0/LGPL 2.1
+*
+* The contents of this file are subject to the Mozilla Public License
+* Version 1.1 (the "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+* http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS IS" basis,
+* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
+* the specific language governing rights and limitations under the License.
+*
+* The Original Code is BBC Research and Development code.
+*
+* The Initial Developer of the Original Code is the British Broadcasting
+* Corporation.
+* Portions created by the Initial Developer are Copyright (C) 2004.
+* All Rights Reserved.
+*
+* Contributor(s): Thomas Davies (Original Author)
+*
+* Alternatively, the contents of this file may be used under the terms of
+* the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
+* Public License Version 2.1 (the "LGPL"), in which case the provisions of
+* the GPL or the LGPL are applicable instead of those above. If you wish to
+* allow use of your version of this file only under the terms of the either
+* the GPL or LGPL and not to allow others to use your version of this file
+* under the MPL, indicate your decision by deleting the provisions above
+* and replace them with the notice and other provisions required by the GPL
+* or LGPL. If you do not delete the provisions above, a recipient may use
+* your version of this file under the terms of any one of the MPL, the GPL
+* or the LGPL.
+* ***** END LICENSE BLOCK ***** */
+
+#ifndef _PIXEL_MATCH_H_
+#define _PIXEL_MATCH_H_
+
+/* *************************************************************************
+*
+* Class for getting motion vectors to pixel-accuracy
+*
+* The class could be implemented in any number of ways. The approach taken
+* has been to do hierarchical matching, which means doing block matching
+* on smaller, downcoverted versions of the pictures in order to get a wider
+* effective search range. At each level of searching the vectors discovered
+* can be used as guides to the next level of searching, and in this way
+* large motions can be detected easily. The danger is that the motions of
+* small objects can be overlooked.
+*
+* *************************************************************************/
+
+#include <libdirac_common/common.h>
+#include <libdirac_common/motion.h>
+#include <libdirac_motionest/block_match.h>
+namespace dirac
+{
+ class EncQueue;
+ class MvData;
+ class EncoderParams;
+ class PicArray;
+
+
+ class PixelMatcher
+ {
+ public:
+
+ //! Constructor
+ PixelMatcher( const EncoderParams& encp);
+
+ //! Do the actual search
+ /* Do the searching.
+
+ \param my_buffer the buffer of pictures from which pictures are taken
+ \param pic_num the number of the picture for which motion is to be estimated
+ \param mv_data class in which the measured motion vectors are stored, together with costs
+
+ */
+ void DoSearch( EncQueue& my_buffer, int pic_num );
+
+ private:
+
+ // Member variables
+
+ //! Local reference to the encoder params
+ const EncoderParams& m_encparams;
+
+ //! Local reference to the picture pred params
+ const PicturePredParams* m_predparams;
+
+ // the depth of the hierarchical match
+ int m_depth;
+
+ // the level we're at (from 0 to depth)
+ int m_level;
+
+ // the search-range sizes for the hierarchical match
+ int m_xr, m_yr;
+
+ // the search-range sizes for when hierarchical match fails
+ int m_big_xr, m_big_yr;
+
+ // the temporal distances to the reference pictures
+ int m_tdiff[2];
+
+ // the picture sort - I, L1 or L2
+ PictureSort m_psort;
+
+ // list of candidate vectors for checking
+ CandidateList m_cand_list;
+
+ // Prediction used for each block. This is derived from neighbouring blocks
+ // and is used to control the variation in the motion vector field.
+ MVector m_mv_prediction;
+
+ // The value used in computing block cost means with a simple recursive filter
+ double m_rho;
+
+ // The mean of the block cost
+ double m_cost_mean;
+
+ // The mean of the square of the block cost
+ double m_cost_mean_sq;
+
+ private:
+
+ // Functions
+
+ //! Make down-converted pictures
+ void MakePicHierarchy(const PicArray& data, OneDArray< PicArray* >& down_data);
+
+ //! Make a hierarchy of MvData structures
+ void MakeMEDataHierarchy(const OneDArray< PicArray*>& down_data,
+ OneDArray< MEData* >& me_data_set );
+
+ //! Tidy up the allocations made in building the picture hirearchy
+ void TidyPics( OneDArray< PicArray*>& down_data );
+
+ //! Tidy up the allocations made in building the MV data hirearchy
+ void TidyMEData( OneDArray< MEData*>& me_data_set );
+
+ //! Match the picture data
+ void MatchPic(const PicArray& ref_data , const PicArray& pic_data , MEData& me_data ,
+ const MvData& guide_data, const int ref_id);
+
+ //! Do a given block
+ void DoBlock(const int xpos, const int ypos ,
+ const MvArray& guide_array,
+ BlockMatcher& block_match);
+
+ };
+
+} // namespace dirac
+
+#endif