From ab74f5c79e6b22c12173b63f7a127b4dc8f4882e Mon Sep 17 00:00:00 2001 From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de> Date: Mon, 25 Mar 2019 19:10:50 +0100 Subject: [PATCH] import JM 14.1 --- CHANGES.TXT | 34 +- bin/encoder.cfg | 75 +- bin/encoder_yuv422.cfg | 112 +- doc/ldecod.dox | 2 +- doc/lencod.dox | 2 +- ldecod/inc/annexb.h | 2 +- ldecod/inc/block.h | 31 +- ldecod/inc/global.h | 115 +- ldecod/inc/ifunctions.h | 19 + ldecod/inc/macroblock.h | 303 +---- ldecod/inc/mbuffer.h | 69 +- ldecod/inc/memalloc.h | 44 +- ldecod/inc/nalu.h | 3 +- ldecod/inc/quant.h | 50 + ldecod/inc/rtp.h | 2 +- ldecod/inc/transform8x8.h | 3 +- ldecod/src/annexb.c | 12 +- ldecod/src/block.c | 956 ++++--------- ldecod/src/cabac.c | 390 ++---- ldecod/src/erc_do_p.c | 37 +- ldecod/src/filehandle.c | 11 + ldecod/src/header.c | 10 +- ldecod/src/image.c | 160 +-- ldecod/src/ldecod.c | 30 +- ldecod/src/loopFilter.c | 35 +- ldecod/src/macroblock.c | 2170 ++++++++++++++++-------------- ldecod/src/mb_access.c | 8 +- ldecod/src/mbuffer.c | 1056 +++++++-------- ldecod/src/mc_prediction.c | 259 ++-- ldecod/src/memalloc.c | 52 +- ldecod/src/nalu.c | 47 +- ldecod/src/output.c | 20 +- ldecod/src/parset.c | 22 +- ldecod/src/quant.c | 459 +++++++ ldecod/src/rtp.c | 18 +- ldecod/src/sei.c | 2 +- ldecod/src/transform8x8.c | 160 +-- ldecod/src/vlc.c | 28 +- ldecod_vc7.vcproj | 9 + ldecod_vc8.vcproj | 9 + lencod/inc/block.h | 134 +- lencod/inc/cconv_yuv2rgb.h | 26 + lencod/inc/configfile.h | 30 +- lencod/inc/conformance.h | 2 +- lencod/inc/defines.h | 14 +- lencod/inc/enc_statistics.h | 64 + lencod/inc/errdo.h | 34 + lencod/inc/errdo_mc_prediction.h | 35 + lencod/inc/filehandle.h | 25 + lencod/inc/frame.h | 4 + lencod/inc/global.h | 375 ++---- lencod/inc/ifunctions.h | 19 + lencod/inc/image.h | 11 +- lencod/inc/img_dist_ms_ssim.h | 25 + lencod/inc/img_dist_snr.h | 24 + lencod/inc/img_dist_ssim.h | 26 + lencod/inc/img_distortion.h | 33 + lencod/inc/macroblock.h | 7 +- lencod/inc/mb_access.h | 3 +- lencod/inc/mbuffer.h | 78 +- lencod/inc/mc_prediction.h | 10 +- lencod/inc/me_epzs.h | 21 +- lencod/inc/me_fullfast.h | 6 +- lencod/inc/me_fullsearch.h | 2 +- lencod/inc/me_umhex.h | 1 + lencod/inc/me_umhexsmp.h | 1 + lencod/inc/memalloc.h | 55 +- lencod/inc/mode_decision.h | 28 +- lencod/inc/mv-search.h | 5 +- lencod/inc/q_around.h | 44 + lencod/inc/quant4x4.h | 79 +- lencod/inc/quant8x8.h | 2 +- lencod/inc/quantChroma.h | 59 + lencod/inc/ratectl.h | 2 - lencod/inc/rc_quadratic.h | 2 +- lencod/inc/rdo_quant.h | 10 +- lencod/inc/rdopt.h | 25 +- lencod/inc/report.h | 25 + lencod/inc/slice.h | 37 + lencod/inc/vlc.h | 30 +- lencod/inc/wp.h | 24 +- lencod/inc/wp_lms.h | 26 + lencod/inc/wp_mcprec.h | 64 + lencod/src/block.c | 1198 +++++++++-------- lencod/src/cabac.c | 299 ++-- lencod/src/cconv_yuv2rgb.c | 122 ++ lencod/src/configfile.c | 112 +- lencod/src/conformance.c | 5 - lencod/src/context_ini.c | 2 +- lencod/src/decoder.c | 669 --------- lencod/src/errdo.c | 580 ++++++++ lencod/src/errdo_mc_prediction.c | 1295 ++++++++++++++++++ lencod/src/explicit_gop.c | 74 +- lencod/src/filehandle.c | 1 + lencod/src/header.c | 13 +- lencod/src/image.c | 1013 ++++++-------- lencod/src/img_dist_ms_ssim.c | 353 +++++ lencod/src/img_dist_snr.c | 52 + lencod/src/img_dist_ssim.c | 113 ++ lencod/src/img_distortion.c | 210 +++ lencod/src/input.c | 3 +- lencod/src/lencod.c | 1471 ++++---------------- lencod/src/loopFilter.c | 24 +- lencod/src/macroblock.c | 358 +++-- lencod/src/mb_access.c | 10 +- lencod/src/mbuffer.c | 1145 ++++++++-------- lencod/src/mc_prediction.c | 92 +- lencod/src/md_high.c | 120 +- lencod/src/md_highfast.c | 144 +- lencod/src/md_highloss.c | 116 +- lencod/src/md_low.c | 164 ++- lencod/src/me_epzs.c | 663 +++++---- lencod/src/me_fullfast.c | 18 +- lencod/src/me_fullsearch.c | 1 + lencod/src/me_umhex.c | 22 +- lencod/src/me_umhexsmp.c | 1 + lencod/src/memalloc.c | 430 +++++- lencod/src/mode_decision.c | 406 +++--- lencod/src/mv-search.c | 314 ++--- lencod/src/nal.c | 1 + lencod/src/parset.c | 3 +- lencod/src/q_around.c | 369 +++++ lencod/src/q_matrix.c | 150 ++- lencod/src/q_offsets.c | 10 +- lencod/src/quant4x4.c | 15 +- lencod/src/quant4x4_around.c | 176 ++- lencod/src/quant4x4_normal.c | 174 ++- lencod/src/quant4x4_trellis.c | 270 ++-- lencod/src/quant8x8.c | 2 +- lencod/src/quant8x8_around.c | 91 +- lencod/src/quant8x8_normal.c | 48 +- lencod/src/quant8x8_trellis.c | 166 +-- lencod/src/quantChroma.c | 57 + lencod/src/quantChroma_around.c | 171 +++ lencod/src/quantChroma_normal.c | 171 +++ lencod/src/quantChroma_trellis.c | 173 +++ lencod/src/ratectl.c | 7 +- lencod/src/rc_quadratic.c | 144 +- lencod/src/rd_intra_jm.c | 65 +- lencod/src/rdo_quant.c | 433 ++++-- lencod/src/rdopt.c | 1291 +++++++----------- lencod/src/rdpicdecision.c | 13 +- lencod/src/refbuf.c | 2 +- lencod/src/report.c | 1181 ++++++++++++++++ lencod/src/slice.c | 627 ++++++--- lencod/src/transform8x8.c | 264 ++-- lencod/src/vlc.c | 14 +- lencod/src/weighted_prediction.c | 535 +++++--- lencod/src/wp_lms.c | 877 ++++++++++++ lencod/src/wp_mcprec.c | 430 ++++++ lencod_vc7.vcproj | 99 +- lencod_vc8.vcproj | 129 +- 152 files changed, 16933 insertions(+), 11191 deletions(-) create mode 100644 ldecod/inc/quant.h create mode 100644 ldecod/src/quant.c create mode 100644 lencod/inc/cconv_yuv2rgb.h create mode 100644 lencod/inc/enc_statistics.h create mode 100644 lencod/inc/errdo.h create mode 100644 lencod/inc/errdo_mc_prediction.h create mode 100644 lencod/inc/filehandle.h create mode 100644 lencod/inc/img_dist_ms_ssim.h create mode 100644 lencod/inc/img_dist_snr.h create mode 100644 lencod/inc/img_dist_ssim.h create mode 100644 lencod/inc/img_distortion.h create mode 100644 lencod/inc/q_around.h create mode 100644 lencod/inc/quantChroma.h create mode 100644 lencod/inc/report.h create mode 100644 lencod/inc/slice.h create mode 100644 lencod/inc/wp_lms.h create mode 100644 lencod/inc/wp_mcprec.h create mode 100644 lencod/src/cconv_yuv2rgb.c delete mode 100644 lencod/src/decoder.c create mode 100644 lencod/src/errdo.c create mode 100644 lencod/src/errdo_mc_prediction.c create mode 100644 lencod/src/img_dist_ms_ssim.c create mode 100644 lencod/src/img_dist_snr.c create mode 100644 lencod/src/img_dist_ssim.c create mode 100644 lencod/src/img_distortion.c create mode 100644 lencod/src/q_around.c create mode 100644 lencod/src/quantChroma.c create mode 100644 lencod/src/quantChroma_around.c create mode 100644 lencod/src/quantChroma_normal.c create mode 100644 lencod/src/quantChroma_trellis.c create mode 100644 lencod/src/report.c create mode 100644 lencod/src/wp_lms.c create mode 100644 lencod/src/wp_mcprec.c diff --git a/CHANGES.TXT b/CHANGES.TXT index 5b96fe3..9c61c94 100644 --- a/CHANGES.TXT +++ b/CHANGES.TXT @@ -1,3 +1,26 @@ +Changes in Version JM 14.1 (since JM 14.0) +------------------------------------------ +- encoder: fixes in lossless coding (KHH) +- encoder: Improved MC precision using Reordering & Weighed Prediction (AL, AT) +- encoder: Weighted Prediction Extensions (AT, AL) +- encoder: MS-SSIM distortion computation (PeP) +- encoder: Rewrite of Error Resilient RDO (PeP, AT) +- encoder: SSIM distortion computation (ZHL, WK, AT) +- encoder: RGB color space distortion computation (WK, AT) +- encoder: Distortion/Statistics functionality cleanups (AT, WK) +- encoder: RDOQ and Quantization cleanups (LL, AT) +- encoder: RC cleanups (AT) +- encoder: Adaptive Rounding Support for Low Complexity RDO (EM) +- encoder: Multipass RD coding bug fix for PicAFF (AL) +- decoder: Motion vector limit checking (LlL) +- encoder/decoder: Various code optimizations (AT) +- encoder/decoder: Various cleanups /reorganizations (AT) +- decoder: SP/SI slice decoder fixes (AT) +- encoder: fix 4:0:0 encoder bit depth initialization (KS) +- encoder: use SPS id parameter in GenerateSequenceParameterSet (KS) +- encoder: fix number of bits calculation for pic aff with slices/DP (CS) + + Changes in Version JM 14.0 (since JM 13.2) ------------------------------------------ - encoder: Bipredictive ME bug fixes (AT) @@ -958,7 +981,7 @@ Changes for Version JM 4.0c to JM 4.0b New features * New Macroblock modes for SP-frames [JVT-B055] (RK) Note: some problems related to decoding of SI-frames - are reported and have to be fixed + are reported and have to be fixed @@ -1262,6 +1285,7 @@ DK Dimitris Kontopodis dkonto@eikon.tum.de DM Detlev Marpe marpe@hhi.de DT Dong Tian tian@cs.tut.fi DW Dong Wang Dong.Wang@bristol.ac.uk +EM Ehsan Maani emaan@dolby.com ES Eric Setton esetton@stanford.edu FB Frank Bossen bossen@docomolabs-usa.com GB Gabi Blaetterman blaetter@hhi.de @@ -1287,10 +1311,12 @@ JX Jian Feng Xu fenax@video.mdc.tsinghua.edu.cn JXi Jun Xin jxin@merl.com JZ Jun Zhang j_zhang1999@yahoo.com KL Karl Lillevold Karll@real.com +KHH Ki-Hun Han khhan@dms.sejong.ac.kr KP Krit Panusopone KPanusopone@gi.com KSa Kazushi Sato kazushi@av.crl.sony.co.jp LK Louis Kerofsky lkerofsky@sharplabs.com LL Limin Liu lliu@dolby.com +LlL Loïc Le Loarer loic_leloarer@sdesigns.eu LW Limin Wang liwang@gi.com LWi Lowell Winger lwinger@videolocus.com LP Luca Pezzoni luca.pezzoni@st.com @@ -1303,6 +1329,7 @@ MT Mario Trentini mario_trentini@realmagic.fr MW Mathias Wien wien@ient.rwth-aachen.de MWa Michael Walter eiMichaelWalter@web.de OD Olivier Deygas olivier.deygas@st.com +PeP Peshala Pahalawatta Peshala.Pahalawatta@dolby.com PK Petr Kadlec Kadlec@FTW.at PL Peter List Peter.List@t-systems.de PN Pavel Novotny pnovotny@lsil.com @@ -1348,7 +1375,7 @@ VG Valeri George valeri.george@hhi.fraunhofer.de VV Viktor Varsa viktor.varsa@nokia.com WC Woong Il Choi creata@ece.skku.ac.kr WF Wenfang Fu fwf@video.mdc.tsinghua.edu.cn -WK Woo-Shik Kim wskim@sait.samsung.co.kr +WK Woo-Shik Kim wooshik.kim@usc.edu WZ Weimin Zeng wzeng@wischip.com XI Xin xin@apple.com XS Xiaoyan Sun sunxiaoyan@msrchina.research.microsoft.com @@ -1356,13 +1383,14 @@ XX Xiaozhong Xu xxz@video.mdc.tsinghua.edu.cn XY Xiaoquan Yi xyi@scu.edu YC Yi-Jen Chiu yi-jen.chiu@intel.com YD Yunyang Dai ydai@dolby.com -YDh Yves Dhondt yves.dhondt@ugent.be +YDh Yves Dhondt yves.dhondt@ugent.be YH Yu-Wen Huang YW_Huang@mtk.com.tw YK Yoshihiro Kikuchi yoshihiro.kikuchi@toshiba.co.jp YL Yann Lemaguet yann.lemaguet@philips.com YW Ye-Kui Wang ye-kui.wang@nokia.com YX Yanjun Xu yxu@sarnoff.com ZH Zhou Heng zhou_heng@yahoo.com +ZHL Zhen Li zhen.li@dolby.com ZL Li Zhang zhangli@jdl.ac.cn ZX Z. Xue jon_xz@yahoo.com ZY Zheng Yanzhao yzzheng@singnet.com diff --git a/bin/encoder.cfg b/bin/encoder.cfg index e66baaa..64d0a47 100644 --- a/bin/encoder.cfg +++ b/bin/encoder.cfg @@ -53,6 +53,7 @@ MEDistortionFPel = 0 # Select error metric for Full-Pel ME (0: SAD, 1: MEDistortionHPel = 2 # Select error metric for Half-Pel ME (0: SAD, 1: SSE, 2: Hadamard SAD) MEDistortionQPel = 2 # Select error metric for Quarter-Pel ME (0: SAD, 1: SSE, 2: Hadamard SAD) MDDistortion = 2 # Select error metric for Mode Decision (0: SAD, 1: SSE, 2: Hadamard SAD) +SkipDeBlockNonRef = 0 # Skip Deblocking (regardless of DFParametersFlag) for non-reference frames (0: off, 1: on) ChromaMCBuffer = 1 # Calculate Color component interpolated values in advance and store them. # Provides a trade-off between memory and computational complexity # (0: disabled/default, 1: enabled) @@ -90,8 +91,13 @@ BSliceSearch8x4 = 1 # B-Slice Inter block search 8x4 (0=disable, 1=ena BSliceSearch4x8 = 1 # B-Slice Inter block search 4x8 (0=disable, 1=enable) BSliceSearch4x4 = 1 # B-Slice Inter block search 4x4 (0=disable, 1=enable) -DisableIntra4x4 = 0 # Disable Intra 4x4 mode -DisableIntra16x16 = 0 # Disable Intra 16x16 mode +BiPredSearch16x16 = 1 # B-Slice Bi-prediction block search 16x16 (0=disable, 1=enable) +BiPredSearch16x8 = 1 # B-Slice Bi-prediction block search 16x8 (0=disable, 1=enable) +BiPredSearch8x16 = 1 # B-Slice Bi-prediction block search 8x16 (0=disable, 1=enable) +BiPredSearch8x8 = 1 # B-Slice Bi-prediction block search 8x8 (0=disable, 1=enable) + +DisableIntra4x4 = 0 # Disable Intra 4x4 modes +DisableIntra16x16 = 0 # Disable Intra 16x16 modes DisableIntraInInter = 0 # Disable Intra modes for inter slices IntraDisableInterOnly = 0 # Apply Disabling Intra conditions only to Inter Slices (0:disable/default,1: enable) Intra4x4ParDisable = 0 # Disable Vertical & Horizontal 4x4 @@ -178,7 +184,21 @@ IntraBottom = 0 # Force Intra Bottom at GOP Period WeightedPrediction = 0 # P picture Weighted Prediction (0=off, 1=explicit mode) WeightedBiprediction = 0 # B picture Weighted Prediciton (0=off, 1=explicit mode, 2=implicit mode) +ChromaWeightSupport = 1 # Enable consideration of weights for Chroma components UseWeightedReferenceME = 1 # Use weighted reference for ME (0=off, 1=on) +WPMethod = 1 # WP method (0: DC based, 1: LMS based) +EnhancedBWeightSupport = 0 # Enhanced B Weight support (needs revisit if we wish to merge with WPMethod) +WPMCPrecision = 0 # Improved Motion Compensation Precision using WP based methods. + # Clones WP references with slightly modified rounding offsets (Requires RDPictureDecision and GenerateMultiplePPS) : + # 0: disabled (default) + # 1: Up to one additional coding pass. Ref0 is 0, ref1 is 0 with a -1 offset + # 2: Up to two additional coding passes. (1) Ref0 is 0, ref1 is 0 with a -1 offset, (1) Ref0 is 0 with a -1 offset, ref1 is 0 +WPMCPrecFullRef = 0 # Increases the number of references in the reference picture lists to account + # for the lost reference slot when reordering is used during a coding pass in WPMCPrecision for reference replication. + # The number of references in non-reordered passes stays unchanged +WPMCPrecBSlice = 1 # 2: Apply rounding on every B slice. This efectively disables the evaluation of alternative QPs during RDPictureDecision. + # 1: Disable rounding for non-reference B slices. Non-reference B slices are evaluated for alternative QPs during RDPictureDecision. + # 0: Disable rounding for B slices. ########################################################################################## # Picture based Multi-pass encoding @@ -190,8 +210,8 @@ RDPictureDecision = 0 # Perform RD optimal decision between differen RDPictureIntra = 0 # Perform RD optimal decision also for intra coded pictures (0: disabled (default), 1: enabled). RDPSliceWeightOnly = 1 # Only consider Weighted Prediction for P slices in Picture RD decision. (0: disabled, 1: enabled (default)) RDBSliceWeightOnly = 0 # Only consider Weighted Prediction for B slices in Picture RD decision. (0: disabled (default), 1: enabled ) -RDPSliceBTest = 1 # Perform Slice level RD decision between P and P slices. - # Requires RDPSliceWeightOnly = 0. (0: disabled (default), 1: enabled ) +RDPSliceBTest = 1 # Perform Slice level RD decision between P and B slices. + # Requires GenerateMultiplePPS = 1 and RDPSliceWeightOnly = 0. (0: disabled (default), 1: enabled ) ########################################################################################## # Deblocking filter parameters @@ -251,6 +271,9 @@ RDOptimization = 1 # rd-optimized mode decision # 1: RD-on (High complexity mode) # 2: RD-on (Fast high complexity mode - not work in FREX Profiles) # 3: with losses +DistortionSSIM = 0 # Compute SSIM distortion. (0: disabled/default, 1: enabled) +SSIMOverlapSize = 8 # Overlap size to calculate SSIM distortion (1: pixel by pixel, 8: no overlap) +DistortionYUVtoRGB = 0 # Calculate distortion in RGB domain after conversion from YCbCr (0:off, 1:on) CtxAdptLagrangeMult = 0 # Context Adaptive Lagrange Multiplier # 0: disabled (default) # 1: enabled (works best when RDOptimization=0) @@ -266,19 +289,21 @@ WeightCr = 1 # Cr weight for RDO # Explicit Lambda Usage ########################################################################################## UseExplicitLambdaParams = 0 # Use explicit lambda scaling parameters (0:disabled, 1:enable lambda weight, 2: use explicit lambda value) -FixedLambdaISlice = 0.1 # Fixed Lambda value for I slices -FixedLambdaPSlice = 0.1 # Fixed Lambda value for P slices -FixedLambdaBSlice = 0.1 # Fixed Lambda value for B slices -FixedLambdaRefBSlice = 0.1 # Fixed Lambda value for Referenced B slices -FixedLambdaSPSlice = 0.1 # Fixed Lambda value for SP slices -FixedLambdaSISlice = 0.1 # Fixed Lambda value for SI slices - -LambdaWeightISlice = 0.65 # scaling param for I slices. This will be used as a multiplier i.e. lambda=LambdaWeightISlice * 2^((QP-12)/3) -LambdaWeightPSlice = 0.68 # scaling param for P slices. This will be used as a multiplier i.e. lambda=LambdaWeightPSlice * 2^((QP-12)/3) -LambdaWeightBSlice = 0.68 # scaling param for B slices. This will be used as a multiplier i.e. lambda=LambdaWeightBSlice * 2^((QP-12)/3) -LambdaWeightRefBSlice = 0.68 # scaling param for Referenced B slices. This will be used as a multiplier i.e. lambda=LambdaWeightRefBSlice * 2^((QP-12)/3) -LambdaWeightSPSlice = 0.68 # scaling param for SP slices. This will be used as a multiplier i.e. lambda=LambdaWeightSPSlice * 2^((QP-12)/3) -LambdaWeightSISlice = 0.65 # scaling param for SI slices. This will be used as a multiplier i.e. lambda=LambdaWeightSISlice * 2^((QP-12)/3) +UpdateLambdaChromaME = 0 # Update lambda given Chroma ME consideration +FixedLambdaIslice = 0.1 # Fixed Lambda value for I slices +FixedLambdaPslice = 0.1 # Fixed Lambda value for P slices +FixedLambdaBslice = 0.1 # Fixed Lambda value for B slices +FixedLambdaRefBslice = 0.1 # Fixed Lambda value for Referenced B slices +FixedLambdaSPslice = 0.1 # Fixed Lambda value for SP slices +FixedLambdaSIslice = 0.1 # Fixed Lambda value for SI slices + +LambdaWeightIslice = 0.65 # scaling param for I slices. This will be used as a multiplier i.e. lambda=LambdaWeightISlice * 2^((QP-12)/3) +LambdaWeightPslice = 0.68 # scaling param for P slices. This will be used as a multiplier i.e. lambda=LambdaWeightPSlice * 2^((QP-12)/3) +LambdaWeightBslice = 0.68 # scaling param for B slices. This will be used as a multiplier i.e. lambda=LambdaWeightBSlice * 2^((QP-12)/3) +LambdaWeightRefBslice = 0.68 # scaling param for Referenced B slices. This will be used as a multiplier i.e. lambda=LambdaWeightRefBSlice * 2^((QP-12)/3) +LambdaWeightSPslice = 0.68 # scaling param for SP slices. This will be used as a multiplier i.e. lambda=LambdaWeightSPSlice * 2^((QP-12)/3) +LambdaWeightSIslice = 0.65 # scaling param for SI slices. This will be used as a multiplier i.e. lambda=LambdaWeightSISlice * 2^((QP-12)/3) + LossRateA = 5 # expected packet loss rate of the channel for the first partition, only valid if RDOptimization = 3 LossRateB = 0 # expected packet loss rate of the channel for the second partition, only valid if RDOptimization = 3 @@ -302,7 +327,7 @@ NumberofLeakyBuckets = 8 # Number of Leaky Bucket valu LeakyBucketRateFile = "leakybucketrate.cfg" # File from which encoder derives rate values LeakyBucketParamFile = "leakybucketparam.cfg" # File where encoder stores leakybucketparams -NumberFramesInEnhancementLayerSubSequence = 0 # number of frames in the Enhanced Scalability Layer(0: no Enhanced Layer) +NumFramesInELayerSubSeq = 0 # number of frames in the Enhanced Scalability Layer(0: no Enhanced Layer) SparePictureOption = 0 # (0: no spare picture info, 1: spare picture available) SparePictureDetectionThr = 6 # Threshold for spare reference pictures detection @@ -319,7 +344,7 @@ Bitrate = 45020 # Bitrate(bps) InitialQP = 0 # Initial Quantization Parameter for the first I frame # InitialQp depends on two values: Bits Per Picture, # and the GOP length -BasicUnit = 1 # Number of basic units in the frame +BasicUnit = 11 # Number of MBs in the basic unit # should be a fraction of the total number # of MBs in a frame ChannelType = 0 # type of channel( 1=time varying channel; 0=Constant channel) @@ -338,7 +363,7 @@ RCBSliceBitRatio4 = 0.25 # target ratio of bits for B-coded pictures comp RCBoverPRatio = 0.45 # ratio of bit rate usage of a B-coded picture over a P-coded picture for the SAME QP (for RCUpdateMode=3) RCIoverPRatio = 3.80 # ratio of bit rate usage of an I-coded picture over a P-coded picture for the SAME QP (for RCUpdateMode=3) RCMinQPPSlice = 8 # minimum P Slice QP value for rate control -RCMaxQPPSlice = 40 # maximum P Slice QP value for rate control +RCMaxQPPSlice = 44 # maximum P Slice QP value for rate control RCMinQPBSlice = 8 # minimum B Slice QP value for rate control RCMaxQPBSlice = 46 # maximum B Slice QP value for rate control RCMinQPISlice = 8 # minimum I Slice QP value for rate control @@ -441,8 +466,12 @@ QPPrimeYZeroTransformBypassFlag = 0 # Enable lossless coding when qpprime_y i #Fast Motion Estimation Control Parameters ######################################################################################## -SearchMode = 0 # Use fast motion estimation (0=disable/default, 1=UMHexagonS, - # 2=Simplified UMHexagonS, 3=EPZS patterns) +SearchMode = 0 # Motion estimation mode + # -1 = Full Search + # 0 = Fast Full Search (default) + # 1 = UMHexagon Search + # 2 = Simplified UMHexagon Search + # 3 = Enhanced Predictive Zonal Search (EPZS) UMHexDSR = 1 # Use Search Range Prediction. Only for UMHexagonS method # (0:disable, 1:enabled/default) UMHexScale = 3 # Use Scale_factor for different image sizes. Only for UMHexagonS method @@ -463,6 +492,8 @@ EPZSTemporal = 1 # Enables temporal predictors # (0: disabled, 1: enabled/default) EPZSSpatialMem = 1 # Enables spatial memory predictors # (0: disabled, 1: enabled/default) +EPZSBlockType = 1 # Enables block type Predictors + # (0: disabled, 1: enabled/default) EPZSMinThresScale = 0 # Scaler for EPZS minimum threshold (0 default). # Increasing value can speed up encoding. EPZSMedThresScale = 1 # Scaler for EPZS median threshold (1 default). diff --git a/bin/encoder_yuv422.cfg b/bin/encoder_yuv422.cfg index 784f216..0277e4a 100644 --- a/bin/encoder_yuv422.cfg +++ b/bin/encoder_yuv422.cfg @@ -15,11 +15,16 @@ InputHeaderLength = 0 # If the inputfile has a header, state it's lengt StartFrame = 0 # Start frame for encoding. (0-N) FramesToBeEncoded = 2 # Number of frames to be coded FrameRate = 30.0 # Frame Rate per second (0.1-100.0) -SourceWidth = 176 # Frame width -SourceHeight = 144 # Frame height +SourceWidth = 176 # Source frame width +SourceHeight = 144 # Source frame height +SourceResize = 0 # Resize source size for output +OutputWidth = 176 # Output frame width +OutputHeight = 144 # Output frame height + TraceFile = "trace_enc.txt" # Trace file ReconFile = "test_rec.yuv" # Recontruction YUV file OutputFile = "test.264" # Bitstream +StatsFile = "stats.dat" # Coding statistics file ########################################################################################## # Encoder Control @@ -52,7 +57,10 @@ ChromaMCBuffer = 1 # Calculate Color component interpolated values in a # Provides a trade-off between memory and computational complexity # (0: disabled/default, 1: enabled) ChromaMEEnable = 0 # Take into account Color component information during ME - # (0: only first component/default, 1: All Color components) + # (0: only first component/default, + # 1: All Color components - Integer refinement only + # 2: All Color components - All refinements) +ChromaMEWeight = 1 # Weighting for chroma components. This parameter should have a relationship with color format. NumberReferenceFrames = 5 # Number of previous frames used for inter motion search (0-16) @@ -82,6 +90,8 @@ BSliceSearch8x4 = 1 # B-Slice Inter block search 8x4 (0=disable, 1=ena BSliceSearch4x8 = 1 # B-Slice Inter block search 4x8 (0=disable, 1=enable) BSliceSearch4x4 = 1 # B-Slice Inter block search 4x4 (0=disable, 1=enable) +DisableIntra4x4 = 0 # Disable Intra 4x4 mode +DisableIntra16x16 = 0 # Disable Intra 16x16 mode DisableIntraInInter = 0 # Disable Intra modes for inter slices IntraDisableInterOnly = 0 # Apply Disabling Intra conditions only to Inter Slices (0:disable/default,1: enable) Intra4x4ParDisable = 0 # Disable Vertical & Horizontal 4x4 @@ -180,9 +190,11 @@ RDPictureDecision = 0 # Perform RD optimal decision between differen RDPictureIntra = 0 # Perform RD optimal decision also for intra coded pictures (0: disabled (default), 1: enabled). RDPSliceWeightOnly = 1 # Only consider Weighted Prediction for P slices in Picture RD decision. (0: disabled, 1: enabled (default)) RDBSliceWeightOnly = 0 # Only consider Weighted Prediction for B slices in Picture RD decision. (0: disabled (default), 1: enabled ) +RDPSliceBTest = 1 # Perform Slice level RD decision between P and P slices. + # Requires RDPSliceWeightOnly = 0. (0: disabled (default), 1: enabled ) ########################################################################################## -# Loop filter parameters +# Deblocking filter parameters ########################################################################################## DFParametersFlag = 0 # Configure deblocking filter (0=parameters below ignored, 1=parameters sent) @@ -290,7 +302,7 @@ NumberofLeakyBuckets = 8 # Number of Leaky Bucket valu LeakyBucketRateFile = "leakybucketrate.cfg" # File from which encoder derives rate values LeakyBucketParamFile = "leakybucketparam.cfg" # File where encoder stores leakybucketparams -NumberFramesInEnhancementLayerSubSequence = 0 # number of frames in the Enhanced Scalability Layer(0: no Enhanced Layer) +NumFramesInELayerSubSeq = 0 # number of frames in the Enhanced Scalability Layer(0: no Enhanced Layer) SparePictureOption = 0 # (0: no spare picture info, 1: spare picture available) SparePictureDetectionThr = 6 # Threshold for spare reference pictures detection @@ -307,8 +319,8 @@ Bitrate = 45020 # Bitrate(bps) InitialQP = 0 # Initial Quantization Parameter for the first I frame # InitialQp depends on two values: Bits Per Picture, # and the GOP length -BasicUnit = 11 # Number of MBs in the basic unit - # should be a fractor of the total number +BasicUnit = 1 # Number of basic units in the frame + # should be a fraction of the total number # of MBs in a frame ChannelType = 0 # type of channel( 1=time varying channel; 0=Constant channel) RCUpdateMode = 0 # Rate Control type. Modes supported : @@ -326,7 +338,7 @@ RCBSliceBitRatio4 = 0.25 # target ratio of bits for B-coded pictures comp RCBoverPRatio = 0.45 # ratio of bit rate usage of a B-coded picture over a P-coded picture for the SAME QP (for RCUpdateMode=3) RCIoverPRatio = 3.80 # ratio of bit rate usage of an I-coded picture over a P-coded picture for the SAME QP (for RCUpdateMode=3) RCMinQPPSlice = 8 # minimum P Slice QP value for rate control -RCMaxQPPSlice = 40 # maximum P Slice QP value for rate control +RCMaxQPPSlice = 44 # maximum P Slice QP value for rate control RCMinQPBSlice = 8 # minimum B Slice QP value for rate control RCMaxQPBSlice = 46 # maximum B Slice QP value for rate control RCMinQPISlice = 8 # minimum I Slice QP value for rate control @@ -335,6 +347,7 @@ RCMinQPSPSlice = 8 # minimum SP Slice QP value for rate control RCMaxQPSPSlice = 40 # maximum SP Slice QP value for rate control RCMinQPSISlice = 8 # minimum SI Slice QP value for rate control RCMaxQPSISlice = 36 # maximum SI Slice QP value for rate control +RCMaxQPChange = 4 # maximum QP change for frames of the base layer ######################################################################################## #Fast Mode Decision @@ -349,8 +362,12 @@ SelectiveIntraEnable = 0 # Selective Intra mode decision (0: Disable 1: E YUVFormat = 2 # YUV format (0=4:0:0, 1=4:2:0, 2=4:2:2, 3=4:4:4) RGBInput = 0 # 1=RGB input, 0=GBR or YUV input SeparateColourPlane = 0 # 4:4:4 coding: 0=Common mode, 1=Independent mode -BitDepthLuma = 8 # Bit Depth for Luminance (8...12 bits) -BitDepthChroma = 8 # Bit Depth for Chrominance (8...12 bits) +SourceBitDepthLuma = 8 # Source Bit Depth for Luma color component (8...14 bits) +SourceBitDepthChroma = 8 # Source Bit Depth for Chroma color components (8...14 bits) +SourceBitDepthRescale = 0 # Rescale bit depth of source for output (0: Disable 1: Enable) +OutputBitDepthLuma = 8 # Output Bit Depth for Luma color component (8...14 bits) +OutputBitDepthChroma = 8 # Output Bit Depth for Chroma color components (8...14 bits) + CbQPOffset = 0 # Chroma QP offset for Cb-part (-51..51) CrQPOffset = 0 # Chroma QP offset for Cr-part (-51..51) Transform8x8Mode = 1 # (0: only 4x4 transform, 1: allow using 8x8 transform additionally, 2: only 8x8 transform) @@ -381,12 +398,12 @@ ScalingListPresentFlag11 = 3 # Inter8x8_ChromaV for 4:4:4 (0 Not present, 1 P #Rounding Offset control ######################################################################################## -OffsetMatrixPresentFlag = 0 # Enable Explicit Offset Quantization Matrices (0: disable 1: enable) +OffsetMatrixPresentFlag = 1 # Enable Explicit Offset Quantization Matrices (0: disable 1: enable) QOffsetMatrixFile = "q_offset.cfg" # Explicit Quantization Matrices file -AdaptiveRounding = 1 # Enable Adaptive Rounding based on JVT-N011 (0: disable, 1: enable) +AdaptiveRounding = 1 # Enable Adaptive Rounding based on JVT-N011 (0: disable, 1: enable) AdaptRoundingFixed = 1 # Enable Global Adaptive rounding for all qps (0: disable, 1: enable - default/old) -AdaptRndPeriod = 1 # Period in terms of MBs for updating rounding offsets. +AdaptRndPeriod = 16 # Period in terms of MBs for updating rounding offsets. # 0 performs update at the picture level. Default is 16. 1 is as in JVT-N011. AdaptRndChroma = 1 # Enables coefficient rounding adaptation for chroma @@ -404,6 +421,16 @@ AdaptRndCrWFactorINRef = 4 # Chroma Adaptive Rounding Weight for I/SI slice AdaptRndCrWFactorPNRef = 4 # Chroma Adaptive Rounding Weight for P/SP slices in non reference pictures /4096 AdaptRndCrWFactorBNRef = 4 # Chroma Adaptive Rounding Weight for B slices in non reference pictures /4096 +################################################################ +# Rate Distortion Optimized Quantization +################################################################ +UseRDOQuant = 0 # Use Rate Distortion Optimized Quantization (0=disable, 1=enable) +RDOQ_CR = 0 # Enable Rate Distortion Optimized Quantization for Chroma components (0=disable, 1=enable) +RDOQ_QP_Num = 1 # 1-5: Number of QP tested in RDO_Q (I/P/B slice) +RDOQ_CP_Mode = 1 # copy Mode from first QP tested +RDOQ_CP_MV = 0 # copy MV from first QP tested +RDOQ_Fast = 0 # Fast RDOQ decision method for multiple QPs + ######################################################################################## #Lossless Coding (FREXT) ######################################################################################## @@ -414,8 +441,12 @@ QPPrimeYZeroTransformBypassFlag = 0 # Enable lossless coding when qpprime_y i #Fast Motion Estimation Control Parameters ######################################################################################## -SearchMode = 0 # Use fast motion estimation (0=disable/default, 1=UMHexagonS, - # 2=Simplified UMHexagonS, 3=EPZS patterns) +SearchMode = 0 # Motion estimation mode + # -1 = Full Search + # 0 = Fast Full Search (default) + # 1 = UMHexagon Search + # 2 = Simplified UMHexagon Search + # 3 = Enhanced Predictive Zonal Search (EPZS) UMHexDSR = 1 # Use Search Range Prediction. Only for UMHexagonS method # (0:disable, 1:enabled/default) UMHexScale = 3 # Use Scale_factor for different image sizes. Only for UMHexagonS method @@ -445,7 +476,7 @@ EPZSMaxThresScale = 2 # Scaler for EPZS maximum threshold (1 default). EPZSSubPelME = 1 # EPZS Subpel ME consideration EPZSSubPelMEBiPred = 1 # EPZS Subpel ME consideration for BiPred partitions EPZSSubPelThresScale = 2 # EPZS Subpel ME Threshold scaler -EPZSSubPelGrid = 0 # Perform EPZS using a subpixel grid +EPZSSubPelGrid = 1 # Perform EPZS using a subpixel grid ######################################################################################## # SEI Parameters @@ -465,6 +496,7 @@ SEIMessageText = "H.264/AVC Encoder" # Text SEI Message EnableVUISupport = 0 # Enable VUI Parameters +# display parameters VUI_aspect_ratio_info_present_flag = 0 VUI_aspect_ratio_idc = 1 VUI_sar_width = 0 @@ -487,40 +519,40 @@ VUI_time_scale = 60000 VUI_fixed_frame_rate_flag = 0 # nal hrd parameters -VUI_nal_hrd_parameters_present_flag = 0 -VUI_nal_cpb_cnt_minus1 = 0 -VUI_nal_bit_rate_scale = 0 -VUI_nal_cpb_size_scale = 0 -VUI_nal_bit_rate_value_minus1 = 0 -VUI_nal_cpb_size_value_minus1 = 0 -VUI_nal_vbr_cbr_flag = 0 +VUI_nal_hrd_parameters_present_flag = 0 +VUI_nal_cpb_cnt_minus1 = 0 +VUI_nal_bit_rate_scale = 0 +VUI_nal_cpb_size_scale = 0 +VUI_nal_bit_rate_value_minus1 = 0 +VUI_nal_cpb_size_value_minus1 = 0 +VUI_nal_vbr_cbr_flag = 0 VUI_nal_initial_cpb_removal_delay_length_minus1 = 23 VUI_nal_cpb_removal_delay_length_minus1 = 23 VUI_nal_dpb_output_delay_length_minus1 = 23 VUI_nal_time_offset_length = 24 # vlc hrd parameters -VUI_vcl_hrd_parameters_present_flag = 0 -VUI_vcl_cpb_cnt_minus1 = 0 -VUI_vcl_bit_rate_scale = 0 -VUI_vcl_cpb_size_scale = 0 -VUI_vcl_bit_rate_value_minus1 = 0 -VUI_vcl_cpb_size_value_minus1 = 0 -VUI_vcl_vbr_cbr_flag = 0 +VUI_vcl_hrd_parameters_present_flag = 0 +VUI_vcl_cpb_cnt_minus1 = 0 +VUI_vcl_bit_rate_scale = 0 +VUI_vcl_cpb_size_scale = 0 +VUI_vcl_bit_rate_value_minus1 = 0 +VUI_vcl_cpb_size_value_minus1 = 0 +VUI_vcl_vbr_cbr_flag = 0 VUI_vcl_initial_cpb_removal_delay_length_minus1 = 23 VUI_vcl_cpb_removal_delay_length_minus1 = 23 VUI_vcl_dpb_output_delay_length_minus1 = 23 VUI_vcl_time_offset_length = 24 -VUI_low_delay_hrd_flag = 0 +VUI_low_delay_hrd_flag = 0 # other params (i.e. bitsream restrictions) -VUI_pic_struct_present_flag = 0 -VUI_bitstream_restriction_flag = 0 -VUI_motion_vectors_over_pic_boundaries_flag = 1 -VUI_max_bytes_per_pic_denom = 0 -VUI_max_bits_per_mb_denom = 0 -VUI_log2_max_mv_length_vertical = 16 -VUI_log2_max_mv_length_horizontal = 16 -VUI_num_reorder_frames = 16 -VUI_max_dec_frame_buffering = 16 +VUI_pic_struct_present_flag = 0 +VUI_bitstream_restriction_flag = 0 +VUI_motion_vectors_over_pic_boundaries_flag = 1 +VUI_max_bytes_per_pic_denom = 0 +VUI_max_bits_per_mb_denom = 0 +VUI_log2_max_mv_length_vertical = 16 +VUI_log2_max_mv_length_horizontal = 16 +VUI_num_reorder_frames = 16 +VUI_max_dec_frame_buffering = 16 diff --git a/doc/ldecod.dox b/doc/ldecod.dox index 7ae0346..9410356 100644 --- a/doc/ldecod.dox +++ b/doc/ldecod.dox @@ -7,7 +7,7 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "H.264/AVC Reference Software Decoder " PROJECT_NUMBER = OUTPUT_DIRECTORY = ./ldec -CREATE_SUBDIRS = YES +CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = NO REPEAT_BRIEF = YES diff --git a/doc/lencod.dox b/doc/lencod.dox index 5ed682f..5dc70ff 100644 --- a/doc/lencod.dox +++ b/doc/lencod.dox @@ -7,7 +7,7 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "H.264/AVC Reference Software Encoder " PROJECT_NUMBER = OUTPUT_DIRECTORY = ./lenc -CREATE_SUBDIRS = YES +CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = NO REPEAT_BRIEF = YES diff --git a/ldecod/inc/annexb.h b/ldecod/inc/annexb.h index dcfe648..8ad83a7 100644 --- a/ldecod/inc/annexb.h +++ b/ldecod/inc/annexb.h @@ -18,7 +18,7 @@ extern int IsFirstByteStreamNALU; extern int LastAccessUnitExists; extern int NALUCount; -int GetAnnexbNALU (NALU_t *nalu); +int GetAnnexbNALU (FILE *bitstream, NALU_t *nalu); void OpenBitstreamFile (char *fn); void CloseBitstreamFile(void); void CheckZeroByteNonVCL(NALU_t *nalu); diff --git a/ldecod/inc/block.h b/ldecod/inc/block.h index 72653fc..e77ac77 100644 --- a/ldecod/inc/block.h +++ b/ldecod/inc/block.h @@ -20,28 +20,25 @@ #include "global.h" -#define DQ_BITS 6 - extern const byte QP_SCALE_CR[52] ; -extern const int dequant_coef[6][4][4]; extern const unsigned char subblk_offset_x[3][8][4]; extern const unsigned char subblk_offset_y[3][8][4]; extern void iMBtrans4x4(ColorPlane pl, ImageParameters *img, int smb); -extern void iMBtrans8x8(ColorPlane pl, ImageParameters *img); +extern void iMBtrans8x8(ImageParameters *img, Macroblock *currMB, ColorPlane pl); extern void itrans_sp_cr(ImageParameters *img, int uv); -void (*itrans_4x4)(ColorPlane pl, ImageParameters *img, int ioff, int joff); -void (*itrans_8x8)(ColorPlane pl, ImageParameters *img, int ioff, int joff); - -extern void Inv_Residual_trans_4x4(ColorPlane pl, ImageParameters *img, int ioff, int joff); -extern void Inv_Residual_trans_8x8(ColorPlane pl, ImageParameters *img, int ioff,int joff); - -extern void itrans8x8(ColorPlane pl, ImageParameters *img, int ioff, int joff); -extern void itrans4x4(ColorPlane pl, ImageParameters *img, int ioff, int joff); -extern void itrans4x4_ls(ColorPlane pl, ImageParameters *img, int ioff, int joff); -extern void itrans_sp(ColorPlane pl, ImageParameters *img, int ioff, int joff); -extern int intrapred(Macroblock *currMB, ColorPlane pl, ImageParameters *img,int ioff,int joff,int i4,int j4); -extern void itrans_2 (ColorPlane pl, ImageParameters *img); -extern void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int need_4x4_transform, int smb); +void (*itrans_4x4)(ImageParameters *img, ColorPlane pl, int ioff, int joff); +void (*itrans_8x8)(ImageParameters *img, Macroblock *currMB, ColorPlane pl, int ioff, int joff); + +extern void Inv_Residual_trans_4x4(ImageParameters *img, ColorPlane pl, int ioff, int joff); +extern void Inv_Residual_trans_8x8(ImageParameters *img, Macroblock *currMB, ColorPlane pl, int ioff,int joff); + +extern void itrans8x8 (ImageParameters *img, Macroblock *currMB, ColorPlane pl, int ioff, int joff); +extern void itrans4x4 (ImageParameters *img, ColorPlane pl, int ioff, int joff); +extern void itrans4x4_ls(ImageParameters *img, ColorPlane pl, int ioff, int joff); +extern void itrans_sp (ImageParameters *img, ColorPlane pl, int ioff, int joff); +extern int intrapred (ImageParameters *img, Macroblock *currMB, ColorPlane pl, int ioff,int joff,int i4,int j4); +extern void itrans_2 (ImageParameters *img, Macroblock *currMB, ColorPlane pl); +extern void iTransform (ImageParameters *img, Macroblock *currMB, ColorPlane pl, int need_4x4_transform, int smb); #endif diff --git a/ldecod/inc/global.h b/ldecod/inc/global.h index c91cbec..d0a8f67 100644 --- a/ldecod/inc/global.h +++ b/ldecod/inc/global.h @@ -66,20 +66,6 @@ int g_nFrame; int TopFieldForSkip_Y[16][16]; int TopFieldForSkip_UV[2][16][16]; -int InvLevelScale4x4Luma_Intra[6][4][4]; -int InvLevelScale4x4Chroma_Intra[2][6][4][4]; - -int InvLevelScale4x4Luma_Inter[6][4][4]; -int InvLevelScale4x4Chroma_Inter[2][6][4][4]; - -int InvLevelScale8x8Luma_Intra[6][8][8]; -int InvLevelScale8x8Chroma_Intra[2][6][8][8]; - -int InvLevelScale8x8Luma_Inter[6][8][8]; -int InvLevelScale8x8Chroma_Inter[2][6][8][8]; - -int *qmatrix[12]; - #define ET_SIZE 300 //!< size of error text buffer char errortext[ET_SIZE]; //!< buffer for error message for exit with error() @@ -140,17 +126,17 @@ typedef enum typedef enum { - BITS_HEADER, - BITS_TOTAL_MB, - BITS_MB_MODE, - BITS_INTER_MB, - BITS_CBP_MB, - BITS_COEFF_Y_MB, - BITS_COEFF_UV_MB, - BITS_COEFF_CB_MB, - BITS_COEFF_CR_MB, - BITS_DELTA_QUANT_MB, - MAX_BITCOUNTER_MB + BITS_HEADER = 0, + BITS_TOTAL_MB = 1, + BITS_MB_MODE = 2, + BITS_INTER_MB = 3, + BITS_CBP_MB = 4, + BITS_COEFF_Y_MB = 5, + BITS_COEFF_CB_MB = 6, + BITS_COEFF_CR_MB = 7, + BITS_DELTA_QUANT_MB = 8, + BITS_STUFFING = 9, + MAX_BITCOUNTER_MB = 10 } BitCountType; typedef enum @@ -343,8 +329,9 @@ typedef struct syntaxelement //! Macroblock typedef struct macroblock { - int qp; //!< QP luma - int qpc[2]; //!< QP chroma + int qp; //!< QP luma + int qpc[2]; //!< QP chroma + int qp_scaled[MAX_PLANE]; //!< QP scaled for all comps. int slice_nr; int delta_quant; //!< for rate control @@ -417,6 +404,8 @@ typedef struct int ei_flag; //!< 0 if the partArr[0] contains valid information int qp; int slice_qp_delta; + int qs; + int slice_qs_delta; int picture_type; //!< picture type PictureStructure structure; //!< Identify picture structure type int start_mb_nr; //!< MUST be set by NAL even in case of ei_flag == 1 @@ -484,20 +473,20 @@ typedef struct img_par int mvscale[6][MAX_REFERENCE_PICTURES]; - imgpel mpr[MAX_PLANE][16][16]; //!< predicted block - int m7 [MAX_PLANE][16][16]; //!< residual macroblock + imgpel mb_pred[MAX_PLANE][16][16]; //!< predicted block + int mb_rres[MAX_PLANE][16][16]; //!< residual macroblock int cof[MAX_PLANE][16][16]; //!< transformed coefficients + int fcf[MAX_PLANE][16][16]; //!< transformed coefficients int cofu[16]; byte **ipredmode; //!< prediction type [90][74] - int ***nz_coeff; + int ****nz_coeff; int **siblock; int cod_counter; //!< Current count of number of skipped macroblocks in a row int newframe; int structure; //!< Identify picture structure type - int pstruct_next_P; // B pictures Slice *currentSlice; //!< pointer to current Slice data struct @@ -603,8 +592,6 @@ typedef struct img_par int bitdepth_luma_qp_scale; int bitdepth_chroma_qp_scale; unsigned int dc_pred_value_comp[MAX_PLANE]; //!< component value for DC prediction (depends on component pel bit depth) - int max_imgpel_value; //!< max value that one luma picture element (pixel) can take (depends on pic_unit_bitdepth) - int max_imgpel_value_uv; //!< max value that one chroma picture element (pixel) can take (depends on pic_unit_bitdepth) int max_imgpel_value_comp[MAX_PLANE]; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth) int Transform8x8Mode; int profile_idc; @@ -620,20 +607,18 @@ typedef struct img_par int mb_size[3][2]; //!< component macroblock dimensions int mb_size_blk[3][2]; //!< component macroblock dimensions int mb_size_shift[3][2]; + + int max_vmv_r; //!< maximum vertical motion vector range in luma quarter frame pixel units for the current level_idc + int max_mb_vmv_r; //!< maximum vertical motion vector range in luma quarter pixel units for the current level_idc int idr_psnr_number; int psnr_number; - time_t ltime_start; // for time measurement - time_t ltime_end; // for time measurement - -#ifdef WIN32 - struct _timeb tstruct_start; - struct _timeb tstruct_end; -#else - struct timeb tstruct_start; - struct timeb tstruct_end; -#endif + // Timing related variables + struct TIMEB tstruct_start; + struct TIMEB tstruct_end; + time_t ltime_start; + time_t ltime_end; // picture error concealment int last_ref_pic_poc; @@ -653,7 +638,6 @@ typedef struct img_par int recovery_poc; int separate_colour_plane_flag; - } ImageParameters; extern ImageParameters *img; @@ -696,7 +680,6 @@ struct inp_par int conceal_mode; int ref_poc_gap; int poc_gap; - }; extern struct inp_par *params; @@ -760,36 +743,27 @@ void init_picture(ImageParameters *img, struct inp_par *inp); void exit_picture(void); int read_new_slice(void); -void decode_one_slice(ImageParameters *img,struct inp_par *inp); - -void start_macroblock(Macroblock **currMB, ImageParameters *img); -void read_one_macroblock(Macroblock *currMB, ImageParameters *img); -void read_ipred_modes(Macroblock *currMB, ImageParameters *img); -int decode_one_macroblock(Macroblock *currMB, ImageParameters *img); -Boolean exit_macroblock(ImageParameters *img,int eos_bit); -void decode_ipcm_mb(Macroblock *currMB, ImageParameters *img); +void decode_one_slice(ImageParameters *img, struct inp_par *inp); +void start_macroblock (ImageParameters *img, Macroblock **currMB); +void read_one_macroblock (ImageParameters *img, Macroblock *currMB); +Boolean exit_macroblock (ImageParameters *img, int eos_bit); +void concealIPCMcoeffs (ImageParameters *img); -void readMotionInfoFromNAL (Macroblock *currMB, ImageParameters *img); -void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img); -void concealIPCMcoeffs(ImageParameters *img); -void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP); -void SetMotionVectorPredictor (Macroblock *currMB, ImageParameters *img, short pmv[2], char ref_frame, byte list, +void SetMotionVectorPredictor (ImageParameters *img, Macroblock *currMB, short pmv[2], char ref_frame, byte list, char ***refPic, short ****tmp_mv, int mb_x, int mb_y, int blockshape_x, int blockshape_y); -void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters *img, int b8); -void copyblock_sp(ImageParameters *img,int block_x,int block_y); -int intrapred_luma_16x16(Macroblock *currMB, ColorPlane pl, ImageParameters *img,int predmode); -void intrapred_chroma(Macroblock *currMB, ImageParameters *img, int uv); +int intrapred_luma_16x16(ImageParameters *img, Macroblock *currMB, ColorPlane pl, int predmode); +void intrapred_chroma (ImageParameters *img, Macroblock *currMB, int uv); // SLICE function pointers -int (*nal_startcode_follows) (ImageParameters*, int ); +int (*nal_startcode_follows) (Slice*, int ); // NAL functions TML/CABAC bitstream -int uvlc_startcode_follows(ImageParameters *img, int dummy); -int cabac_startcode_follows(ImageParameters *img, int eos_bit); +int uvlc_startcode_follows(Slice *currSlice, int dummy); +int cabac_startcode_follows(Slice *currSlice, int eos_bit); void free_Partition(Bitstream *currStream); // ErrorConcealment @@ -827,11 +801,6 @@ void readIPCM_CABAC(struct datapartition *dP); unsigned CeilLog2( unsigned uiVal); unsigned CeilLog2_sf( unsigned uiVal); -// For Q-matrix -void AssignQuantParam(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps); -void CalculateQuantParam(void); -void CalculateQuant8Param(void); - //For residual DPCM int ipmode_DPCM; @@ -839,12 +808,6 @@ int ipmode_DPCM; void change_plane_JV( int nplane ); void make_frame_picture_JV(void); -// Interpret MB mode -void (*interpret_mb_mode)(Macroblock *currMB); -void interpret_mb_mode_P(Macroblock *currMB); -void interpret_mb_mode_B(Macroblock *currMB); -void interpret_mb_mode_I(Macroblock *currMB); -void interpret_mb_mode_SI(Macroblock *currMB); #endif diff --git a/ldecod/inc/ifunctions.h b/ldecod/inc/ifunctions.h index db5a60e..abaf5c6 100644 --- a/ldecod/inc/ifunctions.h +++ b/ldecod/inc/ifunctions.h @@ -21,6 +21,7 @@ #define static #define inline #endif +#include <math.h> static inline int imin(int a, int b) { @@ -141,11 +142,29 @@ static inline int RSD(int x) return ((x&2)?(x|1):(x&(~1))); } +static inline int power2(int x) +{ + return 1 << (x); +} + static inline int float2int (float x) { return (int)((x < 0) ? (x - 0.5f) : (x + 0.5f)); } +#if ZEROSNR +static inline float psnr(int max_sample_sq, int samples, float sse_distortion ) +{ + return (float) (10.0 * log10(max_sample_sq * (double) ((double) samples / (sse_distortion == 0.0 ? 1.0 : sse_distortion)))); +} +#else +static inline float psnr(int max_sample_sq, int samples, float sse_distortion ) +{ + return (float) (sse_distortion == 0.0 ? 0.0 : (10.0 * log10(max_sample_sq * (double) ((double) samples / sse_distortion)))); +} +#endif + + # if !defined(WIN32) && (__STDC_VERSION__ < 199901L) #undef static #undef inline diff --git a/ldecod/inc/macroblock.h b/ldecod/inc/macroblock.h index 10951f0..2dc8cd2 100644 --- a/ldecod/inc/macroblock.h +++ b/ldecod/inc/macroblock.h @@ -16,307 +16,14 @@ #define _MACROBLOCK_H_ -//! single scan pattern -const byte SNGL_SCAN[16][2] = -{ - {0,0},{1,0},{0,1},{0,2}, - {1,1},{2,0},{3,0},{2,1}, - {1,2},{0,3},{1,3},{2,2}, - {3,1},{3,2},{2,3},{3,3} -}; - -//! field scan pattern -const byte FIELD_SCAN[16][2] = -{ - {0,0},{0,1},{1,0},{0,2}, - {0,3},{1,1},{1,2},{1,3}, - {2,0},{2,1},{2,2},{2,3}, - {3,0},{3,1},{3,2},{3,3} -}; - - -//! gives CBP value from codeword number, both for intra and inter -const unsigned char NCBP[2][48][2]= -{ - { // 0 1 2 3 4 5 6 7 8 9 10 11 - {15, 0},{ 0, 1},{ 7, 2},{11, 4},{13, 8},{14, 3},{ 3, 5},{ 5,10},{10,12},{12,15},{ 1, 7},{ 2,11}, - { 4,13},{ 8,14},{ 6, 6},{ 9, 9},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}, - { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}, - { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} - }, - { - {47, 0},{31,16},{15, 1},{ 0, 2},{23, 4},{27, 8},{29,32},{30, 3},{ 7, 5},{11,10},{13,12},{14,15}, - {39,47},{43, 7},{45,11},{46,13},{16,14},{ 3, 6},{ 5, 9},{10,31},{12,35},{19,37},{21,42},{26,44}, - {28,33},{35,34},{37,36},{42,40},{44,39},{ 1,43},{ 2,45},{ 4,46},{ 8,17},{17,18},{18,20},{20,24}, - {24,19},{ 6,21},{ 9,26},{22,28},{25,23},{32,27},{33,29},{34,30},{36,22},{40,25},{38,38},{41,41} - } -}; - - -//! used to control block sizes : Not used/16x16/16x8/8x16/8x8/8x4/4x8/4x4 -const int BLOCK_STEP[8][2]= -{ - {0,0},{4,4},{4,2},{2,4},{2,2},{2,1},{1,2},{1,1} -}; - -//! Dequantization coefficients -const int dequant_coef[6][4][4] = { - {{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}}, - {{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}}, - {{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}}, - {{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}}, - {{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}}, - {{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}} -}; - -const byte QP_SCALE_CR[52]= -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, - 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, - 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37, - 37,38,38,38,39,39,39,39 - -}; - -//! single scan pattern -const byte SNGL_SCAN8x8[64][2] = { - {0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0}, - {4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4}, {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3}, - {3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4}, {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6}, - {2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5}, {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7} -}; - - -//! field scan pattern -const byte FIELD_SCAN8x8[64][2] = { // 8x8 - {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {1,3}, {0,5}, {0,6}, {0,7}, {1,4}, {2,1}, {3,0}, - {2,2}, {1,5}, {1,6}, {1,7}, {2,3}, {3,1}, {4,0}, {3,2}, {2,4}, {2,5}, {2,6}, {2,7}, {3,3}, {4,1}, {5,0}, {4,2}, - {3,4}, {3,5}, {3,6}, {3,7}, {4,3}, {5,1}, {6,0}, {5,2}, {4,4}, {4,5}, {4,6}, {4,7}, {5,3}, {6,1}, {6,2}, {5,4}, - {5,5}, {5,6}, {5,7}, {6,3}, {7,0}, {7,1}, {6,4}, {6,5}, {6,6}, {6,7}, {7,2}, {7,3}, {7,4}, {7,5}, {7,6}, {7,7} -}; - - -static const int dequant_coef8[6][8][8] = -{ - { - {20, 19, 25, 19, 20, 19, 25, 19}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {25, 24, 32, 24, 25, 24, 32, 24}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {20, 19, 25, 19, 20, 19, 25, 19}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {25, 24, 32, 24, 25, 24, 32, 24}, - {19, 18, 24, 18, 19, 18, 24, 18} - }, - { - {22, 21, 28, 21, 22, 21, 28, 21}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {22, 21, 28, 21, 22, 21, 28, 21}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {21, 19, 26, 19, 21, 19, 26, 19} - }, - { - {26, 24, 33, 24, 26, 24, 33, 24}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {33, 31, 42, 31, 33, 31, 42, 31}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {26, 24, 33, 24, 26, 24, 33, 24}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {33, 31, 42, 31, 33, 31, 42, 31}, - {24, 23, 31, 23, 24, 23, 31, 23} - }, - { - {28, 26, 35, 26, 28, 26, 35, 26}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {35, 33, 45, 33, 35, 33, 45, 33}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {35, 33, 45, 33, 35, 33, 45, 33}, - {26, 25, 33, 25, 26, 25, 33, 25} - }, - { - {32, 30, 40, 30, 32, 30, 40, 30}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {40, 38, 51, 38, 40, 38, 51, 38}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {32, 30, 40, 30, 32, 30, 40, 30}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {40, 38, 51, 38, 40, 38, 51, 38}, - {30, 28, 38, 28, 30, 28, 38, 28} - }, - { - {36, 34, 46, 34, 36, 34, 46, 34}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {46, 43, 58, 43, 46, 43, 58, 43}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {36, 34, 46, 34, 36, 34, 46, 34}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {46, 43, 58, 43, 46, 43, 58, 43}, - {34, 32, 43, 32, 34, 32, 43, 32} - } - -}; - -//! single scan pattern -const byte SCAN_YUV422[8][2] = -{ - {0,0},{0,1}, - {1,0},{0,2}, - {0,3},{1,1}, - {1,2},{1,3} -}; +extern const byte QP_SCALE_CR[52]; //! look up tables for FRExt_chroma support -const unsigned char subblk_offset_x[3][8][4] = -{ - { {0, 4, 0, 4}, - {0, 4, 0, 4}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, }, - - { {0, 4, 0, 4}, - {0, 4, 0, 4}, - {0, 4, 0, 4}, - {0, 4, 0, 4}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, }, - - { {0, 4, 0, 4}, - {8,12, 8,12}, - {0, 4, 0, 4}, - {8,12, 8,12}, - {0, 4, 0, 4}, - {8,12, 8,12}, - {0, 4, 0, 4}, - {8,12, 8,12} } -}; - -const unsigned char subblk_offset_y[3][8][4] = -{ { {0, 0, 4, 4}, - {0, 0, 4, 4}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, }, - - { {0, 0, 4, 4}, - {8, 8,12,12}, - {0, 0, 4, 4}, - {8, 8,12,12}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} }, - - { {0, 0, 4, 4}, - {0, 0, 4, 4}, - {8, 8,12,12}, - {8, 8,12,12}, - {0, 0, 4, 4}, - {0, 0, 4, 4}, - {8, 8,12,12}, - {8, 8,12,12} } -}; - - -const unsigned char cofuv_blk_x[3][8][4] = -{ { {0, 1, 0, 1}, - {0, 1, 0, 1}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} }, - - { {0, 1, 0, 1}, - {0, 1, 0, 1}, - {0, 1, 0, 1}, - {0, 1, 0, 1}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} }, - - { {0, 1, 0, 1}, - {2, 3, 2, 3}, - {0, 1, 0, 1}, - {2, 3, 2, 3}, - {0, 1, 0, 1}, - {2, 3, 2, 3}, - {0, 1, 0, 1}, - {2, 3, 2, 3} } -}; - -const unsigned char cofuv_blk_y[3][8][4] = -{ - { { 0, 0, 1, 1}, - { 0, 0, 1, 1}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0} }, - - { { 0, 0, 1, 1}, - { 2, 2, 3, 3}, - { 0, 0, 1, 1}, - { 2, 2, 3, 3}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0}, - { 0, 0, 0, 0} }, - - { { 0, 0, 1, 1}, - { 0, 0, 1, 1}, - { 2, 2, 3, 3}, - { 2, 2, 3, 3}, - { 0, 0, 1, 1}, - { 0, 0, 1, 1}, - { 2, 2, 3, 3}, - { 2, 2, 3, 3}} -}; - -static unsigned char cbp_blk_chroma[8][4] = -{ {16, 17, 18, 19}, - {20, 21, 22, 23}, - {24, 25, 26, 27}, - {28, 29, 30, 31}, - {32, 33, 34, 35}, - {36, 37, 38, 39}, - {40, 41, 42, 43}, - {44, 45, 46, 47} }; - - -int block8x8_idx[3][4][4] = -{ { {0, 1, 2, 3}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, }, - - { {0, 1, 0, 1}, - {2, 3, 2, 3}, - {0, 0, 0, 0}, - {0, 0, 0, 0} }, +extern const unsigned char subblk_offset_x[3][8][4]; +extern const unsigned char subblk_offset_y[3][8][4]; - { {0, 0, 0, 0}, - {1, 1, 1, 1}, - {2, 2, 2, 2}, - {3, 3, 3, 3} } -}; +extern void set_interpret_mb_mode(int slice_type); +extern int decode_one_macroblock(ImageParameters *img, Macroblock *currMB, StorablePicture *dec_picture); #endif diff --git a/ldecod/inc/mbuffer.h b/ldecod/inc/mbuffer.h index 84d4e2e..d608735 100644 --- a/ldecod/inc/mbuffer.h +++ b/ldecod/inc/mbuffer.h @@ -10,6 +10,8 @@ * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Jill Boyce <jill.boyce@thomson.net> * - Saurav K Bandyopadhyay <saurav@ieee.org> * - Zhenyu Wu <Zhenyu.Wu@thomson.net @@ -23,6 +25,16 @@ #include "global.h" #define MAX_LIST_SIZE 33 +//! definition of pic motion parameters +typedef struct pic_motion_params +{ + int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] + int64 *** ref_id; //!< reference picture identifier [list][subblock_y][subblock_x] + short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] + char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] + byte * mb_field; //!< field macroblock indicator + byte ** field_frame; //!< indicates if co_located is field or frame. +} PicMotionParams; //! definition a picture (field or frame) typedef struct storable_picture @@ -61,25 +73,11 @@ typedef struct storable_picture imgpel ** imgY; //!< Y picture component imgpel *** imgUV; //!< U and V picture components + + PicMotionParams motion; //!< Motion info + PicMotionParams JVmotion[MAX_PLANE]; //!< Motion info for 4:4:4 independent mode decoding - byte * mb_field; //!< field macroblock indicator short ** slice_id; //!< reference picture [mb_x][mb_y] - char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] - - int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - // (not simply index) - int64 *** ref_id; //!< reference picture identifier [list][subblock_y][subblock_x] - // (not simply index) - - short **** mv; //!< motion vector [list][subblock_y][subblock_x][component] - - char *** ref_idx_JV[MAX_PLANE]; //!< ref_idx to be used for 4:4:4 independent mode decoding - int64 *** ref_pic_id_JV[MAX_PLANE]; //!< ref_pic_id to be used for 4:4:4 independent mode decoding - int64 *** ref_id_JV[MAX_PLANE]; //!< ref_id to be used for 4:4:4 independent mode decoding - short **** mv_JV[MAX_PLANE]; //!< mv to be used for 4:4:4 independent mode decoding - - byte ** moving_block; - byte ** field_frame; //!< indicates if co_located is field or frame. struct storable_picture *top_field; // for mb aff, if frame for referencing the top field struct storable_picture *bottom_field; // for mb aff, if frame for referencing the bottom field @@ -113,36 +111,25 @@ typedef struct storable_picture imgpel* tone_mapping_lut; //!< tone mapping look up table } StorablePicture; +//! definition of motion parameters +typedef struct motion_params +{ + int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] + short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] + char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] + byte ** moving_block; +} MotionParams; //! definition a picture (field or frame) typedef struct colocated_params { int mb_adaptive_frame_field_flag; int size_x, size_y; - - int64 ref_pic_num[6][MAX_LIST_SIZE]; - - char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] - int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - short **** mv; //!< motion vector [list][subblock_y][subblock_x][component] - byte ** moving_block; - - // Top field params - int64 top_ref_pic_num[6][MAX_LIST_SIZE]; - char *** top_ref_idx; //!< reference picture [list][subblock_y][subblock_x] - int64 *** top_ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - short **** top_mv; //!< motion vector [list][subblock_y][subblock_x][component] - byte ** top_moving_block; - - // Bottom field params - int64 bottom_ref_pic_num[6][MAX_LIST_SIZE]; - char *** bottom_ref_idx; //!< reference picture [list][subblock_y][subblock_x] - int64 *** bottom_ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - short **** bottom_mv; //!< motion vector [list][subblock_y][subblock_x][component] - byte ** bottom_moving_block; - byte is_long_term; - byte ** field_frame; //!< indicates if co_located is field or frame. + + MotionParams frame; + MotionParams top; + MotionParams bottom; } ColocatedParams; @@ -228,7 +215,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]); // For 4:4:4 independent mode void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]); -void copy_storable_param_JV( int nplane, StorablePicture *d, StorablePicture *s ); +void copy_storable_param_JV( PicMotionParams *JVplane, PicMotionParams *motion ); #endif diff --git a/ldecod/inc/memalloc.h b/ldecod/inc/memalloc.h index a298348..18735d7 100644 --- a/ldecod/inc/memalloc.h +++ b/ldecod/inc/memalloc.h @@ -8,6 +8,9 @@ * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * ************************************************************************ */ @@ -23,32 +26,37 @@ int get_mem2Dint(int ***array2D, int rows, int columns); int get_mem3Dint(int ****array3D, int frames, int rows, int columns); int get_mem4Dint(int *****array4D, int idx, int frames, int rows, int columns ); -int get_mem3Dint64(int64 ****array3D, int frames, int rows, int columns); + int get_mem2Dint64(int64 ***array2D, int rows, int columns); +int get_mem3Dint64(int64 ****array3D, int frames, int rows, int columns); + +int get_mem2Dshort(short ***array2D, int dim0, int dim1); +int get_mem3Dshort(short ****array3D, int dim0, int dim1, int dim2); +int get_mem4Dshort(short *****array4D, int dim0, int dim1, int dim2, int dim3); + + +int get_mem2Dpel(imgpel ***array2D, int rows, int columns); +int get_mem3Dpel(imgpel ****array3D, int frames, int rows, int columns); + -int get_mem2Dshort(short ***array2D, int rows, int columns); -int get_mem3Dshort(short ****array3D, int frames, int rows, int columns); -int get_mem4Dshort(short *****array4D, int idx, int frames, int rows, int columns ); +void free_mem2D (byte **array2D); +void free_mem3D (byte ***array2D); -int get_mem2Dpel(imgpel ***array2D, int rows, int columns); -int get_mem3Dpel(imgpel ****array3D, int frames, int rows, int columns); -void free_mem2D(byte **array2D); -void free_mem3D(byte ***array2D); +void free_mem2Dint (int **array2D); +void free_mem3Dint (int ***array3D); +void free_mem4Dint (int ****array4D); -void free_mem2Dint(int **array2D); -void free_mem3Dint(int ***array3D); -void free_mem4Dint(int ****array4D); -void free_mem2Dint64(int64 **array2D); -void free_mem3Dint64(int64 ***array3D); +void free_mem2Dint64(int64 **array2D); +void free_mem3Dint64(int64 ***array3D); -void free_mem2Dshort(short **array2D); -void free_mem3Dshort(short ***array3D); -void free_mem4Dshort(short ****array4D); +void free_mem2Dshort(short **array2D); +void free_mem3Dshort(short ***array3D); +void free_mem4Dshort(short ****array4D); -void free_mem2Dpel(imgpel **array2D); -void free_mem3Dpel(imgpel ***array3D); +void free_mem2Dpel (imgpel **array2D); +void free_mem3Dpel (imgpel ***array3D); void no_mem_exit(char *where); diff --git a/ldecod/inc/nalu.h b/ldecod/inc/nalu.h index d7fc689..51f46c8 100644 --- a/ldecod/inc/nalu.h +++ b/ldecod/inc/nalu.h @@ -21,7 +21,8 @@ extern FILE *bits; -int GetAnnexbNALU (NALU_t *nalu); +//int GetAnnexbNALU (NALU_t *nalu); +int read_next_nalu(FILE *bitstream, NALU_t *nalu); int NALUtoRBSP (NALU_t *nalu); #endif diff --git a/ldecod/inc/quant.h b/ldecod/inc/quant.h new file mode 100644 index 0000000..bb6608a --- /dev/null +++ b/ldecod/inc/quant.h @@ -0,0 +1,50 @@ + +/*! + ************************************************************************ + * \file quant.h + * + * \brief + * definitions for quantization functions + * + * \author + * + ************************************************************************ + */ + +#ifndef _QUANT_H_ +#define _QUANT_H_ + +// Macro defines +#define Q_BITS 15 +#define DQ_BITS 6 +#define Q_BITS_8 16 +#define DQ_BITS_8 6 + +// exported variables +extern const int dequant_coef[6][4][4]; +extern const int quant_coef[6][4][4]; + +extern int InvLevelScale4x4_Intra[3][6][4][4]; +extern int InvLevelScale4x4_Inter[3][6][4][4]; +extern int InvLevelScale8x8_Intra[3][6][8][8]; +extern int InvLevelScale8x8_Inter[3][6][8][8]; + +extern int *qmatrix[12]; + +// SP decoding parameter (EQ. 8-425) +extern const int A[4][4]; + +extern int *qp_per_matrix; +extern int *qp_rem_matrix; + +// exported functions +// quantization initialization +void init_qp_process(ImageParameters *img); + +// For Q-matrix +void AssignQuantParam(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps); +void CalculateQuantParam(void); +void CalculateQuant8Param(void); + +#endif + diff --git a/ldecod/inc/rtp.h b/ldecod/inc/rtp.h index 7fd806b..143e529 100644 --- a/ldecod/inc/rtp.h +++ b/ldecod/inc/rtp.h @@ -40,7 +40,7 @@ typedef struct void DumpRTPHeader (RTPpacket_t *p); -int GetRTPNALU (NALU_t *nalu); +int GetRTPNALU (FILE *bitstream, NALU_t *nalu); void OpenRTPFile (char *fn); void CloseRTPFile(void); diff --git a/ldecod/inc/transform8x8.h b/ldecod/inc/transform8x8.h index 8b8ade1..9851f09 100644 --- a/ldecod/inc/transform8x8.h +++ b/ldecod/inc/transform8x8.h @@ -17,7 +17,6 @@ #ifndef _TRANSFORM8X8_H_ #define _TRANSFORM8X8_H_ -int intrapred8x8(ColorPlane pl, ImageParameters *img, Macroblock *currMB, int b8); -void itrans8x8(ColorPlane pl, ImageParameters *img, int ioff, int joff); +int intrapred8x8(ImageParameters *img, Macroblock *currMB, ColorPlane pl, int b8); #endif diff --git a/ldecod/src/annexb.c b/ldecod/src/annexb.c index 9cd9026..e0481d3 100644 --- a/ldecod/src/annexb.c +++ b/ldecod/src/annexb.c @@ -44,7 +44,7 @@ int NALUCount=0; ************************************************************************ */ -int GetAnnexbNALU (NALU_t *nalu) +int GetAnnexbNALU (FILE *bitstream, NALU_t *nalu) { int info2, info3, pos = 0; int StartCodeFound, rewind; @@ -53,9 +53,9 @@ int GetAnnexbNALU (NALU_t *nalu) if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL) no_mem_exit("GetAnnexbNALU: Buf"); - while(!feof(bits) && (Buf[pos++]= (unsigned char) fgetc(bits))==0); + while(!feof(bitstream) && (Buf[pos++]= (unsigned char) fgetc(bitstream))==0); - if(feof(bits)) + if(feof(bitstream)) { if(pos==0) { @@ -111,7 +111,7 @@ int GetAnnexbNALU (NALU_t *nalu) while (!StartCodeFound) { - if (feof (bits)) + if (feof (bitstream)) { //Count the trailing_zero_8bits while(Buf[pos-2-TrailingZero8Bits]==0) @@ -133,7 +133,7 @@ int GetAnnexbNALU (NALU_t *nalu) free(Buf); return pos-1; } - Buf[pos++] = (unsigned char) fgetc (bits); + Buf[pos++] = (unsigned char) fgetc (bitstream); info3 = FindStartCode(&Buf[pos-4], 3); if(info3 != 1) info2 = FindStartCode(&Buf[pos-3], 2); @@ -160,7 +160,7 @@ int GetAnnexbNALU (NALU_t *nalu) return -1; } - if (0 != fseek (bits, rewind, SEEK_CUR)) + if (0 != fseek (bitstream, rewind, SEEK_CUR)) { snprintf (errortext, ET_SIZE, "GetAnnexbNALU: Cannot fseek %d in the bit stream file", rewind); free(Buf); diff --git a/ldecod/src/block.c b/ldecod/src/block.c index 4e94077..575d1ec 100644 --- a/ldecod/src/block.c +++ b/ldecod/src/block.c @@ -21,80 +21,7 @@ #include "image.h" #include "mb_access.h" #include "transform.h" - -#define Q_BITS 15 - -extern const unsigned char cofuv_blk_y[3][8][4]; -extern const unsigned char cofuv_blk_x[3][8][4]; - -static const int quant_coef[6][4][4] = { - {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}}, - {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}}, - {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}}, - {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}}, - {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}}, - {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}} -}; -static const int A[4][4] = { - { 16, 20, 16, 20}, - { 20, 25, 20, 25}, - { 16, 20, 16, 20}, - { 20, 25, 20, 25} -}; - -int quant_intra_default[16] = { - 6,13,20,28, -13,20,28,32, -20,28,32,37, -28,32,37,42 -}; - -int quant_inter_default[16] = { -10,14,20,24, -14,20,24,27, -20,24,27,30, -24,27,30,34 -}; - -int quant8_intra_default[64] = { - 6,10,13,16,18,23,25,27, -10,11,16,18,23,25,27,29, -13,16,18,23,25,27,29,31, -16,18,23,25,27,29,31,33, -18,23,25,27,29,31,33,36, -23,25,27,29,31,33,36,38, -25,27,29,31,33,36,38,40, -27,29,31,33,36,38,40,42 -}; - -int quant8_inter_default[64] = { - 9,13,15,17,19,21,22,24, -13,13,17,19,21,22,24,25, -15,17,19,21,22,24,25,27, -17,19,21,22,24,25,27,28, -19,21,22,24,25,27,28,30, -21,22,24,25,27,28,30,32, -22,24,25,27,28,30,32,33, -24,25,27,28,30,32,33,35 -}; - -int quant_org[16] = { //to be use if no q matrix is chosen -16,16,16,16, -16,16,16,16, -16,16,16,16, -16,16,16,16 -}; - -int quant8_org[64] = { //to be use if no q matrix is chosen -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16, -16,16,16,16,16,16,16,16 -}; +#include "quant.h" // Notation for comments regarding prediction and predictors. // The pels of the 4x4 block are labelled a..p. The predictor pels above @@ -122,7 +49,9 @@ int quant8_org[64] = { //to be use if no q matrix is chosen #define P_K (PredPel[11]) #define P_L (PredPel[12]) - static int M4[4][4]; + static int M4[BLOCK_SIZE][BLOCK_SIZE]; + static int PBlock[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; + static void intra_chroma_DC_single(imgpel **curr_img, int up_avail, int left_avail, PixelPos up, PixelPos left[17], int blk_x, int blk_y, int *pred, int direction ) { static int i; @@ -174,13 +103,13 @@ static void intra_chroma_DC_all(imgpel **curr_img, int up_avail, int left_avail, * SEARCH_SYNC search next sync element as errors while decoding occured *********************************************************************** */ -int intrapred( Macroblock *currMB, - ColorPlane pl, - ImageParameters *img, //!< image parameters - int ioff, //!< pixel offset X within MB - int joff, //!< pixel offset Y within MB - int img_block_x, //!< location of block X, multiples of 4 - int img_block_y) //!< location of block Y, multiples of 4 +int intrapred(ImageParameters *img, //!< image parameters + Macroblock *currMB, + ColorPlane pl, + int ioff, //!< pixel offset X within MB + int joff, //!< pixel offset Y within MB + int img_block_x, //!< location of block X, multiples of 4 + int img_block_y) //!< location of block Y, multiples of 4 { int i,j; int s0; @@ -199,7 +128,7 @@ int intrapred( Macroblock *currMB, byte predmode = img->ipredmode[img_block_y][img_block_x]; int jpos0 = joff, jpos1 = joff + 1, jpos2 = joff + 2, jpos3 = joff + 3; int ipos0 = ioff, ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3; - imgpel *predrow, prediction, (*mpr)[16] = img->mpr[pl]; + imgpel *predrow, prediction, (*mpr)[16] = img->mb_pred[pl]; ipmode_DPCM = predmode; //For residual DPCM @@ -483,9 +412,9 @@ int intrapred( Macroblock *currMB, * best SAD *********************************************************************** */ -int intrapred_luma_16x16(Macroblock *currMB, //!< Current Macroblock - ColorPlane pl, //!< Current colorplane (for 4:4:4) - ImageParameters *img, //!< image parameters +int intrapred_luma_16x16(ImageParameters *img, //!< image parameters + Macroblock *currMB, //!< Current Macroblock + ColorPlane pl, //!< Current colorplane (for 4:4:4) int predmode) //!< prediction mode { int s0 = 0, s1, s2; @@ -497,9 +426,10 @@ int intrapred_luma_16x16(Macroblock *currMB, //!< Current Macroblock int uv = pl-1; imgpel **imgY = (pl) ? dec_picture->imgUV[uv] : dec_picture->imgY; - imgpel (*mpr)[MB_BLOCK_SIZE] = &(img->mpr[pl][0]); + imgpel (*mpr)[MB_BLOCK_SIZE] = &(img->mb_pred[pl][0]); imgpel *mpr_line; imgpel prediction; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; PixelPos up; //!< pixel position p(0,-1) PixelPos left[17]; //!< pixel positions p(-1, -1..15) @@ -534,7 +464,7 @@ int intrapred_luma_16x16(Macroblock *currMB, //!< Current Macroblock if (!up_avail) error ("invalid 16x16 intra pred Mode VERT_PRED_16",500); for(j=0;j<MB_BLOCK_SIZE;j++) - memcpy(img->mpr[pl][j], &(imgY[up.pos_y][up.pos_x]), MB_BLOCK_SIZE * sizeof(imgpel)); + memcpy(img->mb_pred[pl][j], &(imgY[up.pos_y][up.pos_x]), MB_BLOCK_SIZE * sizeof(imgpel)); break; case HOR_PRED_16: // horizontal prediction from left block if (!left_avail) @@ -596,7 +526,7 @@ int intrapred_luma_16x16(Macroblock *currMB, //!< Current Macroblock { for (i=0;i< MB_BLOCK_SIZE;i++) { - mpr[j][i]=(imgpel) iClip1(img->max_imgpel_value_comp[pl],((iaa+(i-7)*ib +(j-7)*ic + 16)>>5)); + mpr[j][i]=(imgpel) iClip1(max_imgpel_value,((iaa+(i-7)*ib +(j-7)*ic + 16)>>5)); } }// store plane prediction break; @@ -619,12 +549,13 @@ int intrapred_luma_16x16(Macroblock *currMB, //!< Current Macroblock ************************************************************************ */ -void intrapred_chroma(Macroblock *currMB, ImageParameters *img, int uv) +void intrapred_chroma(ImageParameters *img, Macroblock *currMB, int uv) { int i,j, ii, jj; imgpel **imgUV = dec_picture->imgUV[uv]; - imgpel (*mpr)[16] = img->mpr[uv + 1]; + imgpel (*mpr)[16] = img->mb_pred[uv + 1]; + int max_imgpel_value = img->max_imgpel_value_comp[uv + 1]; int ih, iv, ib, ic, iaa; @@ -759,7 +690,7 @@ void intrapred_chroma(Macroblock *currMB, ImageParameters *img, int uv) for (j = 0; j < cr_MB_y; j++) for (i = 0; i < cr_MB_x; i++) - mpr[j][i]=(imgpel) iClip1(img->max_imgpel_value_uv,((iaa + (i - cr_MB_x2 + 1) * ib + (j - cr_MB_y2 + 1) * ic + 16) >> 5)); } + mpr[j][i]=(imgpel) iClip1(max_imgpel_value, ((iaa + (i - cr_MB_x2 + 1) * ib + (j - cr_MB_y2 + 1) * ic + 16) >> 5)); } break; default: error("illegal chroma intra prediction mode", 600); @@ -773,26 +704,27 @@ void intrapred_chroma(Macroblock *currMB, ImageParameters *img, int uv) * Inverse 4x4 transformation, transforms cof to m7 *********************************************************************** */ -void itrans4x4(ColorPlane pl, - ImageParameters *img, //!< image parameters - int ioff, //!< index to 4x4 block - int joff) //!< +void itrans4x4(ImageParameters *img, //!< image parameters + ColorPlane pl, + int ioff, //!< index to 4x4 block + int joff) //!< { static int i,j; - int max_imgpel_value = pl ? img->max_imgpel_value_uv : img->max_imgpel_value; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; - imgpel (*mpr)[16] = img->mpr[pl]; - int (*m7)[16] = img->m7[pl]; + imgpel (*mpr)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*m7) [MB_BLOCK_SIZE] = img->mb_rres[pl]; inverse4x4(img->cof[pl],m7,joff,ioff); for (j = joff; j < joff + BLOCK_SIZE; j++) + { for (i = ioff; i < ioff + BLOCK_SIZE; i++) { m7[j][i] = iClip1(max_imgpel_value, rshift_rnd_sf((m7[j][i] + ((long)mpr[j][i] << DQ_BITS)), DQ_BITS)); } - + } } /*! @@ -801,17 +733,17 @@ void itrans4x4(ColorPlane pl, * Inverse 4x4 lossless_qpprime transformation, transforms cof to m7 *********************************************************************** */ -void itrans4x4_ls(ColorPlane pl, //!< Color plane (for 4:4:4) - ImageParameters *img, //!< image parameters +void itrans4x4_ls(ImageParameters *img, //!< image parameters + ColorPlane pl, //!< Color plane (for 4:4:4) int ioff, //!< index to 4x4 block int joff) //!< { static int i,j; - int max_imgpel_value = pl ? img->max_imgpel_value_uv : img->max_imgpel_value; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; - imgpel (*mpr)[16] = img->mpr[pl]; - int ( *m7)[16] = img->m7 [pl]; + imgpel (*mpr)[16] = img->mb_pred[pl]; + int ( *m7)[16] = img->mb_rres [pl]; inverse4x4(img->cof[pl],m7,joff,ioff); @@ -833,59 +765,60 @@ void itrans4x4_ls(ColorPlane pl, //!< Color plane (for 4:4:4) * ioff_x,joff_y: Block position inside a macro block (0,4,8,12). ************************************************************************ */ //For residual DPCM -void Inv_Residual_trans_4x4(ColorPlane pl, - ImageParameters *img, //!< image parameters - int ioff, //!< index to 4x4 block - int joff) +void Inv_Residual_trans_4x4(ImageParameters *img, //!< image parameters + ColorPlane pl, + int ioff, //!< index to 4x4 block + int joff) { int i,j; int temp[4][4]; - imgpel (*mpr)[16] = img->mpr[pl]; - + imgpel (*mpr)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*m7) [MB_BLOCK_SIZE] = img->mb_rres[pl]; + int (*cof)[MB_BLOCK_SIZE] = img->cof[pl]; if(ipmode_DPCM==VERT_PRED) { for(i=0; i<4; i++) { - temp[0][i] = img->cof[pl][joff + 0][ioff + i]; - temp[1][i] = img->cof[pl][joff + 1][ioff + i] + temp[0][i]; - temp[2][i] = img->cof[pl][joff + 2][ioff + i] + temp[1][i]; - temp[3][i] = img->cof[pl][joff + 3][ioff + i] + temp[2][i]; + temp[0][i] = cof[joff + 0][ioff + i]; + temp[1][i] = cof[joff + 1][ioff + i] + temp[0][i]; + temp[2][i] = cof[joff + 2][ioff + i] + temp[1][i]; + temp[3][i] = cof[joff + 3][ioff + i] + temp[2][i]; } for(i=0; i<4; i++) { - img->m7[pl][joff ][ioff + i]=temp[0][i]; - img->m7[pl][joff + 1][ioff + i]=temp[1][i]; - img->m7[pl][joff + 2][ioff + i]=temp[2][i]; - img->m7[pl][joff + 3][ioff + i]=temp[3][i]; + m7[joff ][ioff + i]=temp[0][i]; + m7[joff + 1][ioff + i]=temp[1][i]; + m7[joff + 2][ioff + i]=temp[2][i]; + m7[joff + 3][ioff + i]=temp[3][i]; } } else if(ipmode_DPCM==HOR_PRED) { for(j=0; j<4; j++) { - temp[j][0] = img->cof[pl][joff + j][ioff ]; - temp[j][1] = img->cof[pl][joff + j][ioff + 1] + temp[j][0]; - temp[j][2] = img->cof[pl][joff + j][ioff + 2] + temp[j][1]; - temp[j][3] = img->cof[pl][joff + j][ioff + 3] + temp[j][2]; + temp[j][0] = cof[joff + j][ioff ]; + temp[j][1] = cof[joff + j][ioff + 1] + temp[j][0]; + temp[j][2] = cof[joff + j][ioff + 2] + temp[j][1]; + temp[j][3] = cof[joff + j][ioff + 3] + temp[j][2]; } for(j=0; j<4; j++) { - img->m7[pl][joff + j][ioff ]=temp[j][0]; - img->m7[pl][joff + j][ioff + 1]=temp[j][1]; - img->m7[pl][joff + j][ioff + 2]=temp[j][2]; - img->m7[pl][joff + j][ioff + 3]=temp[j][3]; + m7[joff + j][ioff ]=temp[j][0]; + m7[joff + j][ioff + 1]=temp[j][1]; + m7[joff + j][ioff + 2]=temp[j][2]; + m7[joff + j][ioff + 3]=temp[j][3]; } } else { for (j = 0; j < BLOCK_SIZE; j++) for (i = 0; i < BLOCK_SIZE; i++) - img->m7[pl][joff+j][ioff+i] = img->cof[pl][joff+j][ioff+i]; + m7[joff+j][ioff+i] = cof[joff+j][ioff+i]; } for (j = 0; j < BLOCK_SIZE; j++) for (i = 0; i < BLOCK_SIZE; i++) - img->m7[pl][joff+j][ioff+i] = img->m7[pl][joff+j][ioff+i] + (long)mpr[joff+j][ioff+i]; + m7[joff+j][ioff+i] += (long)mpr[joff+j][ioff+i]; } @@ -899,225 +832,70 @@ void Inv_Residual_trans_4x4(ColorPlane pl, ************************************************************************ */ //For residual DPCM -void Inv_Residual_trans_8x8(ColorPlane pl, ImageParameters *img, int ioff,int joff) +void Inv_Residual_trans_8x8(ImageParameters *img, Macroblock *currMB, ColorPlane pl, int ioff,int joff) { int i, j; int temp[8][8]; - imgpel (*mpr)[16] = img->mpr[pl]; + imgpel (*mpr)[16] = img->mb_pred[pl]; + int (*m7) [16] = img->mb_rres[pl]; + if(ipmode_DPCM==VERT_PRED) { for(i=0; i<8; i++) { - temp[0][i] = img->m7[pl][joff + 0][ioff + i]; - temp[1][i] = img->m7[pl][joff + 1][ioff + i] + temp[0][i]; - temp[2][i] = img->m7[pl][joff + 2][ioff + i] + temp[1][i]; - temp[3][i] = img->m7[pl][joff + 3][ioff + i] + temp[2][i]; - temp[4][i] = img->m7[pl][joff + 4][ioff + i] + temp[3][i]; - temp[5][i] = img->m7[pl][joff + 5][ioff + i] + temp[4][i]; - temp[6][i] = img->m7[pl][joff + 6][ioff + i] + temp[5][i]; - temp[7][i] = img->m7[pl][joff + 7][ioff + i] + temp[6][i]; + temp[0][i] = m7[joff + 0][ioff + i]; + temp[1][i] = m7[joff + 1][ioff + i] + temp[0][i]; + temp[2][i] = m7[joff + 2][ioff + i] + temp[1][i]; + temp[3][i] = m7[joff + 3][ioff + i] + temp[2][i]; + temp[4][i] = m7[joff + 4][ioff + i] + temp[3][i]; + temp[5][i] = m7[joff + 5][ioff + i] + temp[4][i]; + temp[6][i] = m7[joff + 6][ioff + i] + temp[5][i]; + temp[7][i] = m7[joff + 7][ioff + i] + temp[6][i]; } for(i=0; i<8; i++) { - img->m7[pl][joff ][ioff+i]=temp[0][i]; - img->m7[pl][joff+1][ioff+i]=temp[1][i]; - img->m7[pl][joff+2][ioff+i]=temp[2][i]; - img->m7[pl][joff+3][ioff+i]=temp[3][i]; - img->m7[pl][joff+4][ioff+i]=temp[4][i]; - img->m7[pl][joff+5][ioff+i]=temp[5][i]; - img->m7[pl][joff+6][ioff+i]=temp[6][i]; - img->m7[pl][joff+7][ioff+i]=temp[7][i]; + m7[joff ][ioff+i]=temp[0][i]; + m7[joff+1][ioff+i]=temp[1][i]; + m7[joff+2][ioff+i]=temp[2][i]; + m7[joff+3][ioff+i]=temp[3][i]; + m7[joff+4][ioff+i]=temp[4][i]; + m7[joff+5][ioff+i]=temp[5][i]; + m7[joff+6][ioff+i]=temp[6][i]; + m7[joff+7][ioff+i]=temp[7][i]; } } else if(ipmode_DPCM==HOR_PRED)//HOR_PRED { for(i=0; i<8; i++) { - temp[i][0] = img->m7[pl][joff + i][ioff + 0]; - temp[i][1] = img->m7[pl][joff + i][ioff + 1] + temp[i][0]; - temp[i][2] = img->m7[pl][joff + i][ioff + 2] + temp[i][1]; - temp[i][3] = img->m7[pl][joff + i][ioff + 3] + temp[i][2]; - temp[i][4] = img->m7[pl][joff + i][ioff + 4] + temp[i][3]; - temp[i][5] = img->m7[pl][joff + i][ioff + 5] + temp[i][4]; - temp[i][6] = img->m7[pl][joff + i][ioff + 6] + temp[i][5]; - temp[i][7] = img->m7[pl][joff + i][ioff + 7] + temp[i][6]; + temp[i][0] = m7[joff + i][ioff + 0]; + temp[i][1] = m7[joff + i][ioff + 1] + temp[i][0]; + temp[i][2] = m7[joff + i][ioff + 2] + temp[i][1]; + temp[i][3] = m7[joff + i][ioff + 3] + temp[i][2]; + temp[i][4] = m7[joff + i][ioff + 4] + temp[i][3]; + temp[i][5] = m7[joff + i][ioff + 5] + temp[i][4]; + temp[i][6] = m7[joff + i][ioff + 6] + temp[i][5]; + temp[i][7] = m7[joff + i][ioff + 7] + temp[i][6]; } for(i=0; i<8; i++) { - img->m7[pl][joff+i][ioff+0]=temp[i][0]; - img->m7[pl][joff+i][ioff+1]=temp[i][1]; - img->m7[pl][joff+i][ioff+2]=temp[i][2]; - img->m7[pl][joff+i][ioff+3]=temp[i][3]; - img->m7[pl][joff+i][ioff+4]=temp[i][4]; - img->m7[pl][joff+i][ioff+5]=temp[i][5]; - img->m7[pl][joff+i][ioff+6]=temp[i][6]; - img->m7[pl][joff+i][ioff+7]=temp[i][7]; + m7[joff+i][ioff+0]=temp[i][0]; + m7[joff+i][ioff+1]=temp[i][1]; + m7[joff+i][ioff+2]=temp[i][2]; + m7[joff+i][ioff+3]=temp[i][3]; + m7[joff+i][ioff+4]=temp[i][4]; + m7[joff+i][ioff+5]=temp[i][5]; + m7[joff+i][ioff+6]=temp[i][6]; + m7[joff+i][ioff+7]=temp[i][7]; } } for (j = 0; j < BLOCK_SIZE*2; j++) for (i = 0; i < BLOCK_SIZE*2; i++) - img->m7[pl][j+joff][i+ioff] = img->m7[pl][j+joff][i+ioff] + (long)mpr[j+joff][i+ioff]; + m7[j+joff][i+ioff] += (long)mpr[j+joff][i+ioff]; } -/*! - ************************************************************************ - * \brief - * For mapping the q-matrix to the active id and calculate quantisation values - * - * \param pps - * Picture parameter set - * \param sps - * Sequence parameter set - * - ************************************************************************ - */ -void AssignQuantParam(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps) -{ - int i; - int n_ScalingList; - if(!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag) - { - for(i=0; i<12; i++) - qmatrix[i] = (i<6) ? quant_org:quant8_org; - } - else - { - n_ScalingList = (sps->chroma_format_idc != YUV444) ? 8 : 12; - if(sps->seq_scaling_matrix_present_flag) // check sps first - { - for(i=0; i<n_ScalingList; i++) - { - if(i<6) - { - if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A - { - if(i==0) - qmatrix[i] = quant_intra_default; - else if(i==3) - qmatrix[i] = quant_inter_default; - else - qmatrix[i] = qmatrix[i-1]; - } - else - { - if(sps->UseDefaultScalingMatrix4x4Flag[i]) - qmatrix[i] = (i<3) ? quant_intra_default : quant_inter_default; - else - qmatrix[i] = sps->ScalingList4x4[i]; - } - } - else - { - if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A - { - if(i==6) - qmatrix[i] = quant8_intra_default; - else if(i==7) - qmatrix[i] = quant8_inter_default; - else - qmatrix[i] = qmatrix[i-2]; - } - else - { - if(sps->UseDefaultScalingMatrix8x8Flag[i-6]) - qmatrix[i] = (i==6 || i==8 || i==10) ? quant8_intra_default:quant8_inter_default; - else - qmatrix[i] = sps->ScalingList8x8[i-6]; - } - } - } - } - - if(pps->pic_scaling_matrix_present_flag) // then check pps - { - for(i=0; i<n_ScalingList; i++) - { - if(i<6) - { - if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B - { - if (i==0) - { - if(!sps->seq_scaling_matrix_present_flag) - qmatrix[i] = quant_intra_default; - } - else if (i==3) - { - if(!sps->seq_scaling_matrix_present_flag) - qmatrix[i] = quant_inter_default; - } - else - qmatrix[i] = qmatrix[i-1]; - } - else - { - if(pps->UseDefaultScalingMatrix4x4Flag[i]) - qmatrix[i] = (i<3) ? quant_intra_default:quant_inter_default; - else - qmatrix[i] = pps->ScalingList4x4[i]; - } - } - else - { - if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B - { - if (i==6) - { - if(!sps->seq_scaling_matrix_present_flag) - qmatrix[i] = quant8_intra_default; - } - else if(i==7) - { - if(!sps->seq_scaling_matrix_present_flag) - qmatrix[i] = quant8_inter_default; - } - else - qmatrix[i] = qmatrix[i-2]; - } - else - { - if(pps->UseDefaultScalingMatrix8x8Flag[i-6]) - qmatrix[i] = (i==6 || i==8 || i==10) ? quant8_intra_default:quant8_inter_default; - else - qmatrix[i] = pps->ScalingList8x8[i-6]; - } - } - } - } - } - - CalculateQuantParam(); - if(pps->transform_8x8_mode_flag) - CalculateQuant8Param(); -} - -/*! - ************************************************************************ - * \brief - * For calculating the quantisation values at frame level - * - ************************************************************************ - */ -void CalculateQuantParam() -{ - int i, j, k, temp; - - for(k=0; k<6; k++) - for(i=0; i<4; i++) - for(j=0; j<4; j++) - { - temp = (i<<2)+j; - InvLevelScale4x4Luma_Intra[k][i][j] = dequant_coef[k][i][j] * qmatrix[0][temp]; - InvLevelScale4x4Chroma_Intra[0][k][i][j] = dequant_coef[k][i][j] * qmatrix[1][temp]; - InvLevelScale4x4Chroma_Intra[1][k][i][j] = dequant_coef[k][i][j] * qmatrix[2][temp]; - - InvLevelScale4x4Luma_Inter[k][i][j] = dequant_coef[k][i][j] * qmatrix[3][temp]; - InvLevelScale4x4Chroma_Inter[0][k][i][j] = dequant_coef[k][i][j] * qmatrix[4][temp]; - InvLevelScale4x4Chroma_Inter[1][k][i][j] = dequant_coef[k][i][j] * qmatrix[5][temp]; - } -} /*! *********************************************************************** @@ -1125,422 +903,236 @@ void CalculateQuantParam() * Luma DC inverse transform *********************************************************************** */ -void itrans_2(ColorPlane pl, ImageParameters *img) //!< image parameters +void itrans_2(ImageParameters *img, Macroblock *currMB, ColorPlane pl) //!< image parameters { - static int invLevelScale; int i,j; - int qp, qp_c; - int qp_per, qp_rem; + int (*cof)[16] = img->cof[pl]; + int qp_scaled = currMB->qp_scaled[pl]; - if (pl) - { - int uv = pl - 1; - qp = img->qp + dec_picture->chroma_qp_offset[uv]; - qp = iClip3(-(img->bitdepth_chroma_qp_scale), 51, qp); - qp_c = (qp < 0)? qp : QP_SCALE_CR[qp-MIN_QP]; - qp_per = (qp_c + img->bitdepth_chroma_qp_scale)/6; - qp_rem = (qp_c + img->bitdepth_chroma_qp_scale)%6; - invLevelScale = InvLevelScale4x4Chroma_Intra[uv][qp_rem][0][0]; - } - else - { - qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6; - qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6; - if( IS_INDEPENDENT(img) ) - { - if( img->colour_plane_id == 0 ) - { - invLevelScale = InvLevelScale4x4Luma_Intra[qp_rem][0][0]; - } - else if( img->colour_plane_id == 1 ) - { - invLevelScale = InvLevelScale4x4Chroma_Intra[0][qp_rem][0][0]; - } - else if( img->colour_plane_id == 2 ) - { - invLevelScale = InvLevelScale4x4Chroma_Intra[1][qp_rem][0][0]; - } - } - else - { - invLevelScale = InvLevelScale4x4Luma_Intra[qp_rem][0][0]; - } - } + int qp_per = qp_per_matrix[ qp_scaled ]; + int qp_rem = qp_rem_matrix[ qp_scaled ]; + + int invLevelScale = InvLevelScale4x4_Intra[pl][qp_rem][0][0]; // horizontal for (j=0; j < 4;j++) - for (i=0; i < 4;i++) - { - M4[j][i]=img->cof[pl][j<<2][i<<2]; - } - - ihadamard4x4(M4, M4); - // vertical - - for (j=0; j < 4;j++) - for (i=0; i < 4;i++) - { - img->cof[pl][j<<2][i<<2] = rshift_rnd((( M4[j][i]*invLevelScale) << qp_per), 6); - } -} - - - -void itrans_sp(ColorPlane pl, - ImageParameters *img, //!< image parameters - int ioff, //!< index to 4x4 block - int joff) //!< -{ - int i,j,i1,j1; - int m5[4]; - int m6[4]; - int predicted_block[BLOCK_SIZE][BLOCK_SIZE],ilev; - - int qp_per = (img->qp-MIN_QP)/6; - int qp_rem = (img->qp-MIN_QP)%6; - - int qp_per_sp = (img->qpsp-MIN_QP)/6; - int qp_rem_sp = (img->qpsp-MIN_QP)%6; - int q_bits_sp = Q_BITS+qp_per_sp; - int qp_const2 = (1<<q_bits_sp)/2; //sp_pred - imgpel (*mpr)[16] = img->mpr[LumaComp]; - int (*m7) [16] = img->m7[LumaComp]; - - if (img->type == SI_SLICE) //ES modified - { - qp_per = (img->qpsp-MIN_QP)/6; - qp_rem = (img->qpsp-MIN_QP)%6; - } - - for (j=0; j< BLOCK_SIZE; j++) - for (i=0; i< BLOCK_SIZE; i++) - predicted_block[i][j]=mpr[j+joff][i+ioff]; - - for (j=0; j < BLOCK_SIZE; j++) - { - for (i=0; i < 2; i++) - { - i1=3-i; - m5[i] = predicted_block[i][j]+predicted_block[i1][j]; - m5[i1] = predicted_block[i][j]-predicted_block[i1][j]; - } - predicted_block[0][j]=(m5[0]+m5[1]); - predicted_block[2][j]=(m5[0]-m5[1]); - predicted_block[1][j]=m5[3]*2+m5[2]; - predicted_block[3][j]=m5[3]-m5[2]*2; - } - - // Vertical transform - for (i=0; i < BLOCK_SIZE; i++) { - for (j=0; j < 2; j++) + for (i=0; i < 4;i++) { - j1=3-j; - m5[j]=predicted_block[i][j]+predicted_block[i][j1]; - m5[j1]=predicted_block[i][j]-predicted_block[i][j1]; + M4[j][i]=cof[j<<2][i<<2]; } - predicted_block[i][0]=(m5[0]+m5[1]); - predicted_block[i][2]=(m5[0]-m5[1]); - predicted_block[i][1]=m5[3]*2+m5[2]; - predicted_block[i][3]=m5[3]-m5[2]*2; } - for (j=0;j<BLOCK_SIZE;j++) - for (i=0;i<BLOCK_SIZE;i++) - { - // recovering coefficient since they are already dequantized earlier - img->cof[0][joff + j][ioff + i]=(img->cof[0][joff + j][ioff + i] >> qp_per) / dequant_coef[qp_rem][j][i]; - if(img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI - { - ilev=(iabs(predicted_block[i][j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp; //ES added - ilev= isignab(ilev,predicted_block[i][j])+ img->cof[0][joff + j][ioff + i]; //ES added - img->cof[0][joff + j][ioff + i] = isignab(iabs(ilev) * dequant_coef[qp_rem_sp][j][i] << qp_per_sp ,ilev) ; //ES added - } //ES added - else - { //ES added - ilev=((img->cof[0][joff + j][ioff + i]*dequant_coef[qp_rem][j][i]*A[i][j]<< qp_per) >>6)+predicted_block[i][j] ; - img->cof[0][joff + j][ioff + i]=isignab((iabs(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp, ilev) * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; - } - } - // horizontal - for (j=0;j<BLOCK_SIZE;j++) - { - for (i=0;i<BLOCK_SIZE;i++) - { - m5[i]=img->cof[0][joff + j][ioff + i]; - } - m6[0]=(m5[0]+m5[2]); - m6[1]=(m5[0]-m5[2]); - m6[2]=(m5[1]>>1)-m5[3]; - m6[3]=m5[1]+(m5[3]>>1); + ihadamard4x4(M4, M4); - for (i=0;i<2;i++) - { - i1=3-i; - m7[j][i]=m6[i]+m6[i1]; - m7[j][i1]=m6[i]-m6[i1]; - } - } // vertical - for (i=0;i<BLOCK_SIZE;i++) + for (j=0; j < 4;j++) { - for (j=0;j<BLOCK_SIZE;j++) - m5[j]=m7[j][i]; - - m6[0]=(m5[0]+m5[2]); - m6[1]=(m5[0]-m5[2]); - m6[2]=(m5[1]>>1)-m5[3]; - m6[3]=m5[1]+(m5[3]>>1); - - for (j=0;j<2;j++) + for (i=0; i < 4;i++) { - j1=3-j; - m7[j][i] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS)); - m7[j1][i]=iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]-m6[j1]),DQ_BITS)); + cof[j<<2][i<<2] = rshift_rnd((( M4[j][i] * invLevelScale) << qp_per), 6); } } } -/*! - *********************************************************************** - * \brief - * The routine performs transform,quantization,inverse transform, adds the diff. - * to the prediction and writes the result to the decoded luma frame. Includes the - * RD constrained quantization also. - * - * \par Input: - * block_x,block_y: Block position inside a macro block (0,4,8,12). - * - * \par Output: - * nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels. \n - * coeff_cost: Counter for nonzero coefficients, used to discard expencive levels. - ************************************************************************ - */ -void copyblock_sp(ImageParameters *img,int block_x,int block_y) -{ - int i,j,i1,j1,m5[4],m6[4]; - int predicted_block[BLOCK_SIZE][BLOCK_SIZE]; - int qp_per = (img->qpsp-MIN_QP)/6; - int qp_rem = (img->qpsp-MIN_QP)%6; - int q_bits = Q_BITS+qp_per; - int qp_const2=(1<<q_bits)/2; //sp_pred - imgpel (*mpr)[16] = img->mpr[LumaComp]; - int (*m7) [16] = img->m7[LumaComp]; +void itrans_sp(ImageParameters *img, //!< image parameters + ColorPlane pl, + int ioff, //!< index to 4x4 block + int joff) //!< +{ + int i,j; + int ilev, icof; + int qp = (img->type == SI_SLICE) ? img->qpsp : img->qp; + int qp_per = qp_per_matrix[ qp ]; + int qp_rem = qp_rem_matrix[ qp ]; - // Horizontal transform - for (j=0; j< BLOCK_SIZE; j++) - for (i=0; i< BLOCK_SIZE; i++) - predicted_block[i][j]=mpr[j+block_y][i+block_x]; + int qp_per_sp = qp_per_matrix[ img->qpsp ]; + int qp_rem_sp = qp_rem_matrix[ img->qpsp ]; + int q_bits_sp = Q_BITS + qp_per_sp; - for (j=0; j < BLOCK_SIZE; j++) - { - for (i=0; i < 2; i++) - { - i1=3-i; - m5[i]=predicted_block[i][j]+predicted_block[i1][j]; - m5[i1]=predicted_block[i][j]-predicted_block[i1][j]; - } - predicted_block[0][j]=(m5[0]+m5[1]); - predicted_block[2][j]=(m5[0]-m5[1]); - predicted_block[1][j]=m5[3]*2+m5[2]; - predicted_block[3][j]=m5[3]-m5[2]*2; - } + imgpel (*mpr)[16] = img->mb_pred[pl]; + int (*m7) [16] = img->mb_rres[pl]; + int (*cof)[16] = img->cof[pl]; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; + + //int (*InvLevelScale4x4)[4] = InvLevelScale4x4_Intra[0][qp_rem]; + const int (*InvLevelScale4x4) [4] = dequant_coef[qp_rem]; + const int (*InvLevelScale4x4SP)[4] = dequant_coef[qp_rem_sp]; - // Vertival transform - for (i=0; i < BLOCK_SIZE; i++) - { - for (j=0; j < 2; j++) - { - j1=3-j; - m5[j]=predicted_block[i][j]+predicted_block[i][j1]; - m5[j1]=predicted_block[i][j]-predicted_block[i][j1]; - } - predicted_block[i][0]=(m5[0]+m5[1]); - predicted_block[i][2]=(m5[0]-m5[1]); - predicted_block[i][1]=m5[3]*2+m5[2]; - predicted_block[i][3]=m5[3]-m5[2]*2; - } - - // Quant - for (j=0;j < BLOCK_SIZE; j++) - for (i=0; i < BLOCK_SIZE; i++) - m7[j][i]=isignab((iabs(predicted_block[i][j])* quant_coef[qp_rem][i][j]+qp_const2)>> q_bits,predicted_block[i][j])*dequant_coef[qp_rem][j][i]<<qp_per; + for (j=0; j< BLOCK_SIZE; j++) + for (i=0; i< BLOCK_SIZE; i++) + PBlock[j][i] = mpr[j+joff][i+ioff]; - // IDCT. - // horizontal + forward4x4(PBlock, PBlock, 0, 0); - for (j=0;j<BLOCK_SIZE;j++) - { - for (i=0;i<BLOCK_SIZE;i++) - { - m5[i]=m7[j][i]; - } - m6[0]=(m5[0]+m5[2]); - m6[1]=(m5[0]-m5[2]); - m6[2]=(m5[1]>>1)-m5[3]; - m6[3]=m5[1]+(m5[3]>>1); - - for (i=0;i<2;i++) + if(img->sp_switch || img->type==SI_SLICE) + { + for (j=0;j<BLOCK_SIZE;j++) { - i1=3-i; - m7[j][i]=m6[i]+m6[i1]; - m7[j][i1]=m6[i]-m6[i1]; + for (i=0;i<BLOCK_SIZE;i++) + { + // recovering coefficient since they are already dequantized earlier + icof = (cof[joff + j][ioff + i] >> qp_per) / InvLevelScale4x4[j][i]; + //icof = ((cof[joff + j][ioff + i] * quant_coef[qp_rem][j][i])>> (qp_per + 15)) ; + // icof = rshift_rnd_sf(cof[joff + j][ioff + i] * quant_coef[qp_rem][j][i], qp_per + 15); + ilev = rshift_rnd_sf(iabs(PBlock[j][i]) * quant_coef[qp_rem_sp][j][i], q_bits_sp); + ilev = isignab(ilev, PBlock[j][i]) + icof; + cof[joff + j][ioff + i] = ilev * InvLevelScale4x4SP[j][i] << qp_per_sp; + } } } - // vertical - for (i=0;i<BLOCK_SIZE;i++) + else { for (j=0;j<BLOCK_SIZE;j++) - m5[j]=m7[j][i]; - - m6[0]=(m5[0]+m5[2]); - m6[1]=(m5[0]-m5[2]); - m6[2]=(m5[1]>>1)-m5[3]; - m6[3]=m5[1]+(m5[3]>>1); - - for (j=0;j<2;j++) { - j1=3-j; - m7[j][i] =iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]+m6[j1]),DQ_BITS)); - m7[j1][i]=iClip1(img->max_imgpel_value,rshift_rnd_sf((m6[j]-m6[j1]),DQ_BITS)); + for (i=0;i<BLOCK_SIZE;i++) + { + // recovering coefficient since they are already dequantized earlier + icof = (cof[joff + j][ioff + i] >> qp_per) / InvLevelScale4x4[j][i]; + //icof = cof[joff + j][ioff + i]; + //icof = rshift_rnd_sf(cof[joff + j][ioff + i] * quant_coef[qp_rem][j][i], qp_per + 15); + ilev = PBlock[j][i] + ((icof * InvLevelScale4x4[j][i] * A[j][i] << qp_per) >> 6); + ilev = isign(ilev) * rshift_rnd_sf(iabs(ilev) * quant_coef[qp_rem_sp][j][i], q_bits_sp); + //cof[joff + j][ioff + i] = ilev * InvLevelScale4x4SP[j][i] << qp_per_sp; + cof[joff + j][ioff + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + } } } - // Decoded block moved to frame memory - - for (j=0; j < BLOCK_SIZE; j++) - for (i=0; i < BLOCK_SIZE; i++) - dec_picture->imgY[img->pix_y+block_y+j][img->pix_x+block_x+i]=(imgpel) m7[j][i]; + inverse4x4(cof, m7, joff, ioff); + for (j=0;j<BLOCK_SIZE;j++) + for (i=0;i<BLOCK_SIZE;i++) + m7[j + joff][i + ioff] = iClip1(max_imgpel_value,rshift_rnd_sf(m7[j + joff][i + ioff], DQ_BITS)); } + void itrans_sp_cr(ImageParameters *img, int uv) { - int i,j,i1,j2,ilev,n2,n1,j1,mb_y; - int m5[BLOCK_SIZE]; - int predicted_chroma_block[MB_BLOCK_SIZE/2][MB_BLOCK_SIZE/2],mp1[BLOCK_SIZE]; + int i,j,ilev, icof, n2,n1; + int mp1[BLOCK_SIZE]; int qp_per,qp_rem; - int qp_per_sp,qp_rem_sp,q_bits_sp,qp_const2; - imgpel (*mpr)[16] = img->mpr[uv + 1]; + int qp_per_sp,qp_rem_sp,q_bits_sp; + imgpel (*mpr)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; + int (*cof)[MB_BLOCK_SIZE] = img->cof[uv + 1]; - qp_per = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)/6; - qp_rem = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)%6; + qp_per = qp_per_matrix[ ((img->qp < 0 ? img->qp : QP_SCALE_CR[img->qp]))]; + qp_rem = qp_rem_matrix[ ((img->qp < 0 ? img->qp : QP_SCALE_CR[img->qp]))]; - qp_per_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)/6; - qp_rem_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)%6; - q_bits_sp = Q_BITS+qp_per_sp; - qp_const2=(1<<q_bits_sp)/2; //sp_pred + qp_per_sp = qp_per_matrix[ ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]))]; + qp_rem_sp = qp_rem_matrix[ ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]))]; + q_bits_sp = Q_BITS + qp_per_sp; if (img->type == SI_SLICE) { - qp_per = ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]) - MIN_QP) / 6; - qp_rem = ((img->qpsp < 0 ? img->qpsp : QP_SCALE_CR[img->qpsp]) - MIN_QP) % 6; + qp_per = qp_per_sp; + qp_rem = qp_rem_sp; } - for (j=0; j < MB_BLOCK_SIZE/2; j++) - for (i=0; i < MB_BLOCK_SIZE/2; i++) + for (j=0; j < img->mb_cr_size_y; j++) { - predicted_chroma_block[i][j]=mpr[j][i]; - mpr[j][i]=0; + for (i=0; i < img->mb_cr_size_x; i++) + { + PBlock[j][i] = mpr[j][i]; + mpr[j][i] = 0; + } } - for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE) + + for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE) { - for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE) + for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) { - // Horizontal transform. - for (j=0; j < BLOCK_SIZE; j++) + forward4x4(PBlock, PBlock, n2, n1); + } + } + + // 2X2 transform of DC coeffs. + mp1[0] = (PBlock[0][0] + PBlock[4][0] + PBlock[0][4] + PBlock[4][4]); + mp1[1] = (PBlock[0][0] - PBlock[4][0] + PBlock[0][4] - PBlock[4][4]); + mp1[2] = (PBlock[0][0] + PBlock[4][0] - PBlock[0][4] - PBlock[4][4]); + mp1[3] = (PBlock[0][0] - PBlock[4][0] - PBlock[0][4] + PBlock[4][4]); + + if (img->sp_switch || img->type==SI_SLICE) + { + for (n2=0; n2 < 2; n2 ++) + { + for (n1=0; n1 < 2; n1 ++) { - mb_y=n2+j; - for (i=0; i < 2; i++) - { - i1=3-i; - m5[i]=predicted_chroma_block[i+n1][mb_y]+predicted_chroma_block[i1+n1][mb_y]; - m5[i1]=predicted_chroma_block[i+n1][mb_y]-predicted_chroma_block[i1+n1][mb_y]; - } - predicted_chroma_block[n1][mb_y] =(m5[0]+m5[1]); - predicted_chroma_block[n1+2][mb_y]=(m5[0]-m5[1]); - predicted_chroma_block[n1+1][mb_y]=m5[3]*2+m5[2]; - predicted_chroma_block[n1+3][mb_y]=m5[3]-m5[2]*2; + //quantization fo predicted block + ilev = rshift_rnd_sf(iabs (mp1[n1+n2*2]) * quant_coef[qp_rem_sp][0][0], q_bits_sp + 1); + //addition + ilev = isignab(ilev, mp1[n1+n2*2]) + cof[n2<<2][n1<<2]; + //dequantization + mp1[n1+n2*2] =ilev * dequant_coef[qp_rem_sp][0][0] << qp_per_sp; } + } - // Vertical transform. - - for (i=0; i < BLOCK_SIZE; i++) + for (n2 = 0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE) + { + for (n1 = 0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) { - j1=n1+i; - for (j=0; j < 2; j++) + for (j = 0; j < BLOCK_SIZE; j++) { - j2=3-j; - m5[j]=predicted_chroma_block[j1][n2+j]+predicted_chroma_block[j1][n2+j2]; - m5[j2]=predicted_chroma_block[j1][n2+j]-predicted_chroma_block[j1][n2+j2]; + for (i = 0; i < BLOCK_SIZE; i++) + { + // recovering coefficient since they are already dequantized earlier + cof[n2 + j][n1 + i] = (cof[n2 + j][n1 + i] >> qp_per) / dequant_coef[qp_rem][j][i]; + + //quantization of the predicted block + ilev = rshift_rnd_sf(iabs(PBlock[n2 + j][n1 + i]) * quant_coef[qp_rem_sp][j][i], q_bits_sp); + //addition of the residual + ilev = isignab(ilev,PBlock[n2 + j][n1 + i]) + cof[n2 + j][n1 + i]; + // Inverse quantization + cof[n2 + j][n1 + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + } } - predicted_chroma_block[j1][n2+0]=(m5[0]+m5[1]); - predicted_chroma_block[j1][n2+2]=(m5[0]-m5[1]); - predicted_chroma_block[j1][n2+1]=m5[3]*2+m5[2]; - predicted_chroma_block[j1][n2+3]=m5[3]-m5[2]*2; } } } - - // 2X2 transform of DC coeffs. - mp1[0]=(predicted_chroma_block[0][0]+predicted_chroma_block[4][0]+predicted_chroma_block[0][4]+predicted_chroma_block[4][4]); - mp1[1]=(predicted_chroma_block[0][0]-predicted_chroma_block[4][0]+predicted_chroma_block[0][4]-predicted_chroma_block[4][4]); - mp1[2]=(predicted_chroma_block[0][0]+predicted_chroma_block[4][0]-predicted_chroma_block[0][4]-predicted_chroma_block[4][4]); - mp1[3]=(predicted_chroma_block[0][0]-predicted_chroma_block[4][0]-predicted_chroma_block[0][4]+predicted_chroma_block[4][4]); - - for (n1=0; n1 < 2; n1 ++) - for (n2=0; n2 < 2; n2 ++) + else { - if (img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI - { - //quantization fo predicted block - ilev=(iabs (mp1[n1+n2*2]) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp + 1); - //addition - ilev=img->cof[uv + 1][n2<<2][n1<<2]+isignab(ilev,mp1[n1+n2*2]); - //dequantization - mp1[n1+n2*2] =ilev*dequant_coef[qp_rem_sp][0][0]<<qp_per_sp; - } - else + for (n2=0; n2 < 2; n2 ++) { - ilev=((img->cof[uv + 1][n2<<2][n1<<2]*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)+mp1[n1+n2*2]; - mp1[n1+n2*2]=isignab((iabs(ilev)* quant_coef[qp_rem_sp][0][0]+ 2 * qp_const2)>> (q_bits_sp+1),ilev)*dequant_coef[qp_rem_sp][0][0]<<qp_per_sp; + for (n1=0; n1 < 2; n1 ++) + { + ilev = mp1[n1+n2*2] + (((cof[n2<<2][n1<<2] * dequant_coef[qp_rem][0][0] * A[0][0]) << qp_per) >> 5); + ilev = isign(ilev) * rshift_rnd_sf(iabs(ilev) * quant_coef[qp_rem_sp][0][0], q_bits_sp + 1); + //ilev = isignab(rshift_rnd_sf(iabs(ilev)* quant_coef[qp_rem_sp][0][0], q_bits_sp + 1), ilev); + mp1[n1+n2*2] = ilev * dequant_coef[qp_rem_sp][0][0] << qp_per_sp; + } } - } - - for (n2=0; n2 < 2; n2 ++) - for (n1=0; n1 < 2; n1 ++) - for (i=0;i< BLOCK_SIZE; i++) - for (j=0;j< BLOCK_SIZE; j++) - { - // recovering coefficient since they are already dequantized earlier - img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] = (img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] >> qp_per) / dequant_coef[qp_rem][j][i]; - - if (img->sp_switch || img->type==SI_SLICE) //M.W. patched for SI + for (n2 = 0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE) { - //quantization of the predicted block - ilev = (iabs(predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j]) * quant_coef[qp_rem_sp][i][j] + qp_const2) >> q_bits_sp; - //addition of the residual - ilev = isignab(ilev,predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j]) + img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i]; - // Inverse quantization - img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; - } - else - { - //dequantization and addition of the predicted block - ilev=((img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i]*dequant_coef[qp_rem][j][i]*A[i][j]<< qp_per) >>6)+predicted_chroma_block[n1*BLOCK_SIZE+i][n2*BLOCK_SIZE+j] ; - //quantization and dequantization - img->cof[uv + 1][(n2<<2) + j][(n1<<2) + i] = isignab((iabs(ilev) * quant_coef[qp_rem_sp][i][j] + qp_const2)>> q_bits_sp,ilev)*dequant_coef[qp_rem_sp][j][i]<<qp_per_sp; + for (n1 = 0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) + { + for (j = 0; j< BLOCK_SIZE; j++) + { + for (i = 0; i< BLOCK_SIZE; i++) + { + // recovering coefficient since they are already dequantized earlier + //icof = ((((cof[n2 + j][n1 + i] << 4) + qp_per/2)>> qp_per) + dequant_coef[qp_rem][j][i]/2) / dequant_coef[qp_rem][j][i]; + icof = (cof[n2 + j][n1 + i] >> qp_per) / dequant_coef[qp_rem][j][i]; + //dequantization and addition of the predicted block + ilev = PBlock[n2 + j][n1 + i] + ((icof * dequant_coef[qp_rem][j][i] * A[j][i] << qp_per) >> 6); + //quantization and dequantization + ilev = isign(ilev) * rshift_rnd_sf(iabs(ilev) * quant_coef[qp_rem_sp][j][i], q_bits_sp); + cof[n2 + j][n1 + i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + //printf( " %d %d %d\n", j, i, quant_coef[qp_rem_sp][j][i]); + } + } + } } } - img->cof[uv+1][0][0] = (mp1[0] + mp1[1] + mp1[2] + mp1[3]) >> 1; - img->cof[uv+1][0][4] = (mp1[0] + mp1[1] - mp1[2] - mp1[3]) >> 1; - img->cof[uv+1][4][0] = (mp1[0] - mp1[1] + mp1[2] - mp1[3]) >> 1; - img->cof[uv+1][4][4] = (mp1[0] - mp1[1] - mp1[2] + mp1[3]) >> 1; + + cof[0][0] = (mp1[0] + mp1[1] + mp1[2] + mp1[3]) >> 1; + cof[0][4] = (mp1[0] + mp1[1] - mp1[2] - mp1[3]) >> 1; + cof[4][0] = (mp1[0] - mp1[1] + mp1[2] - mp1[3]) >> 1; + cof[4][4] = (mp1[0] - mp1[1] - mp1[2] + mp1[3]) >> 1; } static const byte decode_block_scan[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15}; @@ -1551,7 +1143,7 @@ void iMBtrans4x4(ColorPlane pl, ImageParameters *img, int smb) int jj, ii; int block8x8; int i, j, k; - int (*m7) [16] = img->m7[pl]; + int (*m7) [16] = img->mb_rres[pl]; imgpel **curr_img = pl ? &(dec_picture->imgUV[pl - 1][img->pix_y]): &dec_picture->imgY[img->pix_y]; //For residual DPCM @@ -1571,7 +1163,7 @@ void iMBtrans4x4(ColorPlane pl, ImageParameters *img, int smb) jj = ((decode_block_scan[k] >> 2) & 3) << BLOCK_SHIFT; ii = (decode_block_scan[k] & 3) << BLOCK_SHIFT; - itrans_4x4(pl, img, ii, jj); // use DCT transform and make 4x4 block m7 from prediction block mpr + itrans_4x4(img, pl, ii, jj); // use DCT transform and make 4x4 block m7 from prediction block mpr for(j = jj; j < jj + BLOCK_SIZE; j++) { @@ -1584,10 +1176,10 @@ void iMBtrans4x4(ColorPlane pl, ImageParameters *img, int smb) } } -void iMBtrans8x8(ColorPlane pl, ImageParameters *img) +void iMBtrans8x8(ImageParameters *img, Macroblock *currMB, ColorPlane pl) { imgpel **curr_img = pl ? &dec_picture->imgUV[pl - 1][img->pix_y]: &dec_picture->imgY[img->pix_y]; - int (*m7)[16] = img->m7[pl]; + int (*m7)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int block8x8; int i,j; int ioff, joff; @@ -1599,7 +1191,7 @@ void iMBtrans8x8(ColorPlane pl, ImageParameters *img) ioff = 8 * (block8x8 & 0x01); joff = 8 * (block8x8 >> 1); - itrans8x8(pl, img, ioff, joff); // use DCT transform and make 8x8 block m7 from prediction block mpr + itrans8x8(img, currMB, pl, ioff, joff); // use DCT transform and make 8x8 block m7 from prediction block mpr for(j = joff; j < joff + 8; j++) { @@ -1611,7 +1203,7 @@ void iMBtrans8x8(ColorPlane pl, ImageParameters *img) } } -void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int need_4x4_transform, int smb) +void iTransform(ImageParameters *img, Macroblock *currMB, ColorPlane pl, int need_4x4_transform, int smb) { static imgpel (*mpr) [16]; static imgpel **curr_img; @@ -1625,16 +1217,16 @@ void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int ne } else // 8x8 inverse transform { - iMBtrans8x8(pl, img); + iMBtrans8x8(img, currMB, pl); } } else { - mpr = img->mpr[pl]; + mpr = img->mb_pred[pl]; curr_img = pl ? &dec_picture->imgUV[uv][img->pix_y] : &dec_picture->imgY[img->pix_y]; for(j = 0; j < MB_BLOCK_SIZE; j++) { - memcpy(&(curr_img[j][img->pix_x]), &(img->mpr[pl][j][0]), MB_BLOCK_SIZE * sizeof(imgpel)); + memcpy(&(curr_img[j][img->pix_x]), &(img->mb_pred[pl][j][0]), MB_BLOCK_SIZE * sizeof(imgpel)); } } @@ -1653,7 +1245,7 @@ void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int ne // =============== 4x4 itrans ================ // ------------------------------------------- curUV = &dec_picture->imgUV[uv][img->pix_c_y]; - m7UV = img->m7[uv+1]; + m7UV = img->mb_rres[uv+1]; if (!smb && (currMB->cbp>>4)) { @@ -1664,7 +1256,7 @@ void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int ne joff = subblk_offset_y[1][b8][b4]; ioff = subblk_offset_x[1][b8][b4]; - itrans_4x4((ColorPlane) (uv + 1), img, ioff, joff); + itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff); for(jj=joff;jj<joff + 4;jj++) { @@ -1682,11 +1274,11 @@ void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int ne { itrans_sp_cr(img, uv); - for (joff=0;joff<8;joff+=4) + for (joff = 0; joff < img->mb_cr_size_y; joff += BLOCK_SIZE) { - for(ioff=0;ioff<8;ioff+=4) + for(ioff = 0; ioff < img->mb_cr_size_x ;ioff += BLOCK_SIZE) { - itrans_4x4((ColorPlane) (uv + 1), img, ioff, joff); + itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff); for(jj=joff;jj<joff + 4;jj++) for(ii=ioff;ii<ioff + 4;ii++) @@ -1698,7 +1290,7 @@ void iTransform(Macroblock *currMB, ColorPlane pl, ImageParameters *img, int ne } else { - mpr = img->mpr[uv + 1]; + mpr = img->mb_pred[uv + 1]; for(jj = 0; jj < img->mb_size[1][1]; jj++) memcpy(&(curUV[jj][img->pix_c_x]), &(mpr[jj][0]), img->mb_size[1][0] * sizeof(imgpel)); } diff --git a/ldecod/src/cabac.c b/ldecod/src/cabac.c index 96df570..a85e457 100644 --- a/ldecod/src/cabac.c +++ b/ldecod/src/cabac.c @@ -123,8 +123,6 @@ void delete_contexts_MotionInfo(MotionInfoContexts *deco_ctx) return; free( deco_ctx ); - - return; } @@ -141,28 +139,17 @@ void delete_contexts_TextureInfo(TextureInfoContexts *deco_ctx) return; free( deco_ctx ); - - return; } void readFieldModeInfo_CABAC( SyntaxElement *se, ImageParameters *img, DecodingEnvironmentPtr dep_dp) -{ - int a,b,act_ctx; +{ MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; - - if (currMB->mbAvailA) - a = img->mb_data[currMB->mbAddrA].mb_field; - else - a = 0; - if (currMB->mbAvailB) - b = img->mb_data[currMB->mbAddrB].mb_field; - else - b=0; - - act_ctx = a + b; + int a = currMB->mbAvailA ? img->mb_data[currMB->mbAddrA].mb_field : 0; + int b = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0; + int act_ctx = a + b; se->value1 = biari_decode_symbol (dep_dp, &ctx->mb_aff_contexts[act_ctx]); @@ -270,7 +257,7 @@ void readMVD_CABAC( SyntaxElement *se, { int i = img->subblock_x << 2; int j = img->subblock_y << 2; - int a, b; + int a = 0, b = 0; int act_ctx; int act_sym; int mv_local_err; @@ -297,8 +284,6 @@ void readMVD_CABAC( SyntaxElement *se, b /= 2; } } - else - b=0; if (block_a.available) { @@ -311,8 +296,6 @@ void readMVD_CABAC( SyntaxElement *se, a /= 2; } } - else - a = 0; if ((mv_local_err=a+b)<3) act_ctx = 5*k; @@ -438,25 +421,16 @@ void readB8_typeInfo_CABAC (SyntaxElement *se, void readMB_skip_flagInfo_CABAC( SyntaxElement *se, ImageParameters *img, DecodingEnvironmentPtr dep_dp) -{ - int a, b; - int act_ctx; +{ int bframe=(img->type==B_SLICE); MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; - + int a = (currMB->mb_available_left != NULL) ? (currMB->mb_available_left->skip_flag == 0) : 0; + int b = (currMB->mb_available_up != NULL) ? (currMB->mb_available_up ->skip_flag == 0) : 0; + int act_ctx; if (bframe) { - if (currMB->mb_available_up == NULL) - b = 0; - else - b = (currMB->mb_available_up->skip_flag==0 ? 1 : 0); - if (currMB->mb_available_left == NULL) - a = 0; - else - a = (currMB->mb_available_left->skip_flag==0 ? 1 : 0); - act_ctx = 7 + a + b; if (biari_decode_symbol (dep_dp, &ctx->mb_type_contexts[2][act_ctx]) == 1) @@ -466,15 +440,6 @@ void readMB_skip_flagInfo_CABAC( SyntaxElement *se, } else { - if (currMB->mb_available_up == NULL) - b = 0; - else - b = (( (currMB->mb_available_up)->skip_flag == 0) ? 1 : 0 ); - if (currMB->mb_available_left == NULL) - a = 0; - else - a = (( (currMB->mb_available_left)->skip_flag == 0) ? 1 : 0 ); - act_ctx = a + b; if (biari_decode_symbol(dep_dp, &ctx->mb_type_contexts[1][act_ctx]) == 1) @@ -492,7 +457,6 @@ void readMB_skip_flagInfo_CABAC( SyntaxElement *se, { last_dquant=0; } - return; } /*! @@ -539,7 +503,7 @@ void readMB_typeInfo_CABAC( SyntaxElement *se, MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; - int a, b; + int a = 0, b = 0; int act_ctx; int act_sym; int bframe=(img->type==B_SLICE); @@ -549,14 +513,10 @@ void readMB_typeInfo_CABAC( SyntaxElement *se, if(img->type == I_SLICE) // INTRA-frame { - if (currMB->mb_available_up == NULL) - b = 0; - else + if (currMB->mb_available_up != NULL) b = (((currMB->mb_available_up)->mb_type != I4MB && currMB->mb_available_up->mb_type != I8MB) ? 1 : 0 ); - if (currMB->mb_available_left == NULL) - a = 0; - else + if (currMB->mb_available_left != NULL) a = (((currMB->mb_available_left)->mb_type != I4MB && currMB->mb_available_left->mb_type != I8MB) ? 1 : 0 ); act_ctx = a + b; @@ -605,13 +565,10 @@ void readMB_typeInfo_CABAC( SyntaxElement *se, else if(img->type == SI_SLICE) // SI-frame { // special ctx's for SI4MB - if (currMB->mb_available_up == NULL) - b = 0; - else + if (currMB->mb_available_up != NULL) b = (( (currMB->mb_available_up)->mb_type != SI4MB) ? 1 : 0 ); - if (currMB->mb_available_left == NULL) - a = 0; - else + + if (currMB->mb_available_left != NULL) a = (( (currMB->mb_available_left)->mb_type != SI4MB) ? 1 : 0 ); act_ctx = a + b; @@ -624,20 +581,16 @@ void readMB_typeInfo_CABAC( SyntaxElement *se, } else // analog INTRA_IMG { - if (currMB->mb_available_up == NULL) - b = 0; - else + if (currMB->mb_available_up != NULL) b = (( (currMB->mb_available_up)->mb_type != I4MB) ? 1 : 0 ); - if (currMB->mb_available_left == NULL) - a = 0; - else + + if (currMB->mb_available_left != NULL) a = (( (currMB->mb_available_left)->mb_type != I4MB) ? 1 : 0 ); act_ctx = a + b; act_sym = biari_decode_symbol(dep_dp, ctx->mb_type_contexts[0] + act_ctx); se->context = act_ctx; // store context - if (act_sym==0) // 4x4 Intra { curr_mb_type = 1; @@ -682,13 +635,10 @@ void readMB_typeInfo_CABAC( SyntaxElement *se, { if (bframe) { - if (currMB->mb_available_up == NULL) - b = 0; - else + if (currMB->mb_available_up != NULL) b = (( (currMB->mb_available_up)->mb_type != 0) ? 1 : 0 ); - if (currMB->mb_available_left == NULL) - a = 0; - else + + if (currMB->mb_available_left != NULL) a = (( (currMB->mb_available_left)->mb_type != 0) ? 1 : 0 ); act_ctx = a + b; @@ -851,12 +801,13 @@ void readRefFrame_CABAC( SyntaxElement *se, { MotionInfoContexts *ctx = img->currentSlice->mot_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + Macroblock *neighborMB = NULL; int addctx = 0; - int a, b; + int a = 0, b = 0; int act_ctx; int act_sym; - char** refframe_array = dec_picture->ref_idx[se->value2]; + char** refframe_array = dec_picture->motion.ref_idx[se->value2]; int b8a, b8b; PixelPos block_a, block_b; @@ -867,31 +818,31 @@ void readRefFrame_CABAC( SyntaxElement *se, b8a=((block_a.x>>1)&0x01)+2*((block_a.y>>1)&0x01); b8b=((block_b.x>>1)&0x01)+2*((block_b.y>>1)&0x01); - if (!block_b.available) - b=0; - else if ( (img->mb_data[block_b.mb_addr].mb_type==IPCM) || IS_DIRECT(&img->mb_data[block_b.mb_addr]) || (img->mb_data[block_b.mb_addr].b8mode[b8b]==0 && img->mb_data[block_b.mb_addr].b8pdir[b8b]==2)) - b=0; - else + if (block_b.available) { - if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (img->mb_data[block_b.mb_addr].mb_field == 1)) - b = (refframe_array[block_b.pos_y][block_b.pos_x] > 1 ? 1 : 0); - else - b = (refframe_array[block_b.pos_y][block_b.pos_x] > 0 ? 1 : 0); + neighborMB = &img->mb_data[block_b.mb_addr]; + if (!( (neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8b]==0 && neighborMB->b8pdir[b8b]==2))) + { + if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (neighborMB->mb_field == 1)) + b = (refframe_array[block_b.pos_y][block_b.pos_x] > 1 ? 2 : 0); + else + b = (refframe_array[block_b.pos_y][block_b.pos_x] > 0 ? 2 : 0); + } } - if (!block_a.available) - a=0; - else if ((img->mb_data[block_a.mb_addr].mb_type==IPCM) || IS_DIRECT(&img->mb_data[block_a.mb_addr]) || (img->mb_data[block_a.mb_addr].b8mode[b8a]==0 && img->mb_data[block_a.mb_addr].b8pdir[b8a]==2)) - a=0; - else + if (block_a.available) { - if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (img->mb_data[block_a.mb_addr].mb_field == 1)) - a = (refframe_array[block_a.pos_y][block_a.pos_x] > 1 ? 1 : 0); - else - a = (refframe_array[block_a.pos_y][block_a.pos_x] > 0 ? 1 : 0); + neighborMB = &img->mb_data[block_a.mb_addr]; + if (!((neighborMB->mb_type==IPCM) || IS_DIRECT(neighborMB) || (neighborMB->b8mode[b8a]==0 && neighborMB->b8pdir[b8a]==2))) + { + if (img->MbaffFrameFlag && (currMB->mb_field == 0) && (neighborMB->mb_field == 1)) + a = (refframe_array[block_a.pos_y][block_a.pos_x] > 1 ? 1 : 0); + else + a = (refframe_array[block_a.pos_y][block_a.pos_x] > 0 ? 1 : 0); + } } - act_ctx = a + 2*b; + act_ctx = a + b; se->context = act_ctx; // store context act_sym = biari_decode_symbol(dep_dp,ctx->ref_no_contexts[addctx] + act_ctx ); @@ -924,14 +875,10 @@ void readDquant_CABAC( SyntaxElement *se, DecodingEnvironmentPtr dep_dp) { MotionInfoContexts *ctx = img->currentSlice->mot_ctx; + int *dquant = &se->value1; + int act_ctx = ((last_dquant != 0) ? 1 : 0); + int act_sym = biari_decode_symbol(dep_dp,ctx->delta_qp_contexts + act_ctx ); - int act_ctx; - int act_sym; - int dquant; - - act_ctx = ( (last_dquant != 0) ? 1 : 0); - - act_sym = biari_decode_symbol(dep_dp,ctx->delta_qp_contexts + act_ctx ); if (act_sym != 0) { act_ctx = 2; @@ -939,12 +886,11 @@ void readDquant_CABAC( SyntaxElement *se, act_sym++; } - dquant = (act_sym + 1)/2; + *dquant = (act_sym + 1) >> 1; if((act_sym & 0x01)==0) // lsb is signed bit - dquant = -dquant; - se->value1 = dquant; + *dquant = -*dquant; - last_dquant = dquant; + last_dquant = *dquant; #if TRACE fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1); @@ -964,6 +910,7 @@ void readCBP_CABAC(SyntaxElement *se, { TextureInfoContexts *ctx = img->currentSlice->tex_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + Macroblock *neighborMB = NULL; int mb_x, mb_y; int a, b; @@ -976,23 +923,24 @@ void readCBP_CABAC(SyntaxElement *se, // coding of luma part (bit by bit) for (mb_y=0; mb_y < 4; mb_y += 2) { + if (mb_y == 0) + { + neighborMB = currMB->mb_available_up; + b = 0; + } + for (mb_x=0; mb_x < 4; mb_x += 2) { if (mb_y == 0) { - if (currMB->mb_available_up == NULL) - b = 0; - else + if (neighborMB != NULL) { - if((currMB->mb_available_up)->mb_type==IPCM) - b=0; - else - b = (( ((currMB->mb_available_up)->cbp & (1<<(2 + (mb_x>>1)))) == 0) ? 1 : 0); + if(neighborMB->mb_type!=IPCM) + b = (( (neighborMB->cbp & (1<<(2 + (mb_x>>1)))) == 0) ? 2 : 0); } - } else - b = ( ((cbp & (1<<(mb_x/2))) == 0) ? 1: 0); + b = ( ((cbp & (1<<(mb_x/2))) == 0) ? 2: 0); if (mb_x == 0) { @@ -1000,7 +948,7 @@ void readCBP_CABAC(SyntaxElement *se, if (block_a.available) { if(img->mb_data[block_a.mb_addr].mb_type==IPCM) - a=0; + a = 0; else a = (( (img->mb_data[block_a.mb_addr].cbp & (1<<(2*(block_a.y/2)+1))) == 0) ? 1 : 0); } @@ -1010,10 +958,11 @@ void readCBP_CABAC(SyntaxElement *se, else a = ( ((cbp & (1<<mb_y)) == 0) ? 1: 0); - curr_cbp_ctx = a+2*b; - mask = (1<<(mb_y+mb_x/2)); + curr_cbp_ctx = a + b; + mask = (1 << (mb_y + (mb_x >> 1))); cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[0] + curr_cbp_ctx ); - if (cbp_bit) cbp += mask; + if (cbp_bit) + cbp += mask; } } @@ -1022,53 +971,46 @@ void readCBP_CABAC(SyntaxElement *se, // coding of chroma part // CABAC decoding for BinIdx 0 b = 0; - if (currMB->mb_available_up != NULL) + neighborMB = currMB->mb_available_up; + if (neighborMB != NULL) { - if((currMB->mb_available_up)->mb_type==IPCM) - b=1; - else - b = ((currMB->mb_available_up)->cbp > 15) ? 1 : 0; + if (neighborMB->mb_type==IPCM || (neighborMB->cbp > 15)) + b = 2; } a = 0; - if (currMB->mb_available_left != NULL) + neighborMB = currMB->mb_available_left; + if (neighborMB != NULL) { - if((currMB->mb_available_left)->mb_type==IPCM) - a=1; - else - a = ((currMB->mb_available_left)->cbp > 15) ? 1 : 0; + if (neighborMB->mb_type==IPCM || (neighborMB->cbp > 15)) + a = 1; } - - curr_cbp_ctx = a+2*b; + curr_cbp_ctx = a + b; cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[1] + curr_cbp_ctx ); // CABAC decoding for BinIdx 1 if (cbp_bit) // set the chroma bits { b = 0; - if (currMB->mb_available_up != NULL) + neighborMB = currMB->mb_available_up; + if (neighborMB != NULL) { - if((currMB->mb_available_up)->mb_type==IPCM) - b=1; - else - if ((currMB->mb_available_up)->cbp > 15) - b = (( ((currMB->mb_available_up)->cbp >> 4) == 2) ? 1 : 0); + //if ((neighborMB->mb_type == IPCM) || ((neighborMB->cbp > 15) && ((neighborMB->cbp >> 4) == 2))) + if ((neighborMB->mb_type == IPCM) || ((neighborMB->cbp >> 4) == 2)) + b = 2; } a = 0; - if (currMB->mb_available_left != NULL) + neighborMB = currMB->mb_available_left; + if (neighborMB != NULL) { - if((currMB->mb_available_left)->mb_type==IPCM) - a=1; - else - if ((currMB->mb_available_left)->cbp > 15) - a = (( ((currMB->mb_available_left)->cbp >> 4) == 2) ? 1 : 0); + if ((neighborMB->mb_type == IPCM) || ((neighborMB->cbp >> 4) == 2)) + a = 1; } - - curr_cbp_ctx = a+2*b; + curr_cbp_ctx = a + b; cbp_bit = biari_decode_symbol(dep_dp, ctx->cbp_contexts[2] + curr_cbp_ctx ); cbp += (cbp_bit == 1) ? 32 : 16; } @@ -1098,33 +1040,21 @@ void readCIPredMode_CABAC(SyntaxElement *se, ImageParameters *img, DecodingEnvironmentPtr dep_dp) { - TextureInfoContexts *ctx = img->currentSlice->tex_ctx; - Macroblock *currMB = &img->mb_data[img->current_mb_nr]; - int act_ctx,a,b; - int act_sym = se->value1; + Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + int *act_sym = &se->value1; Macroblock *MbUp = currMB->mb_available_up; Macroblock *MbLeft = currMB->mb_available_left; - if (MbUp == NULL) - b = 0; - else - b = ((MbUp->c_ipred_mode != 0) && (MbUp->mb_type != IPCM)) ? 1 : 0; - - if (MbLeft == NULL) - a = 0; - else - a = ((MbLeft->c_ipred_mode != 0) && (MbLeft->mb_type != IPCM)) ? 1 : 0; - - act_ctx = a+b; - - act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx ); + int b = (MbUp != NULL) ? (((MbUp->c_ipred_mode != 0) && (MbUp->mb_type != IPCM)) ? 1 : 0) : 0; + int a = (MbLeft != NULL) ? (((MbLeft->c_ipred_mode != 0) && (MbLeft->mb_type != IPCM)) ? 1 : 0) : 0; + int act_ctx = a + b; - if (act_sym!=0) - act_sym = unary_bin_max_decode(dep_dp,ctx->cipr_contexts+3,0,2)+1; + *act_sym = biari_decode_symbol(dep_dp, ctx->cipr_contexts + act_ctx ); - se->value1 = act_sym; + if (*act_sym != 0) + *act_sym = unary_bin_max_decode(dep_dp, ctx->cipr_contexts + 3, 0, 1) + 1; #if TRACE fprintf(p_trace, "@%-6d %-63s (%3d)\n",symbolCount++, se->tracestring, se->value1); @@ -1307,9 +1237,7 @@ int read_and_store_CBP_block_bit (Macroblock *currMB, //===== encode symbol ===== cbp_bit = biari_decode_symbol (dep_dp, img->currentSlice->tex_ctx->bcbp_contexts[type2ctx_bcbp[type]] + ctx); } - - - + //--- set bits for current block --- bit = (y_dc ? 0 : y_ac ? 1+4*j+i : u_dc ? 17 : v_dc ? 18 : u_ac ? 19+4*j+i : 35+4*j+i); @@ -1414,7 +1342,6 @@ static const int* pos2ctx_map_int[] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_m pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8i,pos2ctx_map8x4i, pos2ctx_map8x4i,pos2ctx_map4x4}; - //===== position -> ctx for LAST ===== static const int pos2ctx_last8x8 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -1451,7 +1378,7 @@ int read_significance_map (Macroblock *currMB, int i, sig; int coeff_ctr = 0; int i0 = 0; - int i1 = maxpos[type] + 1; + int i1 = maxpos[type]; int fld = ( img->structure!=FRAME || currMB->mb_field ); const int **pos2ctx_Map = (fld) ? pos2ctx_map_int : pos2ctx_map; @@ -1465,7 +1392,7 @@ int read_significance_map (Macroblock *currMB, i0++; i1++; coeff--; } - for (i=i0; i < i1 - 1; i++) // if last coeff is reached, it has to be significant + for (i=i0; i < i1; i++) // if last coeff is reached, it has to be significant { //--- read significance symbol --- sig = biari_decode_symbol (dep_dp, map_ctx + pos2ctx_Map [type][i]); @@ -1477,8 +1404,8 @@ int read_significance_map (Macroblock *currMB, //--- read last coefficient symbol --- if (biari_decode_symbol (dep_dp, last_ctx + pos2ctx_last[type][i])) { - for (i++; i < i1; i++) - coeff[i] = 0; + memset(&coeff[i + 1], 0, (i1 - i) * sizeof(int)); + i = i1; } } else @@ -1487,7 +1414,7 @@ int read_significance_map (Macroblock *currMB, } } //--- last coefficient must be significant if no last symbol was received --- - if (i < i1) + if (i < i1 + 1) { coeff[i] = 1; coeff_ctr++; @@ -1505,16 +1432,15 @@ int read_significance_map (Macroblock *currMB, ************************************************************************ */ void read_significant_coefficients (DecodingEnvironmentPtr dep_dp, - ImageParameters *img, + TextureInfoContexts *tex_ctx, int type, int coeff[]) { int i, ctx; int c1 = 1; int c2 = 0; - BiContextType *one_contexts = img->currentSlice->tex_ctx->one_contexts[type2ctx_one[type]]; - BiContextType *abs_contexts = img->currentSlice->tex_ctx->abs_contexts[type2ctx_abs[type]]; - + BiContextType *one_contexts = tex_ctx->one_contexts[type2ctx_one[type]]; + BiContextType *abs_contexts = tex_ctx->abs_contexts[type2ctx_abs[type]]; for (i=maxpos[type]; i>=0; i--) { @@ -1567,7 +1493,7 @@ void readRunLevel_CABAC (SyntaxElement *se, coeff_ctr = read_significance_map (currMB, dep_dp, img, se->context, coeff); //===== decode significant coefficients ===== - read_significant_coefficients (dep_dp, img, se->context, coeff); + read_significant_coefficients (dep_dp, img->currentSlice->tex_ctx, se->context, coeff); } } @@ -1592,8 +1518,6 @@ void readRunLevel_CABAC (SyntaxElement *se, #endif } - - /*! ************************************************************************ * \brief @@ -1606,9 +1530,11 @@ int readSyntaxElement_CABAC(SyntaxElement *se, ImageParameters *img, DataPartiti int curr_len; DecodingEnvironmentPtr dep_dp = &(this_dataPart->de_cabac); curr_len = arideco_bits_read(dep_dp); + #if (TRACE==2) fprintf(p_trace, "curr_len: %d\n",curr_len); #endif + // perform the actual decoding by calling the appropriate method se->reading(se, img, dep_dp); //read again and minus curr_len = arideco_bits_read(dep_dp); from above @@ -1633,27 +1559,22 @@ unsigned int unary_bin_max_decode(DecodingEnvironmentPtr dep_dp, int ctx_offset, unsigned int max_symbol) { - unsigned int l; - unsigned int symbol; - BiContextTypePtr ictx; - - symbol = biari_decode_symbol(dep_dp, ctx ); + unsigned int symbol = biari_decode_symbol(dep_dp, ctx ); - if (symbol==0) - return 0; - else - { - if (max_symbol == 1) + if (symbol==0 || (max_symbol == 0)) return symbol; - symbol=0; - ictx=ctx+ctx_offset; + else + { + unsigned int l; + ctx += ctx_offset; + symbol = 0; do { - l=biari_decode_symbol(dep_dp, ictx); + l = biari_decode_symbol(dep_dp, ctx); symbol++; } - while( (l!=0) && (symbol<max_symbol-1) ); - if ((l!=0) && (symbol==max_symbol-1)) + while( (l != 0) && (symbol < max_symbol) ); + if ((l != 0) && (symbol == max_symbol)) symbol++; return symbol; } @@ -1671,24 +1592,21 @@ unsigned int unary_bin_decode(DecodingEnvironmentPtr dep_dp, BiContextTypePtr ctx, int ctx_offset) { - unsigned int l; - unsigned int symbol; - BiContextTypePtr ictx; - - symbol = biari_decode_symbol(dep_dp, ctx ); + unsigned int symbol = biari_decode_symbol(dep_dp, ctx ); - if (symbol==0) + if (symbol == 0) return 0; else { - symbol=0; - ictx=ctx+ctx_offset; + unsigned int l; + ctx += ctx_offset;; + symbol = 0; do { - l=biari_decode_symbol(dep_dp, ictx); + l=biari_decode_symbol(dep_dp, ctx); symbol++; } - while( l!=0 ); + while( l != 0 ); return symbol; } } @@ -1705,19 +1623,16 @@ unsigned int unary_bin_decode(DecodingEnvironmentPtr dep_dp, * StW, 8.7.02 ************************************************************************ */ -int cabac_startcode_follows(ImageParameters *img, int eos_bit) +int cabac_startcode_follows(Slice *currSlice, int eos_bit) { - Slice *currSlice = img->currentSlice; - int *partMap = assignSE2partition[currSlice->dp_mode]; - DataPartition *dP; - unsigned int bit; - DecodingEnvironmentPtr dep_dp; - - dP = &(currSlice->partArr[partMap[SE_MBTYPE]]); - dep_dp = &(dP->de_cabac); + static unsigned int bit; if( eos_bit ) { + int *partMap = assignSE2partition[currSlice->dp_mode]; + DataPartition *dP = &(currSlice->partArr[partMap[SE_MBTYPE]]); + DecodingEnvironmentPtr dep_dp = &(dP->de_cabac); + bit = biari_decode_final (dep_dp); //GB #if TRACE @@ -1730,13 +1645,9 @@ int cabac_startcode_follows(ImageParameters *img, int eos_bit) bit = 0; } - return (bit==1?1:0); + return (bit == 1 ? 1 : 0); } - - - - /*! ************************************************************************ * \brief @@ -1753,8 +1664,8 @@ unsigned int exp_golomb_decode_eq_prob( DecodingEnvironmentPtr dep_dp, do { - l=biari_decode_symbol_eq_prob(dep_dp); - if (l==1) + l = biari_decode_symbol_eq_prob(dep_dp); + if (l == 1) { symbol += (1<<k); k++; @@ -1766,7 +1677,7 @@ unsigned int exp_golomb_decode_eq_prob( DecodingEnvironmentPtr dep_dp, if (biari_decode_symbol_eq_prob(dep_dp)==1) binary_symbol |= (1<<k); - return (unsigned int) (symbol+binary_symbol); + return (unsigned int) (symbol + binary_symbol); } @@ -1779,25 +1690,24 @@ unsigned int exp_golomb_decode_eq_prob( DecodingEnvironmentPtr dep_dp, unsigned int unary_exp_golomb_level_decode( DecodingEnvironmentPtr dep_dp, BiContextTypePtr ctx) { - unsigned int l,k; - unsigned int symbol; - unsigned int exp_start = 13; - - symbol = biari_decode_symbol(dep_dp, ctx ); + unsigned int symbol = biari_decode_symbol(dep_dp, ctx ); if (symbol==0) return 0; else { + unsigned int l, k = 1; + unsigned int exp_start = 13; + symbol=0; - k=1; + do { l=biari_decode_symbol(dep_dp, ctx); symbol++; k++; } - while((l!=0) && (k!=exp_start)); + while((l != 0) && (k != exp_start)); if (l!=0) symbol += exp_golomb_decode_eq_prob(dep_dp,0)+1; return symbol; @@ -1817,34 +1727,30 @@ unsigned int unary_exp_golomb_mv_decode(DecodingEnvironmentPtr dep_dp, BiContextTypePtr ctx, unsigned int max_bin) { - unsigned int l,k; - unsigned int bin=1; - unsigned int symbol; - unsigned int exp_start = 8; - - BiContextTypePtr ictx=ctx; + unsigned int symbol = biari_decode_symbol(dep_dp, ctx ); - symbol = biari_decode_symbol(dep_dp, ictx ); - - if (symbol==0) + if (symbol == 0) return 0; else { + unsigned int exp_start = 8; + unsigned int l,k = 1; + unsigned int bin = 1; + symbol=0; - k=1; - ictx++; + ctx++; do { - l=biari_decode_symbol(dep_dp, ictx ); - if ((++bin)==2) ictx++; - if (bin==max_bin) ictx++; + l=biari_decode_symbol(dep_dp, ctx); + if ((++bin)==2) ctx++; + if (bin==max_bin) ctx++; symbol++; k++; } while((l!=0) && (k!=exp_start)); if (l!=0) - symbol += exp_golomb_decode_eq_prob(dep_dp,3)+1; + symbol += exp_golomb_decode_eq_prob(dep_dp,3) + 1; return symbol; } } diff --git a/ldecod/src/erc_do_p.c b/ldecod/src/erc_do_p.c index c23dc07..38e25a1 100644 --- a/ldecod/src/erc_do_p.c +++ b/ldecod/src/erc_do_p.c @@ -595,7 +595,7 @@ static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgp for(ii=0;ii<BLOCK_SIZE;ii++) for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++) - img->mpr[LumaComp][jj+joff][ii+ioff]=tmp_block[jj][ii]; + img->mb_pred[LumaComp][jj+joff][ii+ioff]=tmp_block[jj][ii]; } } @@ -604,7 +604,7 @@ static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgp { for (i = 0; i < 16; i++) { - pMB[j*16+i] = img->mpr[LumaComp][j][i]; + pMB[j*16+i] = img->mb_pred[LumaComp][j][i]; } } pMB += 256; @@ -652,7 +652,7 @@ static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgp if0=f1_x-if1; jf0=f1_y-jf1; - img->mpr[uv + 1][jj+joff][ii+ioff]=(if0*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii0]+ + img->mb_pred[uv + 1][jj+joff][ii+ioff]=(if0*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii0]+ if1*jf0*listX[0][ref_frame]->imgUV[uv][jj0][ii1]+ if0*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii0]+ if1*jf1*listX[0][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3; @@ -665,7 +665,7 @@ static void buildPredRegionYUV(ImageParameters *img, int *mv, int x, int y, imgp { for (i = 0; i < 8; i++) { - pMB[j*8+i] = img->mpr[uv + 1][j][i]; + pMB[j*8+i] = img->mb_pred[uv + 1][j][i]; } } pMB += 64; @@ -883,14 +883,14 @@ static void buildPredblockRegionYUV(ImageParameters *img, int *mv, for(jj=0;jj<MB_BLOCK_SIZE/BLOCK_SIZE;jj++) for(ii=0;ii<BLOCK_SIZE;ii++) - img->mpr[LumaComp][jj][ii]=tmp_block[jj][ii]; + img->mb_pred[LumaComp][jj][ii]=tmp_block[jj][ii]; for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { - pMB[j*4+i] = img->mpr[LumaComp][j][i]; + pMB[j*4+i] = img->mb_pred[LumaComp][j][i]; } } pMB += 16; @@ -934,7 +934,7 @@ static void buildPredblockRegionYUV(ImageParameters *img, int *mv, if0=f1_x-if1; jf0=f1_y-jf1; - img->mpr[uv + 1][jj][ii]=(if0*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii0]+ + img->mb_pred[uv + 1][jj][ii]=(if0*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii0]+ if1*jf0*listX[list][ref_frame]->imgUV[uv][jj0][ii1]+ if0*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii0]+ if1*jf1*listX[list][ref_frame]->imgUV[uv][jj1][ii1]+f4)/f3; @@ -945,7 +945,7 @@ static void buildPredblockRegionYUV(ImageParameters *img, int *mv, { for (i = 0; i < 2; i++) { - pMB[j*2+i] = img->mpr[uv + 1][j][i]; + pMB[j*2+i] = img->mb_pred[uv + 1][j][i]; } } pMB += 4; @@ -1159,25 +1159,24 @@ static void copy_to_conceal(StorablePicture *src, StorablePicture *dst, ImagePar for(i=0;i<mb_height*4;i++) { - mm = i*BLOCK_SIZE; + mm = i * BLOCK_SIZE; for(j=0;j<mb_width*4;j++) { - nn = j*BLOCK_SIZE; - - mv[0] = src->mv[LIST_0][i][j][0] / scale; - mv[1] = src->mv[LIST_0][i][j][1] / scale; - mv[2] = src->ref_idx[LIST_0][i][j]; + nn = j * BLOCK_SIZE; + mv[0] = src->motion.mv[LIST_0][i][j][0] / scale; + mv[1] = src->motion.mv[LIST_0][i][j][1] / scale; + mv[2] = src->motion.ref_idx[LIST_0][i][j]; if(mv[2]<0) mv[2]=0; - dst->mv[LIST_0][i][j][0] = mv[0]; - dst->mv[LIST_0][i][j][1] = mv[1]; - dst->ref_idx[LIST_0][i][j] = mv[2]; + dst->motion.mv[LIST_0][i][j][0] = mv[0]; + dst->motion.mv[LIST_0][i][j][1] = mv[1]; + dst->motion.ref_idx[LIST_0][i][j] = mv[2]; - x = (j)*multiplier; - y = (i)*multiplier; + x = (j) * multiplier; + y = (i) * multiplier; if ((mm%16==0) && (nn%16==0)) img->current_mb_nr++; diff --git a/ldecod/src/filehandle.c b/ldecod/src/filehandle.c index 7a9c2ad..78d233d 100644 --- a/ldecod/src/filehandle.c +++ b/ldecod/src/filehandle.c @@ -37,6 +37,17 @@ void error(char *text, int code) static int bitcounter = 0; +/*! +************************************************************************ +* \brief +* decrement trace bitcounter (used for special case in mb aff) +************************************************************************ +*/ +void dectracebitcnt(int count) +{ + bitcounter -= count; +} + /*! ************************************************************************ * \brief diff --git a/ldecod/src/header.c b/ldecod/src/header.c index 7bde430..5e6a78d 100644 --- a/ldecod/src/header.c +++ b/ldecod/src/header.c @@ -243,22 +243,20 @@ int RestOfSliceHeader(void) img->model_number = 0; } - val = se_v("SH: slice_qp_delta", currStream); + currSlice->slice_qp_delta = val = se_v("SH: slice_qp_delta", currStream); currSlice->qp = img->qp = 26 + active_pps->pic_init_qp_minus26 + val; + if ((img->qp < -img->bitdepth_luma_qp_scale) || (img->qp > 51)) error ("slice_qp_delta makes slice_qp_y out of range", 500); - - currSlice->slice_qp_delta = val; - if(img->type==SP_SLICE || img->type == SI_SLICE) { if(img->type==SP_SLICE) { img->sp_switch = u_1 ("SH: sp_for_switch_flag", currStream); } - val = se_v("SH: slice_qs_delta", currStream); - img->qpsp = 26 + active_pps->pic_init_qs_minus26 + val; + currSlice->slice_qs_delta = val = se_v("SH: slice_qs_delta", currStream); + currSlice->qs = img->qpsp = 26 + active_pps->pic_init_qs_minus26 + val; if ((img->qpsp < 0) || (img->qpsp > 51)) error ("slice_qs_delta makes slice_qs_y out of range", 500); } diff --git a/ldecod/src/image.c b/ldecod/src/image.c index 76d1d2c..98b7cc5 100644 --- a/ldecod/src/image.c +++ b/ldecod/src/image.c @@ -44,6 +44,7 @@ #include "output.h" #include "mb_access.h" #include "memalloc.h" +#include "macroblock.h" #include "loopfilter.h" @@ -51,6 +52,7 @@ #include "context_ini.h" #include "cabac.h" #include "vlc.h" +#include "quant.h" #include "errorconcealment.h" #include "erc_api.h" @@ -74,28 +76,6 @@ StorablePicture *dec_picture_JV[MAX_PLANE]; //!< dec_picture to be used during OldSliceParams old_slice; -void set_interpret_mb_mode(int slice_type) -{ - switch (slice_type) - { - case P_SLICE: case SP_SLICE: - interpret_mb_mode = interpret_mb_mode_P; - break; - case B_SLICE: - interpret_mb_mode = interpret_mb_mode_B; - break; - case I_SLICE: - interpret_mb_mode = interpret_mb_mode_I; - break; - case SI_SLICE: - interpret_mb_mode = interpret_mb_mode_SI; - break; - default: - printf("Unsupported slice type\n"); - break; - } -} - void MbAffPostProc(void) { imgpel temp[32][16]; @@ -106,7 +86,7 @@ void MbAffPostProc(void) int i, y, x0, y0, uv; for (i=0; i<(int)dec_picture->PicSizeInMbs; i+=2) { - if (dec_picture->mb_field[i]) + if (dec_picture->motion.mb_field[i]) { get_mb_pos(i, img->mb_size[IS_LUMA], &x0, &y0); for (y=0; y<(2*MB_BLOCK_SIZE);y++) @@ -148,7 +128,7 @@ void MbAffPostProc(void) *********************************************************************** */ -int decode_one_frame(ImageParameters *img,struct inp_par *inp, struct snr_par *snr) +int decode_one_frame(ImageParameters *img, struct inp_par *inp, struct snr_par *snr) { int current_header; Slice *currSlice = img->currentSlice; @@ -359,7 +339,7 @@ void find_snr( int comp_size_x[3], comp_size_y[3]; int64 framesize_in_bytes; - unsigned int max_pix_value_sqd[3] = {iabs2(img->max_imgpel_value), iabs2(img->max_imgpel_value_uv), iabs2(img->max_imgpel_value_uv)}; + unsigned int max_pix_value_sqd[3] = {iabs2(img->max_imgpel_value_comp[0]), iabs2(img->max_imgpel_value_comp[1]), iabs2(img->max_imgpel_value_comp[2])}; Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0); unsigned char *buf; @@ -447,22 +427,16 @@ void find_snr( } } -#if ZEROSNR - diff_comp[k] = imax(diff_comp[k], 1); -#endif // Collecting SNR statistics - if (diff_comp[k] != 0) - snr->snr[k]=(float)(10*log10(max_pix_value_sqd[k]*(double)((double)(comp_size_x[k])*(comp_size_y[k]) / diff_comp[k]))); - else - snr->snr[k]=0.0; + snr->snr[k] = psnr( max_pix_value_sqd[k], comp_size_x[k] * comp_size_y[k], (float) diff_comp[k]); if (img->number == 0) // first { - snr->snra[k]=snr->snr1[k]=snr->snr[k]; // keep luma snr for first frame + snr->snra[k] = snr->snr[k]; // keep luma snr for first frame } else { - snr->snra[k]=(float)(snr->snra[k]*(snr->frame_ctr)+snr->snr[k])/(snr->frame_ctr + 1); // average snr chroma for all frames + snr->snra[k] = (float)(snr->snra[k]*(snr->frame_ctr)+snr->snr[k])/(snr->frame_ctr + 1); // average snr chroma for all frames } } @@ -471,14 +445,12 @@ void find_snr( free (buf); - // picture error concealment if(p->concealed_pic) { fprintf(stdout,"%04d(P) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n", frame_no, p->frame_poc, p->pic_num, p->qp, snr->snr[0], snr->snr[1], snr->snr[2], yuv_types[p->chroma_format_idc], 0); - } } @@ -579,50 +551,6 @@ void set_ref_pic_num(void) } } -/*! -************************************************************************ -* \brief -* Read the next NAL unit (with error handling) -************************************************************************ -*/ -int read_next_nalu(NALU_t *nalu) -{ - int ret; - - if (params->FileFormat == PAR_OF_ANNEXB) - ret = GetAnnexbNALU (nalu); - else - ret = GetRTPNALU (nalu); - - if (ret < 0) - { - snprintf (errortext, ET_SIZE, "Error while getting the NALU in file format %s, exit\n", params->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP"); - error (errortext, 601); - } - if (ret == 0) - { - FreeNALU(nalu); - return 0; - } - - //In some cases, zero_byte shall be present. If current NALU is a VCL NALU, we can't tell - //whether it is the first VCL NALU at this point, so only non-VCL NAL unit is checked here. - CheckZeroByteNonVCL(nalu); - - ret = NALUtoRBSP(nalu); - - if (ret < 0) - error ("Invalid startcode emulation prevention found.", 602); - - - // Got a NALU - if (nalu->forbidden_bit) - { - error ("Found NALU with forbidden_bit set, bit error?", 603); - } - - return nalu->len; -} /*! ************************************************************************ @@ -641,12 +569,12 @@ int read_new_slice(void) int slice_id_a, slice_id_b, slice_id_c; int redundant_pic_cnt_b, redundant_pic_cnt_c; long ftell_position; - + while (1) { ftell_position = ftell(bits); - if (0 == read_next_nalu(nalu)) + if (0 == read_next_nalu(bits, nalu)) return EOS; switch (nalu->nal_unit_type) @@ -796,7 +724,7 @@ int read_new_slice(void) // continue with reading next DP ftell_position = ftell(bits); - if (0 == read_next_nalu(nalu)) + if (0 == read_next_nalu(bits, nalu)) return current_header; if ( NALU_TYPE_DPB == nalu->nal_unit_type) @@ -829,7 +757,7 @@ int read_new_slice(void) // we're finished with DP_B, so let's continue with next DP ftell_position = ftell(bits); - if (0 == read_next_nalu(nalu)) + if (0 == read_next_nalu(bits, nalu)) return current_header; } } @@ -927,7 +855,7 @@ int read_new_slice(void) */ void init_picture(ImageParameters *img, struct inp_par *inp) { - int i,k,l; + int i,j,k,l; Slice *currSlice = img->currentSlice; int nplane; @@ -943,8 +871,8 @@ void init_picture(ImageParameters *img, struct inp_par *inp) img->recovery_frame_num = img->frame_num; if (img->recovery_point == 0 && - img->frame_num != img->pre_frame_num && - img->frame_num != (img->pre_frame_num + 1) % img->MaxFrameNum) + img->frame_num != img->pre_frame_num && + img->frame_num != (img->pre_frame_num + 1) % img->MaxFrameNum) { if (active_sps->gaps_in_frame_num_value_allowed_flag == 0) { @@ -985,13 +913,13 @@ void init_picture(ImageParameters *img, struct inp_par *inp) img->pre_frame_num = img->frame_num; } - //img->num_dec_mb = 0; + img->num_dec_mb = 0; //calculate POC decode_poc(img); if (img->recovery_frame_num == img->frame_num && - img->recovery_poc == 0x7fffffff) + img->recovery_poc == 0x7fffffff) img->recovery_poc = img->framepoc; if(img->nal_reference_idc) @@ -1009,8 +937,8 @@ void init_picture(ImageParameters *img, struct inp_par *inp) dec_picture->top_poc=img->toppoc; dec_picture->bottom_poc=img->bottompoc; dec_picture->frame_poc=img->framepoc; - dec_picture->qp=img->qp; - dec_picture->slice_qp_delta=currSlice->slice_qp_delta; + dec_picture->qp = img->qp; + dec_picture->slice_qp_delta = currSlice->slice_qp_delta; dec_picture->chroma_qp_offset[0] = active_pps->chroma_qp_index_offset; dec_picture->chroma_qp_offset[1] = active_pps->second_chroma_qp_index_offset; @@ -1052,10 +980,14 @@ void init_picture(ImageParameters *img, struct inp_par *inp) } // CAVLC init - for (i=0;i < (int)img->PicSizeInMbs; i++) - for (k=0;k<4;k++) - for (l=0;l<(4 + img->num_blk8x8_uv);l++) - img->nz_coeff[i][k][l]=-1; // CAVLC + if (active_pps->entropy_coding_mode_flag == UVLC) + { + for (i=0;i < (int)img->PicSizeInMbs; i++) + for (j = 0; j < 3; j++) + for (l = 0; l < 4; l++) + for (k = 0; k < 4;k++) + img->nz_coeff[i][j][l][k]=-1; // CAVLC + } if(active_pps->constrained_intra_pred_flag) { @@ -1173,7 +1105,7 @@ void exit_picture(void) unsigned int i; int structure, frame_poc, slice_type, refpic, qp, pic_num, chroma_format_idc, is_idr; - static char cslice_type[8]; + static char cslice_type[9]; time_t tmp_time; // time used by decoding the last frame char yuvFormat[10]; @@ -1295,9 +1227,11 @@ void exit_picture(void) else if(refpic) // stored B pictures strcpy(cslice_type," B "); else // B pictures - strcpy(cslice_type," b "); + strcpy(cslice_type," b "); if (structure==FRAME) + { strncat(cslice_type,") ",8-strlen(cslice_type)); + } } else if (structure==BOTTOM_FIELD) { @@ -1395,18 +1329,18 @@ void ercWriteMBMODEandMV(Macroblock *currMB, ImageParameters *img,struct inp_par jj = 4*mby + (i >> 1 )*2; if (currMB->b8mode[i]>=5 && currMB->b8mode[i]<=7) // SMALL BLOCKS { - pRegion->mv[0] = (dec_picture->mv[LIST_0][jj][ii][0] + dec_picture->mv[LIST_0][jj][ii+1][0] + dec_picture->mv[LIST_0][jj+1][ii][0] + dec_picture->mv[LIST_0][jj+1][ii+1][0] + 2)/4; - pRegion->mv[1] = (dec_picture->mv[LIST_0][jj][ii][1] + dec_picture->mv[LIST_0][jj][ii+1][1] + dec_picture->mv[LIST_0][jj+1][ii][1] + dec_picture->mv[LIST_0][jj+1][ii+1][1] + 2)/4; + pRegion->mv[0] = (dec_picture->motion.mv[LIST_0][jj][ii][0] + dec_picture->motion.mv[LIST_0][jj][ii+1][0] + dec_picture->motion.mv[LIST_0][jj+1][ii][0] + dec_picture->motion.mv[LIST_0][jj+1][ii+1][0] + 2)/4; + pRegion->mv[1] = (dec_picture->motion.mv[LIST_0][jj][ii][1] + dec_picture->motion.mv[LIST_0][jj][ii+1][1] + dec_picture->motion.mv[LIST_0][jj+1][ii][1] + dec_picture->motion.mv[LIST_0][jj+1][ii+1][1] + 2)/4; } else // 16x16, 16x8, 8x16, 8x8 { - pRegion->mv[0] = dec_picture->mv[LIST_0][jj][ii][0]; - pRegion->mv[1] = dec_picture->mv[LIST_0][jj][ii][1]; -// pRegion->mv[0] = dec_picture->mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][0]; -// pRegion->mv[1] = dec_picture->mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][1]; + pRegion->mv[0] = dec_picture->motion.mv[LIST_0][jj][ii][0]; + pRegion->mv[1] = dec_picture->motion.mv[LIST_0][jj][ii][1]; +// pRegion->mv[0] = dec_picture->motion.mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][0]; +// pRegion->mv[1] = dec_picture->motion.mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][1]; } erc_mvperMB += iabs(pRegion->mv[0]) + iabs(pRegion->mv[1]); - pRegion->mv[2] = dec_picture->ref_idx[LIST_0][jj][ii]; + pRegion->mv[2] = dec_picture->motion.ref_idx[LIST_0][jj][ii]; } } } @@ -1427,24 +1361,24 @@ void ercWriteMBMODEandMV(Macroblock *currMB, ImageParameters *img,struct inp_par } else { - int idx = (dec_picture->ref_idx[0][jj][ii]<0)?1:0; + int idx = (dec_picture->motion.ref_idx[0][jj][ii]<0)?1:0; // int idx = (currMB->b8mode[i]==0 && currMB->b8pdir[i]==2 ? LIST_0 : currMB->b8pdir[i]==1 ? LIST_1 : LIST_0); // int idx = currMB->b8pdir[i]==0 ? LIST_0 : LIST_1; - mv = dec_picture->mv[idx]; + mv = dec_picture->motion.mv[idx]; pRegion->mv[0] = (mv[jj][ii][0] + mv[jj][ii+1][0] + mv[jj+1][ii][0] + mv[jj+1][ii+1][0] + 2)/4; pRegion->mv[1] = (mv[jj][ii][1] + mv[jj][ii+1][1] + mv[jj+1][ii][1] + mv[jj+1][ii+1][1] + 2)/4; erc_mvperMB += iabs(pRegion->mv[0]) + iabs(pRegion->mv[1]); - pRegion->mv[2] = (dec_picture->ref_idx[idx][jj][ii]); + pRegion->mv[2] = (dec_picture->motion.ref_idx[idx][jj][ii]); /* if (currMB->b8pdir[i]==0 || (currMB->b8pdir[i]==2 && currMB->b8mode[i]!=0)) // forward or bidirect { - pRegion->mv[2] = (dec_picture->ref_idx[LIST_0][jj][ii]); + pRegion->mv[2] = (dec_picture->motion.ref_idx[LIST_0][jj][ii]); ///???? is it right, not only "img->fw_refFrArr[jj][ii-4]" } else { - pRegion->mv[2] = (dec_picture->ref_idx[LIST_1][jj][ii]); + pRegion->mv[2] = (dec_picture->motion.ref_idx[LIST_1][jj][ii]); // pRegion->mv[2] = 0; } */ @@ -1613,12 +1547,12 @@ void decode_one_slice(ImageParameters *img,struct inp_par *inp) #endif // Initializes the current macroblock - start_macroblock(&currMB, img); + start_macroblock(img, &currMB); // Get the syntax elements from the NAL - read_one_macroblock(currMB, img); - decode_one_macroblock(currMB, img); + read_one_macroblock(img, currMB); + decode_one_macroblock(img, currMB, dec_picture); - if(img->MbaffFrameFlag && dec_picture->mb_field[img->current_mb_nr]) + if(img->MbaffFrameFlag && dec_picture->motion.mb_field[img->current_mb_nr]) { img->num_ref_idx_l0_active >>= 1; img->num_ref_idx_l1_active >>= 1; diff --git a/ldecod/src/ldecod.c b/ldecod/src/ldecod.c index 3dd36e4..3d0e542 100644 --- a/ldecod/src/ldecod.c +++ b/ldecod/src/ldecod.c @@ -15,7 +15,7 @@ * The main contributors are listed in contributors.h * * \version - * JM 14.0 (FRExt) + * JM 14.1 (FRExt) * * \note * tags are used for document system "doxygen" @@ -58,9 +58,10 @@ #include "parset.h" #include "sei.h" #include "erc_api.h" +#include "quant.h" #define JM "14 (FRExt)" -#define VERSION "14.0" +#define VERSION "14.1" #define EXT_VERSION "(FRExt)" #define LOGFILE "log.dec" @@ -341,7 +342,7 @@ int main(int argc, char **argv) img->dec_ref_pic_marking_buffer = NULL; // B pictures - Bframe_ctr=snr->frame_ctr=0; + Bframe_ctr = snr->frame_ctr = 0; // time for total decoding session tot_time = 0; @@ -349,7 +350,7 @@ int main(int argc, char **argv) // reference flag initialization for(i=0;i<17;i++) { - ref_flag[i]=1; + ref_flag[i] = 1; } while (decode_one_frame(img, params, snr) != EOS) @@ -434,14 +435,13 @@ void init(ImageParameters *img) //!< image parameters void init_frext(ImageParameters *img) //!< image parameters { //pel bitdepth init - img->bitdepth_luma_qp_scale = 6*(img->bitdepth_luma - 8); + img->bitdepth_luma_qp_scale = 6 * (img->bitdepth_luma - 8); if(img->bitdepth_luma > img->bitdepth_chroma || active_sps->chroma_format_idc == YUV400) img->pic_unit_bitsize_on_disk = (img->bitdepth_luma > 8)? 16:8; else img->pic_unit_bitsize_on_disk = (img->bitdepth_chroma > 8)? 16:8; - img->dc_pred_value_comp[0] = 1<<(img->bitdepth_luma - 1); - img->max_imgpel_value = (1<<img->bitdepth_luma) - 1; - img->max_imgpel_value_comp[0] = img->max_imgpel_value; + img->dc_pred_value_comp[0] = 1<<(img->bitdepth_luma - 1); + img->max_imgpel_value_comp[0] = (1<<img->bitdepth_luma) - 1; img->mb_size[0][0] = img->mb_size[0][1] = MB_BLOCK_SIZE; if (active_sps->chroma_format_idc != YUV400) @@ -450,7 +450,8 @@ void init_frext(ImageParameters *img) //!< image parameters img->bitdepth_chroma_qp_scale = 6 * (img->bitdepth_chroma - 8); img->dc_pred_value_comp[1] = (1 << (img->bitdepth_chroma - 1)); img->dc_pred_value_comp[2] = img->dc_pred_value_comp[1]; - img->max_imgpel_value_uv = (1 << img->bitdepth_chroma) - 1; + img->max_imgpel_value_comp[1] = (1 << img->bitdepth_chroma) - 1; + img->max_imgpel_value_comp[2] = (1 << img->bitdepth_chroma) - 1; img->num_blk8x8_uv = (1 << active_sps->chroma_format_idc) & (~(0x1)); img->num_uv_blocks = (img->num_blk8x8_uv >> 1); img->num_cdc_coeff = (img->num_blk8x8_uv << 1); @@ -460,15 +461,14 @@ void init_frext(ImageParameters *img) //!< image parameters else { img->bitdepth_chroma_qp_scale = 0; - img->max_imgpel_value_uv = 0; + img->max_imgpel_value_comp[1] = 0; + img->max_imgpel_value_comp[2] = 0; img->num_blk8x8_uv = 0; img->num_uv_blocks = 0; img->num_cdc_coeff = 0; img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = 0; img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y = 0; } - img->max_imgpel_value_comp[1] = img->max_imgpel_value_uv; - img->max_imgpel_value_comp[2] = img->max_imgpel_value_uv; img->mb_size_blk[0][0] = img->mb_size_blk[0][1] = img->mb_size[0][0] >> 2; img->mb_size_blk[1][0] = img->mb_size_blk[2][0] = img->mb_size[1][0] >> 2; img->mb_size_blk[1][1] = img->mb_size_blk[2][1] = img->mb_size[1][1] >> 2; @@ -476,6 +476,8 @@ void init_frext(ImageParameters *img) //!< image parameters img->mb_size_shift[0][0] = img->mb_size_shift[0][1] = CeilLog2_sf (img->mb_size[0][0]); img->mb_size_shift[1][0] = img->mb_size_shift[2][0] = CeilLog2_sf (img->mb_size[1][0]); img->mb_size_shift[1][1] = img->mb_size_shift[2][1] = CeilLog2_sf (img->mb_size[1][1]); + + init_qp_process(img); } @@ -967,7 +969,7 @@ int init_global_buffers(void) memory_size += get_mem4Dint(&(img->wbp_weight), 6, MAX_REFERENCE_PICTURES, MAX_REFERENCE_PICTURES, 3); // CAVLC mem - memory_size += get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 4 + img->num_blk8x8_uv); + memory_size += get_mem4Dint(&(img->nz_coeff), img->FrameSizeInMbs, 3, BLOCK_SIZE, BLOCK_SIZE); memory_size += get_mem2Dint(&(img->siblock), img->FrameHeightInMbs, img->PicWidthInMbs); @@ -1000,7 +1002,7 @@ void free_global_buffers(void) free_mem3Dpel (imgUV_ref); // CAVLC free mem - free_mem3Dint(img->nz_coeff); + free_mem4Dint(img->nz_coeff); free_mem2Dint(img->siblock); diff --git a/ldecod/src/loopFilter.c b/ldecod/src/loopFilter.c index e330ae8..de06920 100644 --- a/ldecod/src/loopFilter.c +++ b/ldecod/src/loopFilter.c @@ -285,12 +285,12 @@ void GetStrengthNormal(byte Strength[MB_BLOCK_SIZE], ImageParameters *img, int M if (!ANY_INTRA) { - list0_refPicIdArr = p->ref_pic_id[LIST_0]; - list1_refPicIdArr = p->ref_pic_id[LIST_1]; - list0_mv = p->mv[LIST_0]; - list1_mv = p->mv[LIST_1]; - list0_refIdxArr = p->ref_idx[LIST_0]; - list1_refIdxArr = p->ref_idx[LIST_1]; + list0_refPicIdArr = p->motion.ref_pic_id[LIST_0]; + list1_refPicIdArr = p->motion.ref_pic_id[LIST_1]; + list0_mv = p->motion.mv[LIST_0]; + list1_mv = p->motion.mv[LIST_1]; + list0_refIdxArr = p->motion.ref_idx[LIST_0]; + list1_refIdxArr = p->motion.ref_idx[LIST_1]; get_mb_block_pos (MbQAddr, &mb_x, &mb_y); mb_x <<= 2; @@ -420,12 +420,12 @@ void GetStrengthMBAff(byte Strength[16], ImageParameters *img, int MbQAddr, int int dir_m1 = (1 - dir); MbQ = &(img->mb_data[MbQAddr]); - list0_mv = p->mv[LIST_0]; - list1_mv = p->mv[LIST_1]; - list0_refIdxArr = p->ref_idx[LIST_0]; - list1_refIdxArr = p->ref_idx[LIST_1]; - list0_refPicIdArr = p->ref_pic_id[LIST_0]; - list1_refPicIdArr = p->ref_pic_id[LIST_1]; + list0_mv = p->motion.mv[LIST_0]; + list1_mv = p->motion.mv[LIST_1]; + list0_refIdxArr = p->motion.ref_idx[LIST_0]; + list1_refIdxArr = p->motion.ref_idx[LIST_1]; + list0_refPicIdArr = p->motion.ref_pic_id[LIST_0]; + list1_refPicIdArr = p->motion.ref_pic_id[LIST_1]; for( idx=0 ; idx<16 ; idx++ ) { @@ -821,7 +821,7 @@ void EdgeLoopChromaNormal(imgpel** Img, byte Strength[16],ImageParameters *img, static int QP; int bitdepth_scale = img->bitdepth_scale[IS_CHROMA]; - int max_imgpel_value_uv = img->max_imgpel_value_uv; + int max_imgpel_value = img->max_imgpel_value_comp[uv + 1]; int xQ = dir ? 0 : edge - 1; int yQ = dir ? (edge < 16 ? edge - 1: 0) : 0; @@ -893,8 +893,8 @@ void EdgeLoopChromaNormal(imgpel** Img, byte Strength[16],ImageParameters *img, tc0 = ClipTab[ Strng ] * bitdepth_scale + 1; dif = iClip3( -tc0, tc0, ( ((R0 - L0) << 2) + (L1 - R1) + 4) >> 3 ); - *SrcPtrP = (imgpel) iClip1 ( max_imgpel_value_uv, L0 + dif) ; - *SrcPtrQ = (imgpel) iClip1 ( max_imgpel_value_uv, R0 - dif) ; + *SrcPtrP = (imgpel) iClip1 ( max_imgpel_value, L0 + dif) ; + *SrcPtrQ = (imgpel) iClip1 ( max_imgpel_value, R0 - dif) ; } } } @@ -926,6 +926,7 @@ void EdgeLoopChromaMBAff(imgpel** Img, byte Strength[16],ImageParameters *img, i PixelPos pixP, pixQ; int dir_m1 = 1 - dir; int bitdepth_scale = img->bitdepth_scale[IS_CHROMA]; + int max_imgpel_value = img->max_imgpel_value_comp[uv + 1]; MbQ = &(img->mb_data[MbQAddr]); for( pel = 0 ; pel < PelNum ; pel++ ) @@ -977,8 +978,8 @@ void EdgeLoopChromaMBAff(imgpel** Img, byte Strength[16],ImageParameters *img, i tc0 = (C0 + 1); dif = iClip3( -tc0, tc0, ( ((R0 - L0) << 2) + (L1 - R1) + 4) >> 3 ); - SrcPtrP[0] = (imgpel) iClip1 ( img->max_imgpel_value_uv, L0 + dif ); - SrcPtrQ[0] = (imgpel) iClip1 ( img->max_imgpel_value_uv, R0 - dif ); + SrcPtrP[0] = (imgpel) iClip1 ( max_imgpel_value, L0 + dif ); + SrcPtrQ[0] = (imgpel) iClip1 ( max_imgpel_value, R0 - dif ); } } } diff --git a/ldecod/src/macroblock.c b/ldecod/src/macroblock.c index f3b0a26..31c8838 100644 --- a/ldecod/src/macroblock.c +++ b/ldecod/src/macroblock.c @@ -17,6 +17,7 @@ * - Gabi Blaettermann * - Ye-Kui Wang <wyk@ieee.org> * - Lowell Winger <lwinger@lsil.com> + * - Alexis Michael Tourapis <alexismt@ieee.org> *********************************************************************** */ @@ -39,17 +40,223 @@ #include "transform8x8.h" #include "transform.h" #include "mc_prediction.h" +#include "quant.h" #if TRACE #define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE) +#define TRACE_DECBITS(i) dectracebitcnt(1) +#define TRACE_PRINTF(s) sprintf(type, "%s", s); +#define TRACE_STRING_P(s) strncpy(currSE->tracestring, s, TRACESTRING_SIZE) #else -#define TRACE_STRING(s) // do nothing +#define TRACE_STRING(s) +#define TRACE_DECBITS(i) +#define TRACE_PRINTF(s) +#define TRACE_STRING_P(s) #endif +//! single scan pattern +static const byte SNGL_SCAN[16][2] = +{ + {0,0},{1,0},{0,1},{0,2}, + {1,1},{2,0},{3,0},{2,1}, + {1,2},{0,3},{1,3},{2,2}, + {3,1},{3,2},{2,3},{3,3} +}; + +//! field scan pattern +static const byte FIELD_SCAN[16][2] = +{ + {0,0},{0,1},{1,0},{0,2}, + {0,3},{1,1},{1,2},{1,3}, + {2,0},{2,1},{2,2},{2,3}, + {3,0},{3,1},{3,2},{3,3} +}; + +//! used to control block sizes : Not used/16x16/16x8/8x16/8x8/8x4/4x8/4x4 +static const int BLOCK_STEP[8][2]= +{ + {0,0},{4,4},{4,2},{2,4},{2,2},{2,1},{1,2},{1,1} +}; + +const byte QP_SCALE_CR[52]= +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, + 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37, + 37,38,38,38,39,39,39,39 + +}; + +//! single scan pattern +const byte SNGL_SCAN8x8[64][2] = { + {0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0}, + {4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4}, {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3}, + {3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4}, {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6}, + {2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5}, {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7} +}; + + +//! field scan pattern +const byte FIELD_SCAN8x8[64][2] = { // 8x8 + {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {1,3}, {0,5}, {0,6}, {0,7}, {1,4}, {2,1}, {3,0}, + {2,2}, {1,5}, {1,6}, {1,7}, {2,3}, {3,1}, {4,0}, {3,2}, {2,4}, {2,5}, {2,6}, {2,7}, {3,3}, {4,1}, {5,0}, {4,2}, + {3,4}, {3,5}, {3,6}, {3,7}, {4,3}, {5,1}, {6,0}, {5,2}, {4,4}, {4,5}, {4,6}, {4,7}, {5,3}, {6,1}, {6,2}, {5,4}, + {5,5}, {5,6}, {5,7}, {6,3}, {7,0}, {7,1}, {6,4}, {6,5}, {6,6}, {6,7}, {7,2}, {7,3}, {7,4}, {7,5}, {7,6}, {7,7} +}; + +//! single scan pattern +const byte SCAN_YUV422[8][2] = +{ + {0,0},{0,1}, + {1,0},{0,2}, + {0,3},{1,1}, + {1,2},{1,3} +}; + +static unsigned char cbp_blk_chroma[8][4] = +{ {16, 17, 18, 19}, + {20, 21, 22, 23}, + {24, 25, 26, 27}, + {28, 29, 30, 31}, + {32, 33, 34, 35}, + {36, 37, 38, 39}, + {40, 41, 42, 43}, + {44, 45, 46, 47} }; + +//! look up tables for FRExt_chroma support +const unsigned char subblk_offset_x[3][8][4] = +{ + { {0, 4, 0, 4}, + {0, 4, 0, 4}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, }, + + { {0, 4, 0, 4}, + {0, 4, 0, 4}, + {0, 4, 0, 4}, + {0, 4, 0, 4}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, }, + + { {0, 4, 0, 4}, + {8,12, 8,12}, + {0, 4, 0, 4}, + {8,12, 8,12}, + {0, 4, 0, 4}, + {8,12, 8,12}, + {0, 4, 0, 4}, + {8,12, 8,12} } +}; + +const unsigned char subblk_offset_y[3][8][4] = +{ { {0, 0, 4, 4}, + {0, 0, 4, 4}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, }, + + { {0, 0, 4, 4}, + {8, 8,12,12}, + {0, 0, 4, 4}, + {8, 8,12,12}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} }, + + { {0, 0, 4, 4}, + {0, 0, 4, 4}, + {8, 8,12,12}, + {8, 8,12,12}, + {0, 0, 4, 4}, + {0, 0, 4, 4}, + {8, 8,12,12}, + {8, 8,12,12} } +}; + +const unsigned char cofuv_blk_x[3][8][4] = +{ { {0, 1, 0, 1}, + {0, 1, 0, 1}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} }, + + { {0, 1, 0, 1}, + {0, 1, 0, 1}, + {0, 1, 0, 1}, + {0, 1, 0, 1}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} }, + + { {0, 1, 0, 1}, + {2, 3, 2, 3}, + {0, 1, 0, 1}, + {2, 3, 2, 3}, + {0, 1, 0, 1}, + {2, 3, 2, 3}, + {0, 1, 0, 1}, + {2, 3, 2, 3} } +}; + +static const unsigned char cofuv_blk_y[3][8][4] = +{ + { { 0, 0, 1, 1}, + { 0, 0, 1, 1}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0} }, + + { { 0, 0, 1, 1}, + { 2, 2, 3, 3}, + { 0, 0, 1, 1}, + { 2, 2, 3, 3}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0}, + { 0, 0, 0, 0} }, + + { { 0, 0, 1, 1}, + { 0, 0, 1, 1}, + { 2, 2, 3, 3}, + { 2, 2, 3, 3}, + { 0, 0, 1, 1}, + { 0, 0, 1, 1}, + { 2, 2, 3, 3}, + { 2, 2, 3, 3}} +}; + +void dectracebitcnt(int count); + extern int last_dquant; extern ColocatedParams *Co_located; extern ColocatedParams *Co_located_JV[MAX_PLANE]; //!< Co_located to be used during 4:4:4 independent mode decoding + +static void readMotionInfoFromNAL (ImageParameters *img, Macroblock *currMB); +static void read_ipred_modes (ImageParameters *img, Macroblock *currMB); +static void readCBPandCoeffsFromNAL(ImageParameters *img, Macroblock *currMB); +static void readIPCMcoeffsFromNAL (ImageParameters *img, struct datapartition *dP); + +// Interpret MB mode +static void (*interpret_mb_mode)(Macroblock *currMB); + /*! ************************************************************************ * \brief @@ -152,6 +359,55 @@ static inline void prepareListforRefIdx ( SyntaxElement *currSE, DataPartition * } } +void set_chroma_qp(ImageParameters *img, Macroblock* currMB) +{ + int i; + for (i=0; i<2; i++) + { + currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + dec_picture->chroma_qp_offset[i] ); + currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]]; + currMB->qp_scaled[i + 1] = currMB->qpc[i] + img->bitdepth_chroma_qp_scale; + } +} + +/*! +************************************************************************ +* \brief +* updates chroma QP according to luma QP and bit depth +************************************************************************ +*/ +void update_qp(ImageParameters *img, Macroblock *currMB, int qp) +{ + currMB->qp = qp; + currMB->qp_scaled[0] = qp + img->bitdepth_luma_qp_scale; + set_chroma_qp(img, currMB); +} + +static void read_delta_quant(SyntaxElement *currSE, DataPartition *dP, Slice *currSlice, ImageParameters *img, Macroblock *currMB, int *partMap, int type) +{ + currSE->type = type; + + dP = &(currSlice->partArr[partMap[currSE->type]]); + + if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) + { + currSE->mapping = linfo_se; + } + else + currSE->reading= readDquant_CABAC; + + TRACE_STRING_P("mb_qp_delta"); + + dP->readSyntaxElement(currSE,img,dP); + currMB->delta_quant = currSE->value1; + if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2))) + error ("mb_qp_delta is out of range", 500); + + img->qp = ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) - + img->bitdepth_luma_qp_scale; + update_qp(img, currMB, img->qp); +} + /*! ************************************************************************ * \brief @@ -204,7 +460,7 @@ static inline void readMBMotionVectors (SyntaxElement *currSE, DataPartition *dP kk = 2 * (j0 >> 1) + (i0 >> 1); if ((currMB->b8pdir[kk]== list || currMB->b8pdir[kk]== BI_PRED) && (currMB->b8mode[kk] !=0))//has forward vector { - cur_ref_idx = dec_picture->ref_idx[list][img->block_y+j0][img->block_x+i0]; + cur_ref_idx = dec_picture->motion.ref_idx[list][img->block_y+j0][img->block_x+i0]; mv_mode = currMB->b8mode[kk]; step_h = BLOCK_STEP [mv_mode][0]; step_v = BLOCK_STEP [mv_mode][1]; @@ -213,7 +469,7 @@ static inline void readMBMotionVectors (SyntaxElement *currSE, DataPartition *dP { img->subblock_y = j; // position used for context determination j4 = img->block_y + j; - mv = &dec_picture->mv [list][j4]; + mv = &dec_picture->motion.mv [list][j4]; mvd = &currMB->mvd [list][j]; for (i = i0; i < i0 + step_h0; i += step_h) { @@ -221,7 +477,7 @@ static inline void readMBMotionVectors (SyntaxElement *currSE, DataPartition *dP i4 = img->block_x + i; // first make mv-prediction - SetMotionVectorPredictor (currMB, img, pred_mv, cur_ref_idx, (byte) list, dec_picture->ref_idx, dec_picture->mv, BLOCK_SIZE * i, BLOCK_SIZE * j, 4*step_h, 4*step_v); + SetMotionVectorPredictor (img, currMB, pred_mv, cur_ref_idx, (byte) list, dec_picture->motion.ref_idx, dec_picture->motion.mv, BLOCK_SIZE * i, BLOCK_SIZE * j, 4*step_h, 4*step_v); for (k=0; k < 2; k++) { @@ -265,7 +521,7 @@ static inline void readMBMotionVectors (SyntaxElement *currSE, DataPartition *dP } } -void invScaleCoeff(Macroblock *currMB, ImageParameters *img, int level, int run, int qp_per, int i, int j, int i0, int j0, int coef_ctr, const byte (*pos_scan4x4)[2], int (*InvLevelScale4x4)[4]) +void invScaleCoeff(ImageParameters *img, Macroblock *currMB, int level, int run, int qp_per, int i, int j, int i0, int j0, int coef_ctr, const byte (*pos_scan4x4)[2], int (*InvLevelScale4x4)[4]) { if (level != 0) /* leave if len=1 */ { @@ -285,7 +541,7 @@ void invScaleCoeff(Macroblock *currMB, ImageParameters *img, int level, int run, * initializes the current macroblock ************************************************************************ */ -void start_macroblock(Macroblock **currMB, ImageParameters *img) +void start_macroblock(ImageParameters *img, Macroblock **currMB) { int mb_nr = img->current_mb_nr; *currMB = &img->mb_data[mb_nr]; // intialization code deleted, see below, StW @@ -296,8 +552,8 @@ void start_macroblock(Macroblock **currMB, ImageParameters *img) /* Update coordinates of the current macroblock */ if (img->MbaffFrameFlag) { - img->mb_x = (mb_nr)%((2*img->width)/MB_BLOCK_SIZE); - img->mb_y = 2*((mb_nr)/((2*img->width)/MB_BLOCK_SIZE)); + img->mb_x = (mb_nr) % ((2*img->width) / MB_BLOCK_SIZE); + img->mb_y = 2*((mb_nr) / ((2*img->width) / MB_BLOCK_SIZE)); img->mb_y += (img->mb_x & 0x01); img->mb_x >>= 1; @@ -348,14 +604,13 @@ void start_macroblock(Macroblock **currMB, ImageParameters *img) memset((*currMB)->cbp_bits, 0, 3 * sizeof(int64)); memset((*currMB)->cbp_bits_8x8, 0, 3 * sizeof(int64)); - // initialize img->m7 - memset(&(img->m7[0][0][0]), 0, 3 * MB_PIXELS * sizeof(int)); + // initialize img->mb_rres + memset(&(img->mb_rres[0][0][0]), 0, 3 * MB_PIXELS * sizeof(int)); // store filtering parameters for this MB (*currMB)->DFDisableIdc = img->currentSlice->DFDisableIdc; (*currMB)->DFAlphaC0Offset = img->currentSlice->DFAlphaC0Offset; (*currMB)->DFBetaOffset = img->currentSlice->DFBetaOffset; - } /*! @@ -387,16 +642,16 @@ Boolean exit_macroblock(ImageParameters *img,int eos_bit) if (img->current_mb_nr == -1) // End of Slice group, MUST be end of slice { - assert (nal_startcode_follows (img, eos_bit) == TRUE); + assert (nal_startcode_follows (img->currentSlice, eos_bit) == TRUE); return TRUE; } - if(nal_startcode_follows(img, eos_bit) == FALSE) + if(nal_startcode_follows(img->currentSlice, eos_bit) == FALSE) return FALSE; if(img->type == I_SLICE || img->type == SI_SLICE || active_pps->entropy_coding_mode_flag == CABAC) return TRUE; - if(img->cod_counter<=0) + if(img->cod_counter <= 0) return TRUE; return FALSE; } @@ -408,7 +663,7 @@ Boolean exit_macroblock(ImageParameters *img,int eos_bit) * Interpret the mb mode for P-Frames ************************************************************************ */ -void interpret_mb_mode_P(Macroblock *currMB) +static void interpret_mb_mode_P(Macroblock *currMB) { const int ICBPTAB[6] = {0,16,32,15,31,47}; int mbmode = currMB->mb_type; @@ -461,7 +716,7 @@ void interpret_mb_mode_P(Macroblock *currMB) * Interpret the mb mode for I-Frames ************************************************************************ */ -void interpret_mb_mode_I(Macroblock *currMB) +static void interpret_mb_mode_I(Macroblock *currMB) { static const int ICBPTAB[6] = {0,16,32,15,31,47}; int mbmode = currMB->mb_type; @@ -497,7 +752,7 @@ void interpret_mb_mode_I(Macroblock *currMB) * Interpret the mb mode for B-Frames ************************************************************************ */ -void interpret_mb_mode_B(Macroblock *currMB) +static void interpret_mb_mode_B(Macroblock *currMB) { static const int offset2pdir16x16[12] = {0, 0, 1, 2, 0,0,0,0,0,0,0,0}; static const int offset2pdir16x8[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},{1,0}, @@ -578,7 +833,7 @@ void interpret_mb_mode_B(Macroblock *currMB) * Interpret the mb mode for SI-Frames ************************************************************************ */ -void interpret_mb_mode_SI(Macroblock *currMB) +static void interpret_mb_mode_SI(Macroblock *currMB) { const int ICBPTAB[6] = {0,16,32,15,31,47}; int mbmode = currMB->mb_type; @@ -614,13 +869,41 @@ void interpret_mb_mode_SI(Macroblock *currMB) memset(&currMB->b8pdir[0],-1,4 * sizeof(char)); } } + +/*! + ************************************************************************ + * \brief + * Set mode interpretation based on slice type + ************************************************************************ + */ +void set_interpret_mb_mode(int slice_type) +{ + switch (slice_type) + { + case P_SLICE: case SP_SLICE: + interpret_mb_mode = interpret_mb_mode_P; + break; + case B_SLICE: + interpret_mb_mode = interpret_mb_mode_B; + break; + case I_SLICE: + interpret_mb_mode = interpret_mb_mode_I; + break; + case SI_SLICE: + interpret_mb_mode = interpret_mb_mode_SI; + break; + default: + printf("Unsupported slice type\n"); + break; + } +} /*! ************************************************************************ * \brief * init macroblock I and P frames ************************************************************************ */ -void init_macroblock(ImageParameters *img) +static void init_macroblock(ImageParameters *img) { int i, j, k; @@ -628,13 +911,14 @@ void init_macroblock(ImageParameters *img) { for(j = img->block_y; j < img->block_y + BLOCK_SIZE; j++) memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(char)); + for(j = img->block_y; j < img->block_y + BLOCK_SIZE; j++) { // reset vectors and pred. modes - memset(&dec_picture->mv[k][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short)); - memset(&dec_picture->ref_idx[k][j][img->block_x], -1, BLOCK_SIZE * sizeof(char)); - for (i=img->block_x;i<img->block_x+BLOCK_SIZE;i++) + memset(&dec_picture->motion.mv[k][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short)); + memset(&dec_picture->motion.ref_idx[k][j][img->block_x], -1, BLOCK_SIZE * sizeof(char)); + for (i = img->block_x; i < img->block_x + BLOCK_SIZE;i++) { - dec_picture->ref_pic_id[k][j][i] = INT64_MIN; + dec_picture->motion.ref_pic_id[k][j][i] = INT64_MIN; } } } @@ -658,29 +942,28 @@ void SetB8Mode (ImageParameters* img, Macroblock* currMB, int value, int i) { currMB->b8mode[i] = (char) b_v2b8[value]; currMB->b8pdir[i] = (char) b_v2pd[value]; - } else { currMB->b8mode[i] = (char) p_v2b8[value]; currMB->b8pdir[i] = (char) p_v2pd[value]; } - } void reset_coeffs(void) { // reset all coeffs + memset(&img->fcf[0][0][0], 0, 3 * MB_PIXELS * sizeof(int)); memset(&img->cof[0][0][0], 0, 3 * MB_PIXELS * sizeof(int)); - + // CAVLC - memset(&img->nz_coeff[img->current_mb_nr][0][0],0, BLOCK_SIZE * (BLOCK_SIZE + img->num_blk8x8_uv) * sizeof(int)); + if (active_pps->entropy_coding_mode_flag == UVLC) + memset(&img->nz_coeff[img->current_mb_nr][0][0][0], 0, 3 * BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); } void field_flag_inference(Macroblock *currMB) { - if (currMB->mbAvailA) { currMB->mb_field = img->mb_data[currMB->mbAddrA].mb_field; @@ -692,16 +975,91 @@ void field_flag_inference(Macroblock *currMB) } } -void set_chroma_qp(Macroblock* currMB) + +void copy_macroblock(ImageParameters *img, Macroblock *currMB) { - int i; - for (i=0; i<2; i++) + short pred_mv[2]; + int zeroMotionAbove; + int zeroMotionLeft; + PixelPos mb_a, mb_b; + int i, j; + int a_mv_y = 0; + int a_ref_idx = 0; + int b_mv_y = 0; + int b_ref_idx = 0; + int img_block_y = img->block_y; + int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; + short ***cur_mv = dec_picture->motion.mv[LIST_0]; + get4x4Neighbour(currMB,-1, 0, img->mb_size[IS_LUMA], &mb_a); + get4x4Neighbour(currMB, 0,-1, img->mb_size[IS_LUMA], &mb_b); + + if (mb_a.available) { - currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + dec_picture->chroma_qp_offset[i] ); - currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]]; + a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1]; + a_ref_idx = dec_picture->motion.ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x]; + + if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field) + { + a_mv_y /=2; + a_ref_idx *=2; + } + if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field) + { + a_mv_y *=2; + a_ref_idx >>=1; + } } -} + if (mb_b.available) + { + b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1]; + b_ref_idx = dec_picture->motion.ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x]; + + if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field) + { + b_mv_y /=2; + b_ref_idx *=2; + } + if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field) + { + b_mv_y *=2; + b_ref_idx >>=1; + } + } + + zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && cur_mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0; + zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && cur_mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0; + + currMB->cbp = 0; + reset_coeffs(); + + if (zeroMotionAbove || zeroMotionLeft) + { + for(j = img_block_y; j < img_block_y + BLOCK_SIZE;j++) + { + memset(&cur_mv[j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short)); + } + } + else + { + SetMotionVectorPredictor (img, currMB, pred_mv, 0, LIST_0, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16); + + for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++) + { + for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++) + memcpy(&cur_mv[j][i][0], &pred_mv[0], 2 * sizeof(short)); + } + } + for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++) + { + memset(&dec_picture->motion.ref_idx[LIST_0][j][img->block_x], 0, BLOCK_SIZE * sizeof(char)); + for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++) + { + dec_picture->motion.ref_pic_id[LIST_0][j][i] = + dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->motion.ref_idx[LIST_0][j][i]]; + } + } +} /*! ************************************************************************ @@ -709,9 +1067,9 @@ void set_chroma_qp(Macroblock* currMB) * Get the syntax elements from the NAL ************************************************************************ */ -void read_one_macroblock(Macroblock *currMB, ImageParameters *img) +void read_one_macroblock(ImageParameters *img, Macroblock *currMB) { - int i, j; + int i; SyntaxElement currSE; int mb_nr = img->current_mb_nr; @@ -721,7 +1079,6 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) int *partMap = assignSE2partition[currSlice->dp_mode]; Macroblock *topMB = NULL; int prevMbSkipped = 0; - int img_block_y; int check_bottom, read_bottom, read_top; if (img->MbaffFrameFlag) @@ -740,19 +1097,15 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) currMB->mb_field = ((mb_nr&0x01) == 0)? 0 : img->mb_data[mb_nr-1].mb_field; - currMB->qp = img->qp ; - for (i=0; i<2; i++) - { - currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, img->qp + dec_picture->chroma_qp_offset[i] ); - currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]]; - } + update_qp(img, currMB, img->qp); currSE.type = SE_MBTYPE; // read MB mode ***************************************************************** dP = &(currSlice->partArr[partMap[currSE.type]]); - if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue; + if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) + currSE.mapping = linfo_ue; if(img->type == I_SLICE || img->type == SI_SLICE) { @@ -772,6 +1125,7 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) } currMB->mb_field = currSE.value1; } + if(active_pps->entropy_coding_mode_flag == CABAC) CheckAvailabilityOfNeighborsCABAC(currMB); @@ -802,7 +1156,7 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) if (img->type==B_SLICE) currMB->cbp = currSE.value2; - if(!dP->bitstream->ei_flag) + if (!dP->bitstream->ei_flag) currMB->ei_flag = 0; if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0) @@ -894,6 +1248,7 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) currSE.len = (int64) 1; readSyntaxElement_FLC(&currSE, dP->bitstream); dP->bitstream->frame_bitoffset--; + TRACE_DECBITS(1); currMB->mb_field = currSE.value1; } else if(img->cod_counter > 0 && ((mb_nr&0x01) == 0)) @@ -918,12 +1273,10 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) } } - dec_picture->mb_field[mb_nr] = (byte) currMB->mb_field; + dec_picture->motion.mb_field[mb_nr] = (byte) currMB->mb_field; img->block_y_aff = ((img->MbaffFrameFlag) && (currMB->mb_field)) ? (mb_nr&0x01) ? (img->block_y - 4)>>1 : img->block_y >> 1 : img->block_y; - img->siblock[img->mb_y][img->mb_x]=0; - interpret_mb_mode(currMB); if(img->MbaffFrameFlag) @@ -961,7 +1314,7 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) } //--- init macroblock data --- init_macroblock (img); - readMotionInfoFromNAL (currMB, img); + readMotionInfoFromNAL (img, currMB); } @@ -1041,108 +1394,24 @@ void read_one_macroblock(Macroblock *currMB, ImageParameters *img) if (active_pps->entropy_coding_mode_flag ==CABAC) img->cod_counter=-1; - - return; } - - if (IS_COPY (currMB)) //keep last macroblock + else if (IS_COPY (currMB)) //keep last macroblock { - short pred_mv[2]; - int zeroMotionAbove; - int zeroMotionLeft; - PixelPos mb_a, mb_b; - int a_mv_y = 0; - int a_ref_idx = 0; - int b_mv_y = 0; - int b_ref_idx = 0; - int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0; - short ***cur_mv = dec_picture->mv[LIST_0]; - get4x4Neighbour(currMB,-1, 0, img->mb_size[IS_LUMA], &mb_a); - get4x4Neighbour(currMB, 0,-1, img->mb_size[IS_LUMA], &mb_b); - - if (mb_a.available) - { - a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1]; - a_ref_idx = dec_picture->ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x]; - - if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field) - { - a_mv_y /=2; - a_ref_idx *=2; - } - if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field) - { - a_mv_y *=2; - a_ref_idx >>=1; - } - } - - if (mb_b.available) - { - b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1]; - b_ref_idx = dec_picture->ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x]; - - if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field) - { - b_mv_y /=2; - b_ref_idx *=2; - } - if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field) - { - b_mv_y *=2; - b_ref_idx >>=1; - } - } - - zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && cur_mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0; - zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && cur_mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0; - - currMB->cbp = 0; - reset_coeffs(); - - img_block_y = img->block_y; - - if (zeroMotionAbove || zeroMotionLeft) - { - for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++) - { - memset(&cur_mv[j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short)); - } - } - else - { - SetMotionVectorPredictor (currMB, img, pred_mv, 0, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16); - - for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++) - { - for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++) - memcpy(&cur_mv[j][i][0], &pred_mv[0], 2 * sizeof(short)); - } - } - for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++) - { - memset(&dec_picture->ref_idx[LIST_0][j][img->block_x], 0, BLOCK_SIZE * sizeof(char)); - for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++) - { - dec_picture->ref_pic_id[LIST_0][j][i] = - dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j][i]]; - } - } - return; + copy_macroblock(img, currMB); } - if(currMB->mb_type!=IPCM) + else if(currMB->mb_type != IPCM) { // intra prediction modes for a macroblock 4x4 ********************************************** if (IS_INTRA(currMB)) - read_ipred_modes(currMB, img); + read_ipred_modes(img, currMB); // read inter frame vector data ********************************************************* if (IS_INTERMV (currMB) && (!IS_P8x8(currMB))) { - readMotionInfoFromNAL (currMB, img); + readMotionInfoFromNAL (img, currMB); } // read CBP and Coeffs *************************************************************** - readCBPandCoeffsFromNAL (currMB, img); + readCBPandCoeffsFromNAL (img, currMB); } else { @@ -1216,7 +1485,7 @@ void init_decoding_engine_IPCM(ImageParameters *img) ************************************************************************ */ -void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP) +static void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP) { SyntaxElement currSE; int i,j; @@ -1249,6 +1518,7 @@ void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP) { readSyntaxElement_FLC(&currSE, dP->bitstream); img->cof[0][i][j] = currSE.value1; + img->fcf[0][i][j] = currSE.value1; } } currSE.len=img->bitdepth_chroma; @@ -1260,7 +1530,8 @@ void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP) for(j=0;j<img->mb_cr_size_x;j++) { readSyntaxElement_FLC(&currSE, dP->bitstream); - img->cof[1][i][j] = currSE.value1; + img->cof[1][i][j] = currSE.value1; + img->fcf[1][i][j] = currSE.value1; } } TRACE_STRING("pcm_sample_chroma (v)"); @@ -1269,7 +1540,8 @@ void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP) for(j=0;j<img->mb_cr_size_x;j++) { readSyntaxElement_FLC(&currSE, dP->bitstream); - img->cof[2][i][j] = currSE.value1; + img->cof[2][i][j] = currSE.value1; + img->fcf[2][i][j] = currSE.value1; } } } @@ -1294,6 +1566,7 @@ void concealIPCMcoeffs(ImageParameters *img) for(j=0;j<MB_BLOCK_SIZE;j++) { img->cof[0][i][j] = img->dc_pred_value_comp[0]; + img->fcf[0][i][j] = img->dc_pred_value_comp[0]; } } @@ -1306,6 +1579,7 @@ void concealIPCMcoeffs(ImageParameters *img) for(j=0;j<img->mb_cr_size_x;j++) { img->cof[k][i][j] = img->dc_pred_value_comp[k]; + img->fcf[k][i][j] = img->dc_pred_value_comp[k]; } } } @@ -1314,7 +1588,7 @@ void concealIPCMcoeffs(ImageParameters *img) -void read_ipred_modes(Macroblock *currMB, ImageParameters *img) +static void read_ipred_modes(ImageParameters *img, Macroblock *currMB) { int b8,i,j,bi,bj,bx,by,dec; SyntaxElement currSE; @@ -1367,8 +1641,8 @@ void read_ipred_modes(Macroblock *currMB, ImageParameters *img) dP->readSyntaxElement(&currSE,img,dP); } - get4x4Neighbour(currMB, (bx<<2) - 1, (by<<2), img->mb_size[IS_LUMA], &left_block); - get4x4Neighbour(currMB, (bx<<2), (by<<2) - 1, img->mb_size[IS_LUMA], &top_block); + get4x4Neighbour(currMB, (bx<<2) - 1, (by<<2), img->mb_size[IS_LUMA], &left_block); + get4x4Neighbour(currMB, (bx<<2), (by<<2) - 1, img->mb_size[IS_LUMA], &top_block ); //get from array and decode @@ -1435,8 +1709,8 @@ void read_ipred_modes(Macroblock *currMB, ImageParameters *img) * Set motion vector predictor ************************************************************************ */ -void SetMotionVectorPredictor (Macroblock *currMB, - ImageParameters *img, +void SetMotionVectorPredictor (ImageParameters *img, + Macroblock *currMB, short pred_mv[2], char ref_frame, byte list, @@ -1454,7 +1728,7 @@ void SetMotionVectorPredictor (Macroblock *currMB, PixelPos block_a, block_b, block_c, block_d; - get4x4Neighbour(currMB, mb_x - 1, mb_y, img->mb_size[IS_LUMA], &block_a); + get4x4Neighbour(currMB, mb_x - 1, mb_y, img->mb_size[IS_LUMA], &block_a); get4x4Neighbour(currMB, mb_x, mb_y - 1, img->mb_size[IS_LUMA], &block_b); get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, img->mb_size[IS_LUMA], &block_c); get4x4Neighbour(currMB, mb_x - 1, mb_y - 1, img->mb_size[IS_LUMA], &block_d); @@ -1645,7 +1919,7 @@ void SetMotionVectorPredictor (Macroblock *currMB, * Read motion info ************************************************************************ */ -void readMotionInfoFromNAL (Macroblock *currMB, ImageParameters *img) +static void readMotionInfoFromNAL (ImageParameters *img, Macroblock *currMB) { int i,j,k; int mb_nr = img->current_mb_nr; @@ -1653,7 +1927,7 @@ void readMotionInfoFromNAL (Macroblock *currMB, ImageParameters *img) Slice *currSlice = img->currentSlice; DataPartition *dP = NULL; int *partMap = assignSE2partition[currSlice->dp_mode]; - int bframe = (img->type==B_SLICE); + int bslice = (img->type==B_SLICE); int partmode = (IS_P8x8(currMB)?4:currMB->mb_type); int step_h0 = BLOCK_STEP [partmode][0]; int step_v0 = BLOCK_STEP [partmode][1]; @@ -1661,197 +1935,188 @@ void readMotionInfoFromNAL (Macroblock *currMB, ImageParameters *img) int i0, j0, j6; int j4, i4, ii; - static byte ** moving_block; - static short **** co_located_mv; - static char *** co_located_ref_idx; - static int64 *** co_located_ref_id; + MotionParams *colocated; int mv_scale = 0; int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0; - if ((img->MbaffFrameFlag)&&(currMB->mb_field)) + if (bslice) { - if(mb_nr&0x01) + if ((img->MbaffFrameFlag) && (currMB->mb_field)) { - moving_block = Co_located->bottom_moving_block; - co_located_mv = Co_located->bottom_mv; - co_located_ref_idx = Co_located->bottom_ref_idx; - co_located_ref_id = Co_located->bottom_ref_pic_id; + if(mb_nr&0x01) + { + colocated = &Co_located->bottom; + } + else + { + colocated = &Co_located->top; + } } else { - moving_block = Co_located->top_moving_block; - co_located_mv = Co_located->top_mv; - co_located_ref_idx = Co_located->top_ref_idx; - co_located_ref_id = Co_located->top_ref_pic_id; + colocated = &Co_located->frame; } - } - else - { - moving_block = Co_located->moving_block; - co_located_mv = Co_located->mv; - co_located_ref_idx = Co_located->ref_idx; - co_located_ref_id = Co_located->ref_pic_id; - } - if (bframe && IS_P8x8 (currMB)) - { - if (img->direct_spatial_mv_pred_flag) + if (IS_P8x8 (currMB)) { - char l0_rFrame,l1_rFrame; - short pmvl0[2]={0,0}, pmvl1[2]={0,0}; + if (img->direct_spatial_mv_pred_flag) + { + char l0_rFrame, l1_rFrame; + short pmvl0[2]={0,0}, pmvl1[2]={0,0}; - prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame); + prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame); - for (k = 0; k < 4; k++) - { - if (currMB->b8mode[k] == 0) - { - i = img->block_x + 2 * (k & 0x01); - for(j = 2 * (k >> 1); j < 2 * (k >> 1)+2;j++) + for (k = 0; k < 4; k++) + { + if (currMB->b8mode[k] == 0) { - j6 = img->block_y_aff + j; - j4 = img->block_y + j; - for(i4 = i; i4 < i + 2; i4++) + i = img->block_x + 2 * (k & 0x01); + for(j = 2 * (k >> 1); j < 2 * (k >> 1)+2;j++) { - if (l0_rFrame >= 0) + j6 = img->block_y_aff + j; + j4 = img->block_y + j; + for(i4 = i; i4 < i + 2; i4++) { - if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) + if (l0_rFrame >= 0) { - dec_picture->mv [LIST_0][j4][i4][0] = 0; - dec_picture->mv [LIST_0][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_0][j4][i4] = 0; + if (!l0_rFrame && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) + { + dec_picture->motion.mv [LIST_0][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; + } + else + { + dec_picture->motion.mv [LIST_0][j4][i4][0] = pmvl0[0]; + dec_picture->motion.mv [LIST_0][j4][i4][1] = pmvl0[1]; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = l0_rFrame; + } } else { - dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0]; - dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1]; - dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame; + dec_picture->motion.mv [LIST_0][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = -1; } - } - else - { - dec_picture->mv [LIST_0][j4][i4][0] = 0; - dec_picture->mv [LIST_0][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_0][j4][i4] = -1; - } - if (l1_rFrame >= 0) - { - if (l1_rFrame==0 && ((!moving_block[j6][i4])&& (!listX[LIST_1 + list_offset][0]->is_long_term))) + if (l1_rFrame >= 0) { - dec_picture->mv [LIST_1][j4][i4][0] = 0; - dec_picture->mv [LIST_1][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + if (l1_rFrame==0 && ((!colocated->moving_block[j6][i4])&& (!listX[LIST_1 + list_offset][0]->is_long_term))) + { + dec_picture->motion.mv [LIST_1][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_1][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; + } + else + { + dec_picture->motion.mv [LIST_1][j4][i4][0] = pmvl1[0]; + dec_picture->motion.mv [LIST_1][j4][i4][1] = pmvl1[1]; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = l1_rFrame; + } } else { - dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0]; - dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1]; - dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame; + dec_picture->motion.mv [LIST_1][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_1][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = -1; } - } - else - { - dec_picture->mv [LIST_1][j4][i4][0] = 0; - dec_picture->mv [LIST_1][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = -1; - } - if (l0_rFrame <0 && l1_rFrame <0) - { - dec_picture->ref_idx[LIST_0][j4][i4] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + if (l0_rFrame <0 && l1_rFrame <0) + { + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; + } } } } } } - } - else - { - for (k = 0; k < 4; k++) // Scan all blocks + else { - if (currMB->b8mode[k] == 0) + for (k = 0; k < 4; k++) // Scan all blocks { - for(j0 = 2 * (k >> 1); j0 < 2 * (k >> 1) + 2; j0 += step_v0) + if (currMB->b8mode[k] == 0) { - for(i0 = img->block_x + 2*(k & 0x01); i0 < img->block_x + 2 * (k & 0x01)+2; i0 += step_h0) + for(j0 = 2 * (k >> 1); j0 < 2 * (k >> 1) + 2; j0 += step_v0) { - int refList = co_located_ref_idx[LIST_0 ][img->block_y_aff + j0][i0]== -1 ? LIST_1 : LIST_0; - int ref_idx = co_located_ref_idx[refList][img->block_y_aff + j0][i0]; - int mapped_idx = -1, iref; - - if (ref_idx == -1) + for(i0 = img->block_x + 2*(k & 0x01); i0 < img->block_x + 2 * (k & 0x01)+2; i0 += step_h0) { - for (j4 = img->block_y + j0; j4 < img->block_y + j0 + step_v0; j4++) + int refList = colocated->ref_idx[LIST_0 ][img->block_y_aff + j0][i0]== -1 ? LIST_1 : LIST_0; + int ref_idx = colocated->ref_idx[refList][img->block_y_aff + j0][i0]; + int mapped_idx = -1, iref; + + if (ref_idx == -1) { - memset(&dec_picture->ref_idx [LIST_0][j4][i0], 0, step_h0 * sizeof(char)); - memset(&dec_picture->ref_idx [LIST_1][j4][i0], 0, step_h0 * sizeof(char)); - memset(&dec_picture->mv [LIST_0][j4][i0][0], 0, 2 * step_h0 * sizeof(short)); - memset(&dec_picture->mv [LIST_1][j4][i0][0], 0, 2 * step_h0 * sizeof(short)); + for (j4 = img->block_y + j0; j4 < img->block_y + j0 + step_v0; j4++) + { + memset(&dec_picture->motion.ref_idx [LIST_0][j4][i0], 0, step_h0 * sizeof(char)); + memset(&dec_picture->motion.ref_idx [LIST_1][j4][i0], 0, step_h0 * sizeof(char)); + memset(&dec_picture->motion.mv [LIST_0][j4][i0][0], 0, 2 * step_h0 * sizeof(short)); + memset(&dec_picture->motion.mv [LIST_1][j4][i0][0], 0, 2 * step_h0 * sizeof(short)); + } } - } - else - { - for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]); iref++) + else { - int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field)); - - if(img->structure==0 && curr_mb_field==0) + for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]); iref++) { - // If the current MB is a frame MB and the colocated is from a field picture, - // then the co_located_ref_id may have been generated from the wrong value of - // frame_poc if it references it's complementary field, so test both POC values - if(listX[0][iref]->top_poc * 2 == co_located_ref_id[refList][img->block_y_aff + j0][i0] - || listX[0][iref]->bottom_poc * 2 == co_located_ref_id[refList][img->block_y_aff + j0][i0]) + int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field)); + + if(img->structure==0 && curr_mb_field==0) + { + // If the current MB is a frame MB and the colocated is from a field picture, + // then the colocated->ref_pic_id may have been generated from the wrong value of + // frame_poc if it references it's complementary field, so test both POC values + if(listX[0][iref]->top_poc * 2 == colocated->ref_pic_id[refList][img->block_y_aff + j0][i0] + || listX[0][iref]->bottom_poc * 2 == colocated->ref_pic_id[refList][img->block_y_aff + j0][i0]) + { + mapped_idx=iref; + break; + } + else //! invalid index. Default to zero even though this case should not happen + mapped_idx=INVALIDINDEX; + continue; + } + if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==colocated->ref_pic_id[refList][img->block_y_aff + j0][i0]) { mapped_idx=iref; break; } else //! invalid index. Default to zero even though this case should not happen mapped_idx=INVALIDINDEX; - continue; } - if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][img->block_y_aff + j0][i0]) + + if (INVALIDINDEX == mapped_idx) { - mapped_idx=iref; - break; + error("temporal direct error\ncolocated block has ref that is unavailable",-1111); } - else //! invalid index. Default to zero even though this case should not happen - mapped_idx=INVALIDINDEX; - } - - if (INVALIDINDEX == mapped_idx) - { - error("temporal direct error\ncolocated block has ref that is unavailable",-1111); - } - - for (j = j0; j < j0 + step_v0; j++) - { - j4 = img->block_y + j; - j6 = img->block_y_aff + j; - for (i4 = i0; i4 < i0 + step_h0; i4++) + for (j = j0; j < j0 + step_v0; j++) { - mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx]; - - dec_picture->ref_idx [LIST_0][j4][i4] = (char) mapped_idx; - dec_picture->ref_idx [LIST_1][j4][i4] = 0; + j4 = img->block_y + j; + j6 = img->block_y_aff + j; - for (ii=0; ii < 2; ii++) + for (i4 = i0; i4 < i0 + step_h0; i4++) { - if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term) - { - dec_picture->mv [LIST_0][j4][i4][ii] = co_located_mv[refList][j6][i4][ii]; - dec_picture->mv [LIST_1][j4][i4][ii] = 0; - } - else + mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx]; + + dec_picture->motion.ref_idx [LIST_0][j4][i4] = (char) mapped_idx; + dec_picture->motion.ref_idx [LIST_1][j4][i4] = 0; + + for (ii=0; ii < 2; ii++) { - dec_picture->mv [LIST_0][j4][i4][ii] = (short) ((mv_scale * co_located_mv[refList][j6][i4][ii] + 128 ) >> 8); - dec_picture->mv [LIST_1][j4][i4][ii] = (short) (dec_picture->mv[LIST_0][j4][i4][ii] - co_located_mv[refList][j6][i4][ii]); + if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term) + { + dec_picture->motion.mv [LIST_0][j4][i4][ii] = colocated->mv[refList][j6][i4][ii]; + dec_picture->motion.mv [LIST_1][j4][i4][ii] = 0; + } + else + { + dec_picture->motion.mv [LIST_0][j4][i4][ii] = (short) ((mv_scale * colocated->mv[refList][j6][i4][ii] + 128 ) >> 8); + dec_picture->motion.mv [LIST_1][j4][i4][ii] = (short) (dec_picture->motion.mv[LIST_0][j4][i4][ii] - colocated->mv[refList][j6][i4][ii]); + } } } } @@ -1868,12 +2133,12 @@ void readMotionInfoFromNAL (Macroblock *currMB, ImageParameters *img) currSE.type = SE_REFFRAME; dP = &(currSlice->partArr[partMap[SE_REFFRAME]]); // For LIST_0, if multiple ref. pictures, read LIST_0 reference picture indices for the MB *********** - prepareListforRefIdx (&currSE, dP, img->num_ref_idx_l0_active, !IS_P8x8 (currMB) || bframe || (!img->allrefzero)); - readMBRefPictureIdx (&currSE, dP, currMB, img, &dec_picture->ref_idx[LIST_0][img->block_y], LIST_0, step_v0, step_h0); + prepareListforRefIdx (&currSE, dP, img->num_ref_idx_l0_active, !IS_P8x8 (currMB) || bslice || (!img->allrefzero)); + readMBRefPictureIdx (&currSE, dP, currMB, img, &dec_picture->motion.ref_idx[LIST_0][img->block_y], LIST_0, step_v0, step_h0); // For LIST_1, if multiple ref. pictures, read LIST_1 reference picture indices for the MB *********** - prepareListforRefIdx (&currSE, dP, img->num_ref_idx_l1_active, !IS_P8x8 (currMB) || bframe || (!img->allrefzero)); - readMBRefPictureIdx (&currSE, dP, currMB, img, &dec_picture->ref_idx[LIST_1][img->block_y], LIST_1, step_v0, step_h0); + prepareListforRefIdx (&currSE, dP, img->num_ref_idx_l1_active, !IS_P8x8 (currMB) || bslice || (!img->allrefzero)); + readMBRefPictureIdx (&currSE, dP, currMB, img, &dec_picture->motion.ref_idx[LIST_1][img->block_y], LIST_1, step_v0, step_h0); //===== READ MOTION VECTORS ===== currSE.type = SE_MVD; @@ -1887,20 +2152,21 @@ void readMotionInfoFromNAL (Macroblock *currMB, ImageParameters *img) // LIST_0 Motion vectors readMBMotionVectors (&currSE, dP, currMB, img, LIST_0, step_h0, step_v0); // LIST_1 Motion vectors - readMBMotionVectors (&currSE, dP, currMB, img, LIST_1, step_h0, step_v0); + if (bslice) + readMBMotionVectors (&currSE, dP, currMB, img, LIST_1, step_h0, step_v0); // record reference picture Ids for deblocking decisions - for (k = LIST_0; k <= LIST_1; k++) + for (k = LIST_0; k <= (bslice ? LIST_1: LIST_0); k++) { for(j4 = img->block_y; j4 < (img->block_y +4);j4++) { for(i4 = img->block_x; i4 < (img->block_x + 4);i4++) { - if (dec_picture->ref_idx[k][j4][i4]>=0) - dec_picture->ref_pic_id[k][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][k + list_offset][(short)dec_picture->ref_idx[k][j4][i4]]; + if (dec_picture->motion.ref_idx[k][j4][i4]>=0) + dec_picture->motion.ref_pic_id[k][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][k + list_offset][(short)dec_picture->motion.ref_idx[k][j4][i4]]; else - dec_picture->ref_pic_id[k][j4][i4] = INT64_MIN; + dec_picture->motion.ref_pic_id[k][j4][i4] = INT64_MIN; } } } @@ -1937,15 +2203,15 @@ int predict_nnz(Macroblock *currMB, int block_type, ImageParameters *img, int i, switch (block_type) { case LUMA: - pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][pix.y]; + pred_nnz = img->nz_coeff [pix.mb_addr ][0][pix.y][pix.x]; cnt++; break; case CB: - pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][4+pix.y]; + pred_nnz = img->nz_coeff [pix.mb_addr ][1][pix.y][pix.x]; cnt++; break; case CR: - pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][8+pix.y]; + pred_nnz = img->nz_coeff [pix.mb_addr ][2][pix.y][pix.x]; cnt++; break; default: @@ -1969,15 +2235,15 @@ int predict_nnz(Macroblock *currMB, int block_type, ImageParameters *img, int i, switch (block_type) { case LUMA: - pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][pix.y]; + pred_nnz += img->nz_coeff [pix.mb_addr ][0][pix.y][pix.x]; cnt++; break; case CB: - pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][4+pix.y]; + pred_nnz += img->nz_coeff [pix.mb_addr ][1][pix.y][pix.x]; cnt++; break; case CR: - pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][8+pix.y]; + pred_nnz += img->nz_coeff [pix.mb_addr ][2][pix.y][pix.x]; cnt++; break; default: @@ -2010,13 +2276,13 @@ int predict_nnz_chroma(Macroblock *currMB, ImageParameters *img, int i,int j) PixelPos pix; int pred_nnz = 0; - int cnt =0; + int cnt = 0; if (dec_picture->chroma_format_idc != YUV444) { //YUV420 and YUV422 // left block - get4x4Neighbour(currMB, ((i&0x01)<<2) - 1, ((j-4)<<2), img->mb_size[IS_CHROMA], &pix); + get4x4Neighbour(currMB, ((i&0x01)<<2) - 1, j, img->mb_size[IS_CHROMA], &pix); if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3)) { @@ -2027,12 +2293,12 @@ int predict_nnz_chroma(Macroblock *currMB, ImageParameters *img, int i,int j) if (pix.available) { - pred_nnz = img->nz_coeff [pix.mb_addr ][2 * (i>>1) + pix.x][4 + pix.y]; + pred_nnz = img->nz_coeff [pix.mb_addr ][1][pix.y][2 * (i>>1) + pix.x]; cnt++; } // top block - get4x4Neighbour(currMB, ((i&0x01)<<2), ((j-4)<<2) - 1, img->mb_size[IS_CHROMA], &pix); + get4x4Neighbour(currMB, ((i&0x01)<<2), j - 1, img->mb_size[IS_CHROMA], &pix); if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3)) { @@ -2043,15 +2309,15 @@ int predict_nnz_chroma(Macroblock *currMB, ImageParameters *img, int i,int j) if (pix.available) { - pred_nnz += img->nz_coeff [pix.mb_addr ][2 * (i>>1) + pix.x][4 + pix.y]; + pred_nnz += img->nz_coeff [pix.mb_addr ][1][pix.y][2 * (i>>1) + pix.x]; cnt++; } - } - if (cnt==2) - { - pred_nnz++; - pred_nnz>>=1; + if (cnt==2) + { + pred_nnz++; + pred_nnz >>= 1; + } } return pred_nnz; @@ -2095,97 +2361,75 @@ void readCoeff4x4_CAVLC (Macroblock *currMB, ImageParameters *img, { case LUMA: max_coeff_num = 16; -#if TRACE - sprintf(type, "%s", "Luma"); -#endif + TRACE_PRINTF("Luma"); dptype = IS_INTRA (currMB) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER; - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; break; case LUMA_INTRA16x16DC: max_coeff_num = 16; -#if TRACE - sprintf(type, "%s", "Lum16DC"); -#endif + TRACE_PRINTF("Lum16DC"); dptype = SE_LUM_DC_INTRA; - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; break; case LUMA_INTRA16x16AC: max_coeff_num = 15; -#if TRACE - sprintf(type, "%s", "Lum16AC"); -#endif + TRACE_PRINTF("Lum16AC"); dptype = SE_LUM_AC_INTRA; - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; break; case CB: max_coeff_num = 16; -#if TRACE - sprintf(type, "%s", "Luma_add1"); -#endif + TRACE_PRINTF("Luma_add1"); dptype = (IS_INTRA (currMB)) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER; - img->nz_coeff[mb_nr][i][4+j] = 0; + img->nz_coeff[mb_nr][1][j][i] = 0; break; case CB_INTRA16x16DC: max_coeff_num = 16; -#if TRACE - sprintf(type, "%s", "Luma_add1_16DC"); -#endif + TRACE_PRINTF("Luma_add1_16DC"); dptype = SE_LUM_DC_INTRA; - img->nz_coeff[mb_nr][i][j+4] = 0; + img->nz_coeff[mb_nr][1][j][i] = 0; break; case CB_INTRA16x16AC: max_coeff_num = 15; -#if TRACE - sprintf(type, "%s", "Luma_add1_16AC"); -#endif + TRACE_PRINTF("Luma_add1_16AC"); dptype = SE_LUM_AC_INTRA; - img->nz_coeff[mb_nr][i][4+j] = 0; + img->nz_coeff[mb_nr][1][j][i] = 0; break; case CR: max_coeff_num = 16; -#if TRACE - sprintf(type, "%s", "Luma_add2"); -#endif + TRACE_PRINTF("Luma_add2"); dptype = (IS_INTRA (currMB)) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER; - img->nz_coeff[mb_nr][i][8+j] = 0; + img->nz_coeff[mb_nr][2][j][i] = 0; break; case CR_INTRA16x16DC: max_coeff_num = 16; -#if TRACE - sprintf(type, "%s", "Luma_add2_16DC"); -#endif + TRACE_PRINTF("Luma_add2_16DC"); dptype = SE_LUM_DC_INTRA; - img->nz_coeff[mb_nr][i][8+j] = 0; + img->nz_coeff[mb_nr][2][j][i] = 0; break; case CR_INTRA16x16AC: max_coeff_num = 15; -#if TRACE - sprintf(type, "%s", "LumA_add2_16AC"); -#endif + TRACE_PRINTF("Luma_add1_16AC"); dptype = SE_LUM_AC_INTRA; - img->nz_coeff[mb_nr][i][8+j] = 0; + img->nz_coeff[mb_nr][2][j][i] = 0; break; case CHROMA_DC: max_coeff_num = img->num_cdc_coeff; cdc = 1; -#if TRACE - sprintf(type, "%s", "ChrDC"); -#endif + TRACE_PRINTF("ChrDC"); dptype = IS_INTRA (currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER; - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; break; case CHROMA_AC: max_coeff_num = 15; cac = 1; -#if TRACE - sprintf(type, "%s", "ChrAC"); -#endif + TRACE_PRINTF("ChrDC"); dptype = IS_INTRA (currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER; - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; break; default: error ("readCoeff4x4_CAVLC: invalid block type", 600); - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; break; } @@ -2198,7 +2442,7 @@ void readCoeff4x4_CAVLC (Macroblock *currMB, ImageParameters *img, // luma or chroma AC if(block_type==LUMA || block_type==LUMA_INTRA16x16DC || block_type==LUMA_INTRA16x16AC ||block_type==CHROMA_AC) { - nnz = (!cac) ? predict_nnz(currMB, LUMA, img, i<<2, j<<2) : predict_nnz_chroma(currMB, img, i, j); + nnz = (!cac) ? predict_nnz(currMB, LUMA, img, i<<2, j<<2) : predict_nnz_chroma(currMB, img, i, ((j-4)<<2)); } else if (block_type==CB || block_type==CB_INTRA16x16DC || block_type==CB_INTRA16x16AC) { @@ -2234,11 +2478,11 @@ void readCoeff4x4_CAVLC (Macroblock *currMB, ImageParameters *img, numtrailingones = currSE.value2; if(block_type==LUMA || block_type==LUMA_INTRA16x16DC || block_type==LUMA_INTRA16x16AC ||block_type==CHROMA_AC) - img->nz_coeff[mb_nr][i][j] = numcoeff; + img->nz_coeff[mb_nr][0][j][i] = numcoeff; else if (block_type==CB || block_type==CB_INTRA16x16DC || block_type==CB_INTRA16x16AC) - img->nz_coeff[mb_nr][i][4+j] = numcoeff; + img->nz_coeff[mb_nr][1][j][i] = numcoeff; else - img->nz_coeff[mb_nr][i][8+j] = numcoeff; + img->nz_coeff[mb_nr][2][j][i] = numcoeff; } else { @@ -2366,44 +2610,6 @@ void readCoeff4x4_CAVLC (Macroblock *currMB, ImageParameters *img, -/*! - ************************************************************************ - * \brief - * Calculate the quantisation and inverse quantisation parameters - * - ************************************************************************ - */ -void CalculateQuant8Param() -{ - int i, j, k, temp; - - for(k=0; k<6; k++) - for(i=0; i<8; i++) - { - for(j=0; j<8; j++) - { - temp = (i<<3)+j; - InvLevelScale8x8Luma_Intra[k][i][j] = dequant_coef8[k][i][j] * qmatrix[6][temp]; - InvLevelScale8x8Luma_Inter[k][i][j] = dequant_coef8[k][i][j] * qmatrix[7][temp]; - } - } - - if( active_sps->chroma_format_idc == 3 ) // 4:4:4 - { - for(k=0; k<6; k++) - for(i=0; i<8; i++) - { - for(j=0; j<8; j++) - { - temp = (i<<3)+j; - InvLevelScale8x8Chroma_Intra[0][k][i][j] = dequant_coef8[k][i][j] * qmatrix[8][temp]; - InvLevelScale8x8Chroma_Inter[0][k][i][j] = dequant_coef8[k][i][j] * qmatrix[9][temp]; - InvLevelScale8x8Chroma_Intra[1][k][i][j] = dequant_coef8[k][i][j] * qmatrix[10][temp]; - InvLevelScale8x8Chroma_Inter[1][k][i][j] = dequant_coef8[k][i][j] * qmatrix[11][temp]; - } - } - } -} /*! ************************************************************************ @@ -2412,7 +2618,7 @@ void CalculateQuant8Param() * from the NAL (CABAC Mode) ************************************************************************ */ -void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters *img, int b8) +static void readLumaCoeff8x8_CABAC (ImageParameters *img, Macroblock *currMB, ColorPlane pl, int b8) { static int (*tcoeffs)[16]; int i,j,k; @@ -2422,58 +2628,41 @@ void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters Slice *currSlice = img->currentSlice; DataPartition *dP; int *partMap = assignSE2partition[currSlice->dp_mode]; - int start_scan = 0; // take all coeffs - int coef_ctr = start_scan - 1;// i0, j0; int boff_x, boff_y; - int run; - - int qp, qp_c, qp_per, qp_rem; - int uv = pl-1; + int qp_per, qp_rem; + int uv = pl - 1; int64 cbp_mask = (int64) 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position int64 *cur_cbp; Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1); int (*InvLevelScale8x8)[8] = NULL; // select scan type - const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8; + const byte (*pos_scan8x8) = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8[0] : FIELD_SCAN8x8[0]; if (cbp & (1<<b8)) // are there any coefficients in the current block { if (pl) { - qp = img->qp + dec_picture->chroma_qp_offset[uv]; - qp = iClip3(-(img->bitdepth_chroma_qp_scale), 51, qp); - qp_c = (qp < 0)? qp : QP_SCALE_CR[qp-MIN_QP]; - qp_per = (qp_c + img->bitdepth_chroma_qp_scale)/6; - qp_rem = (qp_c + img->bitdepth_chroma_qp_scale)%6; + qp_per = qp_per_matrix[ currMB->qp_scaled[pl] ]; + qp_rem = qp_rem_matrix[ currMB->qp_scaled[pl] ]; cur_cbp = &currMB->cbp_blk; } else { - qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6; - qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6; + qp_per = qp_per_matrix[ currMB->qp_scaled[pl] ]; + qp_rem = qp_rem_matrix[ currMB->qp_scaled[pl] ]; cur_cbp = &currMB->cbp_blk_CbCr[uv]; } - if( IS_INDEPENDENT(img) ) - { - if( img->colour_plane_id == 0 ) - InvLevelScale8x8 = IS_INTRA(currMB)? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem]; - else if( img->colour_plane_id == 1 ) - InvLevelScale8x8 = IS_INTRA(currMB)? InvLevelScale8x8Chroma_Intra[0][qp_rem] : InvLevelScale8x8Chroma_Inter[0][qp_rem]; - else if( img->colour_plane_id == 2 ) - InvLevelScale8x8 = IS_INTRA(currMB)? InvLevelScale8x8Chroma_Intra[1][qp_rem] : InvLevelScale8x8Chroma_Inter[1][qp_rem]; - } - else - InvLevelScale8x8 = IS_INTRA(currMB)? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem]; + InvLevelScale8x8 = IS_INTRA(currMB)? InvLevelScale8x8_Intra[pl][qp_rem] : InvLevelScale8x8_Inter[pl][qp_rem]; img->is_intra_block = IS_INTRA(currMB); // === set offset in current macroblock === boff_x = (b8&0x01) << 3; boff_y = (b8 >> 1) << 3; - tcoeffs = &img->m7[pl][boff_y]; + tcoeffs = &img->mb_rres[pl][boff_y]; img->subblock_x = boff_x >> 2; // position for coeff_count ctx img->subblock_y = boff_y >> 2; // position for coeff_count ctx @@ -2508,21 +2697,20 @@ void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters //============ decode ============= if (level != 0) /* leave if len=1 */ { - coef_ctr += currSE.value2 + 1; *cur_cbp |= cbp_mask; - i=pos_scan8x8[coef_ctr][0]; - j=pos_scan8x8[coef_ctr][1]; + + pos_scan8x8 += 2 * (currSE.value2); + + i = *pos_scan8x8++; + j = *pos_scan8x8++; tcoeffs[j][boff_x + i] = rshift_rnd_sf((level * InvLevelScale8x8[j][i]) << qp_per, 6); // dequantization - } - if (level != 0) - { // AC coefficients currSE.type = ((img->is_intra_block == 1) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER); dP = &(currSlice->partArr[partMap[currSE.type]]); - for(k=1;(k < 65) && (level != 0);k++) + for(k = 1;(k < 65) && (level != 0);k++) { #if TRACE if (pl==PLANE_Y) @@ -2539,10 +2727,10 @@ void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters //============ decode ============= if (level != 0) /* leave if len=1 */ { - coef_ctr += currSE.value2 + 1; + pos_scan8x8 += 2 * (currSE.value2); - i=pos_scan8x8[coef_ctr][0]; - j=pos_scan8x8[coef_ctr][1]; + i = *pos_scan8x8++; + j = *pos_scan8x8++; tcoeffs[ j][boff_x + i] = rshift_rnd_sf((level * InvLevelScale8x8[j][i]) << qp_per, 6); // dequantization } @@ -2551,7 +2739,7 @@ void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters } else { - for(k=start_scan;(k < 65) && (level != 0);k++) + for(k=0; (k < 65) && (level != 0);k++) { //============ read ============= /* @@ -2577,16 +2765,14 @@ void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters dP->readSyntaxElement(&currSE,img,dP); level = currSE.value1; - run = currSE.value2; - //len = currSE.len; //============ decode ============= if (level != 0) /* leave if len=1 */ { - coef_ctr += run + 1; + pos_scan8x8 += 2 * (currSE.value2); - i=pos_scan8x8[coef_ctr][0]; - j=pos_scan8x8[coef_ctr][1]; + i = *pos_scan8x8++; + j = *pos_scan8x8++; *cur_cbp |= cbp_mask; @@ -2605,7 +2791,7 @@ void readLumaCoeff8x8_CABAC (Macroblock *currMB, ColorPlane pl, ImageParameters * is missing. ************************************************************************ */ -void check_dp_neighbors (Macroblock *currMB) +static void check_dp_neighbors (Macroblock *currMB) { PixelPos up, left; @@ -2633,7 +2819,7 @@ void check_dp_neighbors (Macroblock *currMB) * from the NAL ************************************************************************ */ -void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) +static void readCBPandCoeffsFromNAL(ImageParameters *img, Macroblock *currMB) { int i,j,k; int level; @@ -2642,7 +2828,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) int cbp; SyntaxElement currSE; Slice *currSlice = img->currentSlice; - DataPartition *dP; + DataPartition *dP = NULL; int *partMap = assignSE2partition[currSlice->dp_mode]; int coef_ctr, i0, j0, b8; int ll; @@ -2650,8 +2836,8 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) int start_scan; int levarr[16], runarr[16], numcoeff; - int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6; - int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6; + int qp_per = qp_per_matrix[ (img->qp + img->bitdepth_luma_qp_scale) ]; + int qp_rem = qp_rem_matrix[ (img->qp + img->bitdepth_luma_qp_scale) ]; int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB); int uv; @@ -2663,7 +2849,6 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) int b4; int yuv = dec_picture->chroma_format_idc - 1; - int m5[4]; int m6[4]; int need_transform_size_flag; @@ -2674,6 +2859,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) // select scan type const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8; const byte (*pos_scan4x4)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN : FIELD_SCAN; + const byte *pos_scan_4x4 = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN[0] : FIELD_SCAN[0]; if(img->type==SP_SLICE && currMB->mb_type!=I16MB ) smb=1; @@ -2684,8 +2870,8 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { for (i=0; i<2; i++) { - qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6; - qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6; + qp_per_uv[i] = qp_per_matrix[ currMB->qp_scaled[i + 1] ]; + qp_rem_uv[i] = qp_rem_matrix[ currMB->qp_scaled[i + 1] ]; } } @@ -2712,7 +2898,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) } TRACE_STRING("coded_block_pattern"); - dP->readSyntaxElement(&currSE,img,dP); + dP->readSyntaxElement(&currSE, img, dP); currMB->cbp = cbp = currSE.value1; @@ -2750,27 +2936,8 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) // Delta quant only if nonzero coeffs if (cbp !=0) { - currSE.type = (IS_INTER (currMB)) ? SE_DELTA_QUANT_INTER : SE_DELTA_QUANT_INTRA; + read_delta_quant(&currSE, dP, currSlice, img, currMB, partMap, (IS_INTER (currMB)) ? SE_DELTA_QUANT_INTER : SE_DELTA_QUANT_INTRA); - dP = &(currSlice->partArr[partMap[currSE.type]]); - - if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) - { - currSE.mapping = linfo_se; - } - else - currSE.reading= readDquant_CABAC; - - TRACE_STRING("mb_qp_delta"); - - dP->readSyntaxElement(&currSE,img,dP); - currMB->delta_quant = currSE.value1; - if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2))) - error ("mb_qp_delta is out of range", 500); - - img->qp = ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) - - img->bitdepth_luma_qp_scale; - if (currSlice->dp_mode) { if (IS_INTER (currMB) && currSlice->dpC_NotPresent ) @@ -2798,32 +2965,12 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) } memset(&img->cof[0][0][0], 0, MB_PIXELS * sizeof(int)); // reset luma coeffs + memset(&img->fcf[0][0][0], 0, MB_PIXELS * sizeof(int)); // reset luma coeffs if (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes { - currSE.type = SE_DELTA_QUANT_INTRA; - - dP = &(currSlice->partArr[partMap[currSE.type]]); - - if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) - { - currSE.mapping = linfo_se; - } - else - { - currSE.reading= readDquant_CABAC; - } -#if TRACE - snprintf(currSE.tracestring, TRACESTRING_SIZE, "Delta quant "); -#endif - dP->readSyntaxElement(&currSE,img,dP); - currMB->delta_quant = currSE.value1; - if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2))) - error ("mb_qp_delta is out of range", 500); - - img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) - - img->bitdepth_luma_qp_scale; - + read_delta_quant(&currSE, dP, currSlice, img, currMB, partMap, SE_DELTA_QUANT_INTRA); + for (j=0;j<BLOCK_SIZE;j++) memset(&img->ipredmode[img->block_y+j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(byte)); @@ -2837,30 +2984,29 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) check_dp_neighbors (currMB); if (currMB->dpl_flag) { - cbp =0; - currMB->cbp = cbp; + currMB->cbp = cbp = 0; } } if (!currMB->dpl_flag) { + pos_scan_4x4 = pos_scan4x4[0]; + if (active_pps->entropy_coding_mode_flag == UVLC) { - readCoeff4x4_CAVLC(currMB, img, LUMA_INTRA16x16DC, 0, 0, - levarr, runarr, &numcoeff); + readCoeff4x4_CAVLC(currMB, img, LUMA_INTRA16x16DC, 0, 0, levarr, runarr, &numcoeff); - coef_ctr=-1; - level = 1; // just to get inside the loop for(k = 0; k < numcoeff; k++) { if (levarr[k] != 0) // leave if len=1 { - coef_ctr += runarr[k] + 1; + pos_scan_4x4 += 2 * runarr[k]; - i0=pos_scan4x4[coef_ctr][0]; - j0=pos_scan4x4[coef_ctr][1]; + i0 = ((*pos_scan_4x4++) << 2); + j0 = ((*pos_scan_4x4++) << 2); - img->cof[0][j0<<2][i0<<2]=levarr[k];// add new intra DC coeff + img->cof[0][j0][i0] = levarr[k];// add new intra DC coeff + img->fcf[0][j0][i0] = levarr[k];// add new intra DC coeff } } } @@ -2882,7 +3028,6 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) currSE.reading = readRunLevel_CABAC; } - coef_ctr = -1; level = 1; // just to get inside the loop for(k=0;(k<17) && (level!=0);k++) @@ -2890,66 +3035,44 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) #if TRACE snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC luma 16x16 "); #endif - dP->readSyntaxElement(&currSE,img,dP); + dP->readSyntaxElement(&currSE, img, dP); level = currSE.value1; - //run = currSE.value2; - //len = currSE.len; if (level != 0) // leave if len=1 { - coef_ctr += (currSE.value2 + 1); + pos_scan_4x4 += (2 * currSE.value2); - i0 = pos_scan4x4[coef_ctr][0]; - j0 = pos_scan4x4[coef_ctr][1]; + i0 = ((*pos_scan_4x4++) << 2); + j0 = ((*pos_scan_4x4++) << 2); - img->cof[0][j0<<2][i0<<2] = level;// add new intra DC coeff + img->cof[0][j0][i0] = level;// add new intra DC coeff + img->fcf[0][j0][i0] = level;// add new intra DC coeff } } } + if(!lossless_qpprime) - itrans_2(PLANE_Y, img);// transform new intra DC + itrans_2(img, currMB, PLANE_Y);// transform new intra DC } } - currMB->qp = img->qp; - set_chroma_qp(currMB); - - qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6; - qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6; + update_qp(img, currMB, img->qp); - if( IS_INDEPENDENT(img) ) - { - if( img->colour_plane_id == 0 ) - { - InvLevelScale4x4 = intra? InvLevelScale4x4Luma_Intra[qp_rem] : InvLevelScale4x4Luma_Inter[qp_rem]; - InvLevelScale8x8 = intra? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem]; - } - else if( img->colour_plane_id == 1 ) - { - InvLevelScale4x4 = intra? InvLevelScale4x4Chroma_Intra[0][qp_rem] : InvLevelScale4x4Chroma_Inter[0][qp_rem]; - InvLevelScale8x8 = intra? InvLevelScale8x8Chroma_Intra[0][qp_rem] : InvLevelScale8x8Chroma_Inter[0][qp_rem]; - } - else if( img->colour_plane_id == 2 ) - { - InvLevelScale4x4 = intra? InvLevelScale4x4Chroma_Intra[1][qp_rem] : InvLevelScale4x4Chroma_Inter[1][qp_rem]; - InvLevelScale8x8 = intra? InvLevelScale8x8Chroma_Intra[1][qp_rem] : InvLevelScale8x8Chroma_Inter[1][qp_rem]; - } - } - else - { - InvLevelScale4x4 = intra? InvLevelScale4x4Luma_Intra[qp_rem] : InvLevelScale4x4Luma_Inter[qp_rem]; - InvLevelScale8x8 = intra? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem]; - } - - //init constants for every chroma qp offset + qp_per = qp_per_matrix[ currMB->qp_scaled[img->colour_plane_id] ]; + qp_rem = qp_rem_matrix[ currMB->qp_scaled[img->colour_plane_id] ]; + + //init quant parameters for chroma if (dec_picture->chroma_format_idc != YUV400) { for(i=0; i < 2; i++) { - qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6; - qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6; + qp_per_uv[i] = qp_per_matrix[ currMB->qp_scaled[i + 1] ]; + qp_rem_uv[i] = qp_rem_matrix[ currMB->qp_scaled[i + 1] ]; } } - + + InvLevelScale4x4 = intra? InvLevelScale4x4_Intra[img->colour_plane_id][qp_rem] : InvLevelScale4x4_Inter[img->colour_plane_id][qp_rem]; + InvLevelScale8x8 = intra? InvLevelScale8x8_Intra[img->colour_plane_id][qp_rem] : InvLevelScale8x8_Inter[img->colour_plane_id][qp_rem]; + // luma coefficients if (active_pps->entropy_coding_mode_flag == UVLC) { @@ -2959,106 +3082,115 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { if (!currMB->luma_transform_size_8x8_flag) // 4x4 transform { - int cur_context = IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA; - for (block_y=0; block_y < 4; block_y += 2) /* all modes */ + if (cbp) { - for (block_x=0; block_x < 4; block_x += 2) + int cur_context = IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA; + for (block_y=0; block_y < 4; block_y += 2) /* all modes */ { - b8 = (block_y + (block_x >> 1)); - - if (cbp & (1 << b8)) // test if the block contains any coefficients + for (block_x=0; block_x < 4; block_x += 2) { - for (j=block_y; j < block_y+2; j++) + b8 = (block_y + (block_x >> 1)); + + if (cbp & (1 << b8)) // test if the block contains any coefficients { - for (i=block_x; i < block_x+2; i++) + for (j=block_y; j < block_y + 2; j++) { - readCoeff4x4_CAVLC(currMB, img, cur_context, i, j, levarr, runarr, &numcoeff); - - coef_ctr = start_scan - 1; - - for (k = 0; k < numcoeff; k++) + for (i=block_x; i < block_x + 2; i++) { - if (levarr[k] != 0) + readCoeff4x4_CAVLC(currMB, img, cur_context, i, j, levarr, runarr, &numcoeff); + pos_scan_4x4 = pos_scan4x4[start_scan]; + + for (k = 0; k < numcoeff; k++) { - coef_ctr += runarr[k]+1; + if (levarr[k] != 0) + { + pos_scan_4x4 += (runarr[k] << 1); + + i0 = *pos_scan_4x4++; + j0 = *pos_scan_4x4++; - i0 = pos_scan4x4[coef_ctr][0]; - j0 = pos_scan4x4[coef_ctr][1]; + // inverse quant for 4x4 transform only + currMB->cbp_blk |= (int64) 1 << ((j<<2) + i); - // inverse quant for 4x4 transform only - currMB->cbp_blk |= (int64) 1 << ((j<<2) + i); - img->cof[0][(j<<2) + j0][(i<<2) + i0]= rshift_rnd_sf((levarr[k] * InvLevelScale4x4[j0][i0])<<qp_per, 4); + img->cof[0][(j<<2) + j0][(i<<2) + i0]= rshift_rnd_sf((levarr[k] * InvLevelScale4x4[j0][i0])<<qp_per, 4); + img->fcf[0][(j<<2) + j0][(i<<2) + i0]= levarr[k]; + } } } } } - } - else - { - for (j=block_y; j < block_y+2; j++) + else { - for (i=block_x; i < block_x+2; i++) - { - img->nz_coeff[mb_nr][i][j] = 0; + for (j=block_y; j < block_y + 2; j++) + { + memset(&img->nz_coeff[mb_nr][0][j][block_x], 0, 2 * sizeof(int)); } } } } } + else + { + memset(&img->nz_coeff[mb_nr][0][0][0], 0, BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); + } } else // 8x8 transform { - int cur_context = IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA; - - for (block_y=0; block_y < 4; block_y += 2) /* all modes */ + if (cbp) { - for (block_x=0; block_x < 4; block_x += 2) - { - b8 = 2*(block_y>>1) + (block_x>>1); + int cur_context = IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA; - if (cbp & (1<<b8)) /* are there any coeff in current block at all */ + for (block_y=0; block_y < 4; block_y += 2) /* all modes */ + { + for (block_x=0; block_x < 4; block_x += 2) { - for (j=block_y; j < block_y+2; j++) + b8 = 2*(block_y>>1) + (block_x>>1); + + if (cbp & (1<<b8)) /* are there any coeff in current block at all */ { - for (i=block_x; i < block_x+2; i++) + for (j=block_y; j < block_y+2; j++) { - readCoeff4x4_CAVLC(currMB, img, cur_context, i, j, levarr, runarr, &numcoeff); + for (i=block_x; i < block_x+2; i++) + { + readCoeff4x4_CAVLC(currMB, img, cur_context, i, j, levarr, runarr, &numcoeff); - coef_ctr = start_scan - 1; + coef_ctr = start_scan - 1; - for (k = 0; k < numcoeff; k++) - { - if (levarr[k] != 0) + for (k = 0; k < numcoeff; k++) { - coef_ctr += runarr[k]+1; + if (levarr[k] != 0) + { + coef_ctr += runarr[k]+1; - // do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s - //as containing coefficients - currMB->cbp_blk |= 51 << ((block_y<<2) + block_x); + // do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s + //as containing coefficients + currMB->cbp_blk |= 51 << ((block_y<<2) + block_x); - b4 = (coef_ctr << 2) + 2*(j - block_y)+(i - block_x); + b4 = (coef_ctr << 2) + 2*(j - block_y)+(i - block_x); - i0 = pos_scan8x8[b4][0]; - j0 = pos_scan8x8[b4][1]; + i0 = pos_scan8x8[b4][0]; + j0 = pos_scan8x8[b4][1]; - img->m7[0][block_y*4 +j0][block_x*4 +i0] = rshift_rnd_sf((levarr[k] * InvLevelScale8x8[j0][i0])<<qp_per, 6); // dequantization - } - }//else (!currMB->luma_transform_size_8x8_flag) + img->mb_rres[0][block_y*4 +j0][block_x*4 +i0] = rshift_rnd_sf((levarr[k] * InvLevelScale8x8[j0][i0])<<qp_per, 6); // dequantization + } + }//else (!currMB->luma_transform_size_8x8_flag) + } } } - } - else - { - for (j=block_y; j < block_y+2; j++) + else { - for (i=block_x; i < block_x+2; i++) - { - img->nz_coeff[mb_nr][i][j] = 0; + for (j=block_y; j < block_y+2; j++) + { + memset(&img->nz_coeff[mb_nr][0][j][block_x], 0, 2 * sizeof(int)); } } } } } + else + { + memset(&img->nz_coeff[mb_nr][0][0][0], 0, BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); + } } } else // if (!lossless_qpprime) @@ -3093,6 +3225,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) currMB->cbp_blk |= (int64) 1 << ((j<<2) + i); img->cof[0][(j<<2) + j0][(i<<2) + i0]= levarr[k]; + img->fcf[0][(j<<2) + j0][(i<<2) + i0]= levarr[k]; } } } @@ -3114,14 +3247,14 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) iz=pos_scan8x8[coef_ctr*4+b4][0]; jz=pos_scan8x8[coef_ctr*4+b4][1]; - img->m7[0][block_y*4 +jz][block_x*4 +iz] = levarr[k]; + img->mb_rres[0][block_y*4 +jz][block_x*4 +iz] = levarr[k]; } } }//else (!currMB->luma_transform_size_8x8_flag) } else { - img->nz_coeff[mb_nr][i][j] = 0; + img->nz_coeff[mb_nr][0][j][i] = 0; } } } @@ -3133,14 +3266,13 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { //======= Other Modes & CABAC ======== //------------------------------------ - if(currMB->luma_transform_size_8x8_flag) { for (block_y=0; block_y < 4; block_y += 2) /* all modes */ { for (b8 = block_y; b8 < block_y + 2; b8 += 1) { - readLumaCoeff8x8_CABAC(currMB, PLANE_Y, img, b8); //======= 8x8 trannsform size & CABAC ======== + readLumaCoeff8x8_CABAC(img, currMB, PLANE_Y, b8); //======= 8x8 trannsform size & CABAC ======== } } } @@ -3148,61 +3280,66 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { if(!lossless_qpprime) { - start_scan = IS_NEWINTRA (currMB)? 1 : 0; - img->is_intra_block = intra; - currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4); - - for (block_y=0; block_y < 4; block_y += 2) /* all modes */ + if (cbp) { - for (block_x=0; block_x < 4; block_x += 2) + start_scan = IS_NEWINTRA (currMB)? 1 : 0; + + img->is_intra_block = intra; + currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4); + + for (block_y=0; block_y < 4; block_y += 2) /* all modes */ { - b8 = 2*(block_y>>1) + (block_x>>1); - - if (cbp & (1<<b8)) // are there any coeff in current block at all + for (block_x=0; block_x < 4; block_x += 2) { - for (j = (block_y<<2); j < (block_y<<2) + 8; j += 4) - { - img->subblock_y = (j>>2); // position for coeff_count ctx + b8 = 2*(block_y>>1) + (block_x>>1); - for (i = block_x; i < block_x + 2; i++) + if (cbp & (1<<b8)) // are there any coeff in current block at all + { + for (j = (block_y<<2); j < (block_y<<2) + 8; j += 4) { - img->subblock_x = i; // position for coeff_count ctx + img->subblock_y = (j>>2); // position for coeff_count ctx - coef_ctr = start_scan - 1; - level = 1; - - for(k=start_scan;(k<17) && (level!=0);k++) + for (i = block_x; i < block_x + 2; i++) { - /* - * make distinction between INTRA and INTER coded - * luminance coefficients - */ - currSE.type = (img->is_intra_block - ? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA) - : (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER)); + img->subblock_x = i; // position for coeff_count ctx + pos_scan_4x4 = pos_scan4x4[start_scan]; -#if TRACE - sprintf(currSE.tracestring, "Luma sng "); -#endif - dP = &(currSlice->partArr[partMap[currSE.type]]); + level = 1; - if (dP->bitstream->ei_flag) - currSE.mapping = linfo_levrun_inter; - else - currSE.reading = readRunLevel_CABAC; + for(k=start_scan;(k<17) && (level!=0);k++) + { + /* + * make distinction between INTRA and INTER coded + * luminance coefficients + */ + currSE.type = (img->is_intra_block + ? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA) + : (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER)); - dP->readSyntaxElement(&currSE,img,dP); - level = currSE.value1; +#if TRACE + sprintf(currSE.tracestring, "Luma sng "); +#endif + dP = &(currSlice->partArr[partMap[currSE.type]]); - if (level != 0) /* leave if len=1 */ - { - coef_ctr += currSE.value2 + 1; + if (dP->bitstream->ei_flag) + currSE.mapping = linfo_levrun_inter; + else + currSE.reading = readRunLevel_CABAC; - i0=pos_scan4x4[coef_ctr][0]; - j0=pos_scan4x4[coef_ctr][1]; + dP->readSyntaxElement(&currSE,img,dP); + level = currSE.value1; - currMB->cbp_blk |= (int64)1 << (j + i) ; - img->cof[0][j + j0][(i<<2) + i0]= rshift_rnd_sf((level * InvLevelScale4x4[j0][i0]) << qp_per, 4); + if (level != 0) /* leave if len=1 */ + { + pos_scan_4x4 += 2 * currSE.value2; + + i0 = *pos_scan_4x4++; + j0 = *pos_scan_4x4++; + + currMB->cbp_blk |= (int64)1 << (j + i) ; + img->cof[0][j + j0][(i<<2) + i0]= rshift_rnd_sf((level * InvLevelScale4x4[j0][i0]) << qp_per, 4); + img->fcf[0][j + j0][(i<<2) + i0]= level; + } } } } @@ -3259,8 +3396,6 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) dP->readSyntaxElement(&currSE,img,dP); level = currSE.value1; - //run = currSE.value2; - //len = currSE.len; if (level != 0) /* leave if len=1 */ { @@ -3271,6 +3406,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ; img->cof[0][(j<<2) + j0][(i<<2) + i0] = level; + img->fcf[0][(j<<2) + j0][(i<<2) + i0] = level; } } } @@ -3287,6 +3423,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) for (uv = 0; uv < 2; uv++ ) { memset(&img->cof[uv + 1][0][0], 0, MB_PIXELS * sizeof(int)); + memset(&img->fcf[uv + 1][0][0], 0, MB_PIXELS * sizeof(int)); /*----------------------16x16DC Luma_Add----------------------*/ if (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes @@ -3312,7 +3449,8 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) i0=pos_scan4x4[coef_ctr][0]; j0=pos_scan4x4[coef_ctr][1]; - img->cof[uv + 1][j0<<2][i0<<2]=levarr[k];// add new intra DC coeff + img->cof[uv + 1][j0<<2][i0<<2] = levarr[k];// add new intra DC coeff + img->fcf[uv + 1][j0<<2][i0<<2] = levarr[k];// add new intra DC coeff } //if leavarr[k] } //k loop } //UVLC @@ -3365,30 +3503,30 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) i0=pos_scan4x4[coef_ctr][0]; j0=pos_scan4x4[coef_ctr][1]; - img->cof[uv + 1][j0<<2][i0<<2]=level; + img->cof[uv + 1][j0<<2][i0<<2] = level; + img->fcf[uv + 1][j0<<2][i0<<2] = level; } } //k loop } // else UVLC if(!lossless_qpprime) { - itrans_2((ColorPlane) (uv + 1), img); // transform new intra DC + itrans_2(img, currMB, (ColorPlane) (uv + 1)); // transform new intra DC } } //IS_NEWINTRA - currMB->qp = img->qp; - set_chroma_qp(currMB); + update_qp(img, currMB, img->qp); - qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6; - qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6; + qp_per = qp_per_matrix[ (img->qp + img->bitdepth_luma_qp_scale) ]; + qp_rem = qp_rem_matrix[ (img->qp + img->bitdepth_luma_qp_scale) ]; //init constants for every chroma qp offset - qp_per_uv[uv] = (currMB->qpc[uv] + img->bitdepth_chroma_qp_scale)/6; - qp_rem_uv[uv] = (currMB->qpc[uv] + img->bitdepth_chroma_qp_scale)%6; + qp_per_uv[uv] = qp_per_matrix[ (currMB->qpc[uv] + img->bitdepth_chroma_qp_scale) ]; + qp_rem_uv[uv] = qp_rem_matrix[ (currMB->qpc[uv] + img->bitdepth_chroma_qp_scale) ]; - InvLevelScale4x4 = intra? InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]] : InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]]; - InvLevelScale8x8 = intra? InvLevelScale8x8Chroma_Intra[uv][qp_rem_uv[uv]] : InvLevelScale8x8Chroma_Intra[uv][qp_rem_uv[uv]]; + InvLevelScale4x4 = intra? InvLevelScale4x4_Intra[uv + 1][qp_rem_uv[uv]] : InvLevelScale4x4_Inter[uv + 1][qp_rem_uv[uv]]; + InvLevelScale8x8 = intra? InvLevelScale8x8_Intra[uv + 1][qp_rem_uv[uv]] : InvLevelScale8x8_Inter[uv + 1][qp_rem_uv[uv]]; // luma_add coefficients @@ -3433,7 +3571,8 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) // inverse quant for 4x4 transform only currMB->cbp_blk_CbCr[uv] |= (int64) 1 << ((j<<2) + i); - img->cof[uv + 1][(j << 2) + j0][(i << 2) + i0]= rshift_rnd_sf((levarr[k] * InvLevelScale4x4[j0][i0])<<qp_per_uv[uv],4); + img->cof[uv + 1][(j << 2) + j0][(i << 2) + i0] = rshift_rnd_sf((levarr[k] * InvLevelScale4x4[j0][i0])<<qp_per_uv[uv],4); + img->fcf[uv + 1][(j << 2) + j0][(i << 2) + i0] = levarr[k]; } //levarr[k] != 0 }//k loop } //4x4 @@ -3454,7 +3593,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) iz = pos_scan8x8[(coef_ctr << 2) + b4][0]; jz = pos_scan8x8[(coef_ctr << 2) + b4][1]; - img->m7[uv+1][block_y*4 +jz][block_x*4 +iz] = rshift_rnd_sf((levarr[k]*InvLevelScale8x8[jz][iz])<<qp_per_uv[uv], 6); // dequantization 444_TEMP_NOTE + img->mb_rres[uv+1][block_y*4 +jz][block_x*4 +iz] = rshift_rnd_sf((levarr[k]*InvLevelScale8x8[jz][iz])<<qp_per_uv[uv], 6); // dequantization 444_TEMP_NOTE } //if levarr }//8x8 }//k loop @@ -3473,6 +3612,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) j0=pos_scan4x4[coef_ctr][1]; currMB->cbp_blk_CbCr[uv] |= (int64) 1 << ((j<<2) + i); img->cof[uv + 1][(j << 2) + j0][(i << 2) + i0] = levarr[k]; + img->fcf[uv + 1][(j << 2) + j0][(i << 2) + i0] = levarr[k]; } //levarr[k] } //k loop } //4x4 @@ -3494,7 +3634,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) iz=pos_scan8x8[coef_ctr*4+b4][0]; jz=pos_scan8x8[coef_ctr*4+b4][1]; - img->m7[uv+1][block_y*4 +jz][block_x*4 +iz] = levarr[k]; + img->mb_rres[uv+1][block_y*4 +jz][block_x*4 +iz] = levarr[k]; } //levarr[k] } //k loop } //8x8 @@ -3502,7 +3642,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) } //if (cbp & (1<<b8)) else //!(cbp & (1<<b8)) { - img->nz_coeff[mb_nr][i][(4 << uv) +j] = 0; + img->nz_coeff[mb_nr][uv + 1][j][i] = 0; } //!(cbp & (1<<b8)) } //i=block_x } //j=block_y @@ -3511,7 +3651,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { if(currMB->luma_transform_size_8x8_flag) { - readLumaCoeff8x8_CABAC(currMB, (ColorPlane) (PLANE_U + uv), img, b8); //======= 8x8 trannsform size & CABAC ======== + readLumaCoeff8x8_CABAC(img, currMB, (ColorPlane) (PLANE_U + uv), b8); //======= 8x8 trannsform size & CABAC ======== } else //4x4 { @@ -3581,6 +3721,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) j0=pos_scan4x4[coef_ctr][1]; currMB->cbp_blk_CbCr[uv] |= (int64)1 << ((j<<2) + i) ; img->cof[uv + 1][(j << 2) + j0][(i << 2) + i0] = rshift_rnd_sf((level * InvLevelScale4x4[j0][i0]) << qp_per_uv[uv], 4); //444_TEMP_NOTE + img->fcf[uv + 1][(j << 2) + j0][(i << 2) + i0] = level; }//level != 0 } //k loop }//!lossless @@ -3631,6 +3772,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) j0=pos_scan4x4[coef_ctr][1]; currMB->cbp_blk_CbCr[uv] |= (int64)1 << ((j<<2) + i); img->cof[uv + 1][(j << 2) + j0][(i << 2) + i0] = level; + img->fcf[uv + 1][(j << 2) + j0][(i << 2) + i0] = level; } //level != 0 }//k loop } //lossless @@ -3647,6 +3789,9 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { memset(&img->cof[1][0][0], 0, MB_PIXELS * sizeof(int)); memset(&img->cof[2][0][0], 0, MB_PIXELS * sizeof(int)); + memset(&img->fcf[1][0][0], 0, MB_PIXELS * sizeof(int)); + memset(&img->fcf[2][0][0], 0, MB_PIXELS * sizeof(int)); + //========================== CHROMA DC ============================ //----------------------------------------------------------------- @@ -3654,15 +3799,14 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) if(cbp>15) { if (dec_picture->chroma_format_idc == YUV420) - { - int (*InvLevelScale4x4Chroma)[4]; + { for (ll=0;ll<3;ll+=2) { uv = ll>>1; if (active_pps->entropy_coding_mode_flag == UVLC) { - InvLevelScale4x4Chroma = intra ? InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]] : InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]]; + InvLevelScale4x4 = intra ? InvLevelScale4x4_Intra[uv + 1][qp_rem_uv[uv]] : InvLevelScale4x4_Inter[uv + 1][qp_rem_uv[uv]]; //===================== CHROMA DC YUV420 ====================== memset(&img->cofu[0], 0, 4 *sizeof(int)); @@ -3681,7 +3825,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) } else { - InvLevelScale4x4Chroma = intra ? InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]] : InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]]; + InvLevelScale4x4 = intra ? InvLevelScale4x4_Intra[uv + 1][qp_rem_uv[uv]] : InvLevelScale4x4_Inter[uv + 1][qp_rem_uv[uv]]; //===================== CHROMA DC YUV420 ====================== memset(&img->cofu[0], 0, 4 *sizeof(int)); @@ -3699,7 +3843,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) else currSE.reading = readRunLevel_CABAC; - for(k = 0; (k < (img->num_cdc_coeff+1))&&(level!=0);k++) + for(k = 0; (k < (img->num_cdc_coeff + 1))&&(level!=0);k++) { #if TRACE snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x2 DC Chroma "); @@ -3707,8 +3851,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) dP->readSyntaxElement(&currSE,img,dP); level = currSE.value1; - //run = currSE.value2; - //len = currSE.len; + if (level != 0) { currMB->cbp_blk |= 0xf0000 << (ll<<1) ; @@ -3730,23 +3873,31 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) if (smb || lossless_qpprime) // check to see if MB type is SPred or SIntra4x4 { - img->cof[uv + 1][0][0]=img->cofu[0]; - img->cof[uv + 1][0][4]=img->cofu[1]; - img->cof[uv + 1][4][0]=img->cofu[2]; - img->cof[uv + 1][4][4]=img->cofu[3]; + img->cof[uv + 1][0][0] = img->cofu[0]; + img->cof[uv + 1][4][0] = img->cofu[1]; + img->cof[uv + 1][0][4] = img->cofu[2]; + img->cof[uv + 1][4][4] = img->cofu[3]; + img->fcf[uv + 1][0][0] = img->cofu[0]; + img->fcf[uv + 1][4][0] = img->cofu[1]; + img->fcf[uv + 1][0][4] = img->cofu[2]; + img->fcf[uv + 1][4][4] = img->cofu[3]; } else { ihadamard2x2(img->cofu, temp); + img->fcf[uv + 1][0][0] = temp[0]; + img->fcf[uv + 1][0][4] = temp[1]; + img->fcf[uv + 1][4][0] = temp[2]; + img->fcf[uv + 1][4][4] = temp[3]; for (i=0;i<img->num_cdc_coeff;i++) { - temp[i]= (((temp[i] * InvLevelScale4x4Chroma[0][0])<<qp_per_uv[uv])>>5); + temp[i]= (((temp[i] * InvLevelScale4x4[0][0])<<qp_per_uv[uv])>>5); } - img->cof[uv + 1][0][0]=temp[0]; - img->cof[uv + 1][0][4]=temp[1]; - img->cof[uv + 1][4][0]=temp[2]; - img->cof[uv + 1][4][4]=temp[3]; + img->cof[uv + 1][0][0] = temp[0]; + img->cof[uv + 1][0][4] = temp[1]; + img->cof[uv + 1][4][0] = temp[2]; + img->cof[uv + 1][4][4] = temp[3]; } } } @@ -3754,12 +3905,19 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { for (ll=0;ll<3;ll+=2) { + int (*InvLevelScale4x4)[4] = NULL; uv = ll>>1; { + int (*imgcof)[16] = img->cof[uv + 1]; int m3[2][4] = {{0,0,0,0},{0,0,0,0}}; int m4[2][4] = {{0,0,0,0},{0,0,0,0}}; - int qp_per_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)/6; //for YUV422 only - int qp_rem_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)%6; //for YUV422 only + int qp_per_uv_dc = qp_per_matrix[ (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale) ]; //for YUV422 only + int qp_rem_uv_dc = qp_rem_matrix[ (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale) ]; //for YUV422 only + if (intra) + InvLevelScale4x4 = InvLevelScale4x4_Intra[uv + 1][qp_rem_uv_dc]; + else + InvLevelScale4x4 = InvLevelScale4x4_Inter[uv + 1][qp_rem_uv_dc]; + //===================== CHROMA DC YUV422 ====================== if (active_pps->entropy_coding_mode_flag == UVLC) @@ -3772,7 +3930,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) if (levarr[k] != 0) { currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2); - coef_ctr=coef_ctr+runarr[k]+1; + coef_ctr += runarr[k]+1; i0 = SCAN_YUV422[coef_ctr][0]; j0 = SCAN_YUV422[coef_ctr][1]; @@ -3802,9 +3960,9 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) currSE.reading = readRunLevel_CABAC; dP->readSyntaxElement(&currSE,img,dP); + level = currSE.value1; - //run = currSE.value2; - //len = currSE.len; + if (level != 0) { currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2) ; @@ -3830,63 +3988,40 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) m4[1][1] = m3[0][1] - m3[1][1]; m4[1][2] = m3[0][2] - m3[1][2]; m4[1][3] = m3[0][3] - m3[1][3]; + + for (i = 0; i < 2; i++) + { + m6[0] = m4[i][0] + m4[i][2]; + m6[1] = m4[i][0] - m4[i][2]; + m6[2] = m4[i][1] - m4[i][3]; + m6[3] = m4[i][1] + m4[i][3]; + + imgcof[ 0][i<<2] = m6[0] + m6[3]; + imgcof[ 4][i<<2] = m6[1] + m6[2]; + imgcof[ 8][i<<2] = m6[1] - m6[2]; + imgcof[12][i<<2] = m6[0] - m6[3]; + }//for (i=0;i<2;i++) } else { - for(i=0;i<2;i++) - for(j=0;j<4;j++) - img->cof[uv + 1][j<<2][i<<2]=m3[i][j]; - } - - // vertical - for (i=0;i<2 && !lossless_qpprime;i++) - { - // This is not right with the 16x16 mtr structure. Needs revisit... AMT - int (*imgcof)[16] = img->cof[uv + 1]; - for (j=0; j < 4;j++) //TODO: remove m5 with m4 - m5[j]=m4[i][j]; - - m6[0]=m5[0]+m5[2]; - m6[1]=m5[0]-m5[2]; - m6[2]=m5[1]-m5[3]; - m6[3]=m5[1]+m5[3]; - - - if(qp_per_uv_dc<4) + for(j=0;j<4;j++) { - if(intra == 1) - { - imgcof[ 0][i<<2] = ((((m6[0]+m6[3])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - imgcof[ 4][i<<2] = ((((m6[1]+m6[2])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - imgcof[ 8][i<<2] = ((((m6[1]-m6[2])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - imgcof[12][i<<2] = ((((m6[0]-m6[3])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - } - else + for(i=0;i<2;i++) { - imgcof[ 0][i<<2] = ((((m6[0]+m6[3])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - imgcof[ 4][i<<2] = ((((m6[1]+m6[2])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - imgcof[ 8][i<<2] = ((((m6[1]-m6[2])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; - imgcof[12][i<<2] = ((((m6[0]-m6[3])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2; + img->cof[uv + 1][j<<2][i<<2] = m3[i][j]; + img->fcf[uv + 1][j<<2][i<<2] = m3[i][j]; } } - else + } + + + for(j = 0;j < img->mb_cr_size_y; j += BLOCK_SIZE) + { + for(i=0;i < img->mb_cr_size_x;i+=BLOCK_SIZE) { - if(intra == 1) - { - imgcof[ 0][i<<2] = ((((m6[0]+m6[3])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - imgcof[ 4][i<<2] = ((((m6[1]+m6[2])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - imgcof[ 8][i<<2] = ((((m6[1]-m6[2])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - imgcof[12][i<<2] = ((((m6[0]-m6[3])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - } - else - { - imgcof[ 0][i<<2] = ((((m6[0]+m6[3])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - imgcof[ 4][i<<2] = ((((m6[1]+m6[2])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - imgcof[ 8][i<<2] = ((((m6[1]-m6[2])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - imgcof[12][i<<2] = ((((m6[0]-m6[3])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2; - } + imgcof[j][i] = rshift_rnd_sf((imgcof[j][i] * InvLevelScale4x4[0][0]) << qp_per_uv_dc, 6); } - }//for (i=0;i<2;i++) + } } }//for (ll=0;ll<3;ll+=2) }//else if (dec_picture->chroma_format_idc == YUV422) @@ -3896,30 +4031,28 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) //----------------------------------------------------------------- // chroma AC coeff, all zero fram start_scan if (cbp<=31) - for (i=0; i < 4; i++) - memset(&img->nz_coeff [mb_nr ][i][4], 0, img->num_blk8x8_uv * sizeof(int)); + { + if (active_pps->entropy_coding_mode_flag == UVLC) + memset(&img->nz_coeff [mb_nr ][1][0][0], 0, 2 * BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); + } else { - int (*InvLevelScale4x4Chroma)[4]; - if (active_pps->entropy_coding_mode_flag == UVLC) { if(!lossless_qpprime) { for (b8=0; b8 < img->num_blk8x8_uv; b8++) { - int uvc = (b8 > ((img->num_uv_blocks) - 1 )); - InvLevelScale4x4Chroma = intra ? InvLevelScale4x4Chroma_Intra[uvc][qp_rem_uv[uvc]] : InvLevelScale4x4Chroma_Inter[uvc][qp_rem_uv[uvc]]; - - img->is_v_block = uv = uvc; + img->is_v_block = uv = (b8 > ((img->num_uv_blocks) - 1 )); + InvLevelScale4x4 = intra ? InvLevelScale4x4_Intra[uv + 1][qp_rem_uv[uv]] : InvLevelScale4x4_Inter[uv + 1][qp_rem_uv[uv]]; for (b4=0; b4 < 4; b4++) { i = cofuv_blk_x[yuv][b8][b4]; j = cofuv_blk_y[yuv][b8][b4]; - readCoeff4x4_CAVLC(currMB, img, CHROMA_AC, i + 2*uvc, j + 4, levarr, runarr, &numcoeff); - coef_ctr=0; + readCoeff4x4_CAVLC(currMB, img, CHROMA_AC, i + 2*uv, j + 4, levarr, runarr, &numcoeff); + coef_ctr = 0; for(k = 0; k < numcoeff;k++) { @@ -3931,7 +4064,8 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) i0=pos_scan4x4[coef_ctr][0]; j0=pos_scan4x4[coef_ctr][1]; - img->cof[uv + 1][(j<<2) + j0][(i<<2) + i0] = rshift_rnd_sf((levarr[k]*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4); + img->cof[uv + 1][(j<<2) + j0][(i<<2) + i0] = rshift_rnd_sf((levarr[k] * InvLevelScale4x4[j0][i0])<<qp_per_uv[uv], 4); + img->fcf[uv + 1][(j<<2) + j0][(i<<2) + i0] = levarr[k]; } } } @@ -3941,9 +4075,7 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { for (b8=0; b8 < img->num_blk8x8_uv; b8++) { - int uvc = (b8 > ((img->num_uv_blocks) - 1 )); - - img->is_v_block = uv = uvc; + img->is_v_block = uv = (b8 > ((img->num_uv_blocks) - 1 )); for (b4=0; b4 < 4; b4++) { @@ -3961,10 +4093,11 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) currMB->cbp_blk |= ((int64) 1) << cbp_blk_chroma[b8][b4]; coef_ctr += runarr[k] + 1; - i0=pos_scan4x4[coef_ctr][0]; - j0=pos_scan4x4[coef_ctr][1]; + i0 = pos_scan4x4[coef_ctr][0]; + j0 = pos_scan4x4[coef_ctr][1]; img->cof[uv + 1][(j<<2) + j0][(i<<2) + i0] = levarr[k]; + img->fcf[uv + 1][(j<<2) + j0][(i<<2) + i0] = levarr[k]; } } } @@ -3973,9 +4106,10 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) } else { - currSE.context = CHROMA_AC; - currSE.type = (IS_INTRA(currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER); img->is_intra_block = IS_INTRA(currMB); + currSE.context = CHROMA_AC; + currSE.type = (img->is_intra_block ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER); + dP = &(currSlice->partArr[partMap[currSE.type]]); if (dP->bitstream->ei_flag) @@ -3987,12 +4121,10 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { for (b8=0; b8 < img->num_blk8x8_uv; b8++) { - int uvc = (b8 > ((img->num_uv_blocks) - 1 )); - InvLevelScale4x4Chroma = intra ? InvLevelScale4x4Chroma_Intra[uvc][qp_rem_uv[uvc]] : InvLevelScale4x4Chroma_Inter[uvc][qp_rem_uv[uvc]]; - - img->is_v_block = uv = uvc; + img->is_v_block = uv = (b8 > ((img->num_uv_blocks) - 1 )); + InvLevelScale4x4 = intra ? InvLevelScale4x4_Intra[uv + 1][qp_rem_uv[uv]] : InvLevelScale4x4_Inter[uv + 1][qp_rem_uv[uv]]; - for (b4=0; b4 < 4; b4++) + for (b4 = 0; b4 < 4; b4++) { i = cofuv_blk_x[yuv][b8][b4]; j = cofuv_blk_y[yuv][b8][b4]; @@ -4000,11 +4132,10 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) img->subblock_y = subblk_offset_y[yuv][b8][b4]>>2; img->subblock_x = subblk_offset_x[yuv][b8][b4]>>2; - coef_ctr=0; + pos_scan_4x4 = pos_scan4x4[1]; level=1; - - for(k=0;(k<16)&&(level!=0);k++) + for(k = 0; (k < 16) && (level != 0);k++) { #if TRACE snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma "); @@ -4016,12 +4147,13 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) if (level != 0) { currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4]; - coef_ctr += (currSE.value2 + 1); - - i0=pos_scan4x4[coef_ctr][0]; - j0=pos_scan4x4[coef_ctr][1]; + pos_scan_4x4 += (currSE.value2 << 1); + + i0 = *pos_scan_4x4++; + j0 = *pos_scan_4x4++; - img->cof[uv + 1][(j<<2) + j0][(i<<2) + i0] = rshift_rnd_sf((level * InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4); + img->cof[uv + 1][(j<<2) + j0][(i<<2) + i0] = rshift_rnd_sf((level * InvLevelScale4x4[j0][i0])<<qp_per_uv[uv], 4); + img->fcf[uv + 1][(j<<2) + j0][(i<<2) + i0] = level; } } //for(k=0;(k<16)&&(level!=0);k++) } @@ -4031,16 +4163,14 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) { for (b8=0; b8 < img->num_blk8x8_uv; b8++) { - int uvc = (b8 > ((img->num_uv_blocks) - 1 )); - - img->is_v_block = uv = uvc; + img->is_v_block = uv = (b8 > ((img->num_uv_blocks) - 1 )); for (b4=0; b4 < 4; b4++) { i = cofuv_blk_x[yuv][b8][b4]; j = cofuv_blk_y[yuv][b8][b4]; - coef_ctr=0; + pos_scan_4x4 = pos_scan4x4[1]; level=1; img->subblock_y = subblk_offset_y[yuv][b8][b4]>>2; @@ -4057,12 +4187,13 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) if (level != 0) { currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4]; - coef_ctr += (currSE.value2 + 1); - - i0=pos_scan4x4[coef_ctr][0]; - j0=pos_scan4x4[coef_ctr][1]; + pos_scan_4x4 += (currSE.value2 << 1); + + i0 = *pos_scan_4x4++; + j0 = *pos_scan_4x4++; img->cof[uv + 1][(j<<2) + j0][(i<<2) + i0] = level; + img->fcf[uv + 1][(j<<2) + j0][(i<<2) + i0] = level; } } } @@ -4084,48 +4215,60 @@ void readCBPandCoeffsFromNAL(Macroblock *currMB, ImageParameters *img) ************************************************************************ */ -void decode_ipcm_mb(Macroblock *currMB, ImageParameters *img) +void decode_ipcm_mb(ImageParameters *img, Macroblock *currMB) { - int i,j; + int i, j, k; int mb_nr = img->current_mb_nr; //Copy coefficients to decoded picture buffer //IPCM coefficients are stored in img->cof which is set in function readIPCMcoeffsFromNAL() - for(i=0;i<16;i++) - for(j=0;j<16;j++) + for(i = 0; i < MB_BLOCK_SIZE; i++) + { + for(j = 0;j < MB_BLOCK_SIZE ; j++) + { dec_picture->imgY[img->pix_y+i][img->pix_x+j] = (imgpel) img->cof[0][i][j]; + } + } if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(img)) { - for(i=0;i<img->mb_cr_size_y;i++) - for(j=0;j<img->mb_cr_size_x;j++) - dec_picture->imgUV[0][img->pix_c_y+i][img->pix_c_x+j] = (imgpel) img->cof[1][i][j]; - - for(i=0;i<img->mb_cr_size_y;i++) - for(j=0;j<img->mb_cr_size_x;j++) - dec_picture->imgUV[1][img->pix_c_y+i][img->pix_c_x+j] = (imgpel) img->cof[2][i][j]; + for (k = 0; k < 2; k++) + { + for(i = 0; i < img->mb_cr_size_y; i++) + { + for(j = 0;j < img->mb_cr_size_x; j++) + { + dec_picture->imgUV[k][img->pix_c_y+i][img->pix_c_x+j] = (imgpel) img->cof[k + 1][i][j]; + } + } + } } // for deblocking filter - currMB->qp=0; - set_chroma_qp(currMB); + update_qp(img, currMB, 0); // for CAVLC: Set the nz_coeff to 16. - // These parameters are to be used in CAVLC decoding of neighbour blocks - for(i=0;i<4;i++) - for (j=0;j<(4 + img->num_blk8x8_uv);j++) - img->nz_coeff[mb_nr][i][j]=16; - + // These parameters are to be used in CAVLC decoding of neighbour blocks + for (k = 0; k < 3; k++) + { + for (j = 0; j < BLOCK_SIZE; j++) + { + for(i = 0; i < BLOCK_SIZE; i++) + { + img->nz_coeff[mb_nr][k][j][i] = 16; + } + } + } // for CABAC decoding of MB skip flag currMB->skip_flag = 0; //for deblocking filter CABAC - currMB->cbp_blk=0xFFFF; + currMB->cbp_blk = 0xFFFF; //For CABAC decoding of Dquant - last_dquant=0; + last_dquant = 0; } /*! @@ -4135,93 +4278,86 @@ void decode_ipcm_mb(Macroblock *currMB, ImageParameters *img) ************************************************************************ */ -int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) +int decode_one_macroblock(ImageParameters *img, Macroblock *currMB, StorablePicture *dec_picture) { int i=0,j=0,k,l,ii=0,jj=0, j4=0,i4=0, j6; int refList; int uv, hv; int ioff,joff; int block8x8; // needed for ABT - int j_pos, i_pos; - + int j_pos, i_pos; + static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; int mb_nr = img->current_mb_nr; - + short ref_idx; int mv_mode, pred_dir; // = currMB->ref_frame; - - int block_size_x, block_size_y; - + + int block_size_x, block_size_y; + int mv_scale; static imgpel **curComp; static imgpel (*mpr) [16]; static imgpel *cur_line; static int *cur_m7; - + int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB); int list_offset; - + char l0_rFrame = -1, l1_rFrame = -1; - + short pmvl0[2]={0,0}, pmvl1[2]={0,0}; - + int direct_pdir=-1; - + int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field)); - - static byte ** moving_block; - static short **** co_located_mv; - static char *** co_located_ref_idx; - static int64 *** co_located_ref_id; - + + static MotionParams *colocated; + int need_4x4_transform = (!currMB->luma_transform_size_8x8_flag); int yuv = dec_picture->chroma_format_idc - 1; //For residual DPCM Boolean lossless_qpprime = (Boolean) (((img->qp + img->bitdepth_luma_qp_scale) == 0) && (img->lossless_qpprime_flag == 1)); ipmode_DPCM = NO_INTRA_PMODE; - - if(img->type==SP_SLICE && currMB->mb_type!=I16MB) - smb = 1;// modif ES added - + + if (img->structure != FRAME || (img->MbaffFrameFlag && currMB->mb_field)) + img->max_mb_vmv_r = img->max_vmv_r >> 1; + else + img->max_mb_vmv_r = img->max_vmv_r; + if(currMB->mb_type == IPCM) { //copy readed data into imgY and set parameters - decode_ipcm_mb(currMB, img); + decode_ipcm_mb(img, currMB); return 0; } - + + if (img->type==SP_SLICE && currMB->mb_type!=I16MB) + smb = 1;// modif ES added + ////////////////////////// - + // find out the correct list offsets if (curr_mb_field) { if(mb_nr&0x01) { list_offset = 4; // top field mb - moving_block = Co_located->bottom_moving_block; - co_located_mv = Co_located->bottom_mv; - co_located_ref_idx = Co_located->bottom_ref_idx; - co_located_ref_id = Co_located->bottom_ref_pic_id; + colocated = &Co_located->bottom; } else { list_offset = 2; // bottom field mb - moving_block = Co_located->top_moving_block; - co_located_mv = Co_located->top_mv; - co_located_ref_idx = Co_located->top_ref_idx; - co_located_ref_id = Co_located->top_ref_pic_id; + colocated = &Co_located->top; } } else { list_offset = 0; // no mb aff or frame mb - moving_block = Co_located->moving_block; - co_located_mv = Co_located->mv; - co_located_ref_idx = Co_located->ref_idx; - co_located_ref_id = Co_located->ref_pic_id; + colocated = &Co_located->frame; } - + if (!img->MbaffFrameFlag) { for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++) @@ -4263,18 +4399,18 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) } } } - + // luma decoding ************************************************** - + // get prediction for INTRA_MB_16x16 if (IS_NEWINTRA (currMB)) { - intrapred_luma_16x16(currMB, PLANE_Y, img, currMB->i16mode); + intrapred_luma_16x16(img, currMB, PLANE_Y, currMB->i16mode); ipmode_DPCM = currMB->i16mode; //For residual DPCM // =============== 4x4 itrans ================ // ------------------------------------------- iMBtrans4x4(PLANE_Y, img, smb); - + // chroma decoding ******************************************************* if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) { @@ -4291,25 +4427,25 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) { i = (decode_block_scan[k] & 3); j = ((decode_block_scan[k] >> 2) & 3); - + ioff = (i << 2); joff = (j << 2); i4 = img->block_x + i; j4 = img->block_y + j; j_pos = j4 * BLOCK_SIZE; i_pos = i4 * BLOCK_SIZE; - + // PREDICTION //===== INTRA PREDICTION ===== - if (intrapred(currMB, PLANE_Y, img,ioff,joff,i4,j4) == SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */ + if (intrapred(img, currMB, PLANE_Y, ioff,joff,i4,j4) == SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */ return SEARCH_SYNC; /* bit error */ // =============== 4x4 itrans ================ // ------------------------------------------- - itrans_4x4 ((ColorPlane) LumaComp, img, ioff, joff); // use DCT transform and make 4x4 block m7 from prediction block mpr - + itrans_4x4 (img, (ColorPlane) LumaComp, ioff, joff); // use DCT transform and make 4x4 block m7 from prediction block mpr + for(jj=0;jj<BLOCK_SIZE;jj++) { - cur_m7 = &img->m7[0][jj + joff][ioff]; + cur_m7 = &img->mb_rres[0][jj + joff][ioff]; cur_line = &dec_picture->imgY[j_pos + jj][i_pos]; for(ii=0;ii<BLOCK_SIZE;ii++) { @@ -4318,7 +4454,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) } } } - + // chroma decoding ******************************************************* if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444)) { @@ -4334,15 +4470,15 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) //=========== 8x8 BLOCK TYPE ============ ioff = 8 * (block8x8 & 0x01); joff = 8 * (block8x8 >> 1); - + //PREDICTION - intrapred8x8(PLANE_Y, img, currMB, block8x8); + intrapred8x8(img, currMB, PLANE_Y, block8x8); + + itrans_8x8(img, currMB, PLANE_Y, ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr - itrans_8x8(PLANE_Y, img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr - for(jj = joff; jj < joff + 8;jj++) { - cur_m7 = &img->m7[0][jj][ioff]; + cur_m7 = &img->mb_rres[0][jj][ioff]; cur_line = &dec_picture->imgY[img->pix_y + jj][img->pix_x + ioff]; for(ii = 0; ii < 8; ii++) @@ -4363,11 +4499,11 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) block_size_y = MB_BLOCK_SIZE; i = 0; j = 0; - + pred_dir = LIST_0; perform_mc(PLANE_Y, dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); - - mpr = img->mpr[LumaComp]; + + mpr = img->mb_pred[LumaComp]; curComp = &dec_picture->imgY[img->pix_y]; for(j = 0; j < img->mb_size[0][1]; j++) { @@ -4379,8 +4515,8 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) for(uv=0;uv<2;uv++) { curComp = &dec_picture->imgUV[uv][img->pix_c_y]; - - mpr = img->mpr[uv + 1]; + + mpr = img->mb_pred[uv + 1]; for(jj = 0; jj < img->mb_size[1][1]; jj++) memcpy(&(curComp[jj][img->pix_c_x]), &(mpr[jj][0]), img->mb_size[1][0] * sizeof(imgpel)); } @@ -4392,32 +4528,32 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) block_size_y = MB_BLOCK_SIZE; i = 0; j = 0; - + pred_dir = currMB->b8pdir[0]; perform_mc(PLANE_Y, dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); - iTransform(currMB, PLANE_Y, img, need_4x4_transform, smb); + iTransform(img, currMB, PLANE_Y, need_4x4_transform, smb); } else if (currMB->mb_type == P16x8) { block_size_x = MB_BLOCK_SIZE; block_size_y = 8; - + for (block8x8 = 0; block8x8 < 4; block8x8 += 2) { i = 0; j = block8x8; - + pred_dir = currMB->b8pdir[block8x8]; perform_mc(PLANE_Y, dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); } - iTransform(currMB, PLANE_Y, img, need_4x4_transform, smb); + iTransform(img, currMB, PLANE_Y, need_4x4_transform, smb); } else if (currMB->mb_type == P8x16) { - + block_size_x = 8; block_size_y = 16; - + for (block8x8 = 0; block8x8 < 2; block8x8 ++) { i = block8x8<<1; @@ -4426,7 +4562,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) assert (pred_dir<=2); perform_mc(PLANE_Y, dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); } - iTransform(currMB, PLANE_Y, img, need_4x4_transform, smb); + iTransform(img, currMB, PLANE_Y, need_4x4_transform, smb); } else { @@ -4434,7 +4570,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) if (img->type==B_SLICE && img->direct_spatial_mv_pred_flag && (IS_DIRECT (currMB) || (IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3])))) prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame); - + for (block8x8=0; block8x8<4; block8x8++) { mv_mode = currMB->b8mode[block8x8]; @@ -4499,73 +4635,73 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) if (l0_rFrame >=0) { - if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) + if (!l0_rFrame && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) { - dec_picture->mv [LIST_0][j4][i4][0] = 0; - dec_picture->mv [LIST_0][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; } else { - dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0]; - dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1]; - dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame; + dec_picture->motion.mv [LIST_0][j4][i4][0] = pmvl0[0]; + dec_picture->motion.mv [LIST_0][j4][i4][1] = pmvl0[1]; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = l0_rFrame; } } else { - dec_picture->ref_idx[LIST_0][j4][i4] = -1; - dec_picture->mv [LIST_0][j4][i4][0] = 0; - dec_picture->mv [LIST_0][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = -1; + dec_picture->motion.mv [LIST_0][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][1] = 0; } if (l1_rFrame >=0) { - if (l1_rFrame==0 && ((!moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) + if (l1_rFrame==0 && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) { - dec_picture->mv [LIST_1][j4][i4][0] = 0; - dec_picture->mv [LIST_1][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame; + dec_picture->motion.mv [LIST_1][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_1][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = l1_rFrame; } else { - dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0]; - dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1]; - dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame; + dec_picture->motion.mv [LIST_1][j4][i4][0] = pmvl1[0]; + dec_picture->motion.mv [LIST_1][j4][i4][1] = pmvl1[1]; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = l1_rFrame; } } else { - dec_picture->mv [LIST_1][j4][i4][0] = 0; - dec_picture->mv [LIST_1][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = -1; + dec_picture->motion.mv [LIST_1][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_1][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = -1; } if (l0_rFrame < 0 && l1_rFrame < 0) { - dec_picture->ref_idx[LIST_0][j4][i4] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; } - if (dec_picture->ref_idx[LIST_1][j4][i4]==-1) + if (dec_picture->motion.ref_idx[LIST_1][j4][i4]==-1) { direct_pdir = 0; - ref_idx = (dec_picture->ref_idx[LIST_0][j4][i4] != -1) ? dec_picture->ref_idx[LIST_0][j4][i4] : 0; + ref_idx = (dec_picture->motion.ref_idx[LIST_0][j4][i4] != -1) ? dec_picture->motion.ref_idx[LIST_0][j4][i4] : 0; } - else if (dec_picture->ref_idx[LIST_0][j4][i4]==-1) + else if (dec_picture->motion.ref_idx[LIST_0][j4][i4]==-1) { direct_pdir = 1; - ref_idx = (dec_picture->ref_idx[LIST_1][j4][i4] != -1) ? dec_picture->ref_idx[LIST_1][j4][i4] : 0; + ref_idx = (dec_picture->motion.ref_idx[LIST_1][j4][i4] != -1) ? dec_picture->motion.ref_idx[LIST_1][j4][i4] : 0; } else direct_pdir = 2; pred_dir = direct_pdir; - dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]]; - dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]]; + dec_picture->motion.ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->motion.ref_idx[LIST_0][j4][i4]]; + dec_picture->motion.ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->motion.ref_idx[LIST_1][j4][i4]]; } } else @@ -4586,16 +4722,16 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) j6 = img->block_y_aff + j; - refList = (co_located_ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0); - ref_idx = co_located_ref_idx[refList][j6][i4]; + refList = (colocated->ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0); + ref_idx = colocated->ref_idx[refList][j6][i4]; if(ref_idx==-1) // co-located is intra mode { - memset( &dec_picture->mv [LIST_0][j4][i4][0], 0, 2* sizeof(short)); - memset( &dec_picture->mv [LIST_1][j4][i4][0], 0, 2* sizeof(short)); + memset( &dec_picture->motion.mv [LIST_0][j4][i4][0], 0, 2* sizeof(short)); + memset( &dec_picture->motion.mv [LIST_1][j4][i4][0], 0, 2* sizeof(short)); - dec_picture->ref_idx[LIST_0][j4][i4] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; } else // co-located skip or inter mode { @@ -4607,9 +4743,9 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) if(img->structure==0 && curr_mb_field==0) { // If the current MB is a frame MB and the colocated is from a field picture, - // then the co_located_ref_id may have been generated from the wrong value of + // then the colocated->ref_pic_id may have been generated from the wrong value of // frame_poc if it references it's complementary field, so test both POC values - if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][j6][i4]) + if(listX[0][iref]->top_poc*2 == colocated->ref_pic_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == colocated->ref_pic_id[refList][j6][i4]) { mapped_idx=iref; break; @@ -4619,7 +4755,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) continue; } - if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][j6][i4]) + if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==colocated->ref_pic_id[refList][j6][i4]) { mapped_idx=iref; break; @@ -4639,24 +4775,24 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) //! In such case, an array is needed for each different reference. if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term) { - memcpy(&dec_picture->mv [LIST_0][j4][i4][0], &co_located_mv[refList][j6][i4][0], 2 * sizeof(short)); - memset(&dec_picture->mv [LIST_1][j4][i4][0], 0, 2 * sizeof(short)); + memcpy(&dec_picture->motion.mv [LIST_0][j4][i4][0], &colocated->mv[refList][j6][i4][0], 2 * sizeof(short)); + memset(&dec_picture->motion.mv [LIST_1][j4][i4][0], 0, 2 * sizeof(short)); } else { - dec_picture->mv [LIST_0][j4][i4][0]=(mv_scale * co_located_mv[refList][j6][i4][0] + 128 ) >> 8; - dec_picture->mv [LIST_0][j4][i4][1]=(mv_scale * co_located_mv[refList][j6][i4][1] + 128 ) >> 8; + dec_picture->motion.mv [LIST_0][j4][i4][0]=(mv_scale * colocated->mv[refList][j6][i4][0] + 128 ) >> 8; + dec_picture->motion.mv [LIST_0][j4][i4][1]=(mv_scale * colocated->mv[refList][j6][i4][1] + 128 ) >> 8; - dec_picture->mv [LIST_1][j4][i4][0]=dec_picture->mv[LIST_0][j4][i4][0] - co_located_mv[refList][j6][i4][0] ; - dec_picture->mv [LIST_1][j4][i4][1]=dec_picture->mv[LIST_0][j4][i4][1] - co_located_mv[refList][j6][i4][1] ; + dec_picture->motion.mv [LIST_1][j4][i4][0]=dec_picture->motion.mv[LIST_0][j4][i4][0] - colocated->mv[refList][j6][i4][0] ; + dec_picture->motion.mv [LIST_1][j4][i4][1]=dec_picture->motion.mv[LIST_0][j4][i4][1] - colocated->mv[refList][j6][i4][1] ; } - dec_picture->ref_idx[LIST_0][j4][i4] = (char) mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4]; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = (char) mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4]; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; } // store reference picture ID determined by direct mode - dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]]; - dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]]; + dec_picture->motion.ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->motion.ref_idx[LIST_0][j4][i4]]; + dec_picture->motion.ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->motion.ref_idx[LIST_1][j4][i4]]; } } @@ -4668,15 +4804,15 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) } } } - - iTransform(currMB, PLANE_Y, img, need_4x4_transform, smb); + + iTransform(img, currMB, PLANE_Y, need_4x4_transform, smb); } - + if ((active_sps->chroma_format_idc==YUV444)&&(!IS_INDEPENDENT(img))) { for (uv = 0; uv < 2; uv++ ) { - + if (IS_NEWINTRA (currMB)) { @@ -4684,13 +4820,13 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) // ------------------------------------------- if (uv==0) { - intrapred_luma_16x16(currMB, PLANE_U, img, currMB->i16mode); + intrapred_luma_16x16(img, currMB, PLANE_U, currMB->i16mode); iMBtrans4x4(PLANE_U, img, smb); } else - + { - intrapred_luma_16x16(currMB, PLANE_V, img, currMB->i16mode); + intrapred_luma_16x16(img, currMB, PLANE_V, currMB->i16mode); iMBtrans4x4(PLANE_V, img, smb); } } @@ -4710,22 +4846,22 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) j4 = img->block_y + j; j_pos = j4 * BLOCK_SIZE; i_pos = i4 * BLOCK_SIZE; - + // PREDICTION //===== INTRA PREDICTION ===== - if (intrapred(currMB, (ColorPlane) (uv + 1), img, ioff, joff, i4,j4)==SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */ + if (intrapred(img, currMB, (ColorPlane) (uv + 1), ioff, joff, i4,j4)==SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */ return SEARCH_SYNC; /* bit error */ // =============== 4x4 itrans ================ // ------------------------------------------- - itrans_4x4 ((ColorPlane) (uv + 1), img, ioff, joff); - + itrans_4x4 (img, (ColorPlane) (uv + 1), ioff, joff); + for(jj=0;jj<BLOCK_SIZE;jj++) { for(ii=0;ii<BLOCK_SIZE;ii++) { - dec_picture->imgUV[uv][j_pos + jj][i_pos + ii] = (imgpel) img->m7[uv+1][jj + joff][ii + ioff]; // construct picture from 4x4 blocks + dec_picture->imgUV[uv][j_pos + jj][i_pos + ii] = (imgpel) img->mb_rres[uv+1][jj + joff][ii + ioff]; // construct picture from 4x4 blocks } } } @@ -4740,40 +4876,40 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) //=========== 8x8 BLOCK TYPE ============ ioff = 8 * (block8x8 & 0x01); joff = 8 * (block8x8 >> 1); - + //PREDICTION - intrapred8x8((ColorPlane) (uv + 1), img, currMB, block8x8); + intrapred8x8(img, currMB, (ColorPlane) (uv + 1), block8x8); //For residual DPCM - itrans_8x8((ColorPlane) (uv + 1), img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr + itrans_8x8(img, currMB, (ColorPlane) (uv + 1), ioff, joff); // use DCT transform and make 8x8 block m7 from prediction block mpr for(jj = joff; jj < joff + 8;jj++) { for(ii = ioff; ii < ioff + 8;ii++) { - dec_picture->imgUV[uv][img->pix_y + jj][img->pix_x + ii] = (imgpel) img->m7[uv+1][jj][ii]; // construct picture from 4x4 blocks + dec_picture->imgUV[uv][img->pix_y + jj][img->pix_x + ii] = (imgpel) img->mb_rres[uv+1][jj][ii]; // construct picture from 4x4 blocks } } } } //I8MB - + else if ((img->type == P_SLICE) && (currMB->mb_type == PSKIP)) { block_size_x = MB_BLOCK_SIZE; block_size_y = MB_BLOCK_SIZE; i = 0; j = 0; - + pred_dir = LIST_0; perform_mc((ColorPlane) (uv + 1), dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); - mpr = img->mpr[uv+1]; + mpr = img->mb_pred[uv+1]; curComp = dec_picture->imgUV[uv]; - + for(j = 0; j < img->mb_size[0][1]; j++) { memcpy(&(curComp[img->pix_y + j][img->pix_x]), &(mpr[j][0]), img->mb_size[0][0] * sizeof(imgpel)); } } //PSKIP - + else if (currMB->mb_type == P16x16) { block_size_x = MB_BLOCK_SIZE; @@ -4783,32 +4919,32 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) pred_dir = currMB->b8pdir[0]; perform_mc((ColorPlane) (uv + 1), dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); - iTransform(currMB, (ColorPlane) (uv + 1), img, need_4x4_transform, smb); + iTransform(img, currMB, (ColorPlane) (uv + 1), need_4x4_transform, smb); } //P16x16 - + else if (currMB->mb_type == P16x8) { block_size_x = MB_BLOCK_SIZE; block_size_y = 8; - + for (block8x8 = 0; block8x8 < 4; block8x8 += 2) { i = 0; j = block8x8; - + pred_dir = currMB->b8pdir[block8x8]; perform_mc((ColorPlane) (uv + 1), dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); } - iTransform(currMB, (ColorPlane) (uv + 1), img, need_4x4_transform, smb); + iTransform(img, currMB, (ColorPlane) (uv + 1), need_4x4_transform, smb); } //P16x8 else if (currMB->mb_type == P8x16) { - + block_size_x = 8; block_size_y = 16; - + for (block8x8 = 0; block8x8 < 2; block8x8 ++) { i = block8x8<<1; @@ -4818,7 +4954,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) perform_mc((ColorPlane) (uv + 1), dec_picture, img, pred_dir, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); } - iTransform(currMB, (ColorPlane) (uv + 1), img, need_4x4_transform, smb); + iTransform(img, currMB, (ColorPlane) (uv + 1), need_4x4_transform, smb); } //P8x16 else { @@ -4826,22 +4962,22 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) if (img->type==B_SLICE && img->direct_spatial_mv_pred_flag && (IS_DIRECT (currMB) || (IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3])))) prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame); - + for (block8x8=0; block8x8<4; block8x8++) { mv_mode = currMB->b8mode[block8x8]; pred_dir = currMB->b8pdir[block8x8]; - + //if ( mv_mode == SMB8x8 || mv_mode == SMB8x4 || mv_mode == SMB4x8 || mv_mode == SMB4x4 ) if ( mv_mode != 0 ) { int k_start = (block8x8 << 2); int k_inc = (mv_mode == SMB8x4) ? 2 : 1; int k_end = (mv_mode == SMB8x8) ? k_start + 1 : ((mv_mode == SMB4x4) ? k_start + 4 : k_start + k_inc + 1); - + block_size_x = ( mv_mode == SMB8x4 || mv_mode == SMB8x8 ) ? SMB_BLOCK_SIZE : BLOCK_SIZE; block_size_y = ( mv_mode == SMB4x8 || mv_mode == SMB8x8 ) ? SMB_BLOCK_SIZE : BLOCK_SIZE; - + for (k = k_start; k < k_end; k += k_inc) { i = (decode_block_scan[k] & 3); @@ -4854,7 +4990,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) { int k_start = (block8x8 << 2); int k_end = k_start; - + if (active_sps->direct_8x8_inference_flag) { block_size_x = SMB_BLOCK_SIZE; @@ -4867,127 +5003,127 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) block_size_y = BLOCK_SIZE; k_end += BLOCK_MULTIPLE; } - + // Prepare mvs (needed for deblocking and mv prediction for (k = k_start; k < k_start + BLOCK_MULTIPLE; k ++) { - + i = (decode_block_scan[k] & 3); j = ((decode_block_scan[k] >> 2) & 3); - + ioff = (i << 2); i4 = img->block_x + i; - + joff = (j << 2); j4 = img->block_y + j; - + assert (pred_dir<=2); - + if (img->direct_spatial_mv_pred_flag) { j6 = img->block_y_aff + j; - + //===== DIRECT PREDICTION ===== if (l0_rFrame >=0) { - if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) + if (!l0_rFrame && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) { - dec_picture->mv [LIST_0][j4][i4][0] = 0; - dec_picture->mv [LIST_0][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; } else { - dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0]; - dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1]; - dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame; + dec_picture->motion.mv [LIST_0][j4][i4][0] = pmvl0[0]; + dec_picture->motion.mv [LIST_0][j4][i4][1] = pmvl0[1]; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = l0_rFrame; } } else { - dec_picture->ref_idx[LIST_0][j4][i4] = -1; - dec_picture->mv [LIST_0][j4][i4][0] = 0; - dec_picture->mv [LIST_0][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = -1; + dec_picture->motion.mv [LIST_0][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_0][j4][i4][1] = 0; } - + if (l1_rFrame >=0) { - if (l1_rFrame==0 && ((!moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) + if (l1_rFrame==0 && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term))) { - - dec_picture->mv [LIST_1][j4][i4][0] = 0; - dec_picture->mv [LIST_1][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame; - + + dec_picture->motion.mv [LIST_1][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_1][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = l1_rFrame; + } else { - dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0]; - dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1]; - dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame; + dec_picture->motion.mv [LIST_1][j4][i4][0] = pmvl1[0]; + dec_picture->motion.mv [LIST_1][j4][i4][1] = pmvl1[1]; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = l1_rFrame; } } else { - dec_picture->mv [LIST_1][j4][i4][0] = 0; - dec_picture->mv [LIST_1][j4][i4][1] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = -1; + dec_picture->motion.mv [LIST_1][j4][i4][0] = 0; + dec_picture->motion.mv [LIST_1][j4][i4][1] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = -1; } - + if (l0_rFrame < 0 && l1_rFrame < 0) { - dec_picture->ref_idx[LIST_0][j4][i4] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; } - - if (dec_picture->ref_idx[LIST_1][j4][i4]==-1) + + if (dec_picture->motion.ref_idx[LIST_1][j4][i4]==-1) { direct_pdir = 0; - ref_idx = (dec_picture->ref_idx[LIST_0][j4][i4] != -1) ? dec_picture->ref_idx[LIST_0][j4][i4] : 0; + ref_idx = (dec_picture->motion.ref_idx[LIST_0][j4][i4] != -1) ? dec_picture->motion.ref_idx[LIST_0][j4][i4] : 0; } - else if (dec_picture->ref_idx[LIST_0][j4][i4]==-1) + else if (dec_picture->motion.ref_idx[LIST_0][j4][i4]==-1) { direct_pdir = 1; - ref_idx = (dec_picture->ref_idx[LIST_1][j4][i4] != -1) ? dec_picture->ref_idx[LIST_1][j4][i4] : 0; + ref_idx = (dec_picture->motion.ref_idx[LIST_1][j4][i4] != -1) ? dec_picture->motion.ref_idx[LIST_1][j4][i4] : 0; } else direct_pdir = 2; - + pred_dir = direct_pdir; - + } else { j6= img->block_y_aff + j; - - refList = (co_located_ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0); - ref_idx = co_located_ref_idx[refList][j6][i4]; - + + refList = (colocated->ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0); + ref_idx = colocated->ref_idx[refList][j6][i4]; + if(ref_idx==-1) // co-located is intra mode { for(hv=0; hv<2; hv++) { - dec_picture->mv [LIST_0][j4][i4][hv]=0; - dec_picture->mv [LIST_1][j4][i4][hv]=0; + dec_picture->motion.mv [LIST_0][j4][i4][hv]=0; + dec_picture->motion.mv [LIST_1][j4][i4][hv]=0; } - - dec_picture->ref_idx[LIST_0][j4][i4] = 0; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + + dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; } else // co-located skip or inter mode { int mapped_idx=0; int iref; - + { for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++) { if(img->structure==0 && curr_mb_field==0) { // If the current MB is a frame MB and the colocated is from a field picture, - // then the co_located_ref_id may have been generated from the wrong value of + // then the colocated->ref_pic_id may have been generated from the wrong value of // frame_poc if it references it's complementary field, so test both POC values - if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][j6][i4]) + if(listX[0][iref]->top_poc*2 == colocated->ref_pic_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == colocated->ref_pic_id[refList][j6][i4]) { mapped_idx=iref; break; @@ -4996,8 +5132,8 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) mapped_idx=INVALIDINDEX; continue; } - - if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][j6][i4]) + + if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==colocated->ref_pic_id[refList][j6][i4]) { mapped_idx=iref; break; @@ -5012,39 +5148,39 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) error("temporal direct error\ncolocated block has ref that is unavailable",-1111); } } - + mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx]; - + //! In such case, an array is needed for each different reference. if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term) { - dec_picture->mv [LIST_0][j4][i4][0]=co_located_mv[refList][j6][i4][0]; - dec_picture->mv [LIST_0][j4][i4][1]=co_located_mv[refList][j6][i4][1]; - - dec_picture->mv [LIST_1][j4][i4][0]=0; - dec_picture->mv [LIST_1][j4][i4][1]=0; + dec_picture->motion.mv [LIST_0][j4][i4][0]=colocated->mv[refList][j6][i4][0]; + dec_picture->motion.mv [LIST_0][j4][i4][1]=colocated->mv[refList][j6][i4][1]; + + dec_picture->motion.mv [LIST_1][j4][i4][0]=0; + dec_picture->motion.mv [LIST_1][j4][i4][1]=0; } else { - dec_picture->mv [LIST_0][j4][i4][0] = (short) ((mv_scale * co_located_mv[refList][j6][i4][0] + 128 ) >> 8); - dec_picture->mv [LIST_0][j4][i4][1] = (short) ((mv_scale * co_located_mv[refList][j6][i4][1] + 128 ) >> 8); - - dec_picture->mv [LIST_1][j4][i4][0] = (short) (dec_picture->mv[LIST_0][j4][i4][0] - co_located_mv[refList][j6][i4][0]); - dec_picture->mv [LIST_1][j4][i4][1] = (short) (dec_picture->mv[LIST_0][j4][i4][1] - co_located_mv[refList][j6][i4][1]); + dec_picture->motion.mv [LIST_0][j4][i4][0] = (short) ((mv_scale * colocated->mv[refList][j6][i4][0] + 128 ) >> 8); + dec_picture->motion.mv [LIST_0][j4][i4][1] = (short) ((mv_scale * colocated->mv[refList][j6][i4][1] + 128 ) >> 8); + + dec_picture->motion.mv [LIST_1][j4][i4][0] = (short) (dec_picture->motion.mv[LIST_0][j4][i4][0] - colocated->mv[refList][j6][i4][0]); + dec_picture->motion.mv [LIST_1][j4][i4][1] = (short) (dec_picture->motion.mv[LIST_0][j4][i4][1] - colocated->mv[refList][j6][i4][1]); } - - dec_picture->ref_idx[LIST_0][j4][i4] = (char) mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4]; - dec_picture->ref_idx[LIST_1][j4][i4] = 0; + + dec_picture->motion.ref_idx[LIST_0][j4][i4] = (char) mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4]; + dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0; } } // store reference picture ID determined by direct mode - dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]]; - dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]]; + dec_picture->motion.ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->motion.ref_idx[LIST_0][j4][i4]]; + dec_picture->motion.ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->motion.ref_idx[LIST_1][j4][i4]]; } - + for (k = k_start; k < k_end; k ++) { - + i = (decode_block_scan[k] & 3); j = ((decode_block_scan[k] >> 2) & 3); @@ -5052,7 +5188,7 @@ int decode_one_macroblock(Macroblock *currMB, ImageParameters *img) } } } - iTransform(currMB, (ColorPlane) (uv + 1), img, need_4x4_transform, smb); + iTransform(img, currMB, (ColorPlane) (uv + 1), need_4x4_transform, smb); } } } @@ -5092,10 +5228,12 @@ void make_frame_picture_JV() // Copy Storable Params for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - copy_storable_param_JV( nplane, dec_picture, dec_picture_JV[nplane] ); + copy_storable_param_JV( &dec_picture->JVmotion[nplane], &dec_picture_JV[nplane]->motion ); } - for( uv=0; uv<2; uv++ ){ + // This could be done with pointers and seems not necessary + for( uv=0; uv<2; uv++ ) + { for( line=0; line<img->height; line++ ) { nsize = sizeof(imgpel) * img->width; diff --git a/ldecod/src/mb_access.c b/ldecod/src/mb_access.c index da1815d..eb9f4c4 100644 --- a/ldecod/src/mb_access.c +++ b/ldecod/src/mb_access.c @@ -133,8 +133,8 @@ void get_mb_pos (int mb_addr, int mb_size[2], int *x, int*y) * input x position * \param yN * input y position - * \param is_chroma - * 0 if luma coding, 1 for chroma + * \param mb_size + * Macroblock size in pixel (according to luma or chroma MB access) * \param pix * returns position informations ************************************************************************ @@ -206,8 +206,8 @@ void getNonAffNeighbour(Macroblock *currMb, int xN, int yN, int mb_size[2], Pixe * input x position * \param yN * input y position - * \param is_chroma - * 0 if luma coding, 1 for chroma + * \param mb_size + * Macroblock size in pixel (according to luma or chroma MB access) * \param pix * returns position informations ************************************************************************ diff --git a/ldecod/src/mbuffer.c b/ldecod/src/mbuffer.c index 927a8ab..dcc9a8e 100644 --- a/ldecod/src/mbuffer.c +++ b/ldecod/src/mbuffer.c @@ -65,6 +65,7 @@ void dump_dpb(void) { #if DUMP_DPB unsigned i; + for (i=0; i<dpb.used_size;i++) { printf("("); @@ -121,10 +122,10 @@ int getDpbSize(void) size = 152064; break; case 11: - if (!IS_FREXT_PROFILE(active_sps->profile_idc)&&(active_sps->constrained_set3_flag == 0)) - size = 345600; - else + if (!IS_FREXT_PROFILE(active_sps->profile_idc) && (active_sps->constrained_set3_flag == 1)) size = 152064; + else + size = 345600; break; case 12: size = 912384; @@ -156,12 +157,9 @@ int getDpbSize(void) case 41: size = 12582912; break; - case 42: - if( IS_FREXT_PROFILE(active_sps->profile_idc) ) - size = 13369344; - else - size = 12582912; - break; + case 42: + size = 13369344; + break; case 50: size = 42393600; break; @@ -364,6 +362,20 @@ FrameStore* alloc_frame_store(void) return f; } +void alloc_pic_motion(PicMotionParams *motion, int size_y, int size_x) +{ + get_mem3Dint64 (&(motion->ref_pic_id), 6, size_y, size_x); + get_mem3Dint64 (&(motion->ref_id), 6, size_y, size_x); + get_mem4Dshort (&(motion->mv), 2, size_y, size_x, 2); + get_mem3D ((byte****)(&(motion->ref_idx)), 2, size_y , size_x); + + motion->mb_field = calloc (size_y * size_x, sizeof(int)); + if (motion->mb_field == NULL) + no_mem_exit("alloc_storable_picture: motion->mb_field"); + + get_mem2D (&(motion->field_frame), size_y, size_x); +} + /*! ************************************************************************ * \brief @@ -408,32 +420,18 @@ StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, if (active_sps->chroma_format_idc != YUV400) get_mem3Dpel (&(s->imgUV), 2, size_y_cr, size_x_cr); - - s->mb_field = calloc (s->PicSizeInMbs, sizeof(int)); - if (NULL==s->mb_field) - no_mem_exit("alloc_storable_picture: s->mb_field"); - get_mem2Dshort (&(s->slice_id), size_y / MB_BLOCK_SIZE, size_x / MB_BLOCK_SIZE); - get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_pic_id), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_id) , 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2); + alloc_pic_motion(&s->motion, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); if( IS_INDEPENDENT(img) ) { for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - get_mem3D ((byte****)(&(s->ref_idx_JV[nplane])), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_pic_id_JV[nplane]), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_id_JV[nplane]), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->mv_JV[nplane]), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2); + alloc_pic_motion(&s->JVmotion[nplane], size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); } } - get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - s->pic_num=0; s->frame_num=0; s->long_term_frame_idx=0; @@ -503,6 +501,45 @@ void free_frame_store(FrameStore* f) } } +void free_pic_motion(PicMotionParams *motion) +{ + if (motion->ref_pic_id) + { + free_mem3Dint64 (motion->ref_pic_id); + motion->ref_pic_id = NULL; + } + if (motion->ref_id) + { + free_mem3Dint64 (motion->ref_id); + motion->ref_id = NULL; + } + + if (motion->mv) + { + free_mem4Dshort (motion->mv); + motion->mv = NULL; + } + + if (motion->ref_idx) + { + free_mem3D ((byte***)motion->ref_idx); + motion->ref_idx = NULL; + } + + if (motion->mb_field) + { + free(motion->mb_field); + motion->mb_field = NULL; + } + + if (motion->field_frame) + { + free_mem2D (motion->field_frame); + motion->field_frame=NULL; + } +} + + /*! ************************************************************************ * \brief @@ -518,69 +555,16 @@ void free_storable_picture(StorablePicture* p) int nplane; if (p) { - if (p->ref_idx) - { - free_mem3D ((byte***)p->ref_idx); - p->ref_idx = NULL; - } - - if (p->ref_pic_id) - { - free_mem3Dint64 (p->ref_pic_id); - p->ref_pic_id = NULL; - } - - if (p->ref_id) - { - free_mem3Dint64 (p->ref_id); - p->ref_id = NULL; - } - - if (p->mv) - { - free_mem4Dshort (p->mv); - p->mv = NULL; - } + free_pic_motion(&p->motion); if( IS_INDEPENDENT(img) ) { for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - if (p->ref_idx_JV[nplane]) - { - free_mem3D ((byte***)p->ref_idx_JV[nplane]); - p->ref_idx_JV[nplane] = NULL; - } - if (p->ref_pic_id_JV[nplane]) - { - free_mem3Dint64 (p->ref_pic_id_JV[nplane]); - p->ref_pic_id_JV[nplane] = NULL; - } - if (p->ref_id_JV[nplane]) - { - free_mem3Dint64 (p->ref_id_JV[nplane]); - p->ref_id_JV[nplane] = NULL; - } - if (p->mv_JV[nplane]) - { - free_mem4Dshort (p->mv_JV[nplane]); - p->mv_JV[nplane] = NULL; - } + free_pic_motion(&p->JVmotion[nplane]); } } - if (p->moving_block) - { - free_mem2D (p->moving_block); - p->moving_block=NULL; - } - - if (p->field_frame) - { - free_mem2D (p->field_frame); - p->field_frame=NULL; - } - if (p->imgY) { free_mem2Dpel (p->imgY); @@ -593,12 +577,6 @@ void free_storable_picture(StorablePicture* p) p->imgUV=NULL; } - if (p->mb_field) - { - free(p->mb_field); - p->mb_field=NULL; - } - if (p->slice_id) { free_mem2Dshort(p->slice_id); @@ -651,46 +629,18 @@ static void unmark_for_reference(FrameStore* fs) if(fs->frame) { - if (fs->frame->ref_pic_id) - { - free_mem3Dint64 (fs->frame->ref_pic_id); - fs->frame->ref_pic_id = NULL; - } - if (fs->frame->ref_id) - { - free_mem3Dint64 (fs->frame->ref_id); - fs->frame->ref_id = NULL; - } + free_pic_motion(&fs->frame->motion); } if (fs->top_field) { - if (fs->top_field->ref_pic_id) - { - free_mem3Dint64 (fs->top_field->ref_pic_id); - fs->top_field->ref_pic_id = NULL; - } - if (fs->top_field->ref_id) - { - free_mem3Dint64 (fs->top_field->ref_id); - fs->top_field->ref_id = NULL; - } - + free_pic_motion(&fs->top_field->motion); } + if (fs->bottom_field) { - if (fs->bottom_field->ref_pic_id) - { - free_mem3Dint64 (fs->bottom_field->ref_pic_id); - fs->bottom_field->ref_pic_id = NULL; - } - if (fs->bottom_field->ref_id) - { - free_mem3Dint64 (fs->bottom_field->ref_id); - fs->bottom_field->ref_id = NULL; - } + free_pic_motion(&fs->bottom_field->motion); } - } @@ -1044,7 +994,7 @@ void init_lists(int currSliceType, PictureStructure currPicStructure) } } // update long_term_pic_num - for (i=0; i<dpb.ltref_frames_in_buffer; i++) + for (i = 0; i < dpb.ltref_frames_in_buffer; i++) { if (dpb.fs_ltref[i]->is_used==3) { @@ -1435,7 +1385,7 @@ static StorablePicture* get_short_term_pic(int picNum) return dpb.fs_ref[i]->bottom_field; } } -// return NULL; + return no_reference_picture; } @@ -2892,12 +2842,12 @@ void gen_field_ref_ids(StorablePicture *p) { for (j=0 ; j<p->size_y/4 ; j++) { - dummylist0= p->ref_idx[LIST_0][j][i]; - dummylist1= p->ref_idx[LIST_1][j][i]; + dummylist0= p->motion.ref_idx[LIST_0][j][i]; + dummylist1= p->motion.ref_idx[LIST_1][j][i]; //! association with id already known for fields. - p->ref_id[LIST_0][j][i] = (dummylist0>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; - p->ref_id[LIST_1][j][i] = (dummylist1>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; - p->field_frame[j][i]=1; + p->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; + p->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; + p->motion.field_frame[j][i]=1; } } } @@ -3001,25 +2951,25 @@ void dpb_split_field(FrameStore *fs) idiv = (i >> 2); currentmb = twosz16*(jdiv >> 1)+ (idiv)*2 + (jdiv & 0x01); - if (fs->frame->MbaffFrameFlag && fs->frame->mb_field[currentmb]) + if (fs->frame->MbaffFrameFlag && fs->frame->motion.mb_field[currentmb]) { int list_offset = currentmb%2? 4: 2; - dummylist0 = fs->frame->ref_idx[LIST_0][j][i]; - dummylist1 = fs->frame->ref_idx[LIST_1][j][i]; + dummylist0 = fs->frame->motion.ref_idx[LIST_0][j][i]; + dummylist1 = fs->frame->motion.ref_idx[LIST_1][j][i]; //! association with id already known for fields. - fs->frame->ref_id[LIST_0 + list_offset][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0; - fs->frame->ref_id[LIST_1 + list_offset][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0; + fs->frame->motion.ref_id[LIST_0 + list_offset][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0; + fs->frame->motion.ref_id[LIST_1 + list_offset][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0; //! need to make association with frames - fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0; - fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0; + fs->frame->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0; + fs->frame->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0; } else { - dummylist0 = fs->frame->ref_idx[LIST_0][j][i]; - dummylist1 = fs->frame->ref_idx[LIST_1][j][i]; - fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0][dummylist0] : -1; - fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1][dummylist1] : -1; + dummylist0 = fs->frame->motion.ref_idx[LIST_0][j][i]; + dummylist1 = fs->frame->motion.ref_idx[LIST_1][j][i]; + fs->frame->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0][dummylist0] : -1; + fs->frame->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1][dummylist1] : -1; } } } @@ -3037,29 +2987,29 @@ void dpb_split_field(FrameStore *fs) currentmb = twosz16*(jdiv >> 1)+ (idiv)*2 + (jdiv & 0x01); // Assign field mvs attached to MB-Frame buffer to the proper buffer - if (fs->frame->mb_field[currentmb]) + if (fs->frame->motion.mb_field[currentmb]) { - fs->bottom_field->field_frame[j][i] = fs->top_field->field_frame[j][i]=1; - fs->frame->field_frame[2*j][i] = fs->frame->field_frame[2*j+1][i]=1; - - fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj4][i][0]; - fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj4][i][1]; - fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj4][i][0]; - fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj4][i][1]; - fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj4][i]; - fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj4][i]; - fs->bottom_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+4][jj4][i]; - fs->bottom_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+4][jj4][i]; - - - fs->top_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][i][0]; - fs->top_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][i][1]; - fs->top_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][i][0]; - fs->top_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][i][1]; - fs->top_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][i]; - fs->top_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][i]; - fs->top_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+2][jj][i]; - fs->top_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+2][jj][i]; + fs->bottom_field->motion.field_frame[j][i] = fs->top_field->motion.field_frame[j][i]=1; + fs->frame->motion.field_frame[2*j][i] = fs->frame->motion.field_frame[2*j+1][i]=1; + + fs->bottom_field->motion.mv[LIST_0][j][i][0] = fs->frame->motion.mv[LIST_0][jj4][i][0]; + fs->bottom_field->motion.mv[LIST_0][j][i][1] = fs->frame->motion.mv[LIST_0][jj4][i][1]; + fs->bottom_field->motion.mv[LIST_1][j][i][0] = fs->frame->motion.mv[LIST_1][jj4][i][0]; + fs->bottom_field->motion.mv[LIST_1][j][i][1] = fs->frame->motion.mv[LIST_1][jj4][i][1]; + fs->bottom_field->motion.ref_idx[LIST_0][j][i] = fs->frame->motion.ref_idx[LIST_0][jj4][i]; + fs->bottom_field->motion.ref_idx[LIST_1][j][i] = fs->frame->motion.ref_idx[LIST_1][jj4][i]; + fs->bottom_field->motion.ref_id[LIST_0][j][i] = fs->frame->motion.ref_id[LIST_0+4][jj4][i]; + fs->bottom_field->motion.ref_id[LIST_1][j][i] = fs->frame->motion.ref_id[LIST_1+4][jj4][i]; + + + fs->top_field->motion.mv[LIST_0][j][i][0] = fs->frame->motion.mv[LIST_0][jj][i][0]; + fs->top_field->motion.mv[LIST_0][j][i][1] = fs->frame->motion.mv[LIST_0][jj][i][1]; + fs->top_field->motion.mv[LIST_1][j][i][0] = fs->frame->motion.mv[LIST_1][jj][i][0]; + fs->top_field->motion.mv[LIST_1][j][i][1] = fs->frame->motion.mv[LIST_1][jj][i][1]; + fs->top_field->motion.ref_idx[LIST_0][j][i] = fs->frame->motion.ref_idx[LIST_0][jj][i]; + fs->top_field->motion.ref_idx[LIST_1][j][i] = fs->frame->motion.ref_idx[LIST_1][jj][i]; + fs->top_field->motion.ref_id[LIST_0][j][i] = fs->frame->motion.ref_id[LIST_0+2][jj][i]; + fs->top_field->motion.ref_id[LIST_1][j][i] = fs->frame->motion.ref_id[LIST_1+2][jj][i]; } } } @@ -3079,47 +3029,47 @@ void dpb_split_field(FrameStore *fs) currentmb = twosz16 * (jdiv >> 1)+ (idiv)*2 + (jdiv & 0x01); - if (!fs->frame->MbaffFrameFlag || !fs->frame->mb_field[currentmb]) + if (!fs->frame->MbaffFrameFlag || !fs->frame->motion.mb_field[currentmb]) { - fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]=0; + fs->frame->motion.field_frame[2*j+1][i] = fs->frame->motion.field_frame[2*j][i]=0; - fs->top_field->field_frame[j][i] = fs->bottom_field->field_frame[j][i] = 0; + fs->top_field->motion.field_frame[j][i] = fs->bottom_field->motion.field_frame[j][i] = 0; - fs->top_field->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][ii][0]; - fs->top_field->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][ii][1]; - fs->top_field->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][ii][0]; - fs->top_field->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][ii][1]; + fs->top_field->motion.mv[LIST_0][j][i][0] = fs->bottom_field->motion.mv[LIST_0][j][i][0] = fs->frame->motion.mv[LIST_0][jj][ii][0]; + fs->top_field->motion.mv[LIST_0][j][i][1] = fs->bottom_field->motion.mv[LIST_0][j][i][1] = fs->frame->motion.mv[LIST_0][jj][ii][1]; + fs->top_field->motion.mv[LIST_1][j][i][0] = fs->bottom_field->motion.mv[LIST_1][j][i][0] = fs->frame->motion.mv[LIST_1][jj][ii][0]; + fs->top_field->motion.mv[LIST_1][j][i][1] = fs->bottom_field->motion.mv[LIST_1][j][i][1] = fs->frame->motion.mv[LIST_1][jj][ii][1]; // Scaling of references is done here since it will not affect spatial direct (2*0 =0) - if (fs->frame->ref_idx[LIST_0][jj][ii] == -1) - fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = - 1; + if (fs->frame->motion.ref_idx[LIST_0][jj][ii] == -1) + fs->top_field->motion.ref_idx[LIST_0][j][i] = fs->bottom_field->motion.ref_idx[LIST_0][j][i] = - 1; else { - dummylist0=fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][ii] ; - fs->top_field ->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0; - fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0; + dummylist0=fs->top_field->motion.ref_idx[LIST_0][j][i] = fs->bottom_field->motion.ref_idx[LIST_0][j][i] = fs->frame->motion.ref_idx[LIST_0][jj][ii] ; + fs->top_field ->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0; + fs->bottom_field->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0; } - if (fs->frame->ref_idx[LIST_1][jj][ii] == -1) - fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = - 1; + if (fs->frame->motion.ref_idx[LIST_1][jj][ii] == -1) + fs->top_field->motion.ref_idx[LIST_1][j][i] = fs->bottom_field->motion.ref_idx[LIST_1][j][i] = - 1; else { - dummylist1=fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][ii]; + dummylist1=fs->top_field->motion.ref_idx[LIST_1][j][i] = fs->bottom_field->motion.ref_idx[LIST_1][j][i] = fs->frame->motion.ref_idx[LIST_1][jj][ii]; - fs->top_field ->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0; - fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0; + fs->top_field ->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0; + fs->bottom_field->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0; } } else { - fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]= fs->frame->mb_field[currentmb]; + fs->frame->motion.field_frame[2*j+1][i] = fs->frame->motion.field_frame[2*j][i]= fs->frame->motion.mb_field[currentmb]; } } } } else { - memset( &(fs->frame->field_frame[0][0]), 0, (fs->frame->size_y * fs->frame->size_x >> 4) * sizeof(byte)); + memset( &(fs->frame->motion.field_frame[0][0]), 0, (fs->frame->size_y * fs->frame->size_x >> 4) * sizeof(byte)); } } @@ -3220,41 +3170,41 @@ void dpb_combine_field(FrameStore *fs) jj4 = jj + 4; for (i=0 ; i< (fs->top_field->size_x >> 2) ; i++) { - fs->frame->field_frame[jj][i]= fs->frame->field_frame[jj4][i]=1; + fs->frame->motion.field_frame[jj][i]= fs->frame->motion.field_frame[jj4][i]=1; - fs->frame->mv[LIST_0][jj][i][0] = fs->top_field->mv[LIST_0][j][i][0]; - fs->frame->mv[LIST_0][jj][i][1] = fs->top_field->mv[LIST_0][j][i][1]; - fs->frame->mv[LIST_1][jj][i][0] = fs->top_field->mv[LIST_1][j][i][0]; - fs->frame->mv[LIST_1][jj][i][1] = fs->top_field->mv[LIST_1][j][i][1]; + fs->frame->motion.mv[LIST_0][jj][i][0] = fs->top_field->motion.mv[LIST_0][j][i][0]; + fs->frame->motion.mv[LIST_0][jj][i][1] = fs->top_field->motion.mv[LIST_0][j][i][1]; + fs->frame->motion.mv[LIST_1][jj][i][0] = fs->top_field->motion.mv[LIST_1][j][i][0]; + fs->frame->motion.mv[LIST_1][jj][i][1] = fs->top_field->motion.mv[LIST_1][j][i][1]; - dummylist0=fs->frame->ref_idx[LIST_0][jj][i] = fs->top_field->ref_idx[LIST_0][j][i]; - dummylist1=fs->frame->ref_idx[LIST_1][jj][i] = fs->top_field->ref_idx[LIST_1][j][i]; + dummylist0=fs->frame->motion.ref_idx[LIST_0][jj][i] = fs->top_field->motion.ref_idx[LIST_0][j][i]; + dummylist1=fs->frame->motion.ref_idx[LIST_1][jj][i] = fs->top_field->motion.ref_idx[LIST_1][j][i]; //! association with id already known for fields. - fs->top_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; - fs->top_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; + fs->top_field->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; + fs->top_field->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; //! need to make association with frames - fs->frame->ref_id[LIST_0][jj][i] = (dummylist0>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; - fs->frame->ref_id[LIST_1][jj][i] = (dummylist1>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; + fs->frame->motion.ref_id[LIST_0][jj][i] = (dummylist0>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; + fs->frame->motion.ref_id[LIST_1][jj][i] = (dummylist1>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; - fs->frame->mv[LIST_0][jj4][i][0] = fs->bottom_field->mv[LIST_0][j][i][0]; - fs->frame->mv[LIST_0][jj4][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] ; - fs->frame->mv[LIST_1][jj4][i][0] = fs->bottom_field->mv[LIST_1][j][i][0]; - fs->frame->mv[LIST_1][jj4][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] ; + fs->frame->motion.mv[LIST_0][jj4][i][0] = fs->bottom_field->motion.mv[LIST_0][j][i][0]; + fs->frame->motion.mv[LIST_0][jj4][i][1] = fs->bottom_field->motion.mv[LIST_0][j][i][1] ; + fs->frame->motion.mv[LIST_1][jj4][i][0] = fs->bottom_field->motion.mv[LIST_1][j][i][0]; + fs->frame->motion.mv[LIST_1][jj4][i][1] = fs->bottom_field->motion.mv[LIST_1][j][i][1] ; - dummylist0=fs->frame->ref_idx[LIST_0][jj4][i] = fs->bottom_field->ref_idx[LIST_0][j][i]; - dummylist1=fs->frame->ref_idx[LIST_1][jj4][i] = fs->bottom_field->ref_idx[LIST_1][j][i]; + dummylist0=fs->frame->motion.ref_idx[LIST_0][jj4][i] = fs->bottom_field->motion.ref_idx[LIST_0][j][i]; + dummylist1=fs->frame->motion.ref_idx[LIST_1][jj4][i] = fs->bottom_field->motion.ref_idx[LIST_1][j][i]; - fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; - fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; + fs->bottom_field->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0; + fs->bottom_field->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0; //! need to make association with frames - fs->frame->ref_id[LIST_0][jj4][i] = (dummylist0>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : -1; - fs->frame->ref_id[LIST_1][jj4][i] = (dummylist1>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : -1; + fs->frame->motion.ref_id[LIST_0][jj4][i] = (dummylist0>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : -1; + fs->frame->motion.ref_id[LIST_1][jj4][i] = (dummylist1>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : -1; - fs->top_field->field_frame[j][i]=1; - fs->bottom_field->field_frame[j][i]=1; + fs->top_field->motion.field_frame[j][i]=1; + fs->bottom_field->motion.field_frame[j][i]=1; } } } @@ -3392,6 +3342,21 @@ void fill_frame_num_gap(ImageParameters *img) } +/*! + ************************************************************************ + * \brief + * Allocate motion parameter memory for colocated structure + * + ************************************************************************ + */ +void alloc_motion_params(MotionParams *ftype, int size_y, int size_x) +{ + get_mem3Dint64 (&(ftype->ref_pic_id), 2, size_y, size_x); + get_mem4Dshort (&(ftype->mv) , 2, size_y, size_x, 2); + get_mem3D ((byte****)(&(ftype->ref_idx)) , 2, size_y, size_x); + get_mem2D (&(ftype->moving_block) , size_y, size_x); +} + /*! ************************************************************************ * \brief @@ -3419,25 +3384,12 @@ ColocatedParams* alloc_colocated(int size_x, int size_y, int mb_adaptive_frame_f s->size_x = size_x; s->size_y = size_y; - - get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_pic_id), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2); - - get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); + alloc_motion_params(&s->frame, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); if (mb_adaptive_frame_field_flag) { - get_mem3D ((byte****)(&(s->top_ref_idx)) , 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->top_ref_pic_id), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->top_mv), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE, 2); - get_mem2D (&(s->top_moving_block), size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); - - get_mem3D ((byte****)(&(s->bottom_ref_idx)), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->bottom_ref_pic_id), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->bottom_mv), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE, 2); - get_mem2D (&(s->bottom_moving_block), size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); + alloc_motion_params(&s->top , size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); + alloc_motion_params(&s->bottom, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); } s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag; @@ -3459,43 +3411,38 @@ void free_colocated(ColocatedParams* p) { if (p) { - free_mem3D ((byte***)p->ref_idx); - free_mem3Dint64 (p->ref_pic_id); - free_mem4Dshort (p->mv); + free_mem3D ((byte***)p->frame.ref_idx); + free_mem3Dint64 (p->frame.ref_pic_id); + free_mem4Dshort (p->frame.mv); - if (p->moving_block) - { - free_mem2D (p->moving_block); - p->moving_block=NULL; - } - if (p->field_frame) + if (p->frame.moving_block) { - free_mem2D (p->field_frame); - p->field_frame=NULL; + free_mem2D (p->frame.moving_block); + p->frame.moving_block=NULL; } if (p->mb_adaptive_frame_field_flag) { - free_mem3D ((byte***)p->top_ref_idx); - free_mem3Dint64 (p->top_ref_pic_id); - free_mem4Dshort (p->top_mv); + free_mem3D ((byte***)p->top.ref_idx); + free_mem3Dint64 (p->top.ref_pic_id); + free_mem4Dshort (p->top.mv); - if (p->top_moving_block) + if (p->top.moving_block) { - free_mem2D (p->top_moving_block); - p->top_moving_block=NULL; + free_mem2D (p->top.moving_block); + p->top.moving_block=NULL; } - free_mem3D ((byte***)p->bottom_ref_idx); - free_mem3Dint64 (p->bottom_ref_pic_id); - free_mem4Dshort (p->bottom_mv); + free_mem3D ((byte***)p->bottom.ref_idx); + free_mem3Dint64 (p->bottom.ref_pic_id); + free_mem4Dshort (p->bottom.mv); - if (p->bottom_moving_block) + if (p->bottom.moving_block) { - free_mem2D (p->bottom_moving_block); - p->bottom_moving_block=NULL; + free_mem2D (p->bottom.moving_block); + p->bottom.moving_block=NULL; } } @@ -3554,7 +3501,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i < fs_size_x4 ; i++) { - if (img->MbaffFrameFlag && fs->field_frame[j][i]) + if (img->MbaffFrameFlag && fs->motion.field_frame[j][i]) { //! Assign frame buffers for field MBs //! Check whether we should use top or bottom field mvs. @@ -3562,41 +3509,41 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) if (iabs(dec_picture->poc - fs_bottom->poc)> iabs(dec_picture->poc -fs_top->poc) ) { - p->mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i]; + p->frame.mv[LIST_0][j][i][0] = fs_top->motion.mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs_top->motion.mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs_top->motion.mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs_top->motion.mv[LIST_1][jdiv][i][1] ; + p->frame.ref_idx[LIST_0][j][i] = fs_top->motion.ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs_top->motion.ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj][i]; p->is_long_term = fs_top->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i]; + p->frame.mv[LIST_0][j][i][0] = fs_bottom->motion.mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs_bottom->motion.mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs_bottom->motion.mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs_bottom->motion.mv[LIST_1][jdiv][i][1] ; + p->frame.ref_idx[LIST_0][j][i] = fs_bottom->motion.ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs_bottom->motion.ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj + 4][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs_bottom->is_long_term; } } else { - p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][j][i][1] ; - p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][j][i][1] ; - p->ref_idx[LIST_0][j][i] = fs->ref_idx[LIST_0][j][i]; - p->ref_idx[LIST_1][j][i] = fs->ref_idx[LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i]; + p->frame.mv[LIST_0][j][i][0] = fs->motion.mv[LIST_0][j][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->motion.mv[LIST_0][j][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs->motion.mv[LIST_1][j][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->motion.mv[LIST_1][j][i][1] ; + p->frame.ref_idx[LIST_0][j][i] = fs->motion.ref_idx[LIST_0][j][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->motion.ref_idx[LIST_1][j][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][j][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][j][i]; p->is_long_term = fs->is_long_term; } @@ -3617,102 +3564,102 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) //! Do nothing if macroblock as field coded in MB-AFF if (!img->MbaffFrameFlag ) { - p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][jj][ii][1]; + p->frame.mv[LIST_0][j][i][0] = fs->motion.mv[LIST_0][jj][ii][0]; + p->frame.mv[LIST_0][j][i][1] = fs->motion.mv[LIST_0][jj][ii][1]; + p->frame.mv[LIST_1][j][i][0] = fs->motion.mv[LIST_1][jj][ii][0]; + p->frame.mv[LIST_1][j][i][1] = fs->motion.mv[LIST_1][jj][ii][1]; // Scaling of references is done here since it will not affect spatial direct (2*0 =0) - if (fs->ref_idx[LIST_0][jj][ii] == -1) + if (fs->motion.ref_idx[LIST_0][jj][ii] == -1) { - p->ref_idx [LIST_0][j][i] = -1; - p->ref_pic_id[LIST_0][j][i] = -1; + p->frame.ref_idx [LIST_0][j][i] = -1; + p->frame.ref_pic_id[LIST_0][j][i] = -1; } else { - p->ref_idx [LIST_0][j][i] = fs->ref_idx[LIST_0][jj][ii] ; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id [LIST_0][jj][ii]; + p->frame.ref_idx [LIST_0][j][i] = fs->motion.ref_idx[LIST_0][jj][ii] ; + p->frame.ref_pic_id[LIST_0][j][i] = fs->motion.ref_id [LIST_0][jj][ii]; } - if (fs->ref_idx[LIST_1][jj][ii] == -1) + if (fs->motion.ref_idx[LIST_1][jj][ii] == -1) { - p->ref_idx [LIST_1][j][i] = -1; - p->ref_pic_id[LIST_1][j][i] = -1; + p->frame.ref_idx [LIST_1][j][i] = -1; + p->frame.ref_pic_id[LIST_1][j][i] = -1; } else { - p->ref_idx [LIST_1][j][i] = fs->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id [LIST_1][jj][ii]; + p->frame.ref_idx [LIST_1][j][i] = fs->motion.ref_idx[LIST_1][jj][ii]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->motion.ref_id [LIST_1][jj][ii]; } p->is_long_term = fs->is_long_term; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i] = + p->frame.moving_block[j][i] = !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->frame.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->frame.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->frame.ref_idx[LIST_0][j][i] == -1) + && (p->frame.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->frame.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_1][j][i][1])>>1 == 0))); } } else { - p->bottom_mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jj][ii][0]; - p->bottom_mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jj][ii][1]; - p->bottom_mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jj][ii][0]; - p->bottom_mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jj][ii][1]; - p->bottom_ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jj][ii]; - p->bottom_ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jj][ii]; - p->bottom_ref_pic_id[LIST_0][j][i] = fs_bottom->ref_id[LIST_0][jj][ii]; - p->bottom_ref_pic_id[LIST_1][j][i] = fs_bottom->ref_id[LIST_1][jj][ii]; + p->bottom.mv[LIST_0][j][i][0] = fs_bottom->motion.mv[LIST_0][jj][ii][0]; + p->bottom.mv[LIST_0][j][i][1] = fs_bottom->motion.mv[LIST_0][jj][ii][1]; + p->bottom.mv[LIST_1][j][i][0] = fs_bottom->motion.mv[LIST_1][jj][ii][0]; + p->bottom.mv[LIST_1][j][i][1] = fs_bottom->motion.mv[LIST_1][jj][ii][1]; + p->bottom.ref_idx[LIST_0][j][i] = fs_bottom->motion.ref_idx[LIST_0][jj][ii]; + p->bottom.ref_idx[LIST_1][j][i] = fs_bottom->motion.ref_idx[LIST_1][jj][ii]; + p->bottom.ref_pic_id[LIST_0][j][i] = fs_bottom->motion.ref_id[LIST_0][jj][ii]; + p->bottom.ref_pic_id[LIST_1][j][i] = fs_bottom->motion.ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->bottom_moving_block[j][i] = + p->bottom.moving_block[j][i] = !((!fs_bottom->is_long_term - && ((p->bottom_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->bottom_ref_idx[LIST_0][j][i] == -1) - && (p->bottom_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->bottom.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->bottom.ref_idx[LIST_0][j][i] == -1) + && (p->bottom.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][1])>>1 == 0))); } - p->top_mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jj][ii][0]; - p->top_mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jj][ii][1]; - p->top_mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jj][ii][0]; - p->top_mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jj][ii][1]; - p->top_ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jj][ii]; - p->top_ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jj][ii]; - p->top_ref_pic_id[LIST_0][j][i] = fs_top->ref_id[LIST_0][jj][ii]; - p->top_ref_pic_id[LIST_1][j][i] = fs_top->ref_id[LIST_1][jj][ii]; + p->top.mv[LIST_0][j][i][0] = fs_top->motion.mv[LIST_0][jj][ii][0]; + p->top.mv[LIST_0][j][i][1] = fs_top->motion.mv[LIST_0][jj][ii][1]; + p->top.mv[LIST_1][j][i][0] = fs_top->motion.mv[LIST_1][jj][ii][0]; + p->top.mv[LIST_1][j][i][1] = fs_top->motion.mv[LIST_1][jj][ii][1]; + p->top.ref_idx[LIST_0][j][i] = fs_top->motion.ref_idx[LIST_0][jj][ii]; + p->top.ref_idx[LIST_1][j][i] = fs_top->motion.ref_idx[LIST_1][jj][ii]; + p->top.ref_pic_id[LIST_0][j][i] = fs_top->motion.ref_id[LIST_0][jj][ii]; + p->top.ref_pic_id[LIST_1][j][i] = fs_top->motion.ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->top_moving_block[j][i] = + p->top.moving_block[j][i] = !((!fs_top->is_long_term - && ((p->top_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->top_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->top_ref_idx[LIST_0][j][i] == -1) - && (p->top_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->top_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->top.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->top.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->top.ref_idx[LIST_0][j][i] == -1) + && (p->top.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->top.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_1][j][i][1])>>1 == 0))); } - if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->field_frame[2*j][i]) + if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->motion.field_frame[2*j][i]) { - p->top_mv[LIST_0][j][i][1] /= 2; - p->top_mv[LIST_1][j][i][1] /= 2; - p->bottom_mv[LIST_0][j][i][1] /= 2; - p->bottom_mv[LIST_1][j][i][1] /= 2; + p->top.mv[LIST_0][j][i][1] /= 2; + p->top.mv[LIST_1][j][i][1] /= 2; + p->bottom.mv[LIST_0][j][i][1] /= 2; + p->bottom.mv[LIST_1][j][i][1] /= 2; } } @@ -3735,32 +3682,32 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) for (i = 0 ; i < fs_size_x4; i++) { - if (fs->field_frame[j][i]) + if (fs->motion.field_frame[j][i]) { if (iabs(dec_picture->poc - fs->bottom_field->poc) > iabs(dec_picture->poc - fs->top_field->poc)) { - p->mv[LIST_0][j][i][0] = fs->top_field->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->top_field->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->top_field->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->top_field->mv[LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->top_field->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->top_field->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i]; + p->frame.mv[LIST_0][j][i][0] = fs->top_field->motion.mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->top_field->motion.mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs->top_field->motion.mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->top_field->motion.mv[LIST_1][jdiv][i][1] ; + + p->frame.ref_idx[LIST_0][j][i] = fs->top_field->motion.ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->top_field->motion.ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj][i]; p->is_long_term = fs->top_field->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i]; + p->frame.mv[LIST_0][j][i][0] = fs->bottom_field->motion.mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->bottom_field->motion.mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs->bottom_field->motion.mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->bottom_field->motion.mv[LIST_1][jdiv][i][1] ; + + p->frame.ref_idx[LIST_0][j][i] = fs->bottom_field->motion.ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->bottom_field->motion.ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj + 4][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs->bottom_field->is_long_term; } } @@ -3783,25 +3730,25 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); - p->mv[LIST_0][j][i][0]=p->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1]=p->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0]=p->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1]=p->mv[LIST_1][jj][ii][1]; + p->frame.mv[LIST_0][j][i][0]=p->frame.mv[LIST_0][jj][ii][0]; + p->frame.mv[LIST_0][j][i][1]=p->frame.mv[LIST_0][jj][ii][1]; + p->frame.mv[LIST_1][j][i][0]=p->frame.mv[LIST_1][jj][ii][0]; + p->frame.mv[LIST_1][j][i][1]=p->frame.mv[LIST_1][jj][ii][1]; - p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii]; - p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii]; + p->frame.ref_idx[LIST_0][j][i]=p->frame.ref_idx[LIST_0][jj][ii]; + p->frame.ref_idx[LIST_1][j][i]=p->frame.ref_idx[LIST_1][jj][ii]; + p->frame.ref_pic_id[LIST_0][j][i] = p->frame.ref_pic_id[LIST_0][jj][ii]; + p->frame.ref_pic_id[LIST_1][j][i] = p->frame.ref_pic_id[LIST_1][jj][ii]; - p->moving_block[j][i]= + p->frame.moving_block[j][i]= !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->frame.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->frame.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->frame.ref_idx[LIST_0][j][i] == -1) + && (p->frame.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->frame.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_1][j][i][1])>>1 == 0))); } } } @@ -3814,15 +3761,15 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); - p->mv[LIST_0][j][i][0]=p->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1]=p->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0]=p->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1]=p->mv[LIST_1][jj][ii][1]; + p->frame.mv[LIST_0][j][i][0]=p->frame.mv[LIST_0][jj][ii][0]; + p->frame.mv[LIST_0][j][i][1]=p->frame.mv[LIST_0][jj][ii][1]; + p->frame.mv[LIST_1][j][i][0]=p->frame.mv[LIST_1][jj][ii][0]; + p->frame.mv[LIST_1][j][i][1]=p->frame.mv[LIST_1][jj][ii][1]; - p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii]; - p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii]; + p->frame.ref_idx[LIST_0][j][i]=p->frame.ref_idx[LIST_0][jj][ii]; + p->frame.ref_idx[LIST_1][j][i]=p->frame.ref_idx[LIST_1][jj][ii]; + p->frame.ref_pic_id[LIST_0][j][i] = p->frame.ref_pic_id[LIST_0][jj][ii]; + p->frame.ref_pic_id[LIST_1][j][i] = p->frame.ref_pic_id[LIST_1][jj][ii]; } } } @@ -3833,24 +3780,24 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { for (j=0 ; j < fs_size_y4; j++) { - memcpy(&p->mv[LIST_0][j][0][0], &fs->mv[LIST_0][j][0][0], 2 * fs_size_x4 * sizeof(short)); - memcpy(&p->mv[LIST_1][j][0][0], &fs->mv[LIST_1][j][0][0], 2 * fs_size_x4 * sizeof(short)); - memcpy(p->ref_idx[LIST_0][j], fs->ref_idx[LIST_0][j], fs_size_x4 * sizeof(char)); - memcpy(p->ref_idx[LIST_1][j], fs->ref_idx[LIST_1][j], fs_size_x4 * sizeof(char)); - memcpy(p->ref_pic_id[LIST_0][j], fs->ref_id[LIST_0][j], fs_size_x4 * sizeof(int64)); - memcpy(p->ref_pic_id[LIST_1][j], fs->ref_id[LIST_1][j], fs_size_x4 * sizeof(int64)); + memcpy(&p->frame.mv[LIST_0][j][0][0], &fs->motion.mv[LIST_0][j][0][0], 2 * fs_size_x4 * sizeof(short)); + memcpy(&p->frame.mv[LIST_1][j][0][0], &fs->motion.mv[LIST_1][j][0][0], 2 * fs_size_x4 * sizeof(short)); + memcpy(p->frame.ref_idx[LIST_0][j], fs->motion.ref_idx[LIST_0][j], fs_size_x4 * sizeof(char)); + memcpy(p->frame.ref_idx[LIST_1][j], fs->motion.ref_idx[LIST_1][j], fs_size_x4 * sizeof(char)); + memcpy(p->frame.ref_pic_id[LIST_0][j], fs->motion.ref_id[LIST_0][j], fs_size_x4 * sizeof(int64)); + memcpy(p->frame.ref_pic_id[LIST_1][j], fs->motion.ref_id[LIST_1][j], fs_size_x4 * sizeof(int64)); for (i=0 ; i < fs_size_x4; i++) { - p->moving_block[j][i]= + p->frame.moving_block[j][i]= !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->frame.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->frame.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->frame.ref_idx[LIST_0][j][i] == -1) + && (p->frame.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->frame.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_1][j][i][1])>>1 == 0))); } } } @@ -3858,12 +3805,12 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { for (j=0 ; j < fs_size_y4; j++) { - memcpy(&p->mv[LIST_0][j][0][0], &fs->mv[LIST_0][j][0][0], 2 * fs_size_x4 * sizeof(short)); - memcpy(&p->mv[LIST_1][j][0][0], &fs->mv[LIST_1][j][0][0], 2 * fs_size_x4 * sizeof(short)); - memcpy(p->ref_idx[LIST_0][j], fs->ref_idx[LIST_0][j], fs_size_x4 * sizeof(char)); - memcpy(p->ref_idx[LIST_1][j], fs->ref_idx[LIST_1][j], fs_size_x4 * sizeof(char)); - memcpy(p->ref_pic_id[LIST_0][j], fs->ref_id[LIST_0][j], fs_size_x4 * sizeof(int64)); - memcpy(p->ref_pic_id[LIST_1][j], fs->ref_id[LIST_1][j], fs_size_x4 * sizeof(int64)); + memcpy(&p->frame.mv[LIST_0][j][0][0], &fs->motion.mv[LIST_0][j][0][0], 2 * fs_size_x4 * sizeof(short)); + memcpy(&p->frame.mv[LIST_1][j][0][0], &fs->motion.mv[LIST_1][j][0][0], 2 * fs_size_x4 * sizeof(short)); + memcpy(p->frame.ref_idx[LIST_0][j], fs->motion.ref_idx[LIST_0][j], fs_size_x4 * sizeof(char)); + memcpy(p->frame.ref_idx[LIST_1][j], fs->motion.ref_idx[LIST_1][j], fs_size_x4 * sizeof(char)); + memcpy(p->frame.ref_pic_id[LIST_0][j], fs->motion.ref_id[LIST_0][j], fs_size_x4 * sizeof(int64)); + memcpy(p->frame.ref_pic_id[LIST_1][j], fs->motion.ref_id[LIST_1][j], fs_size_x4 * sizeof(int64)); } } } @@ -3876,10 +3823,10 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { for (i=0 ; i < fs_size_x4 ; i++) { - if (fs->field_frame[j][i]) + if (fs->motion.field_frame[j][i]) { - p->mv[LIST_0][j][i][1] *= 2; - p->mv[LIST_1][j][i][1] *= 2; + p->frame.mv[LIST_0][j][i][1] *= 2; + p->frame.mv[LIST_1][j][i][1] *= 2; } } } @@ -3890,10 +3837,10 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { for (i=0 ; i < fs_size_x4 ; i++) { - if (!fs->field_frame[j][i]) + if (!fs->motion.field_frame[j][i]) { - p->mv[LIST_0][j][i][1] /= 2; - p->mv[LIST_1][j][i][1] /= 2; + p->frame.mv[LIST_0][j][i][1] /= 2; + p->frame.mv[LIST_1][j][i][1] /= 2; } } } @@ -3949,7 +3896,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) int i,j, ii, jj, jdiv; int np = img->colour_plane_id; - fs_top=fs_bottom=fs = listX[LIST_1 ][0]; + fs_top = fs_bottom = fs = listX[LIST_1 ][0]; if (img->MbaffFrameFlag) { @@ -3983,7 +3930,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i<fs->size_x/4 ; i++) { - if (img->MbaffFrameFlag && fs->field_frame[j][i]) + if (img->MbaffFrameFlag && fs->motion.field_frame[j][i]) { //! Assign frame buffers for field MBs //! Check whether we should use top or bottom field mvs. @@ -3991,41 +3938,41 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) if (iabs(dec_picture->poc - fs_bottom->poc)> iabs(dec_picture->poc -fs_top->poc) ) { - p->mv[LIST_0][j][i][0] = fs_top->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_top->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_top->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_top->mv_JV[np][LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_top->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_top->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj][i]; + p->frame.mv[LIST_0][j][i][0] = fs_top->JVmotion[np].mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs_top->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs_top->JVmotion[np].mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs_top->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + p->frame.ref_idx[LIST_0][j][i] = fs_top->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs_top->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj][i]; p->is_long_term = fs_top->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs_bottom->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_bottom->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_bottom->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_bottom->mv_JV[np][LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_bottom->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_bottom->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj + 4][i]; + p->frame.mv[LIST_0][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + p->frame.ref_idx[LIST_0][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj + 4][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs_bottom->is_long_term; } } else { - p->mv[LIST_0][j][i][0] = fs->mv_JV[np][LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1] = fs->mv_JV[np][LIST_0][j][i][1] ; - p->mv[LIST_1][j][i][0] = fs->mv_JV[np][LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1] = fs->mv_JV[np][LIST_1][j][i][1] ; - p->ref_idx[LIST_0][j][i] = fs->ref_idx_JV[np][LIST_0][j][i]; - p->ref_idx[LIST_1][j][i] = fs->ref_idx_JV[np][LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][j][i]; + p->frame.mv[LIST_0][j][i][0] = fs->JVmotion[np].mv[LIST_0][j][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->JVmotion[np].mv[LIST_0][j][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs->JVmotion[np].mv[LIST_1][j][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->JVmotion[np].mv[LIST_1][j][i][1] ; + p->frame.ref_idx[LIST_0][j][i] = fs->JVmotion[np].ref_idx[LIST_0][j][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->JVmotion[np].ref_idx[LIST_1][j][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][j][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][j][i]; p->is_long_term = fs->is_long_term; } @@ -4046,102 +3993,102 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) //! Do nothing if macroblock as field coded in MB-AFF if (!img->MbaffFrameFlag ) { - p->mv[LIST_0][j][i][0] = fs->mv_JV[np][LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1] = fs->mv_JV[np][LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0] = fs->mv_JV[np][LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1] = fs->mv_JV[np][LIST_1][jj][ii][1]; + p->frame.mv[LIST_0][j][i][0] = fs->JVmotion[np].mv[LIST_0][jj][ii][0]; + p->frame.mv[LIST_0][j][i][1] = fs->JVmotion[np].mv[LIST_0][jj][ii][1]; + p->frame.mv[LIST_1][j][i][0] = fs->JVmotion[np].mv[LIST_1][jj][ii][0]; + p->frame.mv[LIST_1][j][i][1] = fs->JVmotion[np].mv[LIST_1][jj][ii][1]; // Scaling of references is done here since it will not affect spatial direct (2*0 =0) - if (fs->ref_idx_JV[np][LIST_0][jj][ii] == -1) + if (fs->JVmotion[np].ref_idx[LIST_0][jj][ii] == -1) { - p->ref_idx [LIST_0][j][i] = -1; - p->ref_pic_id[LIST_0][j][i] = -1; + p->frame.ref_idx [LIST_0][j][i] = -1; + p->frame.ref_pic_id[LIST_0][j][i] = -1; } else { - p->ref_idx [LIST_0][j][i] = fs->ref_idx_JV[np][LIST_0][jj][ii] ; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np] [LIST_0][jj][ii]; + p->frame.ref_idx [LIST_0][j][i] = fs->JVmotion[np].ref_idx[LIST_0][jj][ii] ; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id [LIST_0][jj][ii]; } - if (fs->ref_idx_JV[np][LIST_1][jj][ii] == -1) + if (fs->JVmotion[np].ref_idx[LIST_1][jj][ii] == -1) { - p->ref_idx [LIST_1][j][i] = -1; - p->ref_pic_id[LIST_1][j][i] = -1; + p->frame.ref_idx [LIST_1][j][i] = -1; + p->frame.ref_pic_id[LIST_1][j][i] = -1; } else { - p->ref_idx [LIST_1][j][i] = fs->ref_idx_JV[np][LIST_1][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np] [LIST_1][jj][ii]; + p->frame.ref_idx [LIST_1][j][i] = fs->JVmotion[np].ref_idx[LIST_1][jj][ii]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id [LIST_1][jj][ii]; } p->is_long_term = fs->is_long_term; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i] = + p->frame.moving_block[j][i] = !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->frame.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->frame.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->frame.ref_idx[LIST_0][j][i] == -1) + && (p->frame.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->frame.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_1][j][i][1])>>1 == 0))); } } else { - p->bottom_mv[LIST_0][j][i][0] = fs_bottom->mv_JV[np][LIST_0][jj][ii][0]; - p->bottom_mv[LIST_0][j][i][1] = fs_bottom->mv_JV[np][LIST_0][jj][ii][1]; - p->bottom_mv[LIST_1][j][i][0] = fs_bottom->mv_JV[np][LIST_1][jj][ii][0]; - p->bottom_mv[LIST_1][j][i][1] = fs_bottom->mv_JV[np][LIST_1][jj][ii][1]; - p->bottom_ref_idx[LIST_0][j][i] = fs_bottom->ref_idx_JV[np][LIST_0][jj][ii]; - p->bottom_ref_idx[LIST_1][j][i] = fs_bottom->ref_idx_JV[np][LIST_1][jj][ii]; - p->bottom_ref_pic_id[LIST_0][j][i] = fs_bottom->ref_id_JV[np][LIST_0][jj][ii]; - p->bottom_ref_pic_id[LIST_1][j][i] = fs_bottom->ref_id_JV[np][LIST_1][jj][ii]; + p->bottom.mv[LIST_0][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_0][jj][ii][0]; + p->bottom.mv[LIST_0][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_0][jj][ii][1]; + p->bottom.mv[LIST_1][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_1][jj][ii][0]; + p->bottom.mv[LIST_1][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_1][jj][ii][1]; + p->bottom.ref_idx[LIST_0][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_0][jj][ii]; + p->bottom.ref_idx[LIST_1][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_1][jj][ii]; + p->bottom.ref_pic_id[LIST_0][j][i] = fs_bottom->JVmotion[np].ref_id[LIST_0][jj][ii]; + p->bottom.ref_pic_id[LIST_1][j][i] = fs_bottom->JVmotion[np].ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->bottom_moving_block[j][i] = + p->bottom.moving_block[j][i] = !((!fs_bottom->is_long_term - && ((p->bottom_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->bottom_ref_idx[LIST_0][j][i] == -1) - && (p->bottom_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->bottom.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->bottom.ref_idx[LIST_0][j][i] == -1) + && (p->bottom.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][1])>>1 == 0))); } - p->top_mv[LIST_0][j][i][0] = fs_top->mv_JV[np][LIST_0][jj][ii][0]; - p->top_mv[LIST_0][j][i][1] = fs_top->mv_JV[np][LIST_0][jj][ii][1]; - p->top_mv[LIST_1][j][i][0] = fs_top->mv_JV[np][LIST_1][jj][ii][0]; - p->top_mv[LIST_1][j][i][1] = fs_top->mv_JV[np][LIST_1][jj][ii][1]; - p->top_ref_idx[LIST_0][j][i] = fs_top->ref_idx_JV[np][LIST_0][jj][ii]; - p->top_ref_idx[LIST_1][j][i] = fs_top->ref_idx_JV[np][LIST_1][jj][ii]; - p->top_ref_pic_id[LIST_0][j][i] = fs_top->ref_id_JV[np][LIST_0][jj][ii]; - p->top_ref_pic_id[LIST_1][j][i] = fs_top->ref_id_JV[np][LIST_1][jj][ii]; + p->top.mv[LIST_0][j][i][0] = fs_top->JVmotion[np].mv[LIST_0][jj][ii][0]; + p->top.mv[LIST_0][j][i][1] = fs_top->JVmotion[np].mv[LIST_0][jj][ii][1]; + p->top.mv[LIST_1][j][i][0] = fs_top->JVmotion[np].mv[LIST_1][jj][ii][0]; + p->top.mv[LIST_1][j][i][1] = fs_top->JVmotion[np].mv[LIST_1][jj][ii][1]; + p->top.ref_idx[LIST_0][j][i] = fs_top->JVmotion[np].ref_idx[LIST_0][jj][ii]; + p->top.ref_idx[LIST_1][j][i] = fs_top->JVmotion[np].ref_idx[LIST_1][jj][ii]; + p->top.ref_pic_id[LIST_0][j][i] = fs_top->JVmotion[np].ref_id[LIST_0][jj][ii]; + p->top.ref_pic_id[LIST_1][j][i] = fs_top->JVmotion[np].ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->top_moving_block[j][i] = + p->top.moving_block[j][i] = !((!fs_top->is_long_term - && ((p->top_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->top_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->top_ref_idx[LIST_0][j][i] == -1) - && (p->top_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->top_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->top.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->top.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->top.ref_idx[LIST_0][j][i] == -1) + && (p->top.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->top.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_1][j][i][1])>>1 == 0))); } - if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->field_frame[2*j][i]) + if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->motion.field_frame[2*j][i]) { - p->top_mv[LIST_0][j][i][1] /= 2; - p->top_mv[LIST_1][j][i][1] /= 2; - p->bottom_mv[LIST_0][j][i][1] /= 2; - p->bottom_mv[LIST_1][j][i][1] /= 2; + p->top.mv[LIST_0][j][i][1] /= 2; + p->top.mv[LIST_1][j][i][1] /= 2; + p->bottom.mv[LIST_0][j][i][1] /= 2; + p->bottom.mv[LIST_1][j][i][1] /= 2; } } @@ -4164,32 +4111,32 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i<fs->size_x/4 ; i++) { - if (fs->field_frame[j][i]) + if (fs->motion.field_frame[j][i]) { if (iabs(dec_picture->poc - fs->bottom_field->poc) > iabs(dec_picture->poc - fs->top_field->poc)) { - p->mv[LIST_0][j][i][0] = fs->top_field->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->top_field->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->top_field->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->top_field->mv_JV[np][LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->top_field->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->top_field->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj][i]; + p->frame.mv[LIST_0][j][i][0] = fs->top_field->JVmotion[np].mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->top_field->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs->top_field->JVmotion[np].mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->top_field->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + + p->frame.ref_idx[LIST_0][j][i] = fs->top_field->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->top_field->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj][i]; p->is_long_term = fs->top_field->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs->bottom_field->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->bottom_field->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->bottom_field->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->bottom_field->mv_JV[np][LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj + 4][i]; + p->frame.mv[LIST_0][j][i][0] = fs->bottom_field->JVmotion[np].mv[LIST_0][jdiv][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->bottom_field->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + p->frame.mv[LIST_1][j][i][0] = fs->bottom_field->JVmotion[np].mv[LIST_1][jdiv][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->bottom_field->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + + p->frame.ref_idx[LIST_0][j][i] = fs->bottom_field->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->bottom_field->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj + 4][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs->bottom_field->is_long_term; } } @@ -4209,27 +4156,27 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); - p->mv[LIST_0][j][i][0] = p->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1] = p->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0] = p->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1] = p->mv[LIST_1][jj][ii][1]; + p->frame.mv[LIST_0][j][i][0] = p->frame.mv[LIST_0][jj][ii][0]; + p->frame.mv[LIST_0][j][i][1] = p->frame.mv[LIST_0][jj][ii][1]; + p->frame.mv[LIST_1][j][i][0] = p->frame.mv[LIST_1][jj][ii][0]; + p->frame.mv[LIST_1][j][i][1] = p->frame.mv[LIST_1][jj][ii][1]; - p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii]; - p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii]; + p->frame.ref_idx[LIST_0][j][i]=p->frame.ref_idx[LIST_0][jj][ii]; + p->frame.ref_idx[LIST_1][j][i]=p->frame.ref_idx[LIST_1][jj][ii]; + p->frame.ref_pic_id[LIST_0][j][i] = p->frame.ref_pic_id[LIST_0][jj][ii]; + p->frame.ref_pic_id[LIST_1][j][i] = p->frame.ref_pic_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i]= (byte) ( + p->frame.moving_block[j][i]= (byte) ( !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)))); + && ((p->frame.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->frame.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->frame.ref_idx[LIST_0][j][i] == -1) + && (p->frame.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->frame.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_1][j][i][1])>>1 == 0)))); } } } @@ -4243,27 +4190,27 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); //! Use inference flag to remap mvs/references - p->mv[LIST_0][j][i][0]=fs->mv_JV[np][LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1]=fs->mv_JV[np][LIST_0][j][i][1]; - p->mv[LIST_1][j][i][0]=fs->mv_JV[np][LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1]=fs->mv_JV[np][LIST_1][j][i][1]; + p->frame.mv[LIST_0][j][i][0] = fs->JVmotion[np].mv[LIST_0][j][i][0]; + p->frame.mv[LIST_0][j][i][1] = fs->JVmotion[np].mv[LIST_0][j][i][1]; + p->frame.mv[LIST_1][j][i][0] = fs->JVmotion[np].mv[LIST_1][j][i][0]; + p->frame.mv[LIST_1][j][i][1] = fs->JVmotion[np].mv[LIST_1][j][i][1]; - p->ref_idx[LIST_0][j][i]=fs->ref_idx_JV[np][LIST_0][j][i]; - p->ref_idx[LIST_1][j][i]=fs->ref_idx_JV[np][LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][j][i]; + p->frame.ref_idx[LIST_0][j][i] = fs->JVmotion[np].ref_idx[LIST_0][j][i]; + p->frame.ref_idx[LIST_1][j][i] = fs->JVmotion[np].ref_idx[LIST_1][j][i]; + p->frame.ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][j][i]; + p->frame.ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][j][i]; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i]= (byte) ( + p->frame.moving_block[j][i]= (byte) ( !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)))); + && ((p->frame.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->frame.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->frame.ref_idx[LIST_0][j][i] == -1) + && (p->frame.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->frame.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->frame.mv[LIST_1][j][i][1])>>1 == 0)))); } } } @@ -4276,15 +4223,15 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) { for (i=0 ; i<fs->size_x/4 ; i++) { - if ((!img->MbaffFrameFlag &&!img->structure && fs->field_frame[j][i]) || (img->MbaffFrameFlag && fs->field_frame[j][i])) + if ((!img->MbaffFrameFlag &&!img->structure && fs->motion.field_frame[j][i]) || (img->MbaffFrameFlag && fs->motion.field_frame[j][i])) { - p->mv[LIST_0][j][i][1] *= 2; - p->mv[LIST_1][j][i][1] *= 2; + p->frame.mv[LIST_0][j][i][1] *= 2; + p->frame.mv[LIST_1][j][i][1] *= 2; } - else if (img->structure && !fs->field_frame[j][i]) + else if (img->structure && !fs->motion.field_frame[j][i]) { - p->mv[LIST_0][j][i][1] /= 2; - p->mv[LIST_1][j][i][1] /= 2; + p->frame.mv[LIST_0][j][i][1] /= 2; + p->frame.mv[LIST_1][j][i][1] /= 2; } } @@ -4325,46 +4272,17 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) } } -void copy_storable_param_JV( int nplane, StorablePicture *d, StorablePicture *s ) +void copy_storable_param_JV( PicMotionParams *JVplane, PicMotionParams *motion ) { - int np, ny, nx; - // copy ref_idx - for( np=0; np<2; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - memcpy( d->ref_idx_JV[nplane][np][ny], s->ref_idx[np][ny], sizeof(byte)*(img->width/BLOCK_SIZE) ); - } - } + memcpy( JVplane->ref_idx[0][0], motion->ref_idx[0][0], 2 * (img->height / BLOCK_SIZE) * (img->width / BLOCK_SIZE) * sizeof(byte)); // copy ref_pic_id - for( np=0; np<6; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - memcpy( d->ref_pic_id_JV[nplane][np][ny], s->ref_pic_id[np][ny], sizeof(int64)*(img->width/BLOCK_SIZE) ); - } - } + memcpy( JVplane->ref_pic_id[0][0], motion->ref_pic_id[0][0], 6 * (img->height / BLOCK_SIZE) * (img->width / BLOCK_SIZE) * sizeof(int64)); - // copy ref_id - for( np=0; np<6; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - memcpy( d->ref_id_JV[nplane][np][ny], s->ref_id[np][ny], sizeof(int64)*(img->width/BLOCK_SIZE) ); - } - } + // copy motion.ref_id + memcpy( JVplane->ref_id[0][0], motion->ref_id[0][0], 6 * (img->height / BLOCK_SIZE) * (img->width / BLOCK_SIZE) * sizeof(int64)); // copy mv - for( np=0; np<2; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - for( nx=0; nx<img->width/BLOCK_SIZE; nx++ ) - { - memcpy( d->mv_JV[nplane][np][ny][nx], s->mv[np][ny][nx], sizeof(short)*2 ); - } - } - } + memcpy( JVplane->mv[0][0][0], motion->mv[0][0][0], 2 * (img->height / BLOCK_SIZE) * (img->width / BLOCK_SIZE) * 2 * sizeof(short) ); } diff --git a/ldecod/src/mc_prediction.c b/ldecod/src/mc_prediction.c index 56bdf26..7ca5722 100644 --- a/ldecod/src/mc_prediction.c +++ b/ldecod/src/mc_prediction.c @@ -18,10 +18,9 @@ #include "mc_prediction.h" #include "mbuffer.h" #include "mb_access.h" +#include "macroblock.h" extern StorablePicture *no_reference_picture; -extern const unsigned char subblk_offset_y[3][8][4]; -extern const unsigned char subblk_offset_x[3][8][4]; imgpel tmp_block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; //!< l0 prediction imgpel tmp_block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; //!< l1 prediction @@ -33,7 +32,7 @@ static const int COEF[6] = { 1, -5, 20, 20, -5, 1 }; * block single list prediction ************************************************************************ */ -static inline void mc_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], +static inline void mc_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int ver_block_size, int hor_block_size, int ioff, @@ -43,13 +42,13 @@ static inline void mc_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], if (hor_block_size == MB_BLOCK_SIZE) { - memcpy(&(curr_mpr[0][ioff]), &(block[0][0]), hor_block_size * ver_block_size * sizeof(imgpel)); + memcpy(&(mb_pred[0][ioff]), &(block[0][0]), hor_block_size * ver_block_size * sizeof(imgpel)); } else { for(jj = 0; jj < ver_block_size; jj++) { - memcpy(&(curr_mpr[jj][ioff]), &(block[jj][0]), hor_block_size * sizeof(imgpel)); + memcpy(&(mb_pred[jj][ioff]), &(block[jj][0]), hor_block_size * sizeof(imgpel)); } } } @@ -60,7 +59,7 @@ static inline void mc_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], * block single list weighted prediction ************************************************************************ */ -static inline void weighted_mc_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], +static inline void weighted_mc_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int ver_block_size, int hor_block_size, int ioff, @@ -75,7 +74,7 @@ static inline void weighted_mc_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOC for(jj=0;jj<ver_block_size;jj++) { - mpr = &curr_mpr[jj][ioff]; + mpr = &mb_pred[jj][ioff]; b0 = block[jj]; for(ii=0;ii<hor_block_size;ii++) *(mpr++) = (imgpel) iClip1(color_clip, (rshift_rnd((wp_scale * *(b0++)), weight_denom) + wp_offset )); @@ -89,7 +88,7 @@ static inline void weighted_mc_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOC * block biprediction ************************************************************************ */ -static inline void bi_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], +static inline void bi_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], imgpel block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE], imgpel block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int ver_block_size, @@ -101,7 +100,7 @@ static inline void bi_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], for(jj = 0;jj < ver_block_size;jj++) { - mpr = &curr_mpr[jj][ioff]; + mpr = &mb_pred[jj][ioff]; b0 = block_l0[jj]; b1 = block_l1[jj]; for(ii = 0; ii < hor_block_size;ii++) @@ -115,7 +114,7 @@ static inline void bi_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], * block weighted biprediction ************************************************************************ */ -static inline void weighted_bi_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOCK_SIZE], +static inline void weighted_bi_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], imgpel block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE], imgpel block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int ver_block_size, @@ -132,7 +131,7 @@ static inline void weighted_bi_prediction(imgpel curr_mpr[MB_BLOCK_SIZE][MB_BLOC for(jj = 0; jj < ver_block_size; jj++) { - mpr = &curr_mpr[jj][ioff]; + mpr = &mb_pred[jj][ioff]; b0 = block_l0[jj]; b1 = block_l1[jj]; @@ -163,9 +162,10 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p int i, j, jj; int shift_x = dec_picture->size_x; int maxold_x = dec_picture->size_x_m1; - int maxold_y = (dec_picture->mb_field[img->current_mb_nr]) ? (dec_picture->size_y >> 1) - 1 : dec_picture->size_y_m1; + int maxold_y = (dec_picture->motion.mb_field[img->current_mb_nr]) ? (dec_picture->size_y >> 1) - 1 : dec_picture->size_y_m1; int result; int pres_x; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; if (curr_ref == no_reference_picture && img->framepoc < img->recovery_poc) @@ -237,7 +237,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*(p1++) + *(p4++)) * COEF[1] + (*(p2++) + *(p3++)) * COEF[2]; - *orig_line++ = (imgpel) iClip1(img->max_imgpel_value, ((result + 16)>>5)); + *orig_line++ = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); } } @@ -273,7 +273,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*(p1++) + *(p4++)) * COEF[1] + (*(p2++) + *(p3++)) * COEF[2]; - *orig_line++ = (imgpel) iClip1(img->max_imgpel_value, ((result + 16)>>5)); + *orig_line++ = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); } p0 = p1 - hor_block_size; } @@ -331,7 +331,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*x1++ + *x4++) * COEF[1] + (*x2++ + *x3++) * COEF[2]; - *(orig_line++) = (imgpel) iClip1(img->max_imgpel_value, ((result+512)>>10)); + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result+512)>>10)); } } @@ -344,7 +344,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p orig_line = block[j]; for (i = 0; i < hor_block_size; i++) { - *orig_line = (imgpel) ((*orig_line + iClip1(img->max_imgpel_value, ((*(tmp_line++) + 16) >> 5)) + 1 )>> 1); + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16) >> 5)) + 1 )>> 1); orig_line++; } } @@ -387,7 +387,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*(x1++) + *(x4++)) * COEF[1] + (*(x2++) + *(x3++)) * COEF[2]; - *(orig_line++) = (imgpel) iClip1(img->max_imgpel_value, ((result + 512)>>10)); + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result + 512)>>10)); } } @@ -399,7 +399,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p orig_line = block[j]; for (i = 0; i < hor_block_size; i++) { - *orig_line = (imgpel) ((*orig_line + iClip1(img->max_imgpel_value, ((*(tmp_line++) + 16)>>5))+1)>>1); + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16)>>5))+1)>>1); orig_line ++; } } @@ -426,7 +426,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*(p1++) + *(p4++)) * COEF[1] + (*(p2++) + *(p3++)) * COEF[2]; - *(orig_line++) = (imgpel) iClip1(img->max_imgpel_value, ((result + 16)>>5)); + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); } } @@ -446,7 +446,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*(p1++) + *(p4++)) * COEF[1] + (*(p2++) + *(p3++)) * COEF[2]; - *orig_line = (imgpel) ((*orig_line + iClip1(img->max_imgpel_value, ((result + 16) >> 5)) + 1) >> 1); + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((result + 16) >> 5)) + 1) >> 1); orig_line++; } p0 = p1 - hor_block_size ; @@ -492,7 +492,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1]; result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2]; - block[j][i] = (imgpel) iClip1(img->max_imgpel_value, ((result + 16)>>5)); + block[j][i] = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); } } @@ -532,7 +532,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p result = (p0[pres_x] + p5[pres_x]) * COEF[0]; result += (p1[pres_x] + p4[pres_x]) * COEF[1]; result += (p2[pres_x] + p3[pres_x]) * COEF[2]; - *(orig_line++) = (imgpel) iClip1(img->max_imgpel_value, ((result+16)>>5)); + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result+16)>>5)); } } @@ -589,7 +589,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*x1++ + *x4++) * COEF[1] + (*x2++ + *x3++) * COEF[2]; - *(orig_line++) = (imgpel) iClip1(img->max_imgpel_value, ((result+512)>>10)); + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result+512)>>10)); } } @@ -601,7 +601,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p orig_line = block[j]; for (i = 0; i < hor_block_size; i++) { - *orig_line = (imgpel) ((*orig_line + iClip1(img->max_imgpel_value, ((*(tmp_line++) + 16) >> 5)) + 1 )>>1); + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16) >> 5)) + 1 )>>1); orig_line++; } } @@ -649,7 +649,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p + (*(x1++) + *(x4++)) * COEF[1] + (*(x2++) + *(x3++)) * COEF[2]; - *(orig_line++) = (imgpel) iClip1(img->max_imgpel_value, ((result + 512)>>10)); + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result + 512)>>10)); } } @@ -661,7 +661,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p orig_line = block[j]; for (i = 0; i < hor_block_size; i++) { - *orig_line = (imgpel) ((*orig_line + iClip1(img->max_imgpel_value, ((*(tmp_line++) + 16)>>5)) + 1)>> 1); + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16)>>5)) + 1)>> 1); orig_line++; } } @@ -688,7 +688,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1]; result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2]; - block[j][i] = (imgpel) iClip1(img->max_imgpel_value, ((result+16)>>5)); + block[j][i] = (imgpel) iClip1(max_imgpel_value, ((result+16)>>5)); } } @@ -714,7 +714,7 @@ void get_block_luma(ColorPlane pl, StorablePicture *curr_ref, int x_pos, int y_p result += (p1[pres_x] + p4[pres_x]) * COEF[1]; result += (p2[pres_x] + p3[pres_x]) * COEF[2]; - *orig_line = (imgpel) ((*orig_line + iClip1(img->max_imgpel_value, ((result+16)>>5)) + 1 ) >> 1); + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((result+16)>>5)) + 1 ) >> 1); orig_line++; } } @@ -743,13 +743,14 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i int i, j; int maxold_x = dec_picture->size_x_cr_m1; - int maxold_y = (dec_picture->mb_field[img->current_mb_nr]) ? (dec_picture->size_y_cr >> 1) - 1 : dec_picture->size_y_cr_m1; + int maxold_y = (dec_picture->motion.mb_field[img->current_mb_nr]) ? (dec_picture->size_y_cr >> 1) - 1 : dec_picture->size_y_cr_m1; int result; static imgpel **cur_img, *blk_line; static imgpel *cur_line, *cur_line_p1; int tmp_pos; static int ipos, ipos_p1; + int max_imgpel_value = img->max_imgpel_value_comp[uv + 1]; if (curr_ref == no_reference_picture && img->framepoc < img->recovery_poc) @@ -788,7 +789,7 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i for (i = 0; i < hor_block_size; i++) { result = (w00 * *cur_line++ + w01 * *cur_line_p1++); - *(blk_line++) = (imgpel) iClip1(img->max_imgpel_value_uv, rshift_rnd_sf(result, total_scale)); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); } } } @@ -803,7 +804,7 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i for (i = 0; i < hor_block_size; i++) { result = (w00 * *cur_line++ + w10 * *cur_line_p1++); - *(blk_line++) = (imgpel) iClip1(img->max_imgpel_value_uv, rshift_rnd_sf(result, total_scale)); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); } } } @@ -819,7 +820,7 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i { result = (w00 * *(cur_line++) + w01 * *(cur_line_p1++)); result += (w10 * *(cur_line ) + w11 * *(cur_line_p1 )); - *(blk_line++) = (imgpel) iClip1(img->max_imgpel_value_uv, rshift_rnd_sf(result, total_scale)); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); } } } @@ -852,7 +853,7 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i ipos = iClip3(0, maxold_x, tmp_pos++); result = (w00 * cur_line[ipos] + w01 * cur_line_p1[ipos]); - *(blk_line++) = (imgpel) iClip1(img->max_imgpel_value_uv, rshift_rnd_sf(result, total_scale)); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); } } } @@ -870,7 +871,7 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i ipos_p1 = iClip3(0, maxold_x, tmp_pos ); result = (w00 * cur_line[ipos ] + w10 * cur_line[ipos_p1]); - *(blk_line++) = (imgpel)iClip1(img->max_imgpel_value_uv, rshift_rnd_sf(result, total_scale)); + *(blk_line++) = (imgpel)iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); } } } @@ -893,7 +894,7 @@ void get_block_chroma(int uv, StorablePicture *curr_ref, int x_pos, int y_pos, i w10 * cur_line [ipos_p1] + w01 * cur_line_p1[ipos ] + w11 * cur_line_p1[ipos_p1]); - *(blk_line++) = (imgpel) iClip1(img->max_imgpel_value_uv, rshift_rnd_sf(result, total_scale)); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); } } } @@ -907,7 +908,7 @@ void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int sm int (*m7UV)[16], *m7; int uv; int b8,b4; - int ioff, joff, ii, jj, i, j; + int ioff, joff, ii, jj; for(uv = 0; uv < 2; uv++) { @@ -915,8 +916,8 @@ void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int sm itrans_4x4 = (!lossless_qpprime) ? itrans4x4 : itrans4x4_ls; curUV = dec_picture->imgUV[uv]; - m7UV = img->m7[uv+1]; - intrapred_chroma(currMB, img, uv); + m7UV = img->mb_rres[uv+1]; + intrapred_chroma(img, currMB, uv); if (!smb && (currMB->cbp >> 4)) { @@ -927,7 +928,7 @@ void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int sm joff = subblk_offset_y[yuv][b8][b4]; ioff = subblk_offset_x[yuv][b8][b4]; - itrans_4x4((ColorPlane) (uv + 1), img, ioff, joff); + itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff); for(jj=joff; jj<joff + 4;jj++) { @@ -952,7 +953,7 @@ void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int sm ioff = subblk_offset_x[yuv][b8][b4]; for(jj = joff; jj < 4 + joff;jj++) - memcpy(&(curUV[img->pix_c_y + jj][img->pix_c_x + ioff]), &(img->mpr[uv + 1][jj][ioff]), BLOCK_SIZE * sizeof(imgpel)); + memcpy(&(curUV[img->pix_c_y + jj][img->pix_c_x + ioff]), &(img->mb_pred[uv + 1][jj][ioff]), BLOCK_SIZE * sizeof(imgpel)); } } } @@ -960,18 +961,16 @@ void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int sm { itrans_sp_cr(img, uv); - for (j = 0; j < 2; j++) + for (joff = 0; joff < 8; joff += 4) { - joff = j * 4; - for(i = 0; i < 2;i++) - { - ioff = i * 4; - itrans_4x4((ColorPlane) (uv + 1), img, ioff, joff); + for(ioff = 0; ioff < 8;ioff+=4) + { + itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff); for(jj = joff; jj < joff + 4; jj++) for(ii = ioff; ii < ioff + 4; ii++) { - curUV[img->pix_c_y+jj][ii + img->pix_c_x] = (imgpel) img->m7[uv+1][jj][ii]; + curUV[img->pix_c_y+jj][ii + img->pix_c_x] = (imgpel) img->mb_rres[uv+1][jj][ii]; } } } @@ -993,101 +992,101 @@ void prepare_direct_params(Macroblock *currMB, StorablePicture *dec_picture, Ima if (!img->MbaffFrameFlag) { - l0_rFrameL = (char) (mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1); - l0_rFrameU = (char) (mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1); - l0_rFrameUL = (char) (mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1); - l0_rFrameUR = (char) (mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL); - - l1_rFrameL = (char) (mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1); - l1_rFrameU = (char) (mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1); - l1_rFrameUL = (char) (mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1); - l1_rFrameUR = (char) (mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL); + l0_rFrameL = (char) (mb_left.available ? dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1); + l0_rFrameU = (char) (mb_up.available ? dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1); + l0_rFrameUL = (char) (mb_upleft.available ? dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + l0_rFrameUR = (char) (mb_upright.available ? dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL); + + l1_rFrameL = (char) (mb_left.available ? dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1); + l1_rFrameU = (char) (mb_up.available ? dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1); + l1_rFrameUL = (char) (mb_upleft.available ? dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + l1_rFrameUR = (char) (mb_upright.available ? dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL); } else { if (currMB->mb_field) { l0_rFrameL = (char) (mb_left.available - ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] - : dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1); + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1); l0_rFrameU = (char) (mb_up.available - ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] - : dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1); + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1); l0_rFrameUL = (char) (mb_upleft.available - ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] - : dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1); + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1); l0_rFrameUR = (char) (mb_upright.available - ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] - : dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL); + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL); l1_rFrameL = (char) (mb_left.available - ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] - : dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1); + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1); l1_rFrameU = (char) (mb_up.available - ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] - : dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1); + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1); l1_rFrameUL = (char) (mb_upleft.available - ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] - : dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2 : -1); + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2 : -1); l1_rFrameUR = (char) (mb_upright.available - ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] - : dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL); + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL); } else { l0_rFrameL = (char) (mb_left.available - ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 - : dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1); + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1); l0_rFrameU = (char) (mb_up.available - ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 - : dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1); + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1); l0_rFrameUL = (char) (mb_upleft.available - ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 - : dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1); l0_rFrameUR = (char) (mb_upright.available - ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 - ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 - : dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL); + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL); l1_rFrameL = (char) (mb_left.available - ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 - : dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1); + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1); l1_rFrameU = (char) (mb_up.available - ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 - : dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1); + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1); l1_rFrameUL = (char) (mb_upleft.available - ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 - : dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1); l1_rFrameUR = (char) (mb_upright.available - ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 - ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1 - : dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL); + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL); } } @@ -1098,10 +1097,25 @@ void prepare_direct_params(Macroblock *currMB, StorablePicture *dec_picture, Ima *l1_rFrame = (char) ((*l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(*l1_rFrame,l1_rFrameUR): imax(*l1_rFrame,l1_rFrameUR)); if (*l0_rFrame >=0) - SetMotionVectorPredictor (currMB, img, pmvl0, *l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16); + SetMotionVectorPredictor (img, currMB, pmvl0, *l0_rFrame, LIST_0, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16); if (*l1_rFrame >=0) - SetMotionVectorPredictor (currMB, img, pmvl1, *l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16); + SetMotionVectorPredictor (img, currMB, pmvl1, *l1_rFrame, LIST_1, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16); +} + +void check_motion_vector_range(ImageParameters *img, short mv_x, short mv_y) +{ + if (mv_x > 8191 || mv_x < -8192) + { + fprintf(stderr,"ERROR! Horizontal motion vector %d is out of allowed range {-8192, 8191} in picture %d, macroblock %d\n", mv_x, img->number, img->current_mb_nr); + error("invalid stream: too big horizontal motion vector", 500); + } + + if (mv_y > (img->max_mb_vmv_r - 1) || mv_y < (-img->max_mb_vmv_r)) + { + fprintf(stderr,"ERROR! Vertical motion vector %d is out of allowed range {%d, %d} in picture %d, macroblock %d\n", mv_y, (-img->max_mb_vmv_r), (img->max_mb_vmv_r - 1), img->number, img->current_mb_nr); + error("invalid stream: too big vertical motion vector", 500); + } } void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *img, int pred_dir, int i, int j, int list_offset, int block_size_x, int block_size_y, int curr_mb_field) @@ -1110,6 +1124,7 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im static int vec1_y_cr = 0, vec2_y_cr = 0; static int alpha_l0, alpha_l1, wp_offset; static const int mv_mul = 16; // 4 * 4 + int max_imgpel_value = img->max_imgpel_value_comp[pl]; int i4 = img->block_x + i; int j4 = img->block_y + j; @@ -1121,11 +1136,13 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im if (pred_dir != 2) { //===== Single List Prediction ===== - short ref_idx = dec_picture->ref_idx[pred_dir][j4][i4]; + short ref_idx = dec_picture->motion.ref_idx[pred_dir][j4][i4]; short ref_idx_wp = ref_idx; - short ***mv_array = dec_picture->mv[pred_dir]; + short ***mv_array = dec_picture->motion.mv[pred_dir]; StorablePicture **list = listX[list_offset + pred_dir]; + check_motion_vector_range(img, mv_array[j4][i4][0], mv_array[j4][i4][1]); + vec1_x = i4 * mv_mul + mv_array[j4][i4][0]; vec1_y = (img->block_y_aff + j) * mv_mul + mv_array[j4][i4][1]; @@ -1142,11 +1159,11 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im alpha_l0 = img->wp_weight[pred_dir][ref_idx_wp][0]; wp_offset = img->wp_offset[pred_dir][ref_idx_wp][0]; - weighted_mc_prediction(&img->mpr[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0, alpha_l0, wp_offset, img->luma_log2_weight_denom, img->max_imgpel_value); + weighted_mc_prediction(&img->mb_pred[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0, alpha_l0, wp_offset, img->luma_log2_weight_denom, max_imgpel_value); } else { - mc_prediction(&img->mpr[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0); + mc_prediction(&img->mb_pred[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0); } if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444) ) @@ -1169,11 +1186,11 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im alpha_l0 = img->wp_weight[pred_dir][ref_idx_wp][uv + 1]; wp_offset = img->wp_offset[pred_dir][ref_idx_wp][uv + 1]; - weighted_mc_prediction(&img->mpr[uv + 1][joff_cr], block_size_y_cr, block_size_x_cr, ioff_cr, tmp_block_l0, alpha_l0, wp_offset, img->chroma_log2_weight_denom, img->max_imgpel_value_uv); + weighted_mc_prediction(&img->mb_pred[uv + 1][joff_cr], block_size_y_cr, block_size_x_cr, ioff_cr, tmp_block_l0, alpha_l0, wp_offset, img->chroma_log2_weight_denom, img->max_imgpel_value_comp[uv + 1]); } else { - mc_prediction(&img->mpr[uv + 1][joff_cr], block_size_y_cr, block_size_x_cr, ioff_cr, tmp_block_l0); + mc_prediction(&img->mb_pred[uv + 1][joff_cr], block_size_y_cr, block_size_x_cr, ioff_cr, tmp_block_l0); } } } @@ -1181,14 +1198,16 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im else { //===== BI-PREDICTION ===== - short ***l0_mv_array = dec_picture->mv[LIST_0]; - short ***l1_mv_array = dec_picture->mv[LIST_1]; + short ***l0_mv_array = dec_picture->motion.mv[LIST_0]; + short ***l1_mv_array = dec_picture->motion.mv[LIST_1]; - short l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4]; - short l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4]; + short l0_refframe = dec_picture->motion.ref_idx[LIST_0][j4][i4]; + short l1_refframe = dec_picture->motion.ref_idx[LIST_1][j4][i4]; short l0_ref_idx = l0_refframe; short l1_ref_idx = l1_refframe; + check_motion_vector_range(img, l0_mv_array[j4][i4][0], l0_mv_array[j4][i4][1]); + check_motion_vector_range(img, l1_mv_array[j4][i4][0], l1_mv_array[j4][i4][1]); vec1_x = i4 * mv_mul + l0_mv_array[j4][i4][0]; vec2_x = i4 * mv_mul + l1_mv_array[j4][i4][0]; @@ -1215,11 +1234,11 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][0]; wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][0] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][0] + 1) >>1); - weighted_bi_prediction(&img->mpr[pl][joff], tmp_block_l0, tmp_block_l1, block_size_y, block_size_x, ioff, alpha_l0, alpha_l1, wp_offset, (img->luma_log2_weight_denom + 1), img->max_imgpel_value); + weighted_bi_prediction(&img->mb_pred[pl][joff], tmp_block_l0, tmp_block_l1, block_size_y, block_size_x, ioff, alpha_l0, alpha_l1, wp_offset, (img->luma_log2_weight_denom + 1), max_imgpel_value); } else { - bi_prediction(&img->mpr[pl][joff], tmp_block_l0, tmp_block_l1, block_size_y, block_size_x, ioff); + bi_prediction(&img->mb_pred[pl][joff], tmp_block_l0, tmp_block_l1, block_size_y, block_size_x, ioff); } if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444) ) @@ -1247,11 +1266,11 @@ void perform_mc(ColorPlane pl, StorablePicture *dec_picture, ImageParameters *im alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][uv + 1]; wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][uv + 1] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][uv + 1] + 1) >>1); - weighted_bi_prediction(&img->mpr[uv+1][joff_cr], tmp_block_l0, tmp_block_l1, block_size_y_cr, block_size_x_cr, ioff_cr, alpha_l0, alpha_l1, wp_offset, (img->chroma_log2_weight_denom + 1), img->max_imgpel_value_uv); + weighted_bi_prediction(&img->mb_pred[uv+1][joff_cr], tmp_block_l0, tmp_block_l1, block_size_y_cr, block_size_x_cr, ioff_cr, alpha_l0, alpha_l1, wp_offset, (img->chroma_log2_weight_denom + 1), img->max_imgpel_value_comp[uv + 1]); } else { - bi_prediction(&img->mpr[uv + 1][joff_cr], tmp_block_l0, tmp_block_l1, block_size_y_cr, block_size_x_cr, ioff_cr); + bi_prediction(&img->mb_pred[uv + 1][joff_cr], tmp_block_l0, tmp_block_l1, block_size_y_cr, block_size_x_cr, ioff_cr); } } } diff --git a/ldecod/src/memalloc.c b/ldecod/src/memalloc.c index cc8c89c..8673836 100644 --- a/ldecod/src/memalloc.c +++ b/ldecod/src/memalloc.c @@ -872,14 +872,14 @@ int get_mem2Ddouble(double ***array2D, int rows, int columns) * memory size in bytes ************************************************************************ */ -int get_mem2Ddb_offset(double ***array2D, int rows, int columns, int offset) +int get_mem2Dodouble(double ***array2D, int rows, int columns, int offset) { int i; if((*array2D = (double**)calloc(rows, sizeof(double*))) == NULL) - no_mem_exit("get_mem2Ddb_offset: array2D"); + no_mem_exit("get_mem2Dodouble: array2D"); if(((*array2D)[0] = (double* )calloc(rows*columns,sizeof(double ))) == NULL) - no_mem_exit("get_mem2Ddb_offset: array2D"); + no_mem_exit("get_mem2Dodouble: array2D"); (*array2D)[0] += offset; @@ -898,15 +898,15 @@ int get_mem2Ddb_offset(double ***array2D, int rows, int columns, int offset) * memory size in bytes ************************************************************************ */ -int get_mem3Ddb_offset(double ****array3D, int rows, int columns, int pels, int offset) +int get_mem3Dodouble(double ****array3D, int rows, int columns, int pels, int offset) { int i,j; if(((*array3D) = (double***)calloc(rows,sizeof(double**))) == NULL) - no_mem_exit("get_mem3Ddb_offset: array3D"); + no_mem_exit("get_mem3Dodouble: array3D"); if(((*array3D)[0] = (double** )calloc(rows*columns,sizeof(double*))) == NULL) - no_mem_exit("get_mem3Ddb_offset: array3D"); + no_mem_exit("get_mem3Dodouble: array3D"); (*array3D) [0] += offset; @@ -916,7 +916,7 @@ int get_mem3Ddb_offset(double ****array3D, int rows, int columns, int pels, int for (i = 0; i < rows; i++) for (j = -offset; j < columns - offset; j++) if(((*array3D)[i][j] = (double* )calloc(pels,sizeof(double))) == NULL) - no_mem_exit("get_mem3Ddb_offset: array3D"); + no_mem_exit("get_mem3Dodouble: array3D"); return rows*columns*pels*sizeof(double); } @@ -963,15 +963,15 @@ int get_offset_mem2Dshort(short ***array2D, int rows, int columns, int offset_y, * memory size in bytes ************************************************************************ */ -int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int offset) +int get_mem3Doint(int ****array3D, int rows, int columns, int pels, int offset) { int i,j; if(((*array3D) = (int***)calloc(rows,sizeof(int**))) == NULL) - no_mem_exit("get_mem3Dint_offset: array3D"); + no_mem_exit("get_mem3Doint: array3D"); if(((*array3D)[0] = (int** )calloc(rows*columns,sizeof(int*))) == NULL) - no_mem_exit("get_mem3Dint_offset: array3D"); + no_mem_exit("get_mem3Doint: array3D"); (*array3D) [0] += offset; @@ -981,7 +981,7 @@ int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int of for (i = 0; i < rows; i++) for (j = -offset; j < columns - offset; j++) if(((*array3D)[i][j] = (int* )calloc(pels,sizeof(int))) == NULL) - no_mem_exit("get_mem3Dint_offset: array3D"); + no_mem_exit("get_mem3Doint: array3D"); return rows*columns*pels*sizeof(int); } @@ -996,7 +996,7 @@ int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int of * memory size in bytes ************************************************************************ */ -int get_mem2Dint_offset(int ***array2D, int rows, int columns, int offset) +int get_mem2Doint(int ***array2D, int rows, int columns, int offset) { int i; @@ -1076,20 +1076,20 @@ void free_mem2Ddouble(double **array2D) * which was allocated with get_mem2Ddouble() ************************************************************************ */ -void free_mem2Ddb_offset(double **array2D, int offset) +void free_mem2Dodouble(double **array2D, int offset) { if (array2D) { array2D[0] -= offset; if (array2D[0]) free (array2D[0]); - else error ("free_mem2Ddb_offset: trying to free unused memory",100); + else error ("free_mem2Dodouble: trying to free unused memory",100); free (array2D); } else { - error ("free_mem2Ddb_offset: trying to free unused memory",100); + error ("free_mem2Dodouble: trying to free unused memory",100); } } @@ -1099,7 +1099,7 @@ void free_mem2Ddb_offset(double **array2D, int offset) * free 3D memory array with offset ************************************************************************ */ -void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset) +void free_mem3Dodouble(double ***array3D, int rows, int columns, int offset) { int i, j; @@ -1112,19 +1112,19 @@ void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset) if (array3D[i][j]) free(array3D[i][j]); else - error ("free_mem3Ddb_offset: trying to free unused memory",100); + error ("free_mem3Dodouble: trying to free unused memory",100); } } array3D[0] -= offset; if (array3D[0]) free(array3D[0]); else - error ("free_mem3Ddb_offset: trying to free unused memory",100); + error ("free_mem3Dodouble: trying to free unused memory",100); free (array3D); } else { - error ("free_mem3Ddb_offset: trying to free unused memory",100); + error ("free_mem3Dodouble: trying to free unused memory",100); } } @@ -1134,7 +1134,7 @@ void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset) * free 3D memory array with offset ************************************************************************ */ -void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset) +void free_mem3Doint(int ***array3D, int rows, int columns, int offset) { int i, j; @@ -1147,19 +1147,19 @@ void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset) if (array3D[i][j]) free(array3D[i][j]); else - error ("free_mem3Dint_offset: trying to free unused memory",100); + error ("free_mem3Doint: trying to free unused memory",100); } } array3D[0] -= offset; if (array3D[0]) free(array3D[0]); else - error ("free_mem3Dint_offset: trying to free unused memory",100); + error ("free_mem3Doint: trying to free unused memory",100); free (array3D); } else { - error ("free_mem3Dint_offset: trying to free unused memory",100); + error ("free_mem3Doint: trying to free unused memory",100); } } @@ -1171,7 +1171,7 @@ void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset) * which was allocated with get_mem2Ddouble() ************************************************************************ */ -void free_mem2Dint_offset(int **array2D, int offset) +void free_mem2Doint(int **array2D, int offset) { if (array2D) { @@ -1179,14 +1179,14 @@ void free_mem2Dint_offset(int **array2D, int offset) if (array2D[0]) free (array2D[0]); else - error ("free_mem2Dint_offset: trying to free unused memory",100); + error ("free_mem2Doint: trying to free unused memory",100); free (array2D); } else { - error ("free_mem2Dint_offset: trying to free unused memory",100); + error ("free_mem2Doint: trying to free unused memory",100); } } diff --git a/ldecod/src/nalu.c b/ldecod/src/nalu.c index 5951967..09bbbe0 100644 --- a/ldecod/src/nalu.c +++ b/ldecod/src/nalu.c @@ -14,7 +14,8 @@ #include "global.h" #include "nalu.h" - +#include "annexb.h" +#include "rtp.h" /*! ************************************************************************************* @@ -38,3 +39,47 @@ int NALUtoRBSP (NALU_t *nalu) return nalu->len ; } +/*! +************************************************************************ +* \brief +* Read the next NAL unit (with error handling) +************************************************************************ +*/ +int read_next_nalu(FILE *bitstream, NALU_t *nalu) +{ + int ret; + + if (params->FileFormat == PAR_OF_ANNEXB) + ret = GetAnnexbNALU (bitstream, nalu); + else + ret = GetRTPNALU (bitstream, nalu); + + if (ret < 0) + { + snprintf (errortext, ET_SIZE, "Error while getting the NALU in file format %s, exit\n", params->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP"); + error (errortext, 601); + } + if (ret == 0) + { + FreeNALU(nalu); + return 0; + } + + //In some cases, zero_byte shall be present. If current NALU is a VCL NALU, we can't tell + //whether it is the first VCL NALU at this point, so only non-VCL NAL unit is checked here. + CheckZeroByteNonVCL(nalu); + + ret = NALUtoRBSP(nalu); + + if (ret < 0) + error ("Invalid startcode emulation prevention found.", 602); + + + // Got a NALU + if (nalu->forbidden_bit) + { + error ("Found NALU with forbidden_bit set, bit error?", 603); + } + + return nalu->len; +} diff --git a/ldecod/src/output.c b/ldecod/src/output.c index 313aafe..3d870d7 100644 --- a/ldecod/src/output.c +++ b/ldecod/src/output.c @@ -28,11 +28,11 @@ int recovery_flag = 0; extern int non_conforming_stream; -void write_out_picture(StorablePicture *p, int p_out); -void (*img2buf) (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); -void img2buf_byte (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); -void img2buf_normal (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); -void img2buf_endian (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); +static void write_out_picture(StorablePicture *p, int p_out); +static void (*img2buf) (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); +static void img2buf_byte (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); +static void img2buf_normal (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); +static void img2buf_endian (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom); /*! ************************************************************************ @@ -64,7 +64,7 @@ int testEndian(void) * ************************************************************************ */ -void initOutput(int symbol_size_in_bytes) +static void initOutput(int symbol_size_in_bytes) { if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes)) { @@ -103,7 +103,7 @@ void initOutput(int symbol_size_in_bytes) * pixels to crop from bottom ************************************************************************ */ -void img2buf_normal (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom) +static void img2buf_normal (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom) { int i,j; @@ -171,7 +171,7 @@ void img2buf_normal (imgpel** imgX, unsigned char* buf, int size_x, int size_y, * pixels to crop from bottom ************************************************************************ */ -void img2buf_byte (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom) +static void img2buf_byte (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom) { int i; @@ -211,7 +211,7 @@ void img2buf_byte (imgpel** imgX, unsigned char* buf, int size_x, int size_y, in * pixels to crop from bottom ************************************************************************ */ -void img2buf_endian (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom) +static void img2buf_endian (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes, int crop_left, int crop_right, int crop_top, int crop_bottom) { int i,j; static unsigned char ui8; @@ -445,7 +445,7 @@ void write_picture(StorablePicture *p, int p_out, int real_structure) * Output file ************************************************************************ */ -void write_out_picture(StorablePicture *p, int p_out) +static void write_out_picture(StorablePicture *p, int p_out) { static int SubWidthC [4]= { 1, 2, 2, 1}; static int SubHeightC [4]= { 1, 2, 1, 1}; diff --git a/ldecod/src/parset.c b/ldecod/src/parset.c index 17cf7fd..363fb8d 100644 --- a/ldecod/src/parset.c +++ b/ldecod/src/parset.c @@ -188,7 +188,7 @@ int InterpretSPS (DataPartition *p, seq_parameter_set_rbsp_t *sps) sps->mb_adaptive_frame_field_flag = u_1 ("SPS: mb_adaptive_frame_field_flag" , s); } sps->direct_8x8_inference_flag = u_1 ("SPS: direct_8x8_inference_flag" , s); - sps->frame_cropping_flag = u_1 ("SPS: frame_cropping_flag" , s); + sps->frame_cropping_flag = u_1 ("SPS: frame_cropping_flag" , s); if (sps->frame_cropping_flag) { @@ -197,7 +197,7 @@ int InterpretSPS (DataPartition *p, seq_parameter_set_rbsp_t *sps) sps->frame_cropping_rect_top_offset = ue_v ("SPS: frame_cropping_rect_top_offset" , s); sps->frame_cropping_rect_bottom_offset = ue_v ("SPS: frame_cropping_rect_bottom_offset" , s); } - sps->vui_parameters_present_flag = (Boolean) u_1 ("SPS: vui_parameters_present_flag" , s); + sps->vui_parameters_present_flag = (Boolean) u_1 ("SPS: vui_parameters_present_flag" , s); InitVUI(sps); ReadVUI(p, sps); @@ -581,6 +581,24 @@ void activate_sps (seq_parameter_set_rbsp_t *sps) img->width_cr = 0; img->height_cr = 0; + // maximum vertical motion vector range in luma quarter pixel units + if (active_sps->level_idc <= 10) + { + img->max_vmv_r = 64 * 4; + } + else if (active_sps->level_idc <= 20) + { + img->max_vmv_r = 128 * 4; + } + else if (active_sps->level_idc <= 30) + { + img->max_vmv_r = 256 * 4; + } + else + { + img->max_vmv_r = 512 * 4; // 512 pixels in quarter pixels + } + // Fidelity Range Extensions stuff (part 1) img->bitdepth_luma = sps->bit_depth_luma_minus8 + 8; img->bitdepth_scale[0] = 1 << sps->bit_depth_luma_minus8; diff --git a/ldecod/src/quant.c b/ldecod/src/quant.c new file mode 100644 index 0000000..7dcb6d7 --- /dev/null +++ b/ldecod/src/quant.c @@ -0,0 +1,459 @@ + +/*! + *********************************************************************** + * \file + * quant.c + * + * \brief + * Quantization functions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * + *********************************************************************** + */ + +#include "contributors.h" + +#include "global.h" +#include "memalloc.h" +#include "block.h" +#include "image.h" +#include "mb_access.h" +#include "transform.h" +#include "quant.h" + +const int dequant_coef8[6][8][8] = +{ + { + {20, 19, 25, 19, 20, 19, 25, 19}, + {19, 18, 24, 18, 19, 18, 24, 18}, + {25, 24, 32, 24, 25, 24, 32, 24}, + {19, 18, 24, 18, 19, 18, 24, 18}, + {20, 19, 25, 19, 20, 19, 25, 19}, + {19, 18, 24, 18, 19, 18, 24, 18}, + {25, 24, 32, 24, 25, 24, 32, 24}, + {19, 18, 24, 18, 19, 18, 24, 18} + }, + { + {22, 21, 28, 21, 22, 21, 28, 21}, + {21, 19, 26, 19, 21, 19, 26, 19}, + {28, 26, 35, 26, 28, 26, 35, 26}, + {21, 19, 26, 19, 21, 19, 26, 19}, + {22, 21, 28, 21, 22, 21, 28, 21}, + {21, 19, 26, 19, 21, 19, 26, 19}, + {28, 26, 35, 26, 28, 26, 35, 26}, + {21, 19, 26, 19, 21, 19, 26, 19} + }, + { + {26, 24, 33, 24, 26, 24, 33, 24}, + {24, 23, 31, 23, 24, 23, 31, 23}, + {33, 31, 42, 31, 33, 31, 42, 31}, + {24, 23, 31, 23, 24, 23, 31, 23}, + {26, 24, 33, 24, 26, 24, 33, 24}, + {24, 23, 31, 23, 24, 23, 31, 23}, + {33, 31, 42, 31, 33, 31, 42, 31}, + {24, 23, 31, 23, 24, 23, 31, 23} + }, + { + {28, 26, 35, 26, 28, 26, 35, 26}, + {26, 25, 33, 25, 26, 25, 33, 25}, + {35, 33, 45, 33, 35, 33, 45, 33}, + {26, 25, 33, 25, 26, 25, 33, 25}, + {28, 26, 35, 26, 28, 26, 35, 26}, + {26, 25, 33, 25, 26, 25, 33, 25}, + {35, 33, 45, 33, 35, 33, 45, 33}, + {26, 25, 33, 25, 26, 25, 33, 25} + }, + { + {32, 30, 40, 30, 32, 30, 40, 30}, + {30, 28, 38, 28, 30, 28, 38, 28}, + {40, 38, 51, 38, 40, 38, 51, 38}, + {30, 28, 38, 28, 30, 28, 38, 28}, + {32, 30, 40, 30, 32, 30, 40, 30}, + {30, 28, 38, 28, 30, 28, 38, 28}, + {40, 38, 51, 38, 40, 38, 51, 38}, + {30, 28, 38, 28, 30, 28, 38, 28} + }, + { + {36, 34, 46, 34, 36, 34, 46, 34}, + {34, 32, 43, 32, 34, 32, 43, 32}, + {46, 43, 58, 43, 46, 43, 58, 43}, + {34, 32, 43, 32, 34, 32, 43, 32}, + {36, 34, 46, 34, 36, 34, 46, 34}, + {34, 32, 43, 32, 34, 32, 43, 32}, + {46, 43, 58, 43, 46, 43, 58, 43}, + {34, 32, 43, 32, 34, 32, 43, 32} + } +}; + +//! Dequantization coefficients +const int dequant_coef[6][4][4] = { + { + { 10, 13, 10, 13}, + { 13, 16, 13, 16}, + { 10, 13, 10, 13}, + { 13, 16, 13, 16}}, + { + { 11, 14, 11, 14}, + { 14, 18, 14, 18}, + { 11, 14, 11, 14}, + { 14, 18, 14, 18}}, + { + { 13, 16, 13, 16}, + { 16, 20, 16, 20}, + { 13, 16, 13, 16}, + { 16, 20, 16, 20}}, + { + { 14, 18, 14, 18}, + { 18, 23, 18, 23}, + { 14, 18, 14, 18}, + { 18, 23, 18, 23}}, + { + { 16, 20, 16, 20}, + { 20, 25, 20, 25}, + { 16, 20, 16, 20}, + { 20, 25, 20, 25}}, + { + { 18, 23, 18, 23}, + { 23, 29, 23, 29}, + { 18, 23, 18, 23}, + { 23, 29, 23, 29}} +}; + +const int quant_coef[6][4][4] = { + { + { 13107, 8066, 13107, 8066}, + { 8066, 5243, 8066, 5243}, + { 13107, 8066, 13107, 8066}, + { 8066, 5243, 8066, 5243}}, + { + { 11916, 7490, 11916, 7490}, + { 7490, 4660, 7490, 4660}, + { 11916, 7490, 11916, 7490}, + { 7490, 4660, 7490, 4660}}, + { + { 10082, 6554, 10082, 6554}, + { 6554, 4194, 6554, 4194}, + { 10082, 6554, 10082, 6554}, + { 6554, 4194, 6554, 4194}}, + { + { 9362, 5825, 9362, 5825}, + { 5825, 3647, 5825, 3647}, + { 9362, 5825, 9362, 5825}, + { 5825, 3647, 5825, 3647}}, + { + { 8192, 5243, 8192, 5243}, + { 5243, 3355, 5243, 3355}, + { 8192, 5243, 8192, 5243}, + { 5243, 3355, 5243, 3355}}, + { + { 7282, 4559, 7282, 4559}, + { 4559, 2893, 4559, 2893}, + { 7282, 4559, 7282, 4559}, + { 4559, 2893, 4559, 2893}} +}; + +const int A[4][4] = { + { 16, 20, 16, 20}, + { 20, 25, 20, 25}, + { 16, 20, 16, 20}, + { 20, 25, 20, 25} +}; + +int quant_intra_default[16] = { + 6,13,20,28, + 13,20,28,32, + 20,28,32,37, + 28,32,37,42 +}; + +int quant_inter_default[16] = { + 10,14,20,24, + 14,20,24,27, + 20,24,27,30, + 24,27,30,34 +}; + +int quant8_intra_default[64] = { + 6,10,13,16,18,23,25,27, +10,11,16,18,23,25,27,29, +13,16,18,23,25,27,29,31, +16,18,23,25,27,29,31,33, +18,23,25,27,29,31,33,36, +23,25,27,29,31,33,36,38, +25,27,29,31,33,36,38,40, +27,29,31,33,36,38,40,42 +}; + +int quant8_inter_default[64] = { + 9,13,15,17,19,21,22,24, +13,13,17,19,21,22,24,25, +15,17,19,21,22,24,25,27, +17,19,21,22,24,25,27,28, +19,21,22,24,25,27,28,30, +21,22,24,25,27,28,30,32, +22,24,25,27,28,30,32,33, +24,25,27,28,30,32,33,35 +}; + +int quant_org[16] = { //to be use if no q matrix is chosen +16,16,16,16, +16,16,16,16, +16,16,16,16, +16,16,16,16 +}; + +int quant8_org[64] = { //to be use if no q matrix is chosen +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16 +}; + +int *qp_per_matrix; +int *qp_rem_matrix; + +int InvLevelScale4x4_Intra[3][6][4][4]; +int InvLevelScale4x4_Inter[3][6][4][4]; +int InvLevelScale8x8_Intra[3][6][8][8]; +int InvLevelScale8x8_Inter[3][6][8][8]; + +int *qmatrix[12]; + +/*! + *********************************************************************** + * \brief + * Initiate quantization process arrays + *********************************************************************** + */ +void init_qp_process(ImageParameters *img) +{ + int bitdepth_qp_scale = imax(img->bitdepth_luma_qp_scale,img->bitdepth_chroma_qp_scale); + int i; + + // We should allocate memory outside of this process since maybe we will have a change of SPS + // and we may need to recreate these. Currently should only support same bitdepth + if (qp_per_matrix == NULL) + if ((qp_per_matrix = (int*)malloc((MAX_QP + 1 + bitdepth_qp_scale)*sizeof(int))) == NULL) + no_mem_exit("init_global_buffers: qp_per_matrix"); + if (qp_rem_matrix == NULL) + if ((qp_rem_matrix = (int*)malloc((MAX_QP + 1 + bitdepth_qp_scale)*sizeof(int))) == NULL) + no_mem_exit("init_global_buffers: qp_per_matrix"); + + for (i = 0; i < MAX_QP + bitdepth_qp_scale + 1; i++) + { + qp_per_matrix[i] = i / 6; + qp_rem_matrix[i] = i % 6; + } +} + +/*! + ************************************************************************ + * \brief + * For mapping the q-matrix to the active id and calculate quantisation values + * + * \param pps + * Picture parameter set + * \param sps + * Sequence parameter set + * + ************************************************************************ + */ +void AssignQuantParam(pic_parameter_set_rbsp_t* pps, seq_parameter_set_rbsp_t* sps) +{ + int i; + int n_ScalingList; + + if(!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag) + { + for(i=0; i<12; i++) + qmatrix[i] = (i<6) ? quant_org:quant8_org; + } + else + { + n_ScalingList = (sps->chroma_format_idc != YUV444) ? 8 : 12; + if(sps->seq_scaling_matrix_present_flag) // check sps first + { + for(i=0; i<n_ScalingList; i++) + { + if(i<6) + { + if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A + { + if(i==0) + qmatrix[i] = quant_intra_default; + else if(i==3) + qmatrix[i] = quant_inter_default; + else + qmatrix[i] = qmatrix[i-1]; + } + else + { + if(sps->UseDefaultScalingMatrix4x4Flag[i]) + qmatrix[i] = (i<3) ? quant_intra_default : quant_inter_default; + else + qmatrix[i] = sps->ScalingList4x4[i]; + } + } + else + { + if(!sps->seq_scaling_list_present_flag[i]) // fall-back rule A + { + if(i==6) + qmatrix[i] = quant8_intra_default; + else if(i==7) + qmatrix[i] = quant8_inter_default; + else + qmatrix[i] = qmatrix[i-2]; + } + else + { + if(sps->UseDefaultScalingMatrix8x8Flag[i-6]) + qmatrix[i] = (i==6 || i==8 || i==10) ? quant8_intra_default:quant8_inter_default; + else + qmatrix[i] = sps->ScalingList8x8[i-6]; + } + } + } + } + + if(pps->pic_scaling_matrix_present_flag) // then check pps + { + for(i=0; i<n_ScalingList; i++) + { + if(i<6) + { + if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B + { + if (i==0) + { + if(!sps->seq_scaling_matrix_present_flag) + qmatrix[i] = quant_intra_default; + } + else if (i==3) + { + if(!sps->seq_scaling_matrix_present_flag) + qmatrix[i] = quant_inter_default; + } + else + qmatrix[i] = qmatrix[i-1]; + } + else + { + if(pps->UseDefaultScalingMatrix4x4Flag[i]) + qmatrix[i] = (i<3) ? quant_intra_default:quant_inter_default; + else + qmatrix[i] = pps->ScalingList4x4[i]; + } + } + else + { + if(!pps->pic_scaling_list_present_flag[i]) // fall-back rule B + { + if (i==6) + { + if(!sps->seq_scaling_matrix_present_flag) + qmatrix[i] = quant8_intra_default; + } + else if(i==7) + { + if(!sps->seq_scaling_matrix_present_flag) + qmatrix[i] = quant8_inter_default; + } + else + qmatrix[i] = qmatrix[i-2]; + } + else + { + if(pps->UseDefaultScalingMatrix8x8Flag[i-6]) + qmatrix[i] = (i==6 || i==8 || i==10) ? quant8_intra_default:quant8_inter_default; + else + qmatrix[i] = pps->ScalingList8x8[i-6]; + } + } + } + } + } + + CalculateQuantParam(); + if(pps->transform_8x8_mode_flag) + CalculateQuant8Param(); +} + +/*! + ************************************************************************ + * \brief + * For calculating the quantisation values at frame level + * + ************************************************************************ + */ +void CalculateQuantParam() +{ + int i, j, k, temp; + + for(k=0; k<6; k++) + { + for(i=0; i<4; i++) + { + for(j=0; j<4; j++) + { + temp = (i<<2)+j; + InvLevelScale4x4_Intra[0][k][i][j] = dequant_coef[k][i][j] * qmatrix[0][temp]; + InvLevelScale4x4_Intra[1][k][i][j] = dequant_coef[k][i][j] * qmatrix[1][temp]; + InvLevelScale4x4_Intra[2][k][i][j] = dequant_coef[k][i][j] * qmatrix[2][temp]; + + InvLevelScale4x4_Inter[0][k][i][j] = dequant_coef[k][i][j] * qmatrix[3][temp]; + InvLevelScale4x4_Inter[1][k][i][j] = dequant_coef[k][i][j] * qmatrix[4][temp]; + InvLevelScale4x4_Inter[2][k][i][j] = dequant_coef[k][i][j] * qmatrix[5][temp]; + } + } + } +} + +/*! + ************************************************************************ + * \brief + * Calculate the quantisation and inverse quantisation parameters + * + ************************************************************************ + */ +void CalculateQuant8Param() +{ + int i, j, k, temp; + + for(k=0; k<6; k++) + { + for(i=0; i<8; i++) + { + for(j=0; j<8; j++) + { + temp = (i<<3)+j; + InvLevelScale8x8_Intra[0][k][i][j] = dequant_coef8[k][i][j] * qmatrix[6][temp]; + InvLevelScale8x8_Inter[0][k][i][j] = dequant_coef8[k][i][j] * qmatrix[7][temp]; + } + } + } + + if( active_sps->chroma_format_idc == 3 ) // 4:4:4 + { + for(k=0; k<6; k++) + { + for(i=0; i<8; i++) + { + for(j=0; j<8; j++) + { + temp = (i<<3)+j; + InvLevelScale8x8_Intra[1][k][i][j] = dequant_coef8[k][i][j] * qmatrix[8][temp]; + InvLevelScale8x8_Inter[1][k][i][j] = dequant_coef8[k][i][j] * qmatrix[9][temp]; + InvLevelScale8x8_Intra[2][k][i][j] = dequant_coef8[k][i][j] * qmatrix[10][temp]; + InvLevelScale8x8_Inter[2][k][i][j] = dequant_coef8[k][i][j] * qmatrix[11][temp]; + } + } + } + } +} diff --git a/ldecod/src/rtp.c b/ldecod/src/rtp.c index 0f70178..d6791dd 100644 --- a/ldecod/src/rtp.c +++ b/ldecod/src/rtp.c @@ -102,7 +102,7 @@ FILE *bits; -int RTPReadPacket (RTPpacket_t *p, FILE *bits); +int RTPReadPacket (RTPpacket_t *p, FILE *bitstream); /*! ************************************************************************ @@ -149,7 +149,7 @@ void CloseRTPFile(void) ************************************************************************ */ -int GetRTPNALU (NALU_t *nalu) +int GetRTPNALU (FILE *bitstream, NALU_t *nalu) { static unsigned short first_call = 1; //!< triggers sequence number initialization on first call static unsigned short old_seq = 0; //!< store the last RTP sequence number for loss detection @@ -164,7 +164,7 @@ int GetRTPNALU (NALU_t *nalu) if ((p->payload=malloc (MAXRTPPACKETSIZE))== NULL) no_mem_exit ("GetRTPNALU-3"); - ret = RTPReadPacket (p, bits); + ret = RTPReadPacket (p, bitstream); nalu->forbidden_bit = 1; nalu->len = 0; @@ -344,7 +344,7 @@ void DumpRTPHeader (RTPpacket_t *p) * Stephan Wenger, stewe@cs.tu-berlin.de *****************************************************************************/ -int RTPReadPacket (RTPpacket_t *p, FILE *bits) +int RTPReadPacket (RTPpacket_t *p, FILE *bitstream) { int Filepos, intime; @@ -352,22 +352,22 @@ int RTPReadPacket (RTPpacket_t *p, FILE *bits) assert (p->packet != NULL); assert (p->payload != NULL); - Filepos = ftell (bits); - if (4 != fread (&p->packlen,1, 4, bits)) + Filepos = ftell (bitstream); + if (4 != fread (&p->packlen,1, 4, bitstream)) { return 0; } - if (4 != fread (&intime, 1, 4, bits)) + if (4 != fread (&intime, 1, 4, bitstream)) { - fseek (bits, Filepos, SEEK_SET); + fseek (bitstream, Filepos, SEEK_SET); printf ("RTPReadPacket: File corruption, could not read Timestamp, exit\n"); exit (-1); } assert (p->packlen < MAXRTPPACKETSIZE); - if (p->packlen != fread (p->packet, 1, p->packlen, bits)) + if (p->packlen != fread (p->packet, 1, p->packlen, bitstream)) { printf ("RTPReadPacket: File corruption, could not read %d bytes\n", (int) p->packlen); exit (-1); // EOF inidication diff --git a/ldecod/src/sei.c b/ldecod/src/sei.c index 571b3c0..6492f98 100644 --- a/ldecod/src/sei.c +++ b/ldecod/src/sei.c @@ -407,7 +407,7 @@ void interpret_spare_pic( byte* payload, int size, ImageParameters *img ) for (i=0; i < img->height/16; i++) for (j=0; j < img->width/16; j++) { - tmp=map[kk][i][j]==0? img->max_imgpel_value : 0; + tmp=map[kk][i][j]==0? img->max_imgpel_value_comp[0] : 0; for (i0=0; i0<16; i0++) for (j0=0; j0<16; j0++) Y[i*16+i0][j*16+j0]=tmp; diff --git a/ldecod/src/transform8x8.c b/ldecod/src/transform8x8.c index 4890f38..5e2b73f 100644 --- a/ldecod/src/transform8x8.c +++ b/ldecod/src/transform8x8.c @@ -23,140 +23,9 @@ #include "elements.h" #include "transform8x8.h" #include "transform.h" +#include "quant.h" -#define Q_BITS_8 16 -#define DQ_BITS_8 6 -const int quant_coef8[6][8][8] = -{ - { - {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, - {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, - {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, - {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428} - }, - { - {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, - {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, - {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, - {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826} - }, - { - {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, - {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, - {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, - {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943} - }, - { - {9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931}, - {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, - {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259}, - {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, - {9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931}, - {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, - {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259}, - {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228} - }, - { - {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, - {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, - {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, - {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346} - }, - { - {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, - {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, - {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, - {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428} - } -}; - - - -const int dequant_coef8[6][8][8] = -{ - { - {20, 19, 25, 19, 20, 19, 25, 19}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {25, 24, 32, 24, 25, 24, 32, 24}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {20, 19, 25, 19, 20, 19, 25, 19}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {25, 24, 32, 24, 25, 24, 32, 24}, - {19, 18, 24, 18, 19, 18, 24, 18} - }, - { - {22, 21, 28, 21, 22, 21, 28, 21}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {22, 21, 28, 21, 22, 21, 28, 21}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {21, 19, 26, 19, 21, 19, 26, 19} - }, - { - {26, 24, 33, 24, 26, 24, 33, 24}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {33, 31, 42, 31, 33, 31, 42, 31}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {26, 24, 33, 24, 26, 24, 33, 24}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {33, 31, 42, 31, 33, 31, 42, 31}, - {24, 23, 31, 23, 24, 23, 31, 23} - }, - { - {28, 26, 35, 26, 28, 26, 35, 26}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {35, 33, 45, 33, 35, 33, 45, 33}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {35, 33, 45, 33, 35, 33, 45, 33}, - {26, 25, 33, 25, 26, 25, 33, 25} - }, - { - {32, 30, 40, 30, 32, 30, 40, 30}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {40, 38, 51, 38, 40, 38, 51, 38}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {32, 30, 40, 30, 32, 30, 40, 30}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {40, 38, 51, 38, 40, 38, 51, 38}, - {30, 28, 38, 28, 30, 28, 38, 28} - }, - { - {36, 34, 46, 34, 36, 34, 46, 34}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {46, 43, 58, 43, 46, 43, 58, 43}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {36, 34, 46, 34, 36, 34, 46, 34}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {46, 43, 58, 43, 46, 43, 58, 43}, - {34, 32, 43, 32, 34, 32, 43, 32} - } - -}; // function declarations void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, int block_left); @@ -218,10 +87,10 @@ void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, * ************************************************************************ */ -int intrapred8x8( ColorPlane pl, //!< Current Colorplane - ImageParameters *img, //!< image parameters - Macroblock *currMB, //!< Current Macroblock - int b8) +int intrapred8x8(ImageParameters *img, //!< image parameters + Macroblock *currMB, //!< Current Macroblock + ColorPlane pl, //!< Current Colorplane + int b8) { int i,j; @@ -246,7 +115,7 @@ int intrapred8x8( ColorPlane pl, //!< Current Colorplane int ipos0 = ioff , ipos1 = ioff + 1, ipos2 = ioff + 2, ipos3 = ioff + 3; int ipos4 = ioff + 4, ipos5 = ioff + 5, ipos6 = ioff + 6, ipos7 = ioff + 7; int jpos, ipos; - imgpel *pred_pels, (*mpr)[16] = img->mpr[pl]; + imgpel *pred_pels, (*mpr)[16] = img->mb_pred[pl]; int *mb_size = img->mb_size[IS_LUMA]; byte predmode = img->ipredmode[img_block_y][img_block_x]; @@ -908,17 +777,18 @@ void LowPassForIntra8x8Pred(imgpel *PredPel, int block_up_left, int block_up, in * Inverse 8x8 transformation *********************************************************************** */ -void itrans8x8(ColorPlane pl, - ImageParameters *img, //!< image parameters - int ioff, //!< index to 4x4 block - int joff) //!< +void itrans8x8(ImageParameters *img, //!< image parameters + Macroblock *currMB, + ColorPlane pl, + int ioff, //!< index to 4x4 block + int joff) //!< { int i,j; - Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1); + Boolean lossless_qpprime = (Boolean) (currMB->qp_scaled[pl] == 0 && img->lossless_qpprime_flag==1); - imgpel (*mpr)[16] = img->mpr[pl]; - int (*m7)[16] = img->m7[pl]; - int max_imgpel_value = pl ? img->max_imgpel_value_uv : img->max_imgpel_value; + imgpel (*mpr)[16] = img->mb_pred[pl]; + int (*m7)[16] = img->mb_rres[pl]; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; if(lossless_qpprime) { diff --git a/ldecod/src/vlc.c b/ldecod/src/vlc.c index 9217fca..31298f9 100644 --- a/ldecod/src/vlc.c +++ b/ldecod/src/vlc.c @@ -26,13 +26,31 @@ #define SYMTRACESTRING(s) // do nothing #endif -extern void tracebits(const char *trace_str, int len, int info,int value1); +void tracebits(const char *trace_str, int len, int info,int value1); + int UsedBits; // for internal statistics, is adjusted by se_v, ue_v, u_1 // Note that all NA values are filled with 0 +//! gives CBP value from codeword number, both for intra and inter +static const unsigned char NCBP[2][48][2]= +{ + { // 0 1 2 3 4 5 6 7 8 9 10 11 + {15, 0},{ 0, 1},{ 7, 2},{11, 4},{13, 8},{14, 3},{ 3, 5},{ 5,10},{10,12},{12,15},{ 1, 7},{ 2,11}, + { 4,13},{ 8,14},{ 6, 6},{ 9, 9},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}, + { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}, + { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0} + }, + { + {47, 0},{31,16},{15, 1},{ 0, 2},{23, 4},{27, 8},{29,32},{30, 3},{ 7, 5},{11,10},{13,12},{14,15}, + {39,47},{43, 7},{45,11},{46,13},{16,14},{ 3, 6},{ 5, 9},{10,31},{12,35},{19,37},{21,42},{26,44}, + {28,33},{35,34},{37,36},{42,40},{44,39},{ 1,43},{ 2,45},{ 4,46},{ 8,17},{17,18},{18,20},{20,24}, + {24,19},{ 6,21},{ 9,26},{22,28},{25,23},{32,27},{33,29},{34,30},{36,22},{40,25},{38,38},{41,41} + } +}; + //! for the linfo_levrun_inter routine const byte NTAB1[4][8][2] = { @@ -275,7 +293,6 @@ void linfo_se(int len, int info, int *value1, int *dummy) */ void linfo_cbp_intra(int len,int info,int *cbp, int *dummy) { - extern const byte NCBP[2][48][2]; int cbp_idx; linfo_ue(len, info, &cbp_idx, dummy); @@ -296,7 +313,6 @@ void linfo_cbp_intra(int len,int info,int *cbp, int *dummy) */ void linfo_cbp_inter(int len,int info,int *cbp, int *dummy) { - extern const byte NCBP[2][48][2]; int cbp_idx; linfo_ue(len, info, &cbp_idx, dummy); @@ -530,10 +546,10 @@ int more_rbsp_data (byte buffer[],int totbitoffset,int bytecount) * Check if there are symbols for the next MB ************************************************************************ */ -int uvlc_startcode_follows(ImageParameters *img, int dummy) +int uvlc_startcode_follows(Slice *currSlice, int dummy) { - int dp_Nr = assignSE2partition[img->currentSlice->dp_mode][SE_MBTYPE]; - DataPartition *dP = &(img->currentSlice->partArr[dp_Nr]); + int dp_Nr = assignSE2partition[currSlice->dp_mode][SE_MBTYPE]; + DataPartition *dP = &(currSlice->partArr[dp_Nr]); Bitstream *currStream = dP->bitstream; byte *buf = currStream->streamBuffer; diff --git a/ldecod_vc7.vcproj b/ldecod_vc7.vcproj index cac3788..dd35f02 100644 --- a/ldecod_vc7.vcproj +++ b/ldecod_vc7.vcproj @@ -233,6 +233,9 @@ <File RelativePath=".\ldecod\src\parsetcommon.c"> </File> + <File + RelativePath=".\ldecod\src\quant.c"> + </File> <File RelativePath=".\ldecod\src\rtp.c"> </File> @@ -294,6 +297,9 @@ <File RelativePath=".\ldecod\inc\fmo.h"> </File> + <File + RelativePath=".\lencod\inc\frame.h"> + </File> <File RelativePath=".\ldecod\inc\global.h"> </File> @@ -342,6 +348,9 @@ <File RelativePath=".\ldecod\inc\parsetcommon.h"> </File> + <File + RelativePath=".\ldecod\inc\quant.h"> + </File> <File RelativePath=".\ldecod\inc\rtp.h"> </File> diff --git a/ldecod_vc8.vcproj b/ldecod_vc8.vcproj index 35d855b..beb71e5 100644 --- a/ldecod_vc8.vcproj +++ b/ldecod_vc8.vcproj @@ -4,6 +4,7 @@ Version="8.00" Name="ldecod" ProjectGUID="{5499B067-CF32-4141-A757-E0A29866994A}" + RootNamespace="ldecod" > <Platforms> <Platform @@ -324,6 +325,10 @@ RelativePath=".\ldecod\src\parsetcommon.c" > </File> + <File + RelativePath=".\ldecod\src\quant.c" + > + </File> <File RelativePath=".\ldecod\src\rtp.c" > @@ -469,6 +474,10 @@ RelativePath=".\ldecod\inc\parsetcommon.h" > </File> + <File + RelativePath=".\ldecod\inc\quant.h" + > + </File> <File RelativePath=".\ldecod\inc\rtp.h" > diff --git a/lencod/inc/block.h b/lencod/inc/block.h index 05636c7..2fe9352 100644 --- a/lencod/inc/block.h +++ b/lencod/inc/block.h @@ -18,9 +18,6 @@ #ifndef _BLOCK_H_ #define _BLOCK_H_ -//! make chroma QP from quant -extern const byte QP_SCALE_CR[52] ; - //! single scan pattern const byte SNGL_SCAN[16][2] = @@ -48,6 +45,14 @@ const byte COEFF_COST4x4[2][16] = {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9} }; +const byte SCAN_YUV420 [4][2] = +{ + {0,0}, + {0,1}, + {0,2}, + {0,3} +}; + //! single scan pattern const byte SCAN_YUV422 [8][2] = { @@ -57,58 +62,79 @@ const byte SCAN_YUV422 [8][2] = {1,2},{1,3} }; + //! look up tables for FRExt-chroma support -const unsigned char hor_offset[4][4][4] = - {{{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - - {{0, 4, 0, 4}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - - {{0, 4, 0, 4}, - {0, 4, 0, 4}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - - {{0, 4, 0, 4}, - {8,12, 8,12}, - {0, 4, 0, 4}, - {8,12, 8,12}}}; - -const unsigned char ver_offset[4][4][4] = - { {{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - - {{0, 0, 4, 4}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - - {{0, 0, 4, 4}, - {8, 8,12,12}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - - {{0, 0, 4, 4}, - {0, 0, 4, 4}, - {8, 8,12,12}, - {8, 8,12,12}}}; - -static unsigned char cbp_blk_chroma[8][4] = - { {16, 17, 18, 19}, - {20, 21, 22, 23}, - {24, 25, 26, 27}, - {28, 29, 30, 31}, - {32, 33, 34, 35}, - {36, 37, 38, 39}, - {40, 41, 42, 43}, - {44, 45, 46, 47} }; +const unsigned char hor_offset[4][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }, + { + {0, 4, 0, 4}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }, + { + {0, 4, 0, 4}, + {0, 4, 0, 4}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }, + { + {0, 4, 0, 4}, + {8,12, 8,12}, + {0, 4, 0, 4}, + {8,12, 8,12} + } +}; + +const unsigned char ver_offset[4][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }, + { + {0, 0, 4, 4}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }, + { + {0, 0, 4, 4}, + {8, 8,12,12}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }, + { + {0, 0, 4, 4}, + {0, 0, 4, 4}, + {8, 8,12,12}, + {8, 8,12,12} + } +}; + +static const int A[4][4] = { + { 16, 20, 16, 20}, + { 20, 25, 20, 25}, + { 16, 20, 16, 20}, + { 20, 25, 20, 25} +}; + +static unsigned char cbp_blk_chroma[8][4] = { + {16, 17, 18, 19}, + {20, 21, 22, 23}, + {24, 25, 26, 27}, + {28, 29, 30, 31}, + {32, 33, 34, 35}, + {36, 37, 38, 39}, + {40, 41, 42, 43}, + {44, 45, 46, 47} +}; #endif diff --git a/lencod/inc/cconv_yuv2rgb.h b/lencod/inc/cconv_yuv2rgb.h new file mode 100644 index 0000000..f5e971e --- /dev/null +++ b/lencod/inc/cconv_yuv2rgb.h @@ -0,0 +1,26 @@ +/*! + *************************************************************************** + * \file + * cconv_yuv2rgb.h + * + * \author + * Woo-Shik Kim + * + * \date + * 29 May 2008 + * + * \brief + * Headerfile for YUV to RGB color conversion + ************************************************************************** + */ + +#ifndef _CCONV_YUV2RGB_H_ +#define _CCONV_YUV2RGB_H_ + +#include "img_distortion.h" + +void init_YUVtoRGB(void); +void YUVtoRGB(ImageStructure *YUV, ImageStructure *RGB); + +#endif + diff --git a/lencod/inc/configfile.h b/lencod/inc/configfile.h index 5652be8..a0c5ece 100644 --- a/lencod/inc/configfile.h +++ b/lencod/inc/configfile.h @@ -71,7 +71,7 @@ Mapping Map[] = { {"ResendPPS", &configinput.ResendPPS, 0, 0.0, 1, 0.0, 1.0 }, {"SourceWidth", &configinput.source.width, 0, 176.0, 2, 16.0, 0.0 }, {"SourceHeight", &configinput.source.height, 0, 144.0, 2, 16.0, 0.0 }, - {"SourceResize", &configinput.src_resize, 0, 0.0, 1, 0.0, 1.0 }, + {"SourceResize", &configinput.src_resize, 0, 0.0, 1, 0.0, 1.0 }, {"OutputWidth", &configinput.output.width, 0, 176.0, 2, 16.0, 0.0 }, {"OutputHeight", &configinput.output.height, 0, 144.0, 2, 16.0, 0.0 }, {"MbLineIntraUpdate", &configinput.intra_upd, 0, 0.0, 1, 0.0, 1.0 }, @@ -128,7 +128,7 @@ Mapping Map[] = { {"Intra4x4DirDisable", &configinput.Intra4x4DirDisable, 0, 0.0, 1, 0.0, 1.0 }, {"Intra16x16ParDisable", &configinput.Intra16x16ParDisable, 0, 0.0, 1, 0.0, 1.0 }, {"Intra16x16PlaneDisable", &configinput.Intra16x16PlaneDisable, 0, 0.0, 1, 0.0, 1.0 }, - {"EnableIPCM", &configinput.EnableIPCM, 0, 1.0, 1, 0.0, 1.0 }, + {"EnableIPCM", &configinput.EnableIPCM, 0, 0.0, 1, 0.0, 1.0 }, {"ChromaIntraDisable", &configinput.ChromaIntraDisable, 0, 0.0, 1, 0.0, 1.0 }, // For future use {"FastMDEnable", &configinput.FastMDEnable, 0, 0.0, 1, 0.0, 0.0 }, @@ -149,6 +149,10 @@ Mapping Map[] = { {"ChangeQPStart", &configinput.qp2start, 0, 0.0, 2, 0.0, 0.0 }, #endif {"RDOptimization", &configinput.rdopt, 0, 0.0, 1, 0.0, 3.0 }, + {"DistortionSSIM", &configinput.Distortion[SSIM], 0, 0.0, 1, 0.0, 1.0 }, + {"DistortionMS_SSIM", &configinput.Distortion[MS_SSIM], 0, 0.0, 1, 0.0, 1.0 }, + {"SSIMOverlapSize", &configinput.SSIMOverlapSize, 0, 1.0, 2, 1.0, 1.0 }, + {"DistortionYUVtoRGB", &configinput.DistortionYUVtoRGB, 0, 0.0, 1, 0.0, 1.0 }, {"CtxAdptLagrangeMult", &configinput.CtxAdptLagrangeMult, 0, 0.0, 1, 0.0, 1.0 }, {"FastCrIntraDecision", &configinput.FastCrIntraDecision, 0, 0.0, 1, 0.0, 1.0 }, {"DisableThresholding", &configinput.disthres, 0, 0.0, 1, 0.0, 1.0 }, @@ -157,6 +161,7 @@ Mapping Map[] = { {"LossRateB", &configinput.LossRateB, 0, 0.0, 2, 0.0, 0.0 }, {"LossRateC", &configinput.LossRateC, 0, 0.0, 2, 0.0, 0.0 }, {"NumberOfDecoders", &configinput.NoOfDecoders, 0, 0.0, 2, 0.0, 0.0 }, + {"ErrorConcealment", &configinput.ErrorConcealment, 0, 0.0, 2, 0.0, 0.0 }, {"RestrictRefFrames", &configinput.RestrictRef , 0, 0.0, 1, 0.0, 1.0 }, #ifdef _LEAKYBUCKET_ {"NumberofLeakyBuckets", &configinput.NumberLeakyBuckets, 0, 2.0, 1, 2.0, 255.0 }, @@ -168,10 +173,13 @@ Mapping Map[] = { {"IntraBottom", &configinput.IntraBottom, 0, 0.0, 1, 0.0, 1.0 }, - {"NumberFramesInEnhancementLayerSubSequence", &configinput.NumFramesInELSubSeq, 0, 0.0, 2, 0.0, 0.0 }, + {"NumFramesInELayerSubSeq", &configinput.NumFramesInELSubSeq, 0, 0.0, 2, 0.0, 0.0 }, {"RandomIntraMBRefresh", &configinput.RandomIntraMBRefresh, 0, 0.0, 2, 0.0, 0.0 }, {"WeightedPrediction", &configinput.WeightedPrediction, 0, 0.0, 1, 0.0, 1.0 }, {"WeightedBiprediction", &configinput.WeightedBiprediction, 0, 0.0, 1, 0.0, 2.0 }, + {"WPMethod", &configinput.WPMethod, 0, 0.0, 1, 0.0, 1.0 }, + {"ChromaWeightSupport", &configinput.ChromaWeightSupport, 0, 0.0, 1, 0.0, 1.0 }, + {"EnhancedBWeightSupport", &configinput.EnhancedBWeightSupport, 0, 0.0, 1, 0.0, 1.0 }, {"UseWeightedReferenceME", &configinput.UseWeightedReferenceME, 0, 0.0, 1, 0.0, 1.0 }, {"RDPictureDecision", &configinput.RDPictureDecision, 0, 0.0, 1, 0.0, 1.0 }, {"RDPictureIntra", &configinput.RDPictureIntra, 0, 0.0, 1, 0.0, 1.0 }, @@ -189,6 +197,11 @@ Mapping Map[] = { //Bipredicting Motion Estimation parameters {"BiPredMotionEstimation", &configinput.BiPredMotionEstimation, 0, 0.0, 1, 0.0, 1.0 }, + {"BiPredSearch16x16", &configinput.BiPredSearch[0], 0, 1.0, 1, 0.0, 1.0 }, + {"BiPredSearch16x8", &configinput.BiPredSearch[1], 0, 0.0, 1, 0.0, 1.0 }, + {"BiPredSearch8x16", &configinput.BiPredSearch[2], 0, 0.0, 1, 0.0, 1.0 }, + {"BiPredSearch8x8", &configinput.BiPredSearch[3], 0, 0.0, 1, 0.0, 1.0 }, + {"BiPredMERefinements", &configinput.BiPredMERefinements, 0, 0.0, 1, 0.0, 5.0 }, {"BiPredMESearchRange", &configinput.BiPredMESearchRange, 0, 8.0, 2, 0.0, 0.0 }, {"BiPredMESubPel", &configinput.BiPredMESubPel, 0, 1.0, 1, 0.0, 2.0 }, @@ -256,12 +269,13 @@ Mapping Map[] = { {"MEDistortionHPel", &configinput.MEErrorMetric[H_PEL], 0, 0.0, 1, 0.0, 3.0 }, {"MEDistortionQPel", &configinput.MEErrorMetric[Q_PEL], 0, 0.0, 1, 0.0, 3.0 }, {"MDDistortion", &configinput.ModeDecisionMetric, 0, 2.0, 1, 0.0, 2.0 }, + {"SkipDeBlockNonRef", &configinput.SkipDeBlockNonRef, 0, 0.0, 1, 0.0, 1.0 }, // Rate Control {"RateControlEnable", &configinput.RCEnable, 0, 0.0, 1, 0.0, 1.0 }, {"Bitrate", &configinput.bit_rate, 0, 0.0, 2, 0.0, 0.0 }, {"InitialQP", &configinput.SeinitialQP, 0, 0.0, 3, (double) MIN_QP, (double) MAX_QP }, - {"BasicUnit", &configinput.basicunit, 0, 1.0, 2, 1.0, 0.0 }, + {"BasicUnit", &configinput.basicunit, 0, 0.0, 2, 0.0, 0.0 }, {"ChannelType", &configinput.channel_type, 0, 0.0, 1, 0.0, 1.0 }, {"RCUpdateMode", &configinput.RCUpdateMode, 0, 0.0, 1, 0.0, 4.0 }, {"RCISliceBitRatio", &configinput.RCISliceBitRatio, 2, 1.0, 1, 0.0, 20.0 }, @@ -307,7 +321,7 @@ Mapping Map[] = { // New Input bit-depth entries {"SourceBitDepthLuma", &configinput.source.bit_depth[0], 0, 8.0, 1, 8.0, 14.0 }, {"SourceBitDepthChroma", &configinput.source.bit_depth[1], 0, 8.0, 1, 8.0, 14.0 }, - {"SourceBitDepthRescale", &configinput.src_BitDepthRescale, 0, 1.0, 1, 0.0, 1.0 }, + {"SourceBitDepthRescale", &configinput.src_BitDepthRescale, 0, 0.0, 1, 0.0, 1.0 }, // Old variables replaced from BitDepthLuma and BitDepthChroma. Considered only if SourceBitDepthRescale is 1. {"OutputBitDepthLuma", &configinput.output.bit_depth[0], 0, 8.0, 1, 8.0, 14.0 }, {"OutputBitDepthChroma", &configinput.output.bit_depth[1], 0, 8.0, 1, 8.0, 14.0 }, @@ -323,6 +337,7 @@ Mapping Map[] = { // Explicit Lambda Parameters for RDO {"UseExplicitLambdaParams", &configinput.UseExplicitLambdaParams, 0, 0.0, 1, 0.0, 3.0 }, + {"UpdateLambdaChromaME", &configinput.UpdateLambdaChromaME, 0, 0.0, 1, 0.0, 3.0 }, {"FixedLambdaPSlice", &configinput.FixedLambda[0], 2, 0.1, 2, 0.0, 0.0 }, {"FixedLambdaBSlice", &configinput.FixedLambda[1], 2, 0.1, 2, 0.0, 0.0 }, {"FixedLambdaISlice", &configinput.FixedLambda[2], 2, 0.1, 2, 0.0, 0.0 }, @@ -378,6 +393,7 @@ Mapping Map[] = { {"EPZSFixedPredictors", &configinput.EPZSFixed, 0, 2.0, 1, 0.0, 2.0 }, {"EPZSTemporal", &configinput.EPZSTemporal, 0, 1.0, 1, 0.0, 1.0 }, {"EPZSSpatialMem", &configinput.EPZSSpatialMem, 0, 1.0, 1, 0.0, 1.0 }, + {"EPZSBlockType", &configinput.EPZSBlockType, 0, 1.0, 1, 0.0, 1.0 }, {"EPZSMinThresScale", &configinput.EPZSMinThresScale, 0, 0.0, 0, 0.0, 0.0 }, {"EPZSMaxThresScale", &configinput.EPZSMaxThresScale, 0, 2.0, 0, 0.0, 0.0 }, {"EPZSMedThresScale", &configinput.EPZSMedThresScale, 0, 1.0, 0, 0.0, 0.0 }, @@ -394,7 +410,9 @@ Mapping Map[] = { {"WeightY", &configinput.WeightY, 2, 1.00, 1, 0.0, 4.0 }, {"WeightCb", &configinput.WeightCb, 2, 1.00, 1, 0.0, 4.0 }, {"WeightCr", &configinput.WeightCr, 2, 1.00, 1, 0.0, 4.0 }, - + {"WPMCPrecision", &configinput.WPMCPrecision, 0, 0.0, 1, 0.0, 2.0 }, + {"WPMCPrecFullRef", &configinput.WPMCPrecFullRef, 0, 0.0, 1, 0.0, 1.0 }, + {"WPMCPrecBSlice", &configinput.WPMCPrecBSlice, 0, 1.0, 1, 0.0, 2.0 }, // Trellis based quantization {"UseRDOQuant", &configinput.UseRDOQuant, 0, 0.0, 1, 0.0, 1.0 }, diff --git a/lencod/inc/conformance.h b/lencod/inc/conformance.h index c3013be..9c6c204 100644 --- a/lencod/inc/conformance.h +++ b/lencod/inc/conformance.h @@ -1,7 +1,7 @@ /*! ************************************************************************ - * \file comformance.h + * \file conformance.h * * \brief * Level & Profile Related definitions diff --git a/lencod/inc/defines.h b/lencod/inc/defines.h index a352a0a..de64884 100644 --- a/lencod/inc/defines.h +++ b/lencod/inc/defines.h @@ -6,8 +6,11 @@ * Header file containing some useful global definitions * * \author - * Detlev Marpe - * Copyright (C) 2000 HEINRICH HERTZ INSTITUTE All Rights Reserved. + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Detlev Marpe + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * * * \date * 21. March 2001 @@ -24,6 +27,10 @@ #define TRACE 0 //!< 0:Trace off 1:Trace on 2:detailed CABAC context information #endif +#define JM "14 (FRExt)" +#define VERSION "14.1" +#define EXT_VERSION "(FRExt)" + #define GET_METIME 1 //!< Enables or disables ME computation time #define DUMP_DPB 0 //!< Dump DPB for debug purposes #define IMGTYPE 1 //!< Define imgpel size type. 0 implies byte (cannot handle >8 bit depths) and 1 implies unsigned short @@ -47,7 +54,7 @@ #define FREXT_Hi444 244 //!< YUV 4:4:4/14 "High 4:4:4" #define FREXT_CAVLC444 44 //!< YUV 4:4:4/14 "CAVLC 4:4:4" -#define ZEROSNR 1 +#define ZEROSNR 1 // CAVLC enum { @@ -170,6 +177,7 @@ enum { #define BLOCK_SIZE_8x8 8 #define MB_BLOCK_SIZE 16 #define MB_PIXELS 256 //(MB_BLOCK_SIZE * MB_BLOCK_SIZE) +#define MB_PIXELS_SHIFT 8 // log2(MB_BLOCK_SIZE * MB_BLOCK_SIZE) #define MB_BLOCK_SHIFT 4 #define BLOCK_MULTIPLE 4 //(MB_BLOCK_SIZE/BLOCK_SIZE) #define MB_BLOCK_PARTITIONS 16 //(BLOCK_MULTIPLE * BLOCK_MULTIPLE) diff --git a/lencod/inc/enc_statistics.h b/lencod/inc/enc_statistics.h new file mode 100644 index 0000000..c98fb92 --- /dev/null +++ b/lencod/inc/enc_statistics.h @@ -0,0 +1,64 @@ +/*! + ************************************************************************** + * \file enc_statistics.h + * + * \brief + * statistics reports for the encoding process. + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Tourapis <alexismt@ieee.org> + * - Karsten Sühring <suehring@hhi.de> + * + ************************************************************************** + */ + +#ifndef _ENC_STATISTICS_H_ +#define _ENC_STATISTICS_H_ +#include "global.h" + + typedef struct + { + int quant0; //!< quant for the first frame + int quant1; //!< average quant for the remaining frames + float bitr; //!< bit rate for current frame, used only for output til terminal + float bitrate; //!< average bit rate for the sequence except first frame + int64 bit_ctr; //!< counter for bit usage + int64 bit_ctr_n; //!< bit usage for the current frame + int bit_slice; //!< number of bits in current slice + int stored_bit_slice; //!< keep number of bits in current slice (to restore status in case of MB re-encoding) + int bit_ctr_emulationprevention; //!< stored bits needed to prevent start code emulation + int b8_mode_0_use [NUM_SLICE_TYPES][2]; + int64 mode_use_transform[NUM_SLICE_TYPES][MAXMODE][2]; + int intra_chroma_mode[4]; + + // B pictures + int successive_Bframe; + int *mode_use_Bframe; + int *bit_use_mode_Bframe; + + int frame_counter; + int frame_ctr [NUM_SLICE_TYPES]; + int64 bit_counter[NUM_SLICE_TYPES]; + float bitrate_st [NUM_SLICE_TYPES]; + int64 mode_use [NUM_SLICE_TYPES][MAXMODE]; //!< Macroblock mode usage for Intra frames + int64 bit_use_mode [NUM_SLICE_TYPES][MAXMODE]; //!< statistics of bit usage + int64 bit_use_stuffingBits[NUM_SLICE_TYPES]; + int64 bit_use_mb_type [NUM_SLICE_TYPES]; + int64 bit_use_header [NUM_SLICE_TYPES]; + int64 tmp_bit_use_cbp [NUM_SLICE_TYPES]; + int64 bit_use_coeffC [NUM_SLICE_TYPES]; + int64 bit_use_coeff [3][NUM_SLICE_TYPES]; + int64 bit_use_delta_quant [NUM_SLICE_TYPES]; + + int em_prev_bits_frm; + int em_prev_bits_fld; + int *em_prev_bits; + int bit_ctr_parametersets; + int bit_ctr_parametersets_n; + } StatParameters; + + extern StatParameters *stats; + +#endif + diff --git a/lencod/inc/errdo.h b/lencod/inc/errdo.h new file mode 100644 index 0000000..ba26337 --- /dev/null +++ b/lencod/inc/errdo.h @@ -0,0 +1,34 @@ +/*! + ************************************************************************** + * \file errdo.h + * \brief Header file for error resilient RDO (name of file should change) + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Peshala Pahalawatta <ppaha@dolby.com> + * - Alexis Michael Tourapis <atour@ieee.org> + * + ************************************************************************** + */ + +#ifndef _ERRDO_H_ +#define _ERRDO_H_ + +//============= rate-distortion opt with packet losses =========== + +void init_error_conceal(int concealment_type); + +void compute_residue_block (ImageParameters *image, imgpel **imgY, int res_img[16][16], imgpel mb_pred[16][16], int b8block, int block_size); + +void decode_one_b8block (ImageParameters *image, StorablePicture *enc_pic, int decoder, int mbmode, int block8x8, short mv_mode, short b8ref); +void decode_one_mb (ImageParameters *image, StorablePicture *enc, int decoder, Macroblock* currMB); +void UpdateDecoders (InputParameters *params, ImageParameters *image, StorablePicture *enc_pic); + +void (*error_conceal_picture)(ImageParameters *image, StorablePicture *enc_pic, int decoder); +void copy_conceal_picture(ImageParameters *image, StorablePicture *enc_pic, int decoder); + +void errdo_store_best_block(ImageParameters* image, imgpel*** mbY, imgpel*** dec_img, int j0, int i0, int block_size); +void errdo_get_best_block(ImageParameters* image, imgpel*** dec_img, imgpel*** mbY, int j0, int block_size); + +#endif + diff --git a/lencod/inc/errdo_mc_prediction.h b/lencod/inc/errdo_mc_prediction.h new file mode 100644 index 0000000..683a27c --- /dev/null +++ b/lencod/inc/errdo_mc_prediction.h @@ -0,0 +1,35 @@ +/*! + ************************************************************************************* + * \file errd_mc_prediction.h + * + * \brief + * definitions for motion compensated prediction + * + * \author + * Main contributors (see contributors.h for copyright, + * address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Modified for use in hypothetical decoders at encoder + * by Peshala V. Pahalawatta <pesh@ieee.org> + * + ************************************************************************************* + */ + +#ifndef _ERRDO_MC_PREDICTION_H_ +#define _ERRDO_MC_PREDICTION_H_ + +#include "global.h" +#include "mbuffer.h" + +//extern StorablePicture *enc_picture; + +extern void get_block_luma(int decoder, ColorPlane pl, StorablePicture *dec_picture, StorablePicture *list, int x_pos, int y_pos, int ver_block_size, int hor_block_size, ImageParameters *img, imgpel block[MB_BLOCK_SIZE][MB_BLOCK_SIZE]); +extern void get_block_chroma(int decoder, int uv, StorablePicture *dec_picture, StorablePicture *list, int x_pos, int y_pos, int hor_block_size, int ver_block_size, ImageParameters *img, imgpel block[MB_BLOCK_SIZE][MB_BLOCK_SIZE]); + +//extern void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int smb); +//extern void prepare_direct_params(Macroblock *currMB, StorablePicture *dec_picture, ImageParameters *img, short pmvl0[2], short pmvl1[2],char *l0_rFrame, char *l1_rFrame); + +extern void perform_mc(int decoder, ColorPlane pl, StorablePicture *dec_picture, ImageParameters *img, int pred_dir, int l0_mode, int l1_mode, int i, int j, int list_offset, int block_size_x, int block_size_y, int curr_mb_field); +extern void perform_mc_concealment(int decoder, ColorPlane pl, StorablePicture *dec_picture, ImageParameters *img, int pred_dir, int i, int j, int block_size_x, int block_size_y); +#endif + diff --git a/lencod/inc/filehandle.h b/lencod/inc/filehandle.h new file mode 100644 index 0000000..fdbaf26 --- /dev/null +++ b/lencod/inc/filehandle.h @@ -0,0 +1,25 @@ + +/*! + *************************************************************************** + * + * \file filehandle.h + * + * \brief + * + * \date + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * + **************************************************************************/ + +#ifndef _FILEHANDLE_H_ +#define _FILEHANDLE_H_ + +int rewrite_paramsets(void); +int start_sequence(void); +int terminate_sequence(void); +int write_PPS(int, int); + + +#endif diff --git a/lencod/inc/frame.h b/lencod/inc/frame.h index 1407c3f..40c53ce 100644 --- a/lencod/inc/frame.h +++ b/lencod/inc/frame.h @@ -21,9 +21,13 @@ typedef struct int height; //!< luma component frame height int height_cr; //!< chroma component frame width int width_cr; //!< chroma component frame height + int mb_width; //!< luma component frame width + int mb_height; //!< luma component frame height int size_cmp[3]; //!< component sizes int size; //!< total image size int bit_depth[3]; //!< component bit depth + int max_value[3]; //!< component max value + int max_value_sq[3]; //!< component max value squared } FrameFormat; #endif diff --git a/lencod/inc/global.h b/lencod/inc/global.h index fccadb6..a238c5f 100644 --- a/lencod/inc/global.h +++ b/lencod/inc/global.h @@ -8,20 +8,7 @@ * global definitions for H.264 encoder. * * \author - * Copyright (C) 1999 Telenor Satellite Services,Norway - * Ericsson Radio Systems, Sweden - * - * Inge Lille-Langoy <inge.lille-langoy@telenor.com> - * - * Telenor Satellite Services - * Keysers gt.13 tel.: +47 23 13 86 98 - * N-0130 Oslo,Norway fax.: +47 22 77 79 80 - * - * Rickard Sjoberg <rickard.sjoberg@era.ericsson.se> - * - * Ericsson Radio Systems - * KI/ERA/T/VV - * 164 80 Stockholm, Sweden + * Main contributors (see contributors.h for copyright, address and affiliation details) * ************************************************************************ */ @@ -206,7 +193,8 @@ typedef enum B_SLICE = 1, I_SLICE = 2, SP_SLICE = 3, - SI_SLICE = 4 + SI_SLICE = 4, + NUM_SLICE_TYPES = 5 } SliceType; //Motion Estimation levels @@ -410,15 +398,14 @@ typedef struct macroblock int64 cbp_bits[3]; int64 cbp_bits_8x8[3]; - short bi_pred_me; + short bipred_me[4]; //!< bi prediction ME type for a 8x8 block (0 : not used, 1: type 1, 2: type 2) // rate control double actj; // macroblock activity measure for macroblock j int prev_qp; int prev_dqp; int prev_cbp; - int predict_qp; - int predict_error; + struct macroblock *mb_available_up; //!< pointer to neighboring MB (CABAC) struct macroblock *mb_available_left; //!< pointer to neighboring MB (CABAC) @@ -464,6 +451,7 @@ typedef struct { int picture_id; int qp; + int qs; int picture_type; //!< picture type int start_mb_nr; int max_part_nr; //!< number of different partitions @@ -490,6 +478,33 @@ typedef struct #define MAXSLICEPERPICTURE 100 + +enum { + SSE = 0, + SSE_RGB = 1, + PSNR = 2, + PSNR_RGB = 3, + SSIM = 4, + SSIM_RGB = 5, + MS_SSIM = 6, + MS_SSIM_RGB = 7, + TOTAL_DIST_TYPES = 8 +} distortion_types; + +//! DistortionParams +typedef struct +{ + float value[3]; //!< current frame distortion + float average[3]; //!< average frame distortion + float avslice[NUM_SLICE_TYPES][3]; //!< average frame type distortion +} DistMetric; + +typedef struct +{ + int frame_ctr; //!< number of coded frames + DistMetric metric[TOTAL_DIST_TYPES]; //!< Distortion metrics +} DistortionParams; + typedef struct { int no_slices; @@ -497,9 +512,7 @@ typedef struct int bits_per_picture; Slice *slices[MAXSLICEPERPICTURE]; - float distortion_y; - float distortion_u; - float distortion_v; + DistMetric distortion; } Picture; Picture *p_frame_pic; @@ -514,10 +527,8 @@ long *Bit_Buffer; // global picture format dependend buffers, mem allocation in image.c imgpel **pImgOrg[MAX_PLANE]; imgpel **pCurImg; //!< Reference image. Luma for other profiles, can be any component for 4:4:4 -imgpel ***imgUV_org; //!< Reference chroma image int **imgY_sub_tmp; //!< Y picture temporary component (Quarter pel) - int **PicPos; unsigned int log2_max_frame_num_minus4; unsigned int log2_max_pic_order_cnt_lsb_minus4; @@ -548,17 +559,11 @@ int wp_luma_round; int wp_chroma_round; // global picture format dependend buffers, mem allocation in image.c (field picture) -imgpel **imgY_org_top; -imgpel **imgY_org_bot; - -imgpel ***imgUV_org_top; -imgpel ***imgUV_org_bot; - -imgpel **imgY_org_frm; -imgpel ***imgUV_org_frm; +imgpel **img_org_top[MAX_PLANE]; +imgpel **img_org_bot[MAX_PLANE]; +imgpel **img_org_frm[MAX_PLANE]; imgpel **imgY_com; //!< Encoded luma images -imgpel **imgY_org_frm_JV[MAX_PLANE]; //!< imgY_org_frm to be used during 4:4:4 independent mode encoding imgpel ***imgUV_com; //!< Encoded croma images char ***direct_ref_idx; //!< direct mode reference index buffer @@ -569,7 +574,6 @@ byte **pixel_map; //!< Shows the latest reference frame that is reliable for e byte **refresh_map; //!< Stores the new values for pixel_map int intras; //!< Counts the intra updates in each frame. -int frame_ctr[5]; int frame_no, nextP_tr_fld, nextP_tr_frm; time_t tot_time; @@ -583,42 +587,22 @@ char b8_ipredmode8x8[4][4], b8_intra_pred_modes8x8[16]; //! Info for the "decoders-in-the-encoder" used for rdoptimization with packet losses typedef struct { - int **resY; //!< Residue of Luminance - imgpel ***decY; //!< Decoded values at the simulated decoders - imgpel ****decref; //!< Reference frames of the simulated decoders - imgpel ***decY_best; //!< Decoded frames for the best mode for all decoders - imgpel **RefBlock; - byte **status_map; - byte **dec_mb_mode; + imgpel ***dec_mbY; //!< Best decoded macroblock pixel values in RDO + imgpel ***dec_mbY8x8; //!< Best decoded 8x8 mode pixel values in RDO + int res_img[MAX_PLANE][16][16]; //Residual values for macroblock } Decoders; extern Decoders *decs; -//! SNRParameters -typedef struct -{ - float snr_y; //!< current Y SNR - float snr_u; //!< current U SNR - float snr_v; //!< current V SNR - float snr_y1; //!< SNR Y(dB) first frame - float snr_u1; //!< SNR U(dB) first frame - float snr_v1; //!< SNR V(dB) first frame - float snr_yt[5]; //!< SNR Y(dB) based on frame type - float snr_ut[5]; //!< SNR U(dB) based on frame type - float snr_vt[5]; //!< SNR V(dB) based on frame type - float snr_ya; //!< Average SNR Y(dB) remaining frames - float snr_ua; //!< Average SNR U(dB) remaining frames - float snr_va; //!< Average SNR V(dB) remaining frames - float sse_y; //!< SSE Y - float sse_u; //!< SSE U - float sse_v; //!< SSE V - float msse_y; //!< Average SSE Y - float msse_u; //!< Average SSE U - float msse_v; //!< Average SSE V - int frame_ctr; //!< number of coded frames -} SNRParameters; #define FILE_NAME_SIZE 200 +typedef struct +{ + double md; //!< Mode decision Lambda + double me[3]; //!< Motion Estimation Lambda + int mf[3]; //!< Integer formatted Motion Estimation Lambda +} LambdaParams; + // VUI Parameters typedef struct { @@ -676,7 +660,18 @@ typedef struct int max_dec_frame_buffering; } VUIParameters; - //! all input parameters +//! block 8x8 temporary RD info +typedef struct +{ + short best8x8mode [4]; + char best8x8pdir [MAXMODE][4]; + char best8x8l0ref [MAXMODE][4]; + char best8x8l1ref [MAXMODE][4]; + short bipred8x8me [MAXMODE][4]; +} Block8x8Info; + + +//! all input parameters typedef struct { int ProfileIDC; //!< value of syntax element profile_idc @@ -749,7 +744,9 @@ typedef struct int directInferenceFlag; //!< Direct Mode Inference Flag int BiPredMotionEstimation; - int BiPredMERefinements; + int BiPredSearch[4]; //!< Use Bi prediction for modes 16x16, 16x8, 8x16, and 8x8 + + int BiPredMERefinements; //!< Number of bipred refinements int BiPredMESearchRange; int BiPredMESubPel; @@ -767,7 +764,12 @@ typedef struct int WeightedPrediction; //!< Weighted prediction for P frames (0: not used, 1: explicit) int WeightedBiprediction; //!< Weighted prediction for B frames (0: not used, 1: explicit, 2: implicit) - int WPMethod; + int WPMethod; //!< WP method (0: DC, 1: LMS) + int WPMCPrecision; + int WPMCPrecFullRef; + int WPMCPrecBSlice; + int EnhancedBWeightSupport; + int ChromaWeightSupport; //!< Weighted prediction support for chroma (0: disabled, 1: enabled) int UseWeightedReferenceME; //!< Use Weighted Reference for ME. int RDPictureDecision; //!< Perform RD optimal decision between various coded versions of same picture int RDPictureIntra; //!< Enabled RD pic decision for intra as well. @@ -814,6 +816,7 @@ typedef struct int EPZSFixed; int EPZSTemporal; int EPZSSpatialMem; + int EPZSBlockType; int EPZSMinThresScale; int EPZSMaxThresScale; int EPZSMedThresScale; @@ -835,6 +838,10 @@ typedef struct int qp02, qpBRS2Offset; #endif int rdopt; + int Distortion[TOTAL_DIST_TYPES]; + double VisualResWavPSNR; + int SSIMOverlapSize; + int DistortionYUVtoRGB; int CtxAdptLagrangeMult; //!< context adaptive lagrangian multiplier int FastCrIntraDecision; int disthres; @@ -855,15 +862,16 @@ typedef struct int LossRateB; //!< assumed loss probablility of partition B, in per cent, used for loss-aware R/D int LossRateC; //!< assumed loss probablility of partition C, in per cent, used for loss-aware R/D int NoOfDecoders; + int ErrorConcealment; //!< Error concealment method used for loss-aware RDO (0: Copy Concealment) int RestrictRef; int NumFramesInELSubSeq; int RandomIntraMBRefresh; //!< Number of pseudo-random intra-MBs per picture int DFSendParameters; - int DFDisableIdc[2][5]; - int DFAlpha[2][5]; - int DFBeta[2][5]; + int DFDisableIdc[2][NUM_SLICE_TYPES]; + int DFAlpha [2][NUM_SLICE_TYPES]; + int DFBeta [2][NUM_SLICE_TYPES]; int SparePictureOption; int SPDetectionThreshold; @@ -904,8 +912,8 @@ typedef struct double RCBoverPRatio; double RCISliceBitRatio; double RCBSliceBitRatio[RC_MAX_TEMPORAL_LEVELS]; - int RCMinQP[5]; - int RCMaxQP[5]; + int RCMinQP[NUM_SLICE_TYPES]; + int RCMaxQP[NUM_SLICE_TYPES]; int RCMaxQPChange; // Search Algorithm @@ -925,6 +933,7 @@ typedef struct // Lambda Params int UseExplicitLambdaParams; + int UpdateLambdaChromaME; double LambdaWeight[6]; double FixedLambda[6]; @@ -935,8 +944,8 @@ typedef struct int AdaptRoundingFixed; //!< Global rounding for all qps int AdaptRndPeriod; //!< Set period for adaptive rounding of JVT-N011 in MBs int AdaptRndChroma; - int AdaptRndWFactor[2][5]; //!< Weighting factors for luma component based on reference indicator and slice type - int AdaptRndCrWFactor[2][5]; //!< Weighting factors for chroma components based on reference indicator and slice type + int AdaptRndWFactor [2][NUM_SLICE_TYPES]; //!< Weighting factors for luma component based on reference indicator and slice type + int AdaptRndCrWFactor[2][NUM_SLICE_TYPES]; //!< Weighting factors for chroma components based on reference indicator and slice type // Fast Mode Decision int EarlySkipEnable; int SelectiveIntraEnable; @@ -954,6 +963,7 @@ typedef struct int ChromaMEWeight; int MEErrorMetric[3]; int ModeDecisionMetric; + int SkipDeBlockNonRef; // tone mapping SEI message int ToneMappingSEIPresentFlag; @@ -1047,25 +1057,25 @@ typedef struct imgpel mpr_4x4 [MAX_PLANE][9][16][16]; //!< prediction samples for 4x4 intra prediction modes imgpel mpr_8x8 [MAX_PLANE][9][16][16]; //!< prediction samples for 8x8 intra prediction modes imgpel mpr_16x16[MAX_PLANE][5][16][16]; //!< prediction samples for 16x16 intra prediction modes (and chroma) - imgpel mpr [MAX_PLANE][16][16]; //!< current best prediction mode - int m7 [MAX_PLANE][16][16]; //!< the diff pixel values between the original macroblock/block and its prediction + imgpel mb_pred [MAX_PLANE][16][16]; //!< current best prediction mode + int mb_rres [MAX_PLANE][16][16]; //!< the diff pixel values between the original macroblock/block and its prediction (reconstructed) + int mb_ores [MAX_PLANE][16][16]; //!< the diff pixel values between the original macroblock/block and its prediction (original) int (*curr_res)[16]; //!< pointer to current residual imgpel (*curr_prd)[16]; //!< pointer to current prediction int ****cofAC; //!< AC coefficients [8x8block][4x4block][level/run][scan_pos] - int ***cofDC; //!< DC coefficients [yuv][level/run][scan_pos] + int *** cofDC; //!< DC coefficients [yuv][level/run][scan_pos] int ***fadjust4x4; //!< Transform coefficients for 4x4 luma. Excludes DC for I16x16 int ***fadjust8x8; //!< Transform coefficients for 8x8 luma int ****fadjust4x4Cr; //!< Transform coefficients for 4x4 chroma. Excludes DC chroma. int ****fadjust8x8Cr; //!< Transform coefficients for 4x4 chroma within 8x8 inter blocks. - Picture *currentPicture; //!< The coded picture currently in the works (typically p_frame_pic, field_pic[0], or field_pic[1]) Slice *currentSlice; //!< pointer to current Slice data struct Macroblock *mb_data; //!< array containing all MBs of a whole frame - + Block8x8Info *b8x8info; //!< block 8x8 information for RDopt int *quad; //!< Array containing square values,used for snr computation */ /* Values are limited to 5000 for pixel differences over 70 (sqr(5000)). int *intra_block; @@ -1073,12 +1083,6 @@ typedef struct int fld_type; //!< top or bottom field unsigned int fld_flag; unsigned int rd_pass; - int direct_intraP_ref[4][4]; - int pstruct_next_P; - int imgtr_next_P_frm; - int imgtr_last_P_frm; - int imgtr_next_P_fld; - int imgtr_last_P_fld; // B pictures double b_interval; @@ -1089,17 +1093,15 @@ typedef struct short****** pred_mv; //!< motion vector predictors for all block types and all reference frames short****** all_mv; //!< replaces local all_mv - - short****** bipred_mv1; //!< Biprediction MVs - short****** bipred_mv2; //!< Biprediction MVs - short bi_pred_me[MAXMODE]; - + short******* bipred_mv; //!<Biprediction MVs + int DFDisableIdc; int DFAlphaC0Offset; int DFBetaOffset; int direct_spatial_mv_pred_flag; //!< Direct Mode type to be used (0: Temporal, 1: Spatial) + int num_ref_idx_active_list[2]; int num_ref_idx_l0_active; int num_ref_idx_l1_active; @@ -1110,7 +1112,7 @@ typedef struct int i16offset; int layer; //!< which layer this picture belonged to - int old_layer; //!< old layer number + int NoResidueDirect; int AdaptiveRounding; //!< Adaptive Rounding parameter based on JVT-N011 @@ -1195,6 +1197,7 @@ typedef struct int max_qp_delta; int min_qp_delta; // Lagrangian Parameters + LambdaParams **lambda; double **lambda_md; //!< Mode decision Lambda double ***lambda_me; //!< Motion Estimation Lambda int ***lambda_mf; //!< Integer formatted Motion Estimation Lambda @@ -1203,7 +1206,8 @@ typedef struct unsigned int dc_pred_value_comp[MAX_PLANE]; //!< component value for DC prediction (depends on component pel bit depth) unsigned int dc_pred_value; //!< DC prediction value for current component - int max_imgpel_value_comp[MAX_PLANE]; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth) + int max_imgpel_value_comp [MAX_PLANE]; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth) + int max_imgpel_value_comp_sq [MAX_PLANE]; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth) int max_imgpel_value; //!< max value that one picture element (pixel) can take (depends on pic_unit_bitdepth) int num_blk8x8_uv; @@ -1241,50 +1245,17 @@ typedef struct int masterQP; } ImageParameters; -#define NUM_PIC_TYPE 5 - //!< statistics -typedef struct -{ - int quant0; //!< quant for the first frame - int quant1; //!< average quant for the remaining frames - float bitr; //!< bit rate for current frame, used only for output til terminal - float bitrate; //!< average bit rate for the sequence except first frame - int64 bit_ctr; //!< counter for bit usage - int64 bit_ctr_n; //!< bit usage for the current frame - int bit_slice; //!< number of bits in current slice - int stored_bit_slice; //!< keep number of bits in current slice (to restore status in case of MB re-encoding) - int bit_ctr_emulationprevention; //!< stored bits needed to prevent start code emulation - int b8_mode_0_use[NUM_PIC_TYPE][2]; - int mode_use_transform[2][NUM_PIC_TYPE][MAXMODE]; - int intra_chroma_mode[4]; - // B pictures - int successive_Bframe; - int *mode_use_Bframe; - int *bit_use_mode_Bframe; - int64 bit_ctr_I; - int64 bit_ctr_P; - int64 bit_ctr_B; - float bitrate_I; - float bitrate_P; - float bitrate_B; - - int64 mode_use [NUM_PIC_TYPE][MAXMODE]; //!< Macroblock mode usage for Intra frames - int64 bit_use_mode [NUM_PIC_TYPE][MAXMODE]; //!< statistics of bit usage - int64 bit_use_stuffingBits[NUM_PIC_TYPE]; - int64 bit_use_mb_type [NUM_PIC_TYPE]; - int64 bit_use_header [NUM_PIC_TYPE]; - int64 tmp_bit_use_cbp [NUM_PIC_TYPE]; - int64 bit_use_coeffC [NUM_PIC_TYPE]; - int64 bit_use_coeff [3][NUM_PIC_TYPE]; - int64 bit_use_delta_quant [NUM_PIC_TYPE]; - - int em_prev_bits_frm; - int em_prev_bits_fld; - int *em_prev_bits; - int bit_ctr_parametersets; - int bit_ctr_parametersets_n; -} StatParameters; +//! definition of pic motion parameters +typedef struct pic_motion_params2 +{ + int64 ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] + int64 ref_id; //!< reference picture identifier [list][subblock_y][subblock_x] + short mv[2]; //!< motion vector [list][subblock_x][subblock_y][component] + char ref_idx; //!< reference picture [list][subblock_y][subblock_x] + byte mb_field; //!< field macroblock indicator + byte field_frame; //!< indicates if co_located is field or frame. +} PicMotionParams2; // Motion Vector structure typedef struct @@ -1320,7 +1291,6 @@ typedef struct int prev_cbp; int64 cbp_blk; - short bi_pred_me; short ******pred_mv; //!< predicted motion vectors short ******all_mv; //!< all modes motion vectors @@ -1346,9 +1316,15 @@ typedef struct typedef struct { - int cost8x8; + int mb_p8x8_cost; + int smb_p8x8_cost[4]; + double smb_p8x8_rdcost[4]; int lrec[16][16]; // transform and quantized coefficients will be stored here for SP frames + int cbp8x8; + int cbp_blk8x8; + int cnt_nonz_8x8; short part8x8mode[4]; + short part8x8bipred[4]; char part8x8pdir[4]; char part8x8l0ref[4]; char part8x8l1ref[4]; @@ -1356,9 +1332,9 @@ typedef struct imgpel mpr8x8[16][16]; imgpel mpr8x8CbCr[2][16][16]; imgpel rec_mb8x8_cr[2][16][16]; - } RD_8x8DATA; + typedef struct { double lambda_md; //!< Mode decision Lambda @@ -1382,12 +1358,10 @@ int ***motion_cost8; extern InputParameters *params; extern ImageParameters *img; -extern StatParameters *stats; -extern SNRParameters *snr; +extern DistortionParams *dist; // files -FILE *p_stat; //!< status file for the last encoding session FILE *p_log; //!< SNR file FILE *p_trace; //!< Trace file int p_in; //!< original YUV file handle @@ -1404,38 +1378,21 @@ int CbCr_predmode_8x8[4]; */ void intrapred_4x4 (Macroblock *currMB, ColorPlane pl, int CurrPixX,int CurrPixY, int *left_available, int *up_available, int *all_available); +void intrapred_16x16 (Macroblock *currMB, ColorPlane pl); +// Transform function pointers int (*pDCT_4x4) (Macroblock *currMB, ColorPlane pl, int block_x, int block_y, int *coeff_cost, int intra); int (*pDCT_16x16) (Macroblock *currMB, ColorPlane pl, int); int (*pDCT_8x8) (Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra); -int dct_4x4 (Macroblock *currMB, ColorPlane pl, int pos_mb1, int pos_mb2, int *cnt_nonz, int intra); -int dct_4x4_ls (Macroblock *currMB, ColorPlane pl, int block_x, int block_y, int *coeff_cost, int intra); -int dct_16x16 (Macroblock *currMB, ColorPlane pl, int); -int dct_16x16_ls (Macroblock *currMB, ColorPlane pl, int); +int (*dct_cr_4x4[2]) (Macroblock *currMB, int uv,int i11); + int dct_8x8 (Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra); int dct_8x8_cavlc (Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra); int dct_8x8_ls (Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra); - -int dct_4x4_sp (Macroblock *currMB, ColorPlane pl, int pos_mb1,int pos_mb2,int *cnt_nonz, int intra); -int dct_4x4_sp2 (Macroblock *currMB, ColorPlane pl, int pos_mb1,int pos_mb2,int *cnt_nonz, int intra); void copyblock_sp (Macroblock *currMB, ColorPlane pl, int pos_mb1,int pos_mb2); -int (*dct_cr_4x4[2]) (Macroblock *currMB, int uv,int i11); -int dct_chroma (Macroblock *currMB, int uv,int i11); int dct_chroma_sp (Macroblock *currMB, int uv,int i11); int dct_chroma_sp2 (Macroblock *currMB, int uv,int i11); -//For residual DPCM -int Residual_DPCM_4x4(int ipmode, int m7[16][16], int block_y, int block_x); - - -void intrapred_16x16 (Macroblock *currMB, ColorPlane pl); - -void init_poc(void); - -void init_img(void); -void report(void); -int get_picture_type(void); -void DeblockFrame(ImageParameters *img, imgpel **, imgpel ***) ; int distortion4x4(int*); int distortion8x8(int*); @@ -1444,34 +1401,28 @@ extern int* refbits; extern int**** motion_cost; double *mb16x16_cost_frame; +void FindSkipModeMotionVector (Macroblock *currMB); void Get_Direct_Motion_Vectors (Macroblock *currMB); void PartitionMotionSearch (Macroblock *currMB, int, int, int*); int BIDPartitionCost (Macroblock *currMB, int, int, char[2], int); -int writeAbpCoeffIndex (int, int, int, int); +int BPredPartitionCost (Macroblock *currMB, int, int, short, short, int, int); +int GetDirectCostMB (Macroblock *currMB, int bslice); +int GetDirectCost8x8 (Macroblock *currMB, int, int*); -void poc_based_ref_management(int current_pic_num); +void poc_based_ref_management_frame_pic(int current_pic_num); +void poc_based_ref_management_field_pic(int current_pic_num); + int picture_coding_decision (Picture *picture1, Picture *picture2, int qp); unsigned CeilLog2( unsigned uiVal); -int GetDirectCost8x8 (Macroblock *currMB, int, int*); - -int BPredPartitionCost (Macroblock *currMB, int, int, short, short, int, int); - -int GetDirectCostMB (Macroblock *currMB, int bslice); - -int GetSkipCostMB (Macroblock *currMB); -void FindSkipModeMotionVector (Macroblock *currMB); - // dynamic mem allocation int init_global_buffers(void); void free_global_buffers(void); void no_mem_exit (char *where); -int get_mem_mv (short*******); -void free_mem_mv (short******); void free_img (void); int get_mem_ACcoeff (int*****); @@ -1482,62 +1433,23 @@ void free_mem_DCcoeff (int***); int decide_fld_frame(float snr_frame_Y, float snr_field_Y, int bit_field, int bit_frame, double lambda_picture); void combine_field(void); -Picture *malloc_picture(void); -void free_picture (Picture *pic); - int encode_one_slice(int SLiceGroupId, Picture *pic, int TotalCodedMBs); //! returns the number of MBs in the slice - -void trellis_coding(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb); - void free_slice_list(Picture *currPic); -void report_stats_on_error(void); - #if TRACE void trace2out(SyntaxElement *se); void trace2out_cabac(SyntaxElement *se); #endif - void error(char *text, int code); -int start_sequence(void); -int rewrite_paramsets(void); -int terminate_sequence(void); -int start_slice(void); -int terminate_slice(int); -int write_PPS(int, int); - -// B pictures -void InitMotionVectorSearchModule(void); int field_flag_inference(Macroblock *currMB); - void set_mbaff_parameters(Macroblock *currMB); // For MB AFF -void writeVlcByteAlign(Bitstream* currStream); - -//============= rate-distortion optimization =================== -void clear_rdopt (void); -void init_rdopt (void); -//============= rate-distortion opt with packet losses =========== -void decode_one_macroblock(void); -void decode_one_mb (int, Macroblock*); -void decode_one_b8block (int, int, int, short, short); - -void compute_residue_b8block (int, int); -void compute_residue_mb (int); -void UpdateDecoders(void); //============= restriction of reference frames based on the latest intra-refreshes========== void UpdatePixelMap(void); -//============= fast full integer search ======================= -void ClearFastFullIntegerSearch (void); -void ResetFastFullIntegerSearch (void); - -void SetImgType(void); - - int64 compute_SSE(imgpel **imgRef, imgpel **imgSrc, int xRef, int xSrc, int ySize, int xSize); // Tian Dong: for IGOPs @@ -1553,33 +1465,32 @@ int CalculateFrameNumber(void); void AllocNalPayloadBuffer(void); void FreeNalPayloadBuffer(void); -void SODBtoRBSP(Bitstream *currStream); -int RBSPtoEBSP(byte *streamBuffer, int begin_bytepos, int end_bytepos, int min_num_bytes); -int Bytes_After_Header; - -void reset_valid_modes(RD_PARAMS *enc_mb); +void SODBtoRBSP (Bitstream *currStream); +int RBSPtoEBSP (byte *streamBuffer, int begin_bytepos, int end_bytepos, int min_num_bytes); +int Bytes_After_Header; -// Fast ME enable -int BlockMotionSearch (Macroblock *currMB, short,int,int,int,int,int, int*); -void low_complexity_encode_md (void); void encode_one_macroblock_low (Macroblock *currMB); void encode_one_macroblock_high (Macroblock *currMB); void encode_one_macroblock_highfast (Macroblock *currMB); void encode_one_macroblock_highloss (Macroblock *currMB); void (*encode_one_macroblock) (Macroblock *currMB); -void update_qp (Macroblock *currMB); +int is_bipred_enabled(int mode); + +void update_qp (ImageParameters *img, Macroblock *currMB); void select_plane (ColorPlane color_plane); -void select_dct (Macroblock *currMB); +void select_dct (ImageParameters *img, Macroblock *currMB); void store_coding_state_cs_cm(Macroblock *currMB); void reset_coding_state_cs_cm(Macroblock *currMB); -int writeIPCMBytes(Bitstream *currStream); +int writeIPCMBytes (Bitstream *currStream); int writePCMByteAlign(Bitstream *currStream); void set_slice_type(int slice_type); +void free_encoder_memory(ImageParameters *img); + int check_for_SI16(void); int **lrec ; int ***lrec_uv; @@ -1587,8 +1498,7 @@ int si_frame_indicator; int sp2_frame_indicator; int number_sp2_frames; -//#define sp_output_indicator 0 //will be in the config file -//#define sp_output_filename "sp_stored.txt" // will be in the config file + void output_SP_coefficients(void); void read_SP_coefficients(void); @@ -1601,10 +1511,10 @@ int gaaiMBAFF_NZCoeff[4][12]; // Redundant picture imgpel **imgY_tmp; imgpel **imgUV_tmp[2]; -int frameNuminGOP; -int redundant_coding; -int key_frame; -int redundant_ref_idx; +int frameNuminGOP; +int redundant_coding; +int key_frame; +int redundant_ref_idx; void Init_redundant_frame(void); void Set_redundant_frame(void); void encode_one_redundant_frame(void); @@ -1628,8 +1538,9 @@ int img_cr_padded_size_x2; int img_cr_padded_size_x4; // struct with pointers to the sub-images -typedef struct { - imgpel ****luma; // component 0 (usually Y, X, or R) +typedef struct +{ + imgpel ****luma; // component 0 (usually Y, X, or R) imgpel ****crcb[2]; // component 2 (usually U/V, Y/Z, or G/B) } SubImageContainer; diff --git a/lencod/inc/ifunctions.h b/lencod/inc/ifunctions.h index f552278..157600e 100644 --- a/lencod/inc/ifunctions.h +++ b/lencod/inc/ifunctions.h @@ -21,6 +21,7 @@ #define static #define inline #endif +#include <math.h> static inline int imin(int a, int b) { @@ -97,6 +98,11 @@ static inline int rshift_rnd(int x, int a) return (a > 0) ? ((x + (1 << (a-1) )) >> a) : (x << (-a)); } +static inline int rshift_rnd_sign(int x, int a) +{ + return (x > 0) ? ( ( x + (1 << (a-1)) ) >> a ) : (-( ( iabs(x) + (1 << (a-1)) ) >> a )); +} + static inline unsigned int rshift_rnd_us(unsigned int x, unsigned int a) { return (a > 0) ? ((x + (1 << (a-1))) >> a) : x; @@ -156,6 +162,19 @@ static inline int float2int (float x) return (int)((x < 0) ? (x - 0.5f) : (x + 0.5f)); } +#if ZEROSNR +static inline float psnr(int max_sample_sq, int samples, float sse_distortion ) +{ + return (float) (10.0 * log10(max_sample_sq * (double) ((double) samples / (sse_distortion == 0.0 ? 1.0 : sse_distortion)))); +} +#else +static inline float psnr(int max_sample_sq, int samples, float sse_distortion ) +{ + return (float) (sse_distortion == 0.0 ? 0.0 : (10.0 * log10(max_sample_sq * (double) ((double) samples / sse_distortion)))); +} +#endif + + # if !defined(WIN32) && (__STDC_VERSION__ < 199901L) #undef static #undef inline diff --git a/lencod/inc/image.h b/lencod/inc/image.h index 389f939..94e909f 100644 --- a/lencod/inc/image.h +++ b/lencod/inc/image.h @@ -7,8 +7,11 @@ * headers for image processing * * \author - * Inge Lille-Langoy <inge.lille-langoy@telenor.com> - * Copyright (C) 1999 Telenor Satellite Services, Norway + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Sühring <suehring@hhi.de> + * - Inge Lille-Langoy <inge.lille-langoy@telenor.com> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * ************************************************************************ */ #ifndef _IMAGE_H_ @@ -21,14 +24,14 @@ extern StorablePicture **enc_frame_picture; extern StorablePicture **enc_field_picture; extern StorablePicture *enc_frame_picture_JV[MAX_PLANE]; //!< enc_frame to be used during 4:4:4 independent mode encoding -int encode_one_frame (void); -void report_frame_statistic(void); +int encode_one_frame (void); Boolean dummy_slice_too_big(int bits_slice); void copy_rdopt_data (Macroblock *currMB, int field_type); // For MB level field/frame coding tools void UnifiedOneForthPix (StorablePicture *s); // For 4:4:4 independent mode void UnifiedOneForthPix_JV (int nplane, StorablePicture *s); +void frame_picture (Picture *frame, int rd_pass); #endif diff --git a/lencod/inc/img_dist_ms_ssim.h b/lencod/inc/img_dist_ms_ssim.h new file mode 100644 index 0000000..19c5918 --- /dev/null +++ b/lencod/inc/img_dist_ms_ssim.h @@ -0,0 +1,25 @@ +/*! + *************************************************************************** + * \file + * img_dist_ms_ssim.h + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + * \date + * 18 July 2008 + * + * \brief + * Headerfile to calculate multi-scale structural similarity (SSIM) index + ************************************************************************** + */ + +#ifndef _IMG_DIST_MS_SSIM_H_ +#define _IMG_DIST_MS_SSIM_H_ +#include "img_distortion.h" + +void find_ms_ssim (ImageStructure *imgREF, ImageStructure *imgSRC, DistMetric metricMS_SSIM[3]); + +#endif diff --git a/lencod/inc/img_dist_snr.h b/lencod/inc/img_dist_snr.h new file mode 100644 index 0000000..08d8edc --- /dev/null +++ b/lencod/inc/img_dist_snr.h @@ -0,0 +1,24 @@ +/*! + *************************************************************************** + * \file + * img_dist_snr.h + * + * \author + * Woo-Shik Kim + * + * \date + * 29 May 2008 + * + * \brief + * Headerfile to calculate signal to noise ratio (SNR) + ************************************************************************** + */ + +#ifndef _IMG_DIST_SNR_H_ +#define _IMG_DIST_SNR_H_ +#include "img_distortion.h" + +void find_snr(ImageStructure *imgREF, ImageStructure *imgSRC, DistMetric metricSSE[3], DistMetric metricPSNR[3]); + +#endif + diff --git a/lencod/inc/img_dist_ssim.h b/lencod/inc/img_dist_ssim.h new file mode 100644 index 0000000..c10b278 --- /dev/null +++ b/lencod/inc/img_dist_ssim.h @@ -0,0 +1,26 @@ +/*! + *************************************************************************** + * \file + * img_dist_ssim.h + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + * \date + * 29 May 2008 + * + * \brief + * Headerfile to calculate structural similarity (SSIM) index + ************************************************************************** + */ + +#ifndef _IMG_DIST_SSIM_H_ +#define _IMG_DIST_SSIM_H_ +#include "img_distortion.h" + +void find_ssim (ImageStructure *imgREF, ImageStructure *imgSRC, DistMetric metricSSIM[3]); + +#endif + diff --git a/lencod/inc/img_distortion.h b/lencod/inc/img_distortion.h new file mode 100644 index 0000000..e1479be --- /dev/null +++ b/lencod/inc/img_distortion.h @@ -0,0 +1,33 @@ + +/*! + ************************************************************************ + * \file img_distortion.h + * + * \brief + * Distortion related definitions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * + ************************************************************************ + */ + +#ifndef _IMG_DISTORTION_H_ +#define _IMG_DISTORTION_H_ + +typedef struct +{ + FrameFormat format; //!< ImageStructure format Information + imgpel **data[3]; //!< ImageStructure pixel data +} ImageStructure; + +void accumulate_avslice(DistMetric metric[3], int slice_type, int frames); +void accumulate_average(DistMetric metric[3], int frames); +void find_distortion(void); +void select_img(ImageStructure *imgSRC, ImageStructure *imgREF); +void compute_distortion(void); + +#endif + diff --git a/lencod/inc/macroblock.h b/lencod/inc/macroblock.h index 60ee121..357bcfc 100644 --- a/lencod/inc/macroblock.h +++ b/lencod/inc/macroblock.h @@ -41,7 +41,7 @@ int writeMBLayer (Macroblock *currMB, int rdopt, int *coeff_rate); void write_terminating_bit (short bit); int writeReferenceFrame (Macroblock *currMB, int mode, int i, int j, int fwd_flag, int ref); -int writeMotionVector8x8 (Macroblock *currMB, int i0, int j0, int i1, int j1, int refframe, int list_idx, int mv_mode); +int writeMotionVector8x8 (Macroblock *currMB, int i0, int j0, int i1, int j1, int refframe, int list_idx, int mv_mode, short bipred_me); int writeCoeff4x4_CABAC (Macroblock *currMB, ColorPlane, int, int, int); int writeCoeff8x8_CABAC (Macroblock* currMB, ColorPlane, int, int); @@ -57,7 +57,10 @@ int distortion_hadamard(imgpel **img_org, imgpel pred_img[16][16]); double (*find_sad_16x16) (Macroblock *currMB, int *intra_mode); double find_sad_16x16_JM (Macroblock *currMB, int *intra_mode); -void SetLagrangianMultipliers(); +void SetLagrangianMultipliersOn(); +void SetLagrangianMultipliersOff(); +void (*SetLagrangianMultipliers)(); + void init_slice(int start_mb_addr); #endif diff --git a/lencod/inc/mb_access.h b/lencod/inc/mb_access.h index 80f56a3..3a86eb4 100644 --- a/lencod/inc/mb_access.h +++ b/lencod/inc/mb_access.h @@ -8,7 +8,8 @@ * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) - * - Karsten Sühring <suehring@hhi.de> + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> ************************************************************************************* */ diff --git a/lencod/inc/mbuffer.h b/lencod/inc/mbuffer.h index f5c8aad..bdfe8ab 100644 --- a/lencod/inc/mbuffer.h +++ b/lencod/inc/mbuffer.h @@ -24,6 +24,18 @@ typedef struct picture_stats } PictureStats; +//! definition of pic motion parameters +typedef struct pic_motion_params +{ + int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] + int64 *** ref_id; //!< reference picture identifier [list][subblock_y][subblock_x] + short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] + char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] + byte * mb_field; //!< field macroblock indicator + byte ** field_frame; //!< indicates if co_located is field or frame. + +} PicMotionParams; + //! definition a picture (field or frame) typedef struct storable_picture { @@ -58,28 +70,26 @@ typedef struct storable_picture imgpel ** imgY; //!< Y picture component imgpel **** imgY_sub; //!< Y picture component upsampled (Quarter pel) - imgpel *****imgUV_sub; //!< UV picture component upsampled (Quarter/One-Eighth pel) imgpel *** imgUV; //!< U and V picture components + imgpel *****imgUV_sub; //!< UV picture component upsampled (Quarter/One-Eighth pel) + + //Multiple Decoder Buffers (used if rdopt==3) + imgpel *** dec_imgY; //!< Decoded Y component in multiple hypothetical decoders + imgpel **** dec_imgUV; //!< Decoded U and V components in multiple hypothetical decoders + imgpel *** p_dec_img[MAX_PLANE]; //!< pointer array for accessing decoded pictures in hypothetical decoders + + byte *** mb_error_map; //!< Map of macroblock errors in hypothetical decoders. imgpel ** p_img[MAX_PLANE]; //!< pointer array for accessing imgY/imgUV[] imgpel **** p_img_sub[MAX_PLANE]; //!< pointer array for storing top address of imgY_sub/imgUV_sub[] imgpel ** p_curr_img; //!< current int-pel ref. picture area to be used for motion estimation imgpel **** p_curr_img_sub; //!< current sub-pel ref. picture area to be used for motion estimation - byte * mb_field; //!< field macroblock indicator - - char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] - - int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - // (not simply index) - - int64 *** ref_id; //!< reference picture identifier [list][subblock_y][subblock_x] - // (not simply index) - - short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] + PicMotionParams2 ***mv_info; //!< Motion info + PicMotionParams motion; //!< Motion info + PicMotionParams JVmotion[MAX_PLANE]; //!< Motion info for 4:4:4 independent coding - byte ** moving_block; - byte ** field_frame; //!< indicates if co_located is field or frame. + int colour_plane_id; //!< colour_plane_id to be used for 4:4:4 independent mode encoding struct storable_picture *top_field; // for mb aff, if frame for referencing the top field struct storable_picture *bottom_field; // for mb aff, if frame for referencing the bottom field @@ -93,46 +103,30 @@ typedef struct storable_picture int frame_cropping_rect_top_offset; int frame_cropping_rect_bottom_offset; - char *** ref_idx_JV[MAX_PLANE]; //!< ref_idx to be used for 4:4:4 independent mode encoding - int64 *** ref_pic_id_JV[MAX_PLANE]; //!< ref_pic_id to be used for 4:4:4 independent mode encoding - int64 *** ref_id_JV[MAX_PLANE]; //!< ref_id to be used for 4:4:4 independent mode encoding - short **** mv_JV[MAX_PLANE]; //!< mv to be used for 4:4:4 independent mode encoding - int colour_plane_id; //!< colour_plane_id to be used for 4:4:4 independent mode encoding PictureStats p_stats; } StorablePicture; +//! definition of motion parameters +typedef struct motion_params +{ + int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] + short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] + char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] + byte ** moving_block; +} MotionParams; //! definition a picture (field or frame) typedef struct colocated_params { int mb_adaptive_frame_field_flag; int size_x, size_y; - - int64 ref_pic_num[6][MAX_LIST_SIZE]; - - char *** ref_idx; //!< reference picture [list][subblock_y][subblock_x] - int64 *** ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] - byte ** moving_block; - - // Top field params - int64 top_ref_pic_num[6][MAX_LIST_SIZE]; - char *** top_ref_idx; //!< reference picture [list][subblock_y][subblock_x] - int64 *** top_ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - short **** top_mv; //!< motion vector [list][subblock_x][subblock_y][component] - byte ** top_moving_block; - - // Bottom field params - int64 bottom_ref_pic_num[6][MAX_LIST_SIZE]; - char *** bottom_ref_idx; //!< reference picture [list][subblock_y][subblock_x] - int64 *** bottom_ref_pic_id; //!< reference picture identifier [list][subblock_y][subblock_x] - short **** bottom_mv; //!< motion vector [list][subblock_x][subblock_y][component] - byte ** bottom_moving_block; - byte is_long_term; - byte ** field_frame; //!< indicates if co_located is field or frame. + + MotionParams frame; + MotionParams top; + MotionParams bottom; } ColocatedParams; diff --git a/lencod/inc/mc_prediction.h b/lencod/inc/mc_prediction.h index 0a76fc5..9ef0fba 100644 --- a/lencod/inc/mc_prediction.h +++ b/lencod/inc/mc_prediction.h @@ -16,10 +16,10 @@ #define _MC_PREDICTION_H_ #include "mbuffer.h" -void LumaPrediction ( Macroblock* currMB, int, int, int, int, int, int, int, short, short ); +void LumaPrediction ( Macroblock* currMB, int, int, int, int, int, int, int, short, short, short ); void LumaPredictionBi ( Macroblock* currMB, int, int, int, int, int, int, short, short, int ); -void ChromaPrediction ( Macroblock* currMB, int, int, int, int, int, int, int, int, short, short ); -void ChromaPrediction4x4 ( Macroblock* currMB, int, int, int, int, int, int, short, short); +void ChromaPrediction ( Macroblock* currMB, int, int, int, int, int, int, int, int, short, short, short ); +void ChromaPrediction4x4 ( Macroblock* currMB, int, int, int, int, int, int, short, short, short); // function pointer for different ways of obtaining chroma interpolation void (*OneComponentChromaPrediction4x4) (imgpel* , int , int , short*** , StorablePicture *listX, int ); @@ -29,7 +29,7 @@ void OneComponentChromaPrediction4x4_retrieve (imgpel* , int , int , short*** void IntraChromaPrediction ( Macroblock *currMB, int*, int*, int*); void IntraChromaRDDecision ( Macroblock *currMB, RD_PARAMS); -void ComputeResidue (imgpel **curImg, imgpel mpr[16][16], int img_m7[16][16], int mb_y, int mb_x, int opix_y, int opix_x, int width, int height); -void SampleReconstruct (imgpel **curImg, imgpel mpr[16][16], int img_m7[16][16], int mb_y, int mb_x, int opix_y, int opix_x, int width, int height, int max_imgpel_value, int dq_bits); +void ComputeResidue (imgpel **curImg, imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int img_m7[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int mb_y, int mb_x, int opix_y, int opix_x, int width, int height); +void SampleReconstruct (imgpel **curImg, imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int img_m7[MB_BLOCK_SIZE][MB_BLOCK_SIZE], int mb_y, int mb_x, int opix_y, int opix_x, int width, int height, int max_imgpel_value, int dq_bits); #endif diff --git a/lencod/inc/me_epzs.h b/lencod/inc/me_epzs.h index 1a7bbb2..ba792f1 100644 --- a/lencod/inc/me_epzs.h +++ b/lencod/inc/me_epzs.h @@ -27,14 +27,13 @@ typedef struct { int mb_adaptive_frame_field_flag; int size_x, size_y; - + // Frame - short **** mv; //!< motion vector [list][subblock_x][subblock_y][component] + MotionVector ***frame; //!< motion vector [list][subblock_x][subblock_y] // Top field - short **** top_mv; //!< motion vector [list][subblock_x][subblock_y][component] - // Bottom field params - short **** bottom_mv; //!< motion vector [list][subblock_x][subblock_y][component] - + MotionVector ***top; //!< motion vector [list][subblock_x][subblock_y] + // Bottom field + MotionVector ***bot; //!< motion vector [list][subblock_x][subblock_y] } EPZSColocParams; typedef struct @@ -67,16 +66,16 @@ typedef enum extern EPZSColocParams *EPZSCo_located; extern int ***EPZSDistortion; //!< Array for storing SAD Values -extern int EPZSInit(void); -extern void EPZSDelete (void); -extern void EPZSOutputStats(FILE *stat,short stats_file); -extern void EPZSSliceInit(EPZSColocParams* p, StorablePicture **listX[6]); +extern int EPZSInit (InputParameters *params, ImageParameters *img); +extern void EPZSDelete (InputParameters *params); +extern void EPZSOutputStats (InputParameters *params, FILE * stat, short stats_file); +extern void EPZSSliceInit (InputParameters *params, ImageParameters *img, EPZSColocParams* p, StorablePicture **listX[6]); extern int EPZSPelBlockMotionSearch (Macroblock *, imgpel *, short, int, int, char ***, short ****, int, int, int, short[2], short[2], int, int, int, int); extern int EPZSBiPredBlockMotionSearch (Macroblock *, imgpel *, short, int, int, char ***, short ****, int, int, int, short[2], short[2], - short[2], short[2], int, int, int, int); + short[2], short[2], int, int, int, int, int); extern int EPZSSubPelBlockMotionSearch (imgpel *, short, int, int, int, int, int, short[2], short[2], int, int, int, int*, int); diff --git a/lencod/inc/me_fullfast.h b/lencod/inc/me_fullfast.h index 98931b5..a1d7c3b 100644 --- a/lencod/inc/me_fullfast.h +++ b/lencod/inc/me_fullfast.h @@ -21,9 +21,9 @@ int FastFullPelBlockMotionSearch (Macroblock *currMB, imgpel* orig_pic, short ref, int list, int list_offset, char ***refPic, short ****tmp_mv, int pic_pix_x, int pic_pix_y, int blocktype, short pred_mv[2], short mv[2], int search_range, int min_mcost, int lambda_factor, int apply_weights); -void InitializeFastFullIntegerSearch (); -void ResetFastFullIntegerSearch (); -void ClearFastFullIntegerSearch (); +void InitializeFastFullIntegerSearch (void); +void ResetFastFullIntegerSearch (void); +void ClearFastFullIntegerSearch (void); #endif diff --git a/lencod/inc/me_fullsearch.h b/lencod/inc/me_fullsearch.h index 05783b6..ddee7c8 100644 --- a/lencod/inc/me_fullsearch.h +++ b/lencod/inc/me_fullsearch.h @@ -25,7 +25,7 @@ extern int FullPelBlockMotionSearch (Macroblock *currMB, imgpel* orig_pic, short extern int FullPelBlockMotionBiPred (Macroblock *currMB, imgpel* orig_pic, short ref, int list, int list_offset, char ***refPic, short ****tmp_mv, int pic_pix_x, int pic_pix_y, int blocktype, short pred_mv1[2], short pred_mv2[2], short mv1[2], short mv2[2], - int search_range, int min_mcost, int lambda_factor, int apply_weights); + int search_range, int min_mcost, int iteration_no, int lambda_factor, int apply_weights); extern int SubPelBlockMotionSearch (imgpel* orig_pic, short ref, int list, int list_offset, int pic_pix_x, int pic_pix_y, int blocktype, short pred_mv[2], short mv[2], int search_pos2, int search_pos4, int min_mcost, int* lambda_factor, int apply_weights); diff --git a/lencod/inc/me_umhex.h b/lencod/inc/me_umhex.h index 8734344..6934724 100644 --- a/lencod/inc/me_umhex.h +++ b/lencod/inc/me_umhex.h @@ -200,6 +200,7 @@ UMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB, // <-- current Macr short s_mv[2], // <--> in: search center (x) / out: motion vector (x) - in pel units int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) + int iteration_no, // <-- bi pred iteration number int lambda_factor, // <-- lagrangian parameter for determining motion cost int apply_weights ); diff --git a/lencod/inc/me_umhexsmp.h b/lencod/inc/me_umhexsmp.h index e009f42..0b26b61 100644 --- a/lencod/inc/me_umhexsmp.h +++ b/lencod/inc/me_umhexsmp.h @@ -121,6 +121,7 @@ smpUMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB, // <-- curr short s_mv[2], // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) + int iteration_no, // <-- bi pred iteration number int lambda_factor, // <-- lagrangian parameter for determining motion cost int apply_weights ); diff --git a/lencod/inc/memalloc.h b/lencod/inc/memalloc.h index b31ebf1..9de23ef 100644 --- a/lencod/inc/memalloc.h +++ b/lencod/inc/memalloc.h @@ -8,12 +8,26 @@ * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * ************************************************************************ */ #ifndef _MEMALLOC_H_ #define _MEMALLOC_H_ +int get_mem2Dlm (LambdaParams ***array2D, int dim0, int dim1); +int get_mem2Dolm(LambdaParams ***array2D, int dim0, int dim1, int offset); + +int get_mem2Dmp(PicMotionParams2 ***array2D, int dim0, int dim1); +int get_mem3Dmp(PicMotionParams2 ****array3D, int dim0, int dim1, int dim2); + +int get_mem2Dmv(MotionVector ***array2D, int dim0, int dim1); +int get_mem3Dmv(MotionVector ****array3D, int dim0, int dim1, int dim2); +int get_mem4Dmv(MotionVector *****array4D, int dim0, int dim1, int dim2, int dim3); +int get_mem5Dmv(MotionVector ******array5D, int dim0, int dim1, int dim2, int dim3, int dim4); + int get_mem2D(byte ***array2D, int rows, int columns); int get_mem3D(byte ****array2D, int frames, int rows, int columns); @@ -32,21 +46,33 @@ int get_mem5Dshort(short ******array5D, int dim0, int dim1, int dim2, int dim3, int get_mem6Dshort(short *******array6D, int dim0, int dim1, int dim2, int dim3, int dim4, int dim5); int get_mem7Dshort(short ********array7D, int dim0, int dim1, int dim2, int dim3, int dim4, int dim5, int dim6); -int get_mem2Dpel(imgpel ***array2D, int rows, int columns); -int get_mem3Dpel(imgpel ****array3D, int frames, int rows, int columns); -int get_mem4Dpel(imgpel *****array4D, int sub_x, int sub_y, int rows, int columns); -int get_mem5Dpel(imgpel ******array5D, int dims, int sub_x, int sub_y, int rows, int columns); +int get_mem2Dpel(imgpel ***array2D, int rows, int columns); +int get_mem3Dpel(imgpel ****array3D, int frames, int rows, int columns); +int get_mem4Dpel(imgpel *****array4D, int sub_x, int sub_y, int rows, int columns); +int get_mem5Dpel(imgpel ******array5D, int dims, int sub_x, int sub_y, int rows, int columns); + +int get_mem2Ddouble (double ***array2D, int rows, int columns); +int get_mem2Dodouble(double ***array2D, int rows, int columns, int offset); +int get_mem3Dodouble(double ****array2D, int rows, int columns, int pels, int offset); -int get_mem2Ddouble(double ***array2D, int rows, int columns); -int get_mem2Ddb_offset(double ***array2D, int rows, int columns, int offset); -int get_mem3Ddb_offset(double ****array2D, int rows, int columns, int pels, int offset); +int get_mem2Doint (int ***array2D, int rows, int columns, int offset); +int get_mem3Doint (int ****array3D, int rows, int columns, int pels, int offset); -int get_mem2Dint_offset(int ***array2D, int rows, int columns, int offset); -int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int offset); +int get_offset_mem2Dshort(short ***array2D, int rows, int columns, int offset_y, int offset_x); -int get_offset_mem2Dshort(short ***array2D, int rows, int columns, int offset_y, int offset_x); void free_offset_mem2Dshort(short **array2D, int columns, int offset_x, int offset_y); +void free_mem2Dlm (LambdaParams **array2D); +void free_mem2Dolm (LambdaParams **array2D, int offset); + +void free_mem2Dmp (PicMotionParams2 **array2D); +void free_mem3Dmp (PicMotionParams2 ***array2D); + +void free_mem2Dmv (MotionVector **array2D); +void free_mem3Dmv (MotionVector ***array2D); +void free_mem4Dmv (MotionVector ****array2D); +void free_mem5Dmv (MotionVector *****array2D); + void free_mem2D (byte **array2D); void free_mem3D (byte ***array2D); @@ -71,10 +97,11 @@ void free_mem4Dpel (imgpel ****array4D); void free_mem5Dpel (imgpel *****array5D); void free_mem2Ddouble(double **array2D); -void free_mem2Ddb_offset(double **array2D, int offset); -void free_mem2Dint_offset(int **array2D, int offset); -void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset); -void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset); + +void free_mem2Dodouble(double **array2D, int offset); +void free_mem3Dodouble(double ***array3D, int rows, int columns, int offset); +void free_mem2Doint (int **array2D, int offset); +void free_mem3Doint (int ***array3D, int rows, int columns, int offset); int init_top_bot_planes(imgpel **imgFrame, int rows, int columns, imgpel ***imgTopField, imgpel ***imgBotField); void free_top_bot_planes(imgpel **imgTopField, imgpel **imgBotField); diff --git a/lencod/inc/mode_decision.h b/lencod/inc/mode_decision.h index 452864e..42cedba 100644 --- a/lencod/inc/mode_decision.h +++ b/lencod/inc/mode_decision.h @@ -4,7 +4,8 @@ * mode_decision.h * * \author - * Alexis Michael Tourapis + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> * * \date * 21. February 2005 @@ -34,18 +35,11 @@ extern int cbp, cbp8x8, cnt_nonz_8x8; extern int64 cbp_blk8_8x8ts; extern int cbp8_8x8ts; extern int cnt_nonz8_8x8ts; -extern int qp_mbaff[2][2], qp_mbaff[2][2]; -extern int delta_qp_mbaff[2][2],delta_qp_mbaff[2][2]; // Residue Color Transform extern char b4_ipredmode[16], b4_intra_pred_modes[16]; -extern short bi_pred_me; extern short best_mode; -extern short best8x8mode [4]; // [block] -extern char best8x8pdir [MAXMODE][4]; // [mode][block] -extern char best8x8l0ref[MAXMODE][4]; // [mode][block] -extern char best8x8l1ref[MAXMODE][4]; // [mode][block] extern imgpel pred[16][16]; extern void set_stored_macroblock_parameters (Macroblock *currMB); @@ -53,9 +47,12 @@ extern void StoreMV8x8(int); extern void RestoreMV8x8(int); extern void store_macroblock_parameters (Macroblock *currMB, int); extern void SetModesAndRefframeForBlocks (Macroblock *currMB, int); -extern void SetRefAndMotionVectors (Macroblock *currMB, int, int, int, int, int); +extern void SetRefAndMotionVectors (Macroblock *currMB, int, int, int, int, int, short); extern void StoreNewMotionVectorsBlock8x8(int, int, int, int, int, int, int); -extern void assign_enc_picture_params(int, char, int, int, int, int, int); +extern void assign_enc_picture_params(int, char, int, int, int, int, int, short); +extern void set_subblock8x8_info(Block8x8Info*, int, int, RD_8x8DATA*); +extern void set_block8x8_info(Block8x8Info*, int, int, char[2], char, short); +extern void update_prediction_for_mode16x16(Block8x8Info*, int, int*); extern void update_refresh_map(int intra, int intra1, Macroblock *currMB); extern void SetMotionVectorsMB (Macroblock*, int); extern void SetCoeffAndReconstruction8x8 (Macroblock*); @@ -65,20 +62,23 @@ extern int I16Offset (int, int); extern int CheckReliabilityOfRef (int, int, int, int); extern int Mode_Decision_for_Intra4x4Macroblock (Macroblock *currMB, double, double*); extern int RDCost_for_macroblocks (Macroblock *currMB, double, int, double*, double*, double*, int); -extern double RDCost_for_8x8blocks (Macroblock *currMB, int*, int64*, double, int, int, short, short, short); +extern double RDCost_for_8x8blocks (Macroblock *currMB, int*, int64*, double, int, int, short, short, short, short); extern double *mb16x16_cost_frame; extern const int b8_mode_table[6]; extern const int mb_mode_table[9]; void rc_store_diff(int cpix_x, int cpix_y, imgpel prediction[16][16]); -void submacroblock_mode_decision(RD_PARAMS, RD_8x8DATA *, Macroblock *,int ***, int ***, int ***, int *, short, int, int *, int *, int *, int); +void submacroblock_mode_decision(RD_PARAMS *, RD_8x8DATA *, Macroblock *,int ***, int ***, int ***, int *, short, int, int *, int *, int *, int); void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bslice); -void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_PARAMS enc_mb, int bmcost[5], char best_ref[2]); +void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_PARAMS *enc_mb, int bmcost[5], char best_ref[2]); void determine_prediction_list(int, int [5], char [2], char *, int *, short *); -void compute_mode_RD_cost(int mode, Macroblock *currMB, RD_PARAMS enc_mb, +void compute_mode_RD_cost(int mode, Macroblock *currMB, RD_PARAMS *enc_mb, double *min_rdcost, double *min_dcost, double *min_rate, int i16mode, short bslice, short *inter_skip); + +int iminarray ( int arr[], int size, int *minind ); + extern void update_lambda_costs(RD_PARAMS *enc_mb, int lambda_mf[3]); diff --git a/lencod/inc/mv-search.h b/lencod/inc/mv-search.h index 19831d9..9b83711 100644 --- a/lencod/inc/mv-search.h +++ b/lencod/inc/mv-search.h @@ -9,7 +9,6 @@ * \author * Inge Lille-Langoy <inge.lille-langoy@telenor.com> \n * Alexis Michael Tourapis <alexis.tourapis@dolby.com> \n - * Copyright (C) 1999 Telenor Satellite Services, Norway * ************************************************************************ */ @@ -18,7 +17,7 @@ #define _MV_SEARCH_H_ extern int (*BiPredME) (Macroblock *, imgpel *, short, int, int, char ***, short ****, - int, int, int, short[2], short[2], short[2], short[2], int, int, int, int); + int, int, int, short[2], short[2], short[2], short[2], int, int, int, int, int); extern int (*SubPelBiPredME)(imgpel* orig_pic, short ref, int list, int pic_pix_x, int pic_pix_y, int blocktype, short pred_mv1[2], short pred_mv2[2], short mv1[2], short mv2[2], @@ -30,7 +29,7 @@ extern int (*SubPelME) (imgpel* orig_pic, short ref, int list, int list_off extern void SetMotionVectorPredictor (Macroblock *currMB, short pmv[2], char **refPic, short ***tmp_mv, short ref_frame, int list, int block_x, int block_y, int blockshape_x, int blockshape_y); -extern void PrepareMEParams(int apply_weights, int ChromaMEEnable, int list, int ref); +extern void PrepareMEParams (int apply_weights, int ChromaMEEnable, int list, int ref); extern void PrepareBiPredMEParams(int apply_weights, int ChromaMEEnable, int list, int list_offset, int ref); #endif diff --git a/lencod/inc/q_around.h b/lencod/inc/q_around.h new file mode 100644 index 0000000..af5469e --- /dev/null +++ b/lencod/inc/q_around.h @@ -0,0 +1,44 @@ +/*! + *************************************************************************** + * \file + * q_around.h + * + * \author + * Alexis Michael Tourapis + * + * \brief + * Headerfile for Quantization Adaptive Rounding + ************************************************************************** + */ + +#ifndef _Q_AROUND_H_ +#define _Q_AROUND_H_ + +extern int **fadjust8x8, **fadjust4x4, ***fadjust4x4Cr, ***fadjust8x8Cr; + +typedef struct around_offset +{ + int **InterFAdjust4x4; + int **IntraFAdjust4x4; + int **InterFAdjust8x8; + int **IntraFAdjust8x8; + int ***InterFAdjust4x4Cr; + int ***IntraFAdjust4x4Cr; + int ***InterFAdjust8x8Cr; + int ***IntraFAdjust8x8Cr; +} ARoundOffset; + +// Create / Clear adaptive rounding variables +void setup_adaptive_rounding (InputParameters *params); +void clear_adaptive_rounding (InputParameters *params); + +void store_adaptive_rounding_parameters (Macroblock *currMB, int mode); +void store_adaptive_rounding_parameters_luma (Macroblock *currMB, int mode); +void store_adaptive_rounding_parameters_chroma (Macroblock *currMB, int mode); + +void store_adaptive_rounding (ImageParameters *img, int block_y, int block_x); +void update_adaptive_rounding(ImageParameters *img, int block_y, int block_x); +void update_offset_params (Macroblock *currMB, int mode, int luma_transform_size_8x8_flag); + +#endif + diff --git a/lencod/inc/quant4x4.h b/lencod/inc/quant4x4.h index 48c16e0..e17d6b4 100644 --- a/lencod/inc/quant4x4.h +++ b/lencod/inc/quant4x4.h @@ -15,60 +15,59 @@ #ifndef _QUANT4x4_H_ #define _QUANT4x4_H_ -void init_quant_4x4(ImageParameters *img); +void init_quant_4x4(InputParameters *params, ImageParameters *img); -int quant_4x4_normal(int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_4x4_normal (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); -int quant_4x4_around(int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_4x4_around (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); -int quant_4x4_trellis (int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); -int (*quant_4x4) (int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int (*quant_4x4) (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); -int (*quant_4x4cr) (int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_dc4x4_normal (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]); +int quant_dc4x4_around (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]); -int quant_ac4x4_normal(int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_dc4x4_trellis(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]); -int quant_ac4x4_around(int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int (*quant_dc4x4) (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]); -int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, +int quant_ac4x4_normal (int (*tblock)[16], int block_y, int block_x, int qp, int* ACLevel, int* ACRun, int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); - + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type); -int (*quant_ac4x4) (int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_ac4x4_around (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type); -int (*quant_ac4x4cr) (int (*tblock)[16], int block_y, int block_x, int qp, - int* ACLevel, int* ACRun, - int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); +int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type); +int (*quant_ac4x4) (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type); #endif diff --git a/lencod/inc/quant8x8.h b/lencod/inc/quant8x8.h index 78b45e8..50fd773 100644 --- a/lencod/inc/quant8x8.h +++ b/lencod/inc/quant8x8.h @@ -15,7 +15,7 @@ #ifndef _QUANT8x8_H_ #define _QUANT8x8_H_ -void init_quant_8x8(ImageParameters *img); +void init_quant_8x8(InputParameters *params, ImageParameters *img); int quant_8x8_normal(int (*tblock)[16], int block_y, int block_x, int qp, int* ACLevel, int* ACRun, diff --git a/lencod/inc/quantChroma.h b/lencod/inc/quantChroma.h new file mode 100644 index 0000000..97c02d3 --- /dev/null +++ b/lencod/inc/quantChroma.h @@ -0,0 +1,59 @@ + +/*! +************************************************************************ +* \file quant_cr.h +* +* \brief +* Quantization process for chroma header file +* +* \author +* Alexis Michael Tourapis <alexismt@ieee.org> +* +************************************************************************ +*/ + +#ifndef _QUANT_CR_H_ +#define _QUANT_CR_H_ + +void init_quant_Chroma(InputParameters *params, ImageParameters *img); + +int (*quant_4x4cr) (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost); + +int quant_dc2x2_normal (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust2x2, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int quant_dc2x2_around (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust2x2, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int quant_dc2x2_trellis(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int quant_dc4x2_normal (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int quant_dc4x2_around (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int quant_dc4x2_trellis(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int (*quant_dc_cr) (int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]); + +int (*quant_ac4x4cr) (int (*tblock)[16], int block_y, int block_x, int qp, + int* ACLevel, int* ACRun, + int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type); + +#endif + diff --git a/lencod/inc/ratectl.h b/lencod/inc/ratectl.h index c99afa6..212ef70 100644 --- a/lencod/inc/ratectl.h +++ b/lencod/inc/ratectl.h @@ -53,8 +53,6 @@ typedef struct { // macroblock activity int diffy[16][16]; -int qp_mbaff[2][2], qp_mbaff[2][2]; -int delta_qp_mbaff[2][2], delta_qp_mbaff[2][2]; // generic functions int Qstep2QP ( double Qstep ); diff --git a/lencod/inc/rc_quadratic.h b/lencod/inc/rc_quadratic.h index 07db630..c530336 100644 --- a/lencod/inc/rc_quadratic.h +++ b/lencod/inc/rc_quadratic.h @@ -157,7 +157,7 @@ void updatePparams (rc_quadratic *prc, int complexity ); void updateBparams (rc_quadratic *prc, int complexity ); // external generic functions -void rc_handle_mb ( int prev_mb, Macroblock *currMB, Slice *curr_slice ); +int rc_handle_mb ( int prev_mb, Macroblock *currMB, Slice *curr_slice ); void rc_init_top_field ( void ); void rc_init_bottom_field ( int TopFieldBits ); void rc_init_frame_rdpic ( float rateRatio ); diff --git a/lencod/inc/rdo_quant.h b/lencod/inc/rdo_quant.h index 905bcb6..3728d0e 100644 --- a/lencod/inc/rdo_quant.h +++ b/lencod/inc/rdo_quant.h @@ -51,7 +51,14 @@ void est_significant_coefficients (Macroblock* currMB, EncodingEnvironmentPtr ee int biari_no_bits(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct ); int biari_state(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePtr bi_ct ); -int est_write_and_store_CBP_block_bit(Macroblock* currMB, int type, int block_y, int block_x); +void rdoq_dc(int (*tblock)[4], int qp_per, int qp_rem, int levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[16], int type); +int init_trellis_data (int (*tblock)[16], int block_x, int qp_per, int qp_rem, + int **levelscale, int **leveloffset, const byte *p_scan, Macroblock *currMB, + levelDataStruct levelData[], int* kStart, int* kStop, int type); +int init_trellis_data_DC(int (*tblock)[4], int qp_per, int qp_rem, + int levelscale, int **leveloffset, const byte *p_scan, Macroblock *currMB, + levelDataStruct levelData[], int* kStart, int* kStop, int type); +int est_write_and_store_CBP_block_bit(Macroblock* currMB, int type); void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int type, double lambda, int kStart, int kStop, int noCoeff, int estCBP); int est_unary_exp_golomb_level_encode(unsigned int symbol, int ctx, int type); @@ -59,6 +66,7 @@ int est_unary_exp_golomb_level_encode(unsigned int symbol, int ctx, int type); void RDOQ_update_mode(RD_PARAMS *enc_mb, int bslice); void copy_rddata_trellis (RD_DATA *dest, RD_DATA *src); void updateMV_mp(int *m_cost, short ref, int list, int h, int v, int blocktype, int *lambda_factor, int block8x8); +void trellis_coding(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb); #endif // _RDO_QUANT_H_ diff --git a/lencod/inc/rdopt.h b/lencod/inc/rdopt.h index b9ecd82..0b0072f 100644 --- a/lencod/inc/rdopt.h +++ b/lencod/inc/rdopt.h @@ -17,12 +17,6 @@ #ifndef _RDO_H_ #define _RDO_H_ -extern int **bestInterFAdjust4x4, **bestIntraFAdjust4x4; -extern int **bestInterFAdjust8x8, **bestIntraFAdjust8x8; -extern int ***bestInterFAdjust4x4Cr, ***bestIntraFAdjust4x4Cr; -extern int ***bestInterFAdjust8x8Cr, ***bestIntraFAdjust8x8Cr; -extern int **fadjust8x8, **fadjust4x4, ***fadjust4x4Cr, ***fadjust8x8Cr; - extern int ****cofAC, ****cofAC8x8; // [8x8block][4x4block][level/run][scan_pos] extern int ***cofDC; // [yuv][level/run][scan_pos] extern int **cofAC4x4, ****cofAC4x4intern; // [level/run][scan_pos] @@ -30,17 +24,11 @@ extern int cbp, cbp8x8, cnt_nonz_8x8; extern int cbp_blk8x8; extern char l0_refframe[4][4], l1_refframe[4][4]; extern short b8mode[4], b8pdir[4]; -extern short best8x8mode [4]; // [block] -extern char best8x8pdir [MAXMODE][4]; // [mode][block] -extern char best8x8l0ref [MAXMODE][4]; // [mode][block] -extern char best8x8l1ref [MAXMODE][4]; // [mode][block] -extern char best8x8ref[2][MAXMODE][4]; // [mode][block] //CSptr cs_mb, cs_b8, cs_cm, cs_ib8, cs_ib4; extern int best_c_imode; extern int best_i16offset; extern short best_mode; -extern short bi_pred_me; //mixed transform sizes definitions extern int luma_transform_size_8x8_flag; @@ -68,10 +56,15 @@ int valid_intra_mode(int ipmode); void compute_comp_cost(imgpel **cur_img, imgpel prd_img[16][16], int pic_opix_x, int *cost); void generate_pred_error(imgpel **cur_img, imgpel prd_img[16][16], imgpel cur_prd[16][16], int m7[16][16], int pic_opix_x, int block_x); - - -void store_adaptive_rounding (int block_y, int block_x); -void update_adaptive_rounding(int block_y, int block_x); +extern void SetMotionVectorPredictor (Macroblock *currMB, short pmv[2], char **refPic, + short ***tmp_mv, short ref_frame, + int list, int mb_x, int mb_y, + int blockshape_x, int blockshape_y); +extern void UpdateMotionVectorPredictor(Macroblock* currMB); + +//============= rate-distortion optimization =================== +void clear_rdopt (InputParameters *params); +void init_rdopt (InputParameters *params); #endif diff --git a/lencod/inc/report.h b/lencod/inc/report.h new file mode 100644 index 0000000..00966c0 --- /dev/null +++ b/lencod/inc/report.h @@ -0,0 +1,25 @@ + +/*! + ************************************************************************ + * \file report.h + * + * \brief + * headers for frame format related information + * + * \author + * + ************************************************************************ + */ +#ifndef _REPORT_H_ +#define _REPORT_H_ +#include "contributors.h" +#include "global.h" +#include "enc_statistics.h" + +void report ( ImageParameters *img, InputParameters *params, StatParameters *stats); +void information_init ( ImageParameters *img, InputParameters *params, StatParameters *stats); +void report_frame_statistic(void); +void report_stats_on_error (void); + +#endif + diff --git a/lencod/inc/slice.h b/lencod/inc/slice.h new file mode 100644 index 0000000..af1ee04 --- /dev/null +++ b/lencod/inc/slice.h @@ -0,0 +1,37 @@ +/*! + *************************************************************************** + * \file + * slice.h + * + * \author + * Athanasios Leontaris + * + * \date + * 16 July 2008 + * + * \brief + * Headerfile for slice-related functions + ************************************************************************** + */ + +#ifndef _SLICE_H_ +#define _SLICE_H_ + +#include "global.h" +#include "mbuffer.h" + +void poc_ref_pic_reorder_frame( StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no ); +void poc_ref_pic_reorder_field( StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no ); + +void init_ref_pic_list_reordering( void ); +int start_slice( void ); +int terminate_slice( int lastslice ); +int encode_one_slice ( int SliceGroupId, Picture *pic, int TotalCodedMBs ); +void init_slice ( int start_mb_addr ); +void free_slice_list( Picture *currPic ); + +void SetLambda( int j, int qp, double lambda_scale ); +void SetLagrangianMultipliersOn( void ); +void SetLagrangianMultipliersOff( void ); + +#endif diff --git a/lencod/inc/vlc.h b/lencod/inc/vlc.h index 0491b81..ef10173 100644 --- a/lencod/inc/vlc.h +++ b/lencod/inc/vlc.h @@ -21,22 +21,22 @@ int u_v (int n, char *tracestring, int value, Bitstream *bitstream); void levrun_linfo_c2x2(int level,int run,int *len,int *info); void levrun_linfo_inter(int level,int run,int *len,int *info); -void writeSE_Fix (SyntaxElement *se, Bitstream *bitstream); -void writeSE_UVLC (SyntaxElement *se, DataPartition *dp); -void writeSE_SVLC (SyntaxElement *se, DataPartition *dp); -void writeSE_Flag (SyntaxElement *se, DataPartition *dp); -void writeSE_invFlag(SyntaxElement *se, DataPartition *dp); -void writeSE_Dummy (SyntaxElement *se, DataPartition *dp); - -void writeCBP_VLC (Macroblock* currMB, SyntaxElement *se, DataPartition *dp); -void writeIntraPredMode_CAVLC(SyntaxElement *se, DataPartition *dp); - -int writeSyntaxElement2Buf_UVLC(SyntaxElement *se, Bitstream* this_streamBuffer ); -void writeUVLC2buffer(SyntaxElement *se, Bitstream *currStream); +void writeSE_Fix (SyntaxElement *se, Bitstream *bitstream); +void writeSE_UVLC (SyntaxElement *se, DataPartition *dp); +void writeSE_SVLC (SyntaxElement *se, DataPartition *dp); +void writeSE_Flag (SyntaxElement *se, DataPartition *dp); +void writeSE_invFlag (SyntaxElement *se, DataPartition *dp); +void writeSE_Dummy (SyntaxElement *se, DataPartition *dp); + +void writeCBP_VLC (Macroblock* currMB, SyntaxElement *se, DataPartition *dp); +void writeIntraPredMode_CAVLC (SyntaxElement *se, DataPartition *dp); +int writeSyntaxElement2Buf_UVLC (SyntaxElement *se, Bitstream* this_streamBuffer ); +void writeUVLC2buffer (SyntaxElement *se, Bitstream *currStream); +void writeVlcByteAlign (Bitstream* currStream); int writeSyntaxElement2Buf_Fixed(SyntaxElement *se, Bitstream* this_streamBuffer ); -int symbol2uvlc(SyntaxElement *se); -void ue_linfo(int n, int dummy, int *len,int *info); -void se_linfo(int mvd, int dummy, int *len,int *info); +int symbol2uvlc (SyntaxElement *se); +void ue_linfo (int n, int dummy, int *len,int *info); +void se_linfo (int mvd, int dummy, int *len,int *info); void cbp_linfo_intra(int cbp, int dummy, int *len,int *info); void cbp_linfo_inter(int cbp, int dummy, int *len,int *info); diff --git a/lencod/inc/wp.h b/lencod/inc/wp.h index c223899..776f29d 100644 --- a/lencod/inc/wp.h +++ b/lencod/inc/wp.h @@ -17,17 +17,23 @@ #ifndef _WP_H_ #define _WP_H_ +#include "wp_lms.h" +#include "wp_mcprec.h" + +#define DEBUG_WP 0 + void InitWP(InputParameters *params); -void (*EstimateWPPSlice) (int offset); -void (*EstimateWPBSlice)(void); -int (*TestWPPSlice)(int offset); -int (*TestWPBSlice)(int method); +void (*EstimateWPBSlice) (ImageParameters *img, InputParameters *params); +void (*EstimateWPPSlice) (ImageParameters *img, InputParameters *params, int offset); +int (*TestWPPSlice) (ImageParameters *img, InputParameters *params, int offset); +int (*TestWPBSlice) (ImageParameters *img, InputParameters *params, int method); + +void EstimateWPBSliceAlg0(ImageParameters *img, InputParameters *params); +void EstimateWPPSliceAlg0(ImageParameters *img, InputParameters *params, int offset); +int TestWPPSliceAlg0 (ImageParameters *img, InputParameters *params, int offset); +int TestWPBSliceAlg0 (ImageParameters *img, InputParameters *params, int method); -void estimate_weighting_factor_B_slice(void); -void estimate_weighting_factor_P_slice(int offset); -int test_wp_P_slice(int offset); -int test_wp_B_slice(int method); +double ComputeImgSum (imgpel **CurrentImage, int height, int width); -double ComputeImgSum(imgpel **CurrentImage, int height, int width); #endif diff --git a/lencod/inc/wp_lms.h b/lencod/inc/wp_lms.h new file mode 100644 index 0000000..1682058 --- /dev/null +++ b/lencod/inc/wp_lms.h @@ -0,0 +1,26 @@ +/*! + *************************************************************************** + * \file + * wp_lms.h + * + * \author + * Alexis Michael Tourapis + * + * \date + * 22. February 2008 + * + * \brief + * Headerfile for weighted prediction support using LMS + ************************************************************************** + */ + +#ifndef _WP_LMS_H_ +#define _WP_LMS_H_ + +void EstimateWPPSliceAlg1(ImageParameters *img, InputParameters *params, int offset); +void EstimateWPBSliceAlg1(ImageParameters *img, InputParameters *params); +int TestWPPSliceAlg1 (ImageParameters *img, InputParameters *input, int offset); +int TestWPBSliceAlg1 (ImageParameters *img, InputParameters *input, int method); + +#endif + diff --git a/lencod/inc/wp_mcprec.h b/lencod/inc/wp_mcprec.h new file mode 100644 index 0000000..8684553 --- /dev/null +++ b/lencod/inc/wp_mcprec.h @@ -0,0 +1,64 @@ +/*! + *************************************************************************** + * \file + * wp_mcprec.h + * + * \brief + * Headerfile for Improved Motion Compensatation Precision Scheme using Weighted Prediction + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Athanasios Leontaris <aleon@dolby.com> + * + * \date + * 16 July 2008 + * + ************************************************************************** + */ + +#ifndef _WP_MCPREC_H_ +#define _WP_MCPREC_H_ + + +#define WP_MCPREC_PLUS0 4 +#define WP_MCPREC_PLUS1 5 +#define WP_MCPREC_MINUS0 6 +#define WP_MCPREC_MINUS1 7 +#define WP_MCPREC_MINUS_PLUS0 8 +#define WP_REGULAR 9 + +typedef struct +{ + int PicNum; // PicNum/FrameNum + int POCNum; // POC +} +WeightedPredRefX; + +typedef struct +{ + int algorithm; +} +WPXPass; + +typedef struct +{ + int num_wp_ref_list[2]; // num of elements in each of the above matrices [LIST] + WeightedPredRefX *wp_ref_list[2]; // structure with reordering and WP information for ref frames [LIST] + WPXPass *curr_wp_rd_pass; + WPXPass wp_rd_passes[3]; // frame_picture [0...4] (MultiRefWeightedPred == 2) +} +WPXObject; + +WPXObject *pWPX; + +void wpxInitWPXObject( void ); +void wpxFreeWPXObject( void ); +void wpxInitWPXPasses( InputParameters *params ); +void wpxModifyRefPicList( ImageParameters *img ); +// Note that at some point, InputParameters params contents should be copied into ImageParameters *img. +// This would eliminate need of having to use both structures +int wpxDetermineWP( InputParameters *params, ImageParameters *img, int clist, int n ); +void wpxAdaptRefNum( ImageParameters *img ); +void wpxReorderLists( ImageParameters *img, Slice *currSlice ); + +#endif + diff --git a/lencod/src/block.c b/lencod/src/block.c index 8c946a8..5ddc54d 100644 --- a/lencod/src/block.c +++ b/lencod/src/block.c @@ -24,6 +24,7 @@ #include <math.h> #include "global.h" +#include "enc_statistics.h" #include "image.h" #include "mb_access.h" @@ -34,39 +35,7 @@ #include "q_offsets.h" #include "q_matrix.h" #include "quant4x4.h" - -const int quant_coef[6][4][4] = { - {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}}, - {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}}, - {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}}, - {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}}, - {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}}, - {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}} -}; - -const int dequant_coef[6][4][4] = { - {{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}}, - {{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}}, - {{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}}, - {{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}}, - {{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}}, - {{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}} -}; -static const int A[4][4] = { - { 16, 20, 16, 20}, - { 20, 25, 20, 25}, - { 16, 20, 16, 20}, - { 20, 25, 20, 25} -}; - - -const byte QP_SCALE_CR[52]= -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, - 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, - 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37, - 37,38,38,38,39,39,39,39 -}; +#include "quantChroma.h" // Notation for comments regarding prediction and predictors. // The pels of the 4x4 block are labelled a..p. The predictor pels above @@ -94,19 +63,27 @@ const byte QP_SCALE_CR[52]= #define P_K (PredPel[11]) #define P_L (PredPel[12]) +extern const unsigned char subblk_offset_y[3][8][4]; +extern const unsigned char subblk_offset_x[3][8][4]; // global pointers for 4x4 quantization parameters extern int ****ptLevelOffset4x4; static int **levelscale = NULL, **leveloffset = NULL; static int **invlevelscale = NULL; +static int **levelscale_sp = NULL, **leveloffset_sp = NULL; +static int **invlevelscale_sp = NULL; static int **fadjust4x4 = NULL; +static int **fadjust2x2 = NULL; +static int **fadjust4x2 = NULL; // note that this is in fact 2x4 but the coefficients have been transposed for better memory access static int **levelscaleDC = NULL, **leveloffsetDC = NULL; static int **invlevelscaleDC = NULL; static int M1[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; static int M4[4][4]; -int Inv_Residual_DPCM_4x4(int m7[16][16], int block_y, int block_x); -int Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode); -int Inv_Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode); +//For residual DPCM +static int Residual_DPCM_4x4_for_Intra16x16(int mb_ores[4][4], int ipmode); +static int Inv_Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode); +static int Residual_DPCM_4x4(int ipmode, int mb_ores[16][16], int mb_rres[16][16], int block_y, int block_x); +static int Inv_Residual_DPCM_4x4(int m7[16][16], int block_y, int block_x); /*! ************************************************************************ @@ -566,11 +543,9 @@ void intrapred_16x16(Macroblock *currMB, ColorPlane pl) */ int dct_16x16(Macroblock *currMB, ColorPlane pl, int new_intra_mode) { - //int qp_const; int i,j; int ii,jj; - - int run,scan_pos,coeff_ctr,level; + int ac_coef = 0; static imgpel *img_Y, *predY; int nonzero = FALSE; @@ -594,7 +569,6 @@ int dct_16x16(Macroblock *currMB, ColorPlane pl, int new_intra_mode) int qp_per = qp_per_matrix[qp]; int qp_rem = qp_rem_matrix[qp]; - int q_bits = Q_BITS + qp_per + 1; // select scaling parameters levelscale = LevelScale4x4Comp[pl][1][qp_rem]; @@ -613,105 +587,88 @@ int dct_16x16(Macroblock *currMB, ColorPlane pl, int new_intra_mode) } } - // forward 4x4 DCT - for (j = 0; j < 16; j+=4) + // forward 4x4 DCT + for (j = 0; j < 16; j+=4) + { + for (i = 0;i < 16; i+=4) { - for (i = 0;i < 16; i+=4) - { - forward4x4(M1, M1, j, i); - } + forward4x4(M1, M1, j, i); } + } - // pick out DC coeff - for (j = 0; j < 4; j++) - for (i = 0; i < 4; i++) - M4[j][i]= M1[j << 2][i << 2]; + // pick out DC coeff + for (j = 0; j < 4; j++) + for (i = 0; i < 4; i++) + M4[j][i]= M1[j << 2][i << 2]; - // hadamard of DC coefficients - hadamard4x4(M4, M4); + // hadamard of DC coefficients + hadamard4x4(M4, M4); - // quant - run=-1; - scan_pos=0; - - for (coeff_ctr=0;coeff_ctr<16;coeff_ctr++) - { - i=pos_scan[coeff_ctr][0]; - j=pos_scan[coeff_ctr][1]; + nonzero = quant_dc4x4(&M4[0], qp, DCLevel, DCRun, levelscale[0][0], invlevelscale[0][0], leveloffset, pos_scan); - run++; - level= (iabs(M4[j][i]) * levelscale[0][0] + (leveloffset[0][0]<<1)) >> q_bits; + // inverse DC transform + if (nonzero) + { + ihadamard4x4(M4, M4); - if (level != 0) + // Reset DC coefficients + for (j = 0; j < 4; j++) + { + for (i = 0; i<4;i++) { - nonzero = TRUE; - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); - - level = isignab(level, M4[j][i]); - DCLevel[scan_pos ] = level; - DCRun [scan_pos++] = run; - run=-1; - M4[j][i] = level; + M1[j<<2][i<<2] = rshift_rnd_sf(((M4[j][i]) * invlevelscale[0][0]) << qp_per, 6); } - else - M4[j][i] = 0; } - DCLevel[scan_pos]=0; - - // inverse DC transform - if (nonzero) - { - ihadamard4x4(M4, M4); - - // Reset DC coefficients - for (j=0;j<4;j++) - for (i=0;i<4;i++) - M1[j<<2][i<<2] = rshift_rnd_sf(((M4[j][i]) * invlevelscale[0][0]) << qp_per, 6); - } - else // All DC equal to 0. + } + else // All DC equal to 0. + { + for (j=0;j<4;j++) { - for (j=0;j<4;j++) - for (i=0;i<4;i++) - M1[j<<2][i<<2] = 0; + for (i=0;i<4;i++) + { + M1[j<<2][i<<2] = 0; + } } + } - // AC processing for MB - for (jj=0;jj<4;jj++) + // AC processing for MB + for (jj=0;jj<4;jj++) + { + jpos = (jj << 2); + for (ii=0;ii<4;ii++) { - jpos = (jj << 2); - for (ii=0;ii<4;ii++) - { - ipos = (ii << 2); + ipos = (ii << 2); - b8 = 2*(jj >> 1) + (ii >> 1); - b4 = 2*(jj & 0x01) + (ii & 0x01); - ACLevel = cofAC[b8][b4][0]; - ACRun = cofAC[b8][b4][1]; + b8 = 2*(jj >> 1) + (ii >> 1); + b4 = 2*(jj & 0x01) + (ii & 0x01); + ACLevel = cofAC[b8][b4][0]; + ACRun = cofAC[b8][b4][1]; + img->subblock_y = jj; + img->subblock_x = ii; - // Quantization process - nonzero = quant_ac4x4(&M1[jpos], jpos, ipos, qp, ACLevel, ACRun, &fadjust4x4[jpos], - levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, COEFF_COST4x4[params->disthres]); + // Quantization process + nonzero = quant_ac4x4(&M1[jpos], jpos, ipos, qp, ACLevel, ACRun, &fadjust4x4[jpos], + levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, COEFF_COST4x4[params->disthres], LUMA_16AC); - if (nonzero) - ac_coef = 15; + if (nonzero) + ac_coef = 15; - //IDCT - if (M1[jpos][ipos]!= 0 || nonzero) - inverse4x4(M1, M1, jpos, ipos); - } + //IDCT + if (M1[jpos][ipos]!= 0 || nonzero) + inverse4x4(M1, M1, jpos, ipos); } + } // Reconstruct samples SampleReconstruct (img_enc, curr_mpr_16x16[new_intra_mode], M1, 0, 0, img->pix_y, img->pix_x, 16, 16, max_imgpel_value, DQ_BITS); - if(img->type == SP_SLICE) - { - for (j = img->pix_y; j < img->pix_y + 16;j++) - for (i = img->pix_x; i < img->pix_x + 16;i++) - lrec[j][i]=-16; //signals an I16 block in the SP frame - } + if(img->type == SP_SLICE) + { + for (j = img->pix_y; j < img->pix_y + 16;j++) + for (i = img->pix_x; i < img->pix_x + 16;i++) + lrec[j][i]=-16; //signals an I16 block in the SP frame + } return ac_coef; } @@ -824,7 +781,7 @@ int dct_16x16_ls(Macroblock *currMB, ColorPlane pl, int new_intra_mode) j=pos_scan[coeff_ctr][1]; run++; - *m7 = M4[j][i]; + m7 = &M4[j][i]; if (*m7 != 0) { @@ -891,7 +848,7 @@ int dct_4x4(Macroblock *currMB, ColorPlane pl, int block_x,int block_y, int *coe { int j; - int nonzero = FALSE; + int nonzero = FALSE; int pos_x = block_x >> BLOCK_SHIFT; int pos_y = block_y >> BLOCK_SHIFT; @@ -901,8 +858,9 @@ int dct_4x4(Macroblock *currMB, ColorPlane pl, int block_x,int block_y, int *coe int* ACRun = img->cofAC[b8][b4][1]; imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int max_imgpel_value = img->max_imgpel_value; int qp = currMB->qp_scaled[pl]; @@ -916,31 +874,33 @@ int dct_4x4(Macroblock *currMB, ColorPlane pl, int block_x,int block_y, int *coe leveloffset = ptLevelOffset4x4[intra][qp]; fadjust4x4 = img->AdaptiveRounding ? (pl ? &img->fadjust4x4Cr[pl-1][intra][block_y] : &img->fadjust4x4[intra][block_y]) : NULL; + img->subblock_x = ((b8&0x1)==0) ? (((b4&0x1)==0)? 0: 1) : (((b4&0x1)==0)? 2: 3); // horiz. position for coeff_count context + img->subblock_y = (b8<2) ? ((b4<2) ? 0: 1) : ((b4<2) ? 2: 3); // vert. position for coeff_count context // Forward 4x4 transform - forward4x4(curr_res, M1, block_y, block_x); + forward4x4(mb_ores, M1, block_y, block_x); // Quantization process nonzero = quant_4x4(&M1[block_y], block_y, block_x, qp, ACLevel, ACRun, fadjust4x4, levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST4x4[params->disthres]); + // Decoded block moved to frame memory if (nonzero) { // Inverse 4x4 transform - inverse4x4(M1, curr_res, block_y, block_x); + inverse4x4(M1, mb_rres, block_y, block_x); // generate final block - SampleReconstruct (img_enc, curr_mpr, curr_res, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE, BLOCK_SIZE, max_imgpel_value, DQ_BITS); + SampleReconstruct (img_enc, mb_pred, mb_rres, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE, BLOCK_SIZE, max_imgpel_value, DQ_BITS); } else // if (nonzero) => No transformed residual. Just use prediction. { for (j=block_y; j < block_y + BLOCK_SIZE; j++) { - memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(curr_mpr[j][block_x]), BLOCK_SIZE * sizeof(imgpel)); + memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE * sizeof(imgpel)); } } - // Decoded block moved to frame memory return nonzero; } @@ -982,18 +942,19 @@ int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c int pix_y, pix_x; imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int *m7; const byte *p_scan = currMB->is_field_mode ? &FIELD_SCAN[0][0] : &SNGL_SCAN[0][0]; // select scaling parameters - fadjust4x4 = img->AdaptiveRounding ? &img->fadjust4x4[intra][block_y] : NULL; + fadjust4x4 = img->AdaptiveRounding ? &img->fadjust4x4[intra][block_y] : NULL; - if((ipmode_DPCM < 2)) + if( (ipmode_DPCM < 2) && (intra)) { - Residual_DPCM_4x4(ipmode_DPCM, curr_res, block_y, block_x); + Residual_DPCM_4x4(ipmode_DPCM, mb_ores, mb_rres, block_y, block_x); } for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++) @@ -1002,8 +963,8 @@ int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c j = *p_scan++; run++; - - m7 = &curr_res[j+block_y][i+block_x]; + + m7 = &mb_rres[j+block_y][i+block_x]; if (img->AdaptiveRounding) fadjust4x4[j][block_x+i] = 0; @@ -1022,9 +983,9 @@ int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c } *ACL = 0; - if(ipmode_DPCM<2) //For residual DPCM + if( (ipmode_DPCM < 2) && (intra)) { - Inv_Residual_DPCM_4x4(curr_res, block_y, block_x); + Inv_Residual_DPCM_4x4(mb_rres, block_y, block_x); } for (j=0; j < BLOCK_SIZE; j++) @@ -1033,14 +994,13 @@ int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c pix_x = img->pix_x+block_x; for (i=0; i < BLOCK_SIZE; i++) { - img_enc[pix_y][pix_x+i] = curr_res[j+block_y][i+block_x] + curr_mpr[j+block_y][i+block_x]; + img_enc[pix_y][pix_x+i] = mb_rres[j+block_y][i+block_x] + mb_pred[j+block_y][i+block_x]; } } return nonzero; } - /*! ************************************************************************ * \brief @@ -1050,45 +1010,54 @@ int dct_4x4_ls(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c * block_x,block_y: Block position inside a macro block (0,4,8,12). ************************************************************************ */ -int Residual_DPCM_4x4(int ipmode, int m7[16][16], int block_y, int block_x) +static int Residual_DPCM_4x4(int ipmode, int mb_ores[16][16], int mb_rres[16][16], int block_y, int block_x) { - int i,j; + int i; int temp[4][4]; if(ipmode==VERT_PRED) { + temp[0][0] = mb_ores[block_y][block_x ]; + temp[0][1] = mb_ores[block_y][block_x + 1]; + temp[0][2] = mb_ores[block_y][block_x + 2]; + temp[0][3] = mb_ores[block_y][block_x + 3]; for (i=1; i<4; i++) { - temp[i][0] = m7[block_y + i][block_x ] - m7[block_y + i - 1][block_x ]; - temp[i][1] = m7[block_y + i][block_x + 1] - m7[block_y + i - 1][block_x + 1]; - temp[i][2] = m7[block_y + i][block_x + 2] - m7[block_y + i - 1][block_x + 2]; - temp[i][3] = m7[block_y + i][block_x + 3] - m7[block_y + i - 1][block_x + 3]; + temp[i][0] = mb_ores[block_y + i][block_x ] - mb_ores[block_y + i - 1][block_x ]; + temp[i][1] = mb_ores[block_y + i][block_x + 1] - mb_ores[block_y + i - 1][block_x + 1]; + temp[i][2] = mb_ores[block_y + i][block_x + 2] - mb_ores[block_y + i - 1][block_x + 2]; + temp[i][3] = mb_ores[block_y + i][block_x + 3] - mb_ores[block_y + i - 1][block_x + 3]; } - for (i=1; i<4; i++) + for (i = 0; i < 4; i++) { - m7[block_y+i][block_x ] = temp[i][0]; - m7[block_y+i][block_x + 1] = temp[i][1]; - m7[block_y+i][block_x + 2] = temp[i][2]; - m7[block_y+i][block_x + 3] = temp[i][3]; + mb_ores[block_y+i][block_x ] = temp[i][0]; + mb_ores[block_y+i][block_x + 1] = temp[i][1]; + mb_ores[block_y+i][block_x + 2] = temp[i][2]; + mb_ores[block_y+i][block_x + 3] = temp[i][3]; } } else //HOR_PRED { + temp[0][0] = mb_ores[block_y ][block_x]; + temp[1][0] = mb_ores[block_y + 1][block_x]; + temp[2][0] = mb_ores[block_y + 2][block_x]; + temp[3][0] = mb_ores[block_y + 3][block_x]; + for (i=0; i<4; i++) - for (j=1; j<4; j++) - { - temp[i][1] = m7[block_y + i][block_x + 1] - m7[block_y + i][block_x ]; - temp[i][2] = m7[block_y + i][block_x + 2] - m7[block_y + i][block_x + 1]; - temp[i][3] = m7[block_y + i][block_x + 3] - m7[block_y + i][block_x + 2]; - } + { + temp[i][1] = mb_ores[block_y + i][block_x + 1] - mb_ores[block_y + i][block_x ]; + temp[i][2] = mb_ores[block_y + i][block_x + 2] - mb_ores[block_y + i][block_x + 1]; + temp[i][3] = mb_ores[block_y + i][block_x + 3] - mb_ores[block_y + i][block_x + 2]; + } for (i=0; i<4; i++) { - m7[block_y+i][block_x + 1] = temp[i][1]; - m7[block_y+i][block_x + 2] = temp[i][2]; - m7[block_y+i][block_x + 3] = temp[i][3]; + mb_ores[block_y + i][block_x + 0] = temp[i][0]; + mb_ores[block_y + i][block_x + 1] = temp[i][1]; + mb_ores[block_y + i][block_x + 2] = temp[i][2]; + mb_ores[block_y + i][block_x + 3] = temp[i][3]; } } return 0; @@ -1104,7 +1073,7 @@ int Residual_DPCM_4x4(int ipmode, int m7[16][16], int block_y, int block_x) ************************************************************************ */ //For residual DPCM -int Inv_Residual_DPCM_4x4(int m7[16][16], int block_y, int block_x) +static int Inv_Residual_DPCM_4x4(int m7[16][16], int block_y, int block_x) { int i; int temp[4][4]; @@ -1153,7 +1122,7 @@ int Inv_Residual_DPCM_4x4(int m7[16][16], int block_y, int block_x) ************************************************************************ */ //For residual DPCM -int Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) +static int Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) { int i,j; int temp[4][4]; @@ -1173,9 +1142,9 @@ int Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) for (i=0; i<4; i++) for (j=1; j<4; j++) temp[i][j] = m7[i][j] - m7[i][j-1]; - - for (i=0; i<4; i++) - for (j=1; j<4; j++) + + for (i=0; i<4; i++) + for (j=1; j<4; j++) m7[i][j] = temp[i][j]; } return 0; @@ -1187,7 +1156,7 @@ int Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) ************************************************************************ */ //For residual DPCM -int Inv_Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) +static int Inv_Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) { int i; int temp[4][4]; @@ -1246,11 +1215,13 @@ int Inv_Residual_DPCM_4x4_for_Intra16x16(int m7[4][4], int ipmode) */ int dct_chroma(Macroblock *currMB, int uv, int cr_cbp) { - int i,j,n2,n1,coeff_ctr,level ,scan_pos,run; - static int m1[BLOCK_SIZE],m5[BLOCK_SIZE]; - int coeff_cost; - int cr_cbp_tmp; - int DCcoded=0 ; + int i, j, n2, n1, coeff_ctr; + static int m1[BLOCK_SIZE]; + int coeff_cost = 0; + int cr_cbp_tmp = 0; + int DCzero = FALSE; + int nonzero[4][4] = {{FALSE}}; + int nonezero = FALSE; const byte *c_cost = COEFF_COST4x4[params->disthres]; @@ -1265,154 +1236,100 @@ int dct_chroma(Macroblock *currMB, int uv, int cr_cbp) //FRExt static const int64 cbpblk_pattern[4]={0, 0xf0000, 0xff0000, 0xffff0000}; int yuv = img->yuv_format; - int b8; - static int m3[4][4]; - int qp_per_dc = 0; - int qp_rem_dc = 0; - int q_bits_422 = 0; + int b8; + const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN; - int cur_qp = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale; - int cur_qp_dc = currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale; + int cur_qp = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale; - int qp_per = qp_per_matrix[cur_qp]; int qp_rem = qp_rem_matrix[cur_qp]; - int q_bits = Q_BITS + qp_per + 1; - int max_imgpel_value_uv = img->max_imgpel_value_comp[1]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[uv + 1]; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[uv + 1]; - int nonzero[4][4] = {{FALSE}}; - int nonezero = FALSE; + + int max_imgpel_value_uv = img->max_imgpel_value_comp[uv + 1]; + + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; levelscale = LevelScale4x4Comp [uv + 1][intra][qp_rem]; leveloffset = LevelOffset4x4Comp [uv + 1][intra][cur_qp]; invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem]; fadjust4x4 = img->AdaptiveRounding ? img->fadjust4x4Cr[intra][uv] : NULL; + img->is_v_block = uv; //============= dct transform =============== for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE) { for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) { - forward4x4(curr_res, curr_res, n2, n1); + forward4x4(mb_ores, mb_rres, n2, n1); } } if (yuv == YUV420) { //================== CHROMA DC YUV420 =================== - // 2X2 transform of DC coeffs. - run=-1; - scan_pos=0; - + // forward 2x2 hadamard - hadamard2x2(curr_res, m1); + hadamard2x2(mb_rres, m1); - // Quant of chroma 2X2 coeffs. - for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) - { - run++; - - level =(iabs(m1[coeff_ctr]) * levelscale[0][0] + (leveloffset[0][0]<<1)) >> q_bits; - - if (level != 0) - { - if (params->symbol_mode == CAVLC && img->qp < 4) - level = imin(level, CAVLC_LEVEL_LIMIT); + // Quantization process of chroma 2X2 hadamard transformed DC coeffs. + DCzero = quant_dc_cr(&m1, cur_qp, DCLevel, DCRun, fadjust2x2, levelscale[0][0], invlevelscale[0][0], leveloffset, SCAN_YUV420); + if (DCzero) + { currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 set the cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-19 or 20-23) - DCcoded = 1; - level = isignab(level, m1[coeff_ctr]); - DCLevel[scan_pos ] = level; - DCRun [scan_pos++] = run; - run=-1; - m1[coeff_ctr] = level; - } - else - m1[coeff_ctr] = 0; } - DCLevel[scan_pos] = 0; // Inverse transform of 2x2 DC levels - ihadamard2x2(m1, m5); + ihadamard2x2(m1, m1); - curr_res[0][0] = ((m5[0] * invlevelscale[0][0]) << qp_per) >> 5; - curr_res[0][4] = ((m5[1] * invlevelscale[0][0]) << qp_per) >> 5; - curr_res[4][0] = ((m5[2] * invlevelscale[0][0]) << qp_per) >> 5; - curr_res[4][4] = ((m5[3] * invlevelscale[0][0]) << qp_per) >> 5; + mb_rres[0][0] = m1[0]; + mb_rres[0][4] = m1[1]; + mb_rres[4][0] = m1[2]; + mb_rres[4][4] = m1[3]; } - else if(yuv == YUV422) + else if (yuv == YUV422) { //for YUV422 only - qp_per_dc = qp_per_matrix[cur_qp_dc]; - qp_rem_dc = qp_rem_matrix[cur_qp_dc]; + int cur_qp_dc = currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale; + int qp_rem_dc = qp_rem_matrix[cur_qp_dc]; invlevelscaleDC = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_dc]; levelscaleDC = LevelScale4x4Comp [uv + 1][intra][qp_rem_dc]; leveloffsetDC = LevelOffset4x4Comp [uv + 1][intra][cur_qp_dc]; - q_bits_422 = Q_BITS + qp_per_dc + 1; - //================== CHROMA DC YUV422 =================== - //transform DC coeff - //horizontal - //pick out DC coeff for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE) { for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE) - m3[i>>2][j>>2]= curr_res[j][i]; + M4[i>>2][j>>2]= mb_rres[j][i]; } - // forward transform. Note that coeffs have been transposed (4x2 instead of 2x4) which makes transform a bit faster - hadamard4x2(m3, M4); - - run=-1; - scan_pos=0; - //quant of chroma DC-coeffs - for (coeff_ctr=0;coeff_ctr<8;coeff_ctr++) - { - i = SCAN_YUV422[coeff_ctr][0]; - j = SCAN_YUV422[coeff_ctr][1]; + // forward hadamard transform. Note that coeffs have been transposed (4x2 instead of 2x4) which makes transform a bit faster + hadamard4x2(M4, M4); - run++; + // Quantization process of chroma transformed DC coeffs. + DCzero = quant_dc_cr(M4, cur_qp_dc, DCLevel, DCRun, fadjust4x2, levelscaleDC[0][0], invlevelscaleDC[0][0], leveloffsetDC, SCAN_YUV422); - level =(iabs(M4[i][j]) * levelscaleDC[0][0] + (leveloffsetDC[0][0]<<1)) >> q_bits_422; - - if (level != 0) - { - //YUV422 - currMB->cbp_blk |= 0xff0000 << (uv << 3) ; // if one of the DC levels is != 0 set the - cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444 - DCcoded = 1 ; - - level = isignab(level,M4[i][j]); - DCLevel[scan_pos ] = level; - DCRun [scan_pos++] = run; - run=-1; - m3[i][j] = level; - } - else - m3[i][j] = 0; + if (DCzero) + { + currMB->cbp_blk |= 0xff0000 << (uv << 3) ; // if one of the DC levels is != 0 set the + cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444 } - DCLevel[scan_pos]=0; - //inverse DC transform. Note that now M4 is transposed back - ihadamard4x2(m3, M4); + ihadamard4x2(M4, M4); // This code assumes sizeof(int) > 16. Therefore, no need to have conditional for (j = 0; j < 4; j++) { - curr_res[j << 2 ][0] = rshift_rnd_sf(((M4[j][0]) * invlevelscaleDC[0][0]) << qp_per_dc, 6); - curr_res[j << 2 ][4] = rshift_rnd_sf(((M4[j][1]) * invlevelscaleDC[0][0]) << qp_per_dc, 6); + mb_rres[j << 2 ][0] = M4[j][0]; + mb_rres[j << 2 ][4] = M4[j][1]; } } // Quant of chroma AC-coeffs. - coeff_cost=0; - cr_cbp_tmp=0; - for (b8=0; b8 < (img->num_blk8x8_uv >> 1); b8++) { for (b4=0; b4 < 4; b4++) @@ -1422,17 +1339,16 @@ int dct_chroma(Macroblock *currMB, int uv, int cr_cbp) n2 = ver_offset[yuv][b8][b4]; ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0]; ACRun = img->cofAC[4 + b8 + uv_scale][b4][1]; - run=-1; - scan_pos=0; - + img->subblock_y = subblk_offset_y[img->yuv_format - 1][b8][b4]>>2; + img->subblock_x = subblk_offset_x[img->yuv_format - 1][b8][b4]>>2; // Quantization process - nonzero[n2>>2][n1>>2] = quant_ac4x4cr(&curr_res[n2], n2, n1, cur_qp, ACLevel, ACRun, &fadjust4x4[n2], - levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, c_cost); + nonzero[n2>>2][n1>>2] = quant_ac4x4cr(&mb_rres[n2], n2, n1, cur_qp, ACLevel, ACRun, &fadjust4x4[n2], + levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, c_cost, CHROMA_AC); if (nonzero[n2>>2][n1>>2]) { currMB->cbp_blk |= uv_cbpblk; - cr_cbp_tmp=2; + cr_cbp_tmp = 2; nonezero = TRUE; } } @@ -1457,14 +1373,14 @@ int dct_chroma(Macroblock *currMB, int uv, int cr_cbp) ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0]; ACRun = img->cofAC[4 + b8 + uv_scale][b4][1]; - if (DCcoded == 0) + if (DCzero == 0) currMB->cbp_blk &= ~(uv_cbpblk); // if no chroma DC's: then reset coded-bits of this chroma subblock ACLevel[0] = 0; for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// ac coeff { - curr_res[n2 + pos_scan[coeff_ctr][1]][n1 + pos_scan[coeff_ctr][0]] = 0; + mb_rres[n2 + pos_scan[coeff_ctr][1]][n1 + pos_scan[coeff_ctr][0]] = 0; ACLevel[coeff_ctr] = 0; } } @@ -1482,9 +1398,9 @@ int dct_chroma(Macroblock *currMB, int uv, int cr_cbp) { for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) { - if (curr_res[n2][n1] != 0 || nonzero[n2>>2][n1>>2] == TRUE) + if (mb_rres[n2][n1] != 0 || nonzero[n2>>2][n1>>2] == TRUE) { - inverse4x4(curr_res, curr_res, n2, n1); + inverse4x4(mb_rres, mb_rres, n2, n1); nonezero = TRUE; } } @@ -1493,13 +1409,13 @@ int dct_chroma(Macroblock *currMB, int uv, int cr_cbp) // Decoded block moved to memory if (nonezero == TRUE) { - SampleReconstruct (enc_picture->imgUV[uv], curr_mpr, curr_res, 0, 0, img->pix_c_y, img->pix_c_x, img->mb_cr_size_x, img->mb_cr_size_y, max_imgpel_value_uv, DQ_BITS); + SampleReconstruct (enc_picture->imgUV[uv], mb_pred, mb_rres, 0, 0, img->pix_c_y, img->pix_c_x, img->mb_cr_size_x, img->mb_cr_size_y, max_imgpel_value_uv, DQ_BITS); } else { for (j=0; j < img->mb_cr_size_y; j++) { - memcpy(&enc_picture->imgUV[uv][img->pix_c_y + j][img->pix_c_x], curr_mpr[j], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[uv][img->pix_c_y + j][img->pix_c_x], mb_pred[j], img->mb_cr_size_x * sizeof(imgpel)); } } @@ -1529,7 +1445,7 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) static int m1[BLOCK_SIZE]; int coeff_cost; int cr_cbp_tmp; - int DCcoded=0 ; + int nonzero = FALSE; static imgpel *orig_img, *pred_img; int b4; @@ -1548,8 +1464,9 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[uv + 1]; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[uv + 1]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; fadjust4x4 = img->AdaptiveRounding ? img->fadjust4x4Cr[intra][uv] : NULL; @@ -1560,10 +1477,10 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) // 2X2 transform of DC coeffs. run=-1; scan_pos=0; - m1[0]=curr_res[0][0]; - m1[1]=curr_res[0][4]; - m1[2]=curr_res[4][0]; - m1[3]=curr_res[4][4]; + m1[0] = mb_rres[0][0] = mb_ores[0][0]; + m1[1] = mb_rres[0][4] = mb_ores[0][4]; + m1[2] = mb_rres[4][0] = mb_ores[4][0]; + m1[3] = mb_rres[4][4] = mb_ores[4][4]; for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) { @@ -1573,12 +1490,12 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) if (level != 0) { - if (params->symbol_mode == CAVLC && img->qp < 4) + if (params->symbol_mode == CAVLC) level = imin(level, CAVLC_LEVEL_LIMIT); currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 set the cr_cbp=imax(1, cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-19 or 20-23) - DCcoded = 1; + nonzero = TRUE; level = isignab(level, m1[coeff_ctr]); DCLevel[scan_pos ] = level; DCRun [scan_pos++] = run; @@ -1597,7 +1514,10 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE) { for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE) - m3[i>>2][j>>2]= curr_res[j][i]; + { + m3[i>>2][j>>2] = mb_ores[j][i]; + mb_rres[j][i] = mb_ores[j][i]; + } } @@ -1620,7 +1540,7 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) //YUV422 currMB->cbp_blk |= 0xff0000 << (uv << 3) ; // if one of the DC levels is != 0 set the cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444 - DCcoded = 1 ; + nonzero = TRUE; DCLevel[scan_pos ] = isignab(level,M4[i][j]); DCRun [scan_pos++] = run; @@ -1656,7 +1576,8 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) ++run; - level = iabs(curr_res[n2+j][n1+i]); + level = iabs(mb_ores[n2+j][n1+i]); + mb_rres[n2+j][n1+i] = mb_ores[n2+j][n1+i]; if (img->AdaptiveRounding) { @@ -1669,11 +1590,11 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) coeff_cost += MAX_VALUE; // set high cost, shall not be discarded cr_cbp_tmp=2; - ACLevel[scan_pos ] = isignab(level,curr_res[n2+j][n1+i]); + ACLevel[scan_pos ] = isignab(level, mb_ores[n2+j][n1+i]); ACRun [scan_pos++] = run; run=-1; - level=isignab(level, curr_res[n2+j][n1+i]); + level = isignab(level, mb_ores[n2+j][n1+i]); } } ACLevel[scan_pos] = 0; @@ -1683,8 +1604,8 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) for (j=0; j < img->mb_cr_size_y; j++) { orig_img = &enc_picture->imgUV[uv][img->pix_c_y + j][img->pix_c_x]; - m7 = curr_res[j]; - pred_img = curr_mpr[j]; + m7 = mb_rres[j]; + pred_img = mb_pred[j]; for (i=0; i < img->mb_cr_size_x; i++) { orig_img[i] = (imgpel) m7[i] + pred_img[i]; @@ -1714,15 +1635,18 @@ int dct_chroma_ls(Macroblock *currMB, int uv, int cr_cbp) int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *coeff_cost, int intra) { int i,j,coeff_ctr; - int qp_const,ilev, level,scan_pos,run; - int nonzero; + int qp_const,ilev, level,scan_pos = 0,run = -1; + int nonzero = FALSE; imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; int c_err,qp_const2; - int qp_per,qp_rem, q_bits; - int qp_per_sp,qp_rem_sp,q_bits_sp; + + int qp = currMB->qp_scaled[pl]; + int qp_sp = (currMB->qpsp); + const byte *c_cost = COEFF_COST4x4[params->disthres]; const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN; @@ -1737,39 +1661,43 @@ int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c int c_err1, c_err2, level1, level2; double D_dis1, D_dis2; int len, info; - double lambda_mode = 0.85 * pow (2, (currMB->qp - SHIFT_QP)/3.0) * 4; + double lambda_mode = 0.85 * pow (2, (qp - SHIFT_QP)/3.0) * 4; - qp_per = qp_per_matrix[(currMB->qp - MIN_QP)]; - qp_rem = qp_rem_matrix[(currMB->qp - MIN_QP)]; - q_bits = Q_BITS + qp_per; - qp_per_sp = qp_per_matrix[(currMB->qpsp - MIN_QP)]; - qp_rem_sp = qp_rem_matrix[(currMB->qpsp - MIN_QP)]; - q_bits_sp = Q_BITS + qp_per_sp; + int qp_per = qp_per_matrix[qp]; + int qp_rem = qp_rem_matrix[qp]; + int q_bits = Q_BITS + qp_per; + int qp_per_sp = qp_per_matrix[qp_sp]; + int qp_rem_sp = qp_rem_matrix[qp_sp]; + int q_bits_sp = Q_BITS + qp_per_sp; + + levelscale = LevelScale4x4Comp[pl][intra][qp_rem]; + invlevelscale = InvLevelScale4x4Comp[pl][intra][qp_rem]; + leveloffset = ptLevelOffset4x4[intra][qp]; + + levelscale_sp = LevelScale4x4Comp[pl][intra][qp_rem_sp]; + invlevelscale_sp = InvLevelScale4x4Comp[pl][intra][qp_rem_sp]; + leveloffset_sp = ptLevelOffset4x4[intra][qp_sp]; qp_const = (1<<q_bits)/6; // inter qp_const2 = (1<<q_bits_sp)/2; //sp_pred // Horizontal transform - for (j=0; j< BLOCK_SIZE; j++) - for (i=0; i< BLOCK_SIZE; i++) - { - curr_res[j][i]+=curr_mpr[j+block_y][i+block_x]; - M1[j][i]=curr_mpr[j+block_y][i+block_x]; + for (j=block_y; j< block_x + BLOCK_SIZE; j++) + { + for (i=block_x; i< block_x + BLOCK_SIZE; i++) + { + mb_rres[j][i] = mb_ores[j][i]; + mb_rres[j][i]+=mb_pred[j][i]; + M1[j][i] = mb_pred[j][i]; } + } - - forward4x4(curr_res, curr_res, 0, 0); - forward4x4(M1, M1, 0, 0); - - // Quant - nonzero=FALSE; + // 4x4 transform + forward4x4(mb_rres, mb_rres, block_y, block_x); + forward4x4(M1, M1, block_y, block_x); - run=-1; - scan_pos=0; - - for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++) // 8 times if double scan, 16 normal scan + for (coeff_ctr = 0;coeff_ctr < 16;coeff_ctr++) { - i = pos_scan[coeff_ctr][0]; j = pos_scan[coeff_ctr][1]; @@ -1779,35 +1707,33 @@ int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c // decide prediction // case 1 - level1 = (iabs (M1[j][i]) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp; - level1 = (level1 << q_bits_sp) / quant_coef[qp_rem_sp][j][i]; - c_err1 = curr_res[j][i]-isignab(level1, M1[j][i]); - level1 = (iabs (c_err1) * quant_coef[qp_rem][j][i] + qp_const) >> q_bits; + level1 = (iabs (M1[j][i]) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp; + level1 = (level1 << q_bits_sp) / levelscale_sp[j][i]; + c_err1 = mb_rres[j][i] - isignab(level1, M1[j][i]); + level1 = (iabs (c_err1) * levelscale[j][i] + qp_const) >> q_bits; // case 2 - c_err2=curr_res[j][i]-M1[j][i]; - level2 = (iabs (c_err2) * quant_coef[qp_rem][j][i] + qp_const) >> q_bits; + c_err2 = mb_rres[j][i] - M1[j][i]; + level2 = (iabs (c_err2) * levelscale[j][i] + qp_const) >> q_bits; // select prediction if ((level1 != level2) && (level1 != 0) && (level2 != 0)) { - D_dis1 = curr_res[j][i] - ((isignab(level1,c_err1)*dequant_coef[qp_rem][j][i]*A[j][i]<< qp_per) >>6) - M1[j][i]; + D_dis1 = mb_rres[j][i] - ((isignab(level1,c_err1) * invlevelscale[j][i] * A[j][i]<< qp_per) >>6) - M1[j][i]; levrun_linfo_inter(level1, run, &len, &info); - D_dis1 = D_dis1*D_dis1 + lambda_mode * len; + D_dis1 = D_dis1 * D_dis1 + lambda_mode * len; - D_dis2 = curr_res[j][i] - ((isignab(level2,c_err2)*dequant_coef[qp_rem][j][i]*A[j][i]<< qp_per) >>6) - M1[j][i]; + D_dis2 = mb_rres[j][i] - ((isignab(level2,c_err2)*invlevelscale[j][i] * A[j][i]<< qp_per) >>6) - M1[j][i]; levrun_linfo_inter(level2, run, &len, &info); D_dis2 = D_dis2 * D_dis2 + lambda_mode * len; if (D_dis1 == D_dis2) level = (iabs(level1) < iabs(level2)) ? level1 : level2; + else if (D_dis1 < D_dis2) + level = level1; else - { - if (D_dis1 < D_dis2) - level = level1; - else - level = level2; - } + level = level2; + c_err = (level == level1) ? c_err1 : c_err2; } else if (level1 == level2) @@ -1824,7 +1750,7 @@ int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c if (level != 0) { nonzero = TRUE; - + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; level = isignab(level,c_err); @@ -1832,32 +1758,41 @@ int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c ACRun [scan_pos] = run; ++scan_pos; run=-1; // reset zero level counter - ilev=((level * dequant_coef[qp_rem][j][i] * A[j][i] << qp_per) >>6); + ilev=((level * invlevelscale[j][i] * A[j][i] << qp_per) >>6); } - ilev+=M1[j][i]; - + + ilev += M1[j][i]; + if(!si_frame_indicator && !sp2_frame_indicator)//stores the SP frame coefficients in lrec, will be useful to encode these and create SI or SP switching frame { lrec[img->pix_y+block_y+j][img->pix_x+block_x+i]= - isignab((iabs(ilev) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp, ilev); + isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp, ilev); } - curr_res[j][i] = isignab((iabs(ilev) * quant_coef[qp_rem_sp][j][i] + qp_const2)>> q_bits_sp, ilev) * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + mb_rres[j][i] = isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2)>> q_bits_sp, ilev) * invlevelscale_sp[j][i] << qp_per_sp; } ACLevel[scan_pos] = 0; // inverse transform - inverse4x4(curr_res, curr_res, 0, 0); + // inverse4x4(mb_rres, mb_rres, block_y, block_x); + inverse4x4(M1, mb_rres, 0, 0); for (j=0; j < BLOCK_SIZE; j++) for (i=0; i < BLOCK_SIZE; i++) - curr_res[j][i] = iClip1 (img->max_imgpel_value,rshift_rnd_sf(curr_res[j][i], DQ_BITS)); + { + //printf("%d ",mb_rres[j][i]); + mb_rres[j][i] = iClip1 (img->max_imgpel_value, rshift_rnd_sf(mb_rres[j][i], DQ_BITS)); + //printf("%d\n",mb_rres[j][i]); + } // Decoded block moved to frame memory - for (j=0; j < BLOCK_SIZE; j++) - for (i=0; i < BLOCK_SIZE; i++) - img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i]= (imgpel) curr_res[j][i]; - + { + for (i=0; i < BLOCK_SIZE; i++) + { + img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i]= (imgpel) mb_rres[j][i]; + //printf("%d\n",mb_rres[j][i]); + } + } return nonzero; } @@ -1879,16 +1814,222 @@ int dct_4x4_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *c */ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) { - int i,j,ilev,n2,n1,coeff_ctr,qp_const,c_err,level ,scan_pos,run; + int i, j, n2, n1, coeff_ctr; + static int m1[BLOCK_SIZE]; + int coeff_cost = 0; + int cr_cbp_tmp = 0; + int DCzero = FALSE; + int nonzero[4][4] = {{FALSE}}; + int nonezero = FALSE; + + const byte *c_cost = COEFF_COST4x4[params->disthres]; + + int b4; + int* DCLevel = img->cofDC[uv+1][0]; + int* DCRun = img->cofDC[uv+1][1]; + int* ACLevel; + int* ACRun; + int intra = IS_INTRA (currMB); + int uv_scale = uv * (img->num_blk8x8_uv >> 1); + + //FRExt + static const int64 cbpblk_pattern[4]={0, 0xf0000, 0xff0000, 0xffff0000}; + int yuv = img->yuv_format; + int b8; + + const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN; + int cur_qp = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale; + + int qp_rem = qp_rem_matrix[cur_qp]; + + int max_imgpel_value_uv = img->max_imgpel_value_comp[uv + 1]; + + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; + + levelscale = LevelScale4x4Comp [uv + 1][intra][qp_rem]; + leveloffset = LevelOffset4x4Comp [uv + 1][intra][cur_qp]; + invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem]; + fadjust4x4 = img->AdaptiveRounding ? img->fadjust4x4Cr[intra][uv] : NULL; + + //============= dct transform =============== + for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE) + { + for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) + { + forward4x4(mb_ores, mb_rres, n2, n1); + } + } + + if (yuv == YUV420) + { + //================== CHROMA DC YUV420 =================== + + // forward 2x2 hadamard + hadamard2x2(mb_rres, m1); + + // Quantization process of chroma 2X2 hadamard transformed DC coeffs. + DCzero = quant_dc_cr(&m1, cur_qp, DCLevel, DCRun, fadjust2x2, levelscale[0][0], invlevelscale[0][0], leveloffset, pos_scan); + + if (DCzero) + { + currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 set the + cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-19 or 20-23) + } + + // Inverse transform of 2x2 DC levels + ihadamard2x2(m1, m1); + + mb_rres[0][0] = m1[0]; + mb_rres[0][4] = m1[1]; + mb_rres[4][0] = m1[2]; + mb_rres[4][4] = m1[3]; + } + else if (yuv == YUV422) + { + //for YUV422 only + int cur_qp_dc = currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale; + int qp_rem_dc = qp_rem_matrix[cur_qp_dc]; + + invlevelscaleDC = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_dc]; + levelscaleDC = LevelScale4x4Comp [uv + 1][intra][qp_rem_dc]; + leveloffsetDC = LevelOffset4x4Comp [uv + 1][intra][cur_qp_dc]; + + //================== CHROMA DC YUV422 =================== + //pick out DC coeff + for (j=0; j < img->mb_cr_size_y; j+=BLOCK_SIZE) + { + for (i=0; i < img->mb_cr_size_x; i+=BLOCK_SIZE) + M4[i>>2][j>>2]= mb_rres[j][i]; + } + + // forward hadamard transform. Note that coeffs have been transposed (4x2 instead of 2x4) which makes transform a bit faster + hadamard4x2(M4, M4); + + // Quantization process of chroma transformed DC coeffs. + DCzero = quant_dc_cr(M4, cur_qp_dc, DCLevel, DCRun, fadjust4x2, levelscaleDC[0][0], invlevelscaleDC[0][0], leveloffsetDC, SCAN_YUV422); + + if (DCzero) + { + currMB->cbp_blk |= 0xff0000 << (uv << 3) ; // if one of the DC levels is != 0 set the + cr_cbp=imax(1,cr_cbp); // coded-bit all 4 4x4 blocks (bit 16-31 or 32-47) //YUV444 + } + + //inverse DC transform. Note that now M4 is transposed back + ihadamard4x2(M4, M4); + + // This code assumes sizeof(int) > 16. Therefore, no need to have conditional + for (j = 0; j < 4; j++) + { + mb_rres[j << 2 ][0] = M4[j][0]; + mb_rres[j << 2 ][4] = M4[j][1]; + } + } + + // Quant of chroma AC-coeffs. + for (b8=0; b8 < (img->num_blk8x8_uv >> 1); b8++) + { + for (b4=0; b4 < 4; b4++) + { + int64 uv_cbpblk = ((int64)1) << cbp_blk_chroma[b8 + uv_scale][b4]; + n1 = hor_offset[yuv][b8][b4]; + n2 = ver_offset[yuv][b8][b4]; + ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0]; + ACRun = img->cofAC[4 + b8 + uv_scale][b4][1]; + + // Quantization process + nonzero[n2>>2][n1>>2] = quant_ac4x4cr(&mb_rres[n2], n2, n1, cur_qp, ACLevel, ACRun, &fadjust4x4[n2], + levelscale, invlevelscale, leveloffset, &coeff_cost, pos_scan, c_cost, CHROMA_AC); + + if (nonzero[n2>>2][n1>>2]) + { + currMB->cbp_blk |= uv_cbpblk; + cr_cbp_tmp = 2; + nonezero = TRUE; + } + } + } + + // Perform thresholding + // * reset chroma coeffs + if(nonezero && coeff_cost < _CHROMA_COEFF_COST_) + { + int64 uv_cbpblk = ((int64)cbpblk_pattern[yuv] << (uv << (1+yuv))); + cr_cbp_tmp = 0; + + for (b8 = 0; b8 < (img->num_blk8x8_uv >> 1); b8++) + { + for (b4 = 0; b4 < 4; b4++) + { + n1 = hor_offset[yuv][b8][b4]; + n2 = ver_offset[yuv][b8][b4]; + if (nonzero[n2>>2][n1>>2] == TRUE) + { + nonzero[n2>>2][n1>>2] = FALSE; + ACLevel = img->cofAC[4 + b8 + uv_scale][b4][0]; + ACRun = img->cofAC[4 + b8 + uv_scale][b4][1]; + + if (DCzero == 0) + currMB->cbp_blk &= ~(uv_cbpblk); // if no chroma DC's: then reset coded-bits of this chroma subblock + + ACLevel[0] = 0; + + for (coeff_ctr=1; coeff_ctr < 16; coeff_ctr++)// ac coeff + { + mb_rres[n2 + pos_scan[coeff_ctr][1]][n1 + pos_scan[coeff_ctr][0]] = 0; + ACLevel[coeff_ctr] = 0; + } + } + } + } + } + + // IDCT. + // Horizontal. + if(cr_cbp_tmp == 2) + cr_cbp = 2; + + nonezero = FALSE; + for (n2=0; n2 < img->mb_cr_size_y; n2 += BLOCK_SIZE) + { + for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) + { + if (mb_rres[n2][n1] != 0 || nonzero[n2>>2][n1>>2] == TRUE) + { + inverse4x4(mb_rres, mb_rres, n2, n1); + nonezero = TRUE; + } + } + } + + // Decoded block moved to memory + if (nonezero == TRUE) + { + SampleReconstruct (enc_picture->imgUV[uv], mb_pred, mb_rres, 0, 0, img->pix_c_y, img->pix_c_x, img->mb_cr_size_x, img->mb_cr_size_y, max_imgpel_value_uv, DQ_BITS); + } + else + { + for (j=0; j < img->mb_cr_size_y; j++) + { + memcpy(&enc_picture->imgUV[uv][img->pix_c_y + j][img->pix_c_x], mb_pred[j], img->mb_cr_size_x * sizeof(imgpel)); + } + } + + return cr_cbp; +} + +int dct_chroma_sp_old(Macroblock *currMB, int uv,int cr_cbp) +{ + int i,j,ilev,n2,n1,coeff_ctr,c_err,level ,scan_pos,run; int m1[BLOCK_SIZE]; int coeff_cost; int cr_cbp_tmp; - int qp_const2,mp1[BLOCK_SIZE]; + int mp1[BLOCK_SIZE]; const byte *c_cost = COEFF_COST4x4[params->disthres]; const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN; - int qp_per, qp_rem, q_bits; - int qp_per_sp, qp_rem_sp, q_bits_sp; + int intra = IS_INTRA (currMB); int b4; int* DCLevel = img->cofDC[uv+1][0]; @@ -1902,28 +2043,36 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) double lambda_mode = 0.85 * pow (2, (currMB->qp -SHIFT_QP)/3.0) * 4; int max_imgpel_value_uv = img->max_imgpel_value_comp[1]; - - int qpChroma = iClip3(-img->bitdepth_chroma_qp_scale, 51, currMB->qp + active_pps->chroma_qp_index_offset); + int qpChroma = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale; int qpChromaSP=iClip3(-img->bitdepth_chroma_qp_scale, 51, currMB->qpsp + active_pps->chroma_qp_index_offset); - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[uv + 1]; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[uv + 1]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; + + int qp_per = qp_per_matrix[qpChroma]; + int qp_rem = qp_rem_matrix[qpChroma]; + int q_bits = Q_BITS + qp_per; + int qp_const = (1<<q_bits)/6; // inter + int qp_per_sp = qp_per_matrix[qpChromaSP]; + int qp_rem_sp = qp_rem_matrix[qpChromaSP]; + int q_bits_sp = Q_BITS + qp_per_sp; + int qp_const2 = (1<<q_bits_sp)/2; //sp_pred - qp_per = ((qpChroma<0?qpChroma:QP_SCALE_CR[qpChroma])-MIN_QP)/6; - qp_rem = ((qpChroma<0?qpChroma:QP_SCALE_CR[qpChroma])-MIN_QP)%6; - q_bits = Q_BITS+qp_per; - qp_const=(1<<q_bits)/6; // inter - qp_per_sp = ((qpChromaSP<0?currMB->qpsp:QP_SCALE_CR[qpChromaSP])-MIN_QP)/6; - qp_rem_sp = ((qpChromaSP<0?currMB->qpsp:QP_SCALE_CR[qpChromaSP])-MIN_QP)%6; - q_bits_sp = Q_BITS+qp_per_sp; - qp_const2 = (1<<q_bits_sp)/2; //sp_pred + levelscale = LevelScale4x4Comp [uv + 1][intra][qp_rem]; + invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem]; + leveloffset = LevelOffset4x4Comp [uv + 1][intra][qpChroma]; + levelscale_sp = LevelScale4x4Comp [uv + 1][intra][qp_rem_sp]; + invlevelscale_sp = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_sp]; + leveloffset_sp = LevelOffset4x4Comp [uv + 1][intra][qpChromaSP]; for (j=0; j < img->mb_cr_size_y; j++) { for (i=0; i < img->mb_cr_size_x; i++) { - curr_res[j][i] += curr_mpr[j][i]; - M1[j][i] = curr_mpr[j][i]; + mb_rres[j][i] = mb_ores[j][i]; + mb_rres[j][i] += mb_pred[j][i]; + M1[j][i] = mb_pred[j][i]; } } @@ -1931,52 +2080,50 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) { for (n1=0; n1 < img->mb_cr_size_x; n1 += BLOCK_SIZE) { - forward4x4(curr_res, curr_res, n2, n1); + forward4x4(mb_rres, mb_rres, n2, n1); forward4x4(M1, M1, n2, n1); } } // 2X2 transform of DC coeffs. - hadamard2x2(curr_res, m1); + hadamard2x2(mb_rres, m1); hadamard2x2(M1, mp1); run=-1; scan_pos=0; - for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) + for (coeff_ctr = 0; coeff_ctr < 4; coeff_ctr++) { run++; ilev=0; // case 1 - c_err1 = (iabs (mp1[coeff_ctr]) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp + 1); - c_err1 = (c_err1 << (q_bits_sp + 1)) / quant_coef[qp_rem_sp][0][0]; + c_err1 = (iabs (mp1[coeff_ctr]) * levelscale_sp[0][0] + 2 * qp_const2) >> (q_bits_sp + 1); + c_err1 = (c_err1 << (q_bits_sp + 1)) / levelscale_sp[0][0]; c_err1 = m1[coeff_ctr] - isignab(c_err1, mp1[coeff_ctr]); - level1 = (iabs(c_err1) * quant_coef[qp_rem][0][0] + 2 * qp_const) >> (q_bits+1); + level1 = (iabs(c_err1) * levelscale[0][0] + 2 * qp_const) >> (q_bits+1); // case 2 c_err2 = m1[coeff_ctr] - mp1[coeff_ctr]; - level2 = (iabs(c_err2) * quant_coef[qp_rem][0][0] + 2 * qp_const) >> (q_bits+1); + level2 = (iabs(c_err2) * levelscale[0][0] + 2 * qp_const) >> (q_bits+1); if (level1 != level2 && level1 != 0 && level2 != 0) { - D_dis1 = m1[coeff_ctr] - ((isignab(level1,c_err1)*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)- mp1[coeff_ctr]; + D_dis1 = m1[coeff_ctr] - ((isignab(level1,c_err1)*invlevelscale[0][0] * A[0][0]<< qp_per) >>5)- mp1[coeff_ctr]; levrun_linfo_c2x2(level1, run, &len, &info); D_dis1 = D_dis1 * D_dis1 + lambda_mode * len; - D_dis2 = m1[coeff_ctr] - ((isignab(level2,c_err2)*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5)- mp1[coeff_ctr]; + D_dis2 = m1[coeff_ctr] - ((isignab(level2,c_err2)*invlevelscale[0][0] * A[0][0]<< qp_per) >>5)- mp1[coeff_ctr]; levrun_linfo_c2x2(level2, run, &len, &info); D_dis2 = D_dis2 * D_dis2 + lambda_mode * len; if (D_dis1 == D_dis2) level = (iabs(level1) < iabs(level2)) ? level1 : level2; + else if (D_dis1 < D_dis2) + level = level1; else - { - if (D_dis1 < D_dis2) - level = level1; - else - level = level2; - } + level = level2; + c_err = (level == level1) ? c_err1 : c_err2; } else if (level1 == level2) @@ -1992,30 +2139,31 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) if (level != 0) { - if (params->symbol_mode == CAVLC && img->qp < 4) + if (params->symbol_mode == CAVLC) level = imin(level, CAVLC_LEVEL_LIMIT); currMB->cbp_blk |= 0xf0000 << (uv << 2) ; // if one of the 2x2-DC levels is != 0 the coded-bit - cr_cbp=imax(1,cr_cbp); + cr_cbp = imax(1, cr_cbp); DCLevel[scan_pos ] = isignab(level ,c_err); DCRun [scan_pos++] = run; run=-1; - ilev=((isignab(level,c_err)*dequant_coef[qp_rem][0][0]*A[0][0]<< qp_per) >>5); + ilev=((isignab(level,c_err)*invlevelscale[0][0]*A[0][0]<< qp_per) >>5); } + ilev+= mp1[coeff_ctr]; - m1[coeff_ctr]=isignab((iabs(ilev) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp+1), ilev) * dequant_coef[qp_rem_sp][0][0] << qp_per_sp; + m1[coeff_ctr]=isignab((iabs(ilev) * levelscale_sp[0][0] + 2 * qp_const2) >> (q_bits_sp+1), ilev) * invlevelscale_sp[0][0] << qp_per_sp; if(!si_frame_indicator && !sp2_frame_indicator) - lrec_uv[uv][img->pix_c_y+4*(coeff_ctr%2)][img->pix_c_x+4*(coeff_ctr/2)]=isignab((iabs(ilev) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp+1), ilev);// stores the SP frames coefficients, will be useful to encode SI or switching SP frame + lrec_uv[uv][img->pix_c_y+4*(coeff_ctr%2)][img->pix_c_x+4*(coeff_ctr/2)]=isignab((iabs(ilev) * levelscale_sp[0][0] + 2 * qp_const2) >> (q_bits_sp+1), ilev);// stores the SP frames coefficients, will be useful to encode SI or switching SP frame } DCLevel[scan_pos] = 0; // Inverse transform of 2x2 DC levels ihadamard2x2(m1, m1); - curr_res[0][0]=(m1[0])>>1; - curr_res[0][4]=(m1[1])>>1; - curr_res[4][0]=(m1[2])>>1; - curr_res[4][4]=(m1[3])>>1; + mb_rres[0][0]=(m1[0])>>1; + mb_rres[0][4]=(m1[1])>>1; + mb_rres[4][0]=(m1[2])>>1; + mb_rres[4][4]=(m1[3])>>1; // Quant of chroma AC-coeffs. coeff_cost=0; @@ -2041,23 +2189,23 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) ilev=0; // quantization on prediction - c_err1 = (iabs(M1[n2+j][n1+i]) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp; - c_err1 = (c_err1 << q_bits_sp) / quant_coef[qp_rem_sp][j][i]; - c_err1 = curr_res[n2+j][n1+i] - isignab(c_err1, M1[n2+j][n1+i]); - level1 = (iabs(c_err1) * quant_coef[qp_rem][j][i] + qp_const) >> q_bits; + c_err1 = (iabs(M1[n2+j][n1+i]) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp; + c_err1 = (c_err1 << q_bits_sp) / levelscale_sp[j][i]; + c_err1 = mb_rres[n2+j][n1+i] - isignab(c_err1, M1[n2+j][n1+i]); + level1 = (iabs(c_err1) * levelscale[j][i] + qp_const) >> q_bits; // no quantization on prediction - c_err2 = curr_res[n2+j][n1+i] - M1[n2+j][n1+i]; - level2 = (iabs(c_err2) * quant_coef[qp_rem][j][i] + qp_const) >> q_bits; + c_err2 = mb_rres[n2+j][n1+i] - M1[n2+j][n1+i]; + level2 = (iabs(c_err2) * levelscale[j][i] + qp_const) >> q_bits; if (level1 != level2 && level1 != 0 && level2 != 0) { - D_dis1 = curr_res[n2+j][n1+i] - ((isignab(level1,c_err1)*dequant_coef[qp_rem][j][i]*A[j][i]<< qp_per) >>6) - M1[n2+j][n1+i]; + D_dis1 = mb_rres[n2+j][n1+i] - ((isignab(level1,c_err1)*invlevelscale[j][i]*A[j][i]<< qp_per) >>6) - M1[n2+j][n1+i]; levrun_linfo_inter(level1, run, &len, &info); D_dis1 = D_dis1 * D_dis1 + lambda_mode * len; - D_dis2 = curr_res[n2+j][n1+i] - ((isignab(level2,c_err2)*dequant_coef[qp_rem][j][i]*A[j][i]<< qp_per) >>6) - M1[n2+j][n1+i]; + D_dis2 = mb_rres[n2+j][n1+i] - ((isignab(level2,c_err2)*invlevelscale[j][i]*A[j][i]<< qp_per) >>6) - M1[n2+j][n1+i]; levrun_linfo_inter(level2, run, &len, &info); D_dis2 = D_dis2 * D_dis2 + lambda_mode * len; @@ -2095,13 +2243,13 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) ACRun [scan_pos] = run; ++scan_pos; run=-1; - ilev=((level * dequant_coef[qp_rem][j][i]*A[j][i]<< qp_per) >>6); + ilev=((level * invlevelscale[j][i]*A[j][i]<< qp_per) >>6); } ilev+=M1[n2+j][n1+i]; if(!si_frame_indicator && !sp2_frame_indicator) if(!( (n2+j) % 4==0 && (n1+i)%4 ==0 )) - lrec_uv[uv][img->pix_c_y+n1+j][img->pix_c_x+n2+i]=isignab((iabs(ilev) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp,ilev);//stores the SP frames coefficients, will be useful to encode SI or switching SP frame - curr_res[n2+j][n1+i] = isignab((iabs(ilev) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp,ilev) * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + lrec_uv[uv][img->pix_c_y+n1+j][img->pix_c_x+n2+i]=isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp,ilev);//stores the SP frames coefficients, will be useful to encode SI or switching SP frame + mb_rres[n2+j][n1+i] = isignab((iabs(ilev) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp,ilev) * invlevelscale_sp[j][i] << qp_per_sp; } ACLevel[scan_pos] = 0; } @@ -2113,18 +2261,18 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) cr_cbp=2; // IDCT. - // Horizontal. + // Horizontal. for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE) { for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE) { - inverse4x4(curr_res, curr_res, n2, n1); + inverse4x4(mb_rres, mb_rres, n2, n1); for (j=0; j < BLOCK_SIZE; j++) - for (i=0; i < BLOCK_SIZE; i++) - { - curr_res[n2+j][n1+i] = iClip1 (max_imgpel_value_uv,rshift_rnd_sf(curr_res[n2+j][n1+i], DQ_BITS)); - } + for (i=0; i < BLOCK_SIZE; i++) + { + mb_rres[n2+j][n1+i] = iClip1 (max_imgpel_value_uv,rshift_rnd_sf(mb_rres[n2+j][n1+i], DQ_BITS)); + } } } @@ -2132,10 +2280,10 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) for (j=0; j < BLOCK_SIZE*2; j++) for (i=0; i < BLOCK_SIZE*2; i++) { - enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i]= (imgpel) curr_res[j][i]; + enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x+i]= (imgpel) mb_rres[j][i]; } - return cr_cbp; + return cr_cbp; } /*! @@ -2155,109 +2303,61 @@ int dct_chroma_sp(Macroblock *currMB, int uv,int cr_cbp) */ void copyblock_sp(Macroblock *currMB, ColorPlane pl, int block_x,int block_y) { - int i,j,i1,j1,m5[4],m6[4]; + int i, j; - int qp_per = (currMB->qpsp-MIN_QP)/6; - int qp_rem = (currMB->qpsp-MIN_QP)%6; - int q_bits = Q_BITS+qp_per; + int cur_qp = currMB->qpsp + img->bitdepth_luma_qp_scale; + int qp_per = qp_per_matrix[cur_qp]; + int qp_rem = qp_rem_matrix[cur_qp]; + int q_bits = Q_BITS + qp_per; int qp_const2=(1<<q_bits)/2; //sp_pred imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; - + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; + + levelscale = LevelScale4x4Comp[pl][0][qp_rem]; + invlevelscale = InvLevelScale4x4Comp[pl][0][qp_rem]; + leveloffset = ptLevelOffset4x4[0][cur_qp]; // Horizontal transform for (j=0; j< BLOCK_SIZE; j++) - for (i=0; i< BLOCK_SIZE; i++) - { - M1[i][j]=curr_mpr[j+block_y][i+block_x]; - } - - for (j=0; j < BLOCK_SIZE; j++) { - for (i=0; i < 2; i++) + for (i=0; i< BLOCK_SIZE; i++) { - i1=3-i; - m5[i]=M1[i][j]+M1[i1][j]; - m5[i1]=M1[i][j]-M1[i1][j]; + mb_rres[j+block_y][i+block_x] = mb_ores[j+block_y][i+block_x]; + M1[i][j]=mb_pred[j+block_y][i+block_x]; } - M1[0][j]=(m5[0]+m5[1]); - M1[2][j]=(m5[0]-m5[1]); - M1[1][j]=m5[3]*2+m5[2]; - M1[3][j]=m5[3]-m5[2]*2; } - // Vertical transform - - for (i=0; i < BLOCK_SIZE; i++) - { - for (j=0; j < 2; j++) - { - j1=3-j; - m5[j]=M1[i][j]+M1[i][j1]; - m5[j1]=M1[i][j]-M1[i][j1]; - } - M1[i][0]=(m5[0]+m5[1]); - M1[i][2]=(m5[0]-m5[1]); - M1[i][1]=m5[3]*2+m5[2]; - M1[i][3]=m5[3]-m5[2]*2; - } + forward4x4(M1, M1, 0, 0); // Quant for (j=0;j < BLOCK_SIZE; j++) { for (i=0; i < BLOCK_SIZE; i++) { - curr_res[j][i]=isignab((iabs(M1[i][j])* quant_coef[qp_rem][i][j]+qp_const2)>> q_bits,M1[i][j])*dequant_coef[qp_rem][i][j]<<qp_per; + mb_rres[j][i]=isignab((iabs(M1[i][j])* levelscale[i][j]+qp_const2)>> q_bits,M1[i][j])*levelscale[i][j]<<qp_per; if(!si_frame_indicator && !sp2_frame_indicator) { lrec[img->pix_y+block_y+j][img->pix_x+block_x+i] = - isignab((iabs(M1[i][j]) * quant_coef[qp_rem][i][j] + qp_const2) >> q_bits, M1[i][j]);// stores the SP frames coefficients, will be useful to encode SI or switching SP frame + isignab((iabs(M1[i][j]) * levelscale[i][j] + qp_const2) >> q_bits, M1[i][j]);// stores the SP frames coefficients, will be useful to encode SI or switching SP frame } } } // IDCT. // horizontal + inverse4x4(mb_rres, mb_rres, 0, 0); - for (j=0;j<BLOCK_SIZE;j++) + // Decoded block moved to frame memory + for (j=0; j < BLOCK_SIZE; j++) { - for (i=0;i<BLOCK_SIZE;i++) + for (i=0; i < BLOCK_SIZE; i++) { - m5[i]=curr_res[j][i]; + mb_rres[j][i] = iClip1 (img->max_imgpel_value, mb_rres[j][i]); + img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i]=(imgpel) mb_rres[j][i]; } - m6[0]=(m5[0]+m5[2]); - m6[1]=(m5[0]-m5[2]); - m6[2]=(m5[1]>>1)-m5[3]; - m6[3]=m5[1]+(m5[3]>>1); - - curr_res[j][0]=m6[0]+m6[3]; - curr_res[j][1]=m6[1]+m6[2]; - curr_res[j][2]=m6[1]-m6[2]; - curr_res[j][3]=m6[0]-m6[3]; } - // vertical - for (i=0;i<BLOCK_SIZE;i++) - { - for (j=0;j<BLOCK_SIZE;j++) - m5[j]=curr_res[j][i]; - - m6[0]=(m5[0]+m5[2]); - m6[1]=(m5[0]-m5[2]); - m6[2]=(m5[1]>>1)-m5[3]; - m6[3]=m5[1]+(m5[3]>>1); - - curr_res[0][i] = iClip1 (img->max_imgpel_value,rshift_rnd_sf(m6[0]+m6[3], DQ_BITS)); - curr_res[1][i] = iClip1 (img->max_imgpel_value,rshift_rnd_sf(m6[1]+m6[2], DQ_BITS)); - curr_res[2][i] = iClip1 (img->max_imgpel_value,rshift_rnd_sf(m6[1]-m6[2], DQ_BITS)); - curr_res[3][i] = iClip1 (img->max_imgpel_value,rshift_rnd_sf(m6[0]-m6[3], DQ_BITS)); - } - - // Decoded block moved to frame memory - - for (j=0; j < BLOCK_SIZE; j++) - for (i=0; i < BLOCK_SIZE; i++) - img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i]=(imgpel) curr_res[j][i]; } @@ -2336,15 +2436,14 @@ int writePCMByteAlign(Bitstream *currStream) int dct_4x4_sp2(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int *coeff_cost, int intra) { int i,j,ilev,coeff_ctr; - int qp_const,level,scan_pos,run; - int nonzero; + int qp_const,level,scan_pos = 0,run = -1; + int nonzero = FALSE; imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; +// int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int c_err,qp_const2; - int qp_per,qp_rem,q_bits; - int qp_per_sp,qp_rem_sp,q_bits_sp; int pos_x = block_x >> BLOCK_SHIFT; int pos_y = block_y >> BLOCK_SHIFT; @@ -2357,34 +2456,40 @@ int dct_4x4_sp2(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int * int level1; - qp_per = (img->qpsp-MIN_QP)/6 ; - qp_rem = (img->qpsp-MIN_QP)%6; - q_bits = Q_BITS+qp_per; - qp_per_sp = (img->qpsp-MIN_QP)/6; - qp_rem_sp = (img->qpsp-MIN_QP)%6; - q_bits_sp = Q_BITS+qp_per_sp; + int qp = (currMB->qpsp); // should double check spec why these are equal + int qp_sp = (currMB->qpsp); + + int qp_per = qp_per_matrix[qp]; + int qp_rem = qp_rem_matrix[qp]; + int q_bits = Q_BITS + qp_per; + int qp_per_sp = qp_per_matrix[qp_sp]; + int qp_rem_sp = qp_rem_matrix[qp_sp]; + int q_bits_sp = Q_BITS + qp_per_sp; + + levelscale = LevelScale4x4Comp[pl][intra][qp_rem]; + invlevelscale = InvLevelScale4x4Comp[pl][intra][qp_rem]; + leveloffset = ptLevelOffset4x4[intra][qp]; + + levelscale_sp = LevelScale4x4Comp[pl][intra][qp_rem_sp]; + invlevelscale_sp = InvLevelScale4x4Comp[pl][intra][qp_rem_sp]; + leveloffset_sp = ptLevelOffset4x4[intra][qp_sp]; qp_const=(1<<q_bits)/6; // inter qp_const2=(1<<q_bits_sp)/2; //sp_pred for (j=0; j< BLOCK_SIZE; j++) + { for (i=0; i< BLOCK_SIZE; i++) { //Coefficients obtained from the prior encoding of the SP frame - curr_res[j][i]=lrec[img->pix_y+block_y+j][img->pix_x+block_x+i]; + mb_rres[j][i] = lrec[img->pix_y+block_y+j][img->pix_x+block_x+i]; //Predicted block - M1[j][i]=curr_mpr[j+block_y][i+block_x]; + M1[j][i]=mb_pred[j+block_y][i+block_x]; } - + } // forward transform forward4x4(M1, M1, 0, 0); - // Quant - nonzero=FALSE; - - run=-1; - scan_pos=0; - for (coeff_ctr=0;coeff_ctr < 16;coeff_ctr++) // 8 times if double scan, 16 normal scan { @@ -2395,9 +2500,9 @@ int dct_4x4_sp2(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int * ilev=0; //quantization of the predicted block - level1 = (iabs (M1[j][i]) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp; + level1 = (iabs (M1[j][i]) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp; //substracted from lrec - c_err = curr_res[j][i]-isignab(level1, M1[j][i]); //substracting the predicted block + c_err = mb_rres[j][i]-isignab(level1, M1[j][i]); //substracting the predicted block level = iabs(c_err); if (level != 0) @@ -2413,17 +2518,17 @@ int dct_4x4_sp2(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int * } //from now on we are in decoder land ilev=c_err + isignab(level1,M1[j][i]) ; // adding the quantized predicted block - curr_res[j][i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + mb_rres[j][i] = ilev * invlevelscale_sp[j][i] << qp_per_sp; } ACLevel[scan_pos] = 0; // Inverse transform - inverse4x4(curr_res, curr_res, 0, 0); + inverse4x4(mb_rres, mb_rres, 0, 0); for (j=0; j < BLOCK_SIZE; j++) for (i=0; i < BLOCK_SIZE; i++) - img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i] =iClip3 (0, img->max_imgpel_value,rshift_rnd_sf(curr_res[j][i], DQ_BITS)); + img_enc[img->pix_y+block_y+j][img->pix_x+block_x+i] =iClip3 (0, img->max_imgpel_value,rshift_rnd_sf(mb_rres[j][i], DQ_BITS)); return nonzero; } @@ -2450,44 +2555,54 @@ int dct_4x4_sp2(Macroblock *currMB, ColorPlane pl, int block_x,int block_y,int * */ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) { - int i,j,ilev,n2,n1,coeff_ctr,qp_const,c_err,level ,scan_pos,run; + int i,j,ilev,n2,n1,coeff_ctr,c_err,level ,scan_pos = 0,run = -1; int m1[BLOCK_SIZE]; int coeff_cost; int cr_cbp_tmp; - int qp_const2,mp1[BLOCK_SIZE]; + int mp1[BLOCK_SIZE]; const byte *c_cost = COEFF_COST4x4[params->disthres]; const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN : SNGL_SCAN; - int qp_per,qp_rem,q_bits; - int qp_per_sp,qp_rem_sp,q_bits_sp; - int b4; int* DCLevel = img->cofDC[uv+1][0]; int* DCRun = img->cofDC[uv+1][1]; int* ACLevel; int* ACRun; int level1; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[uv + 1]; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[uv + 1]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[uv + 1]; + //int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[uv + 1]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[uv + 1]; + int intra = IS_INTRA (currMB); - qp_per = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)/6; - qp_rem = ((img->qp<0?img->qp:QP_SCALE_CR[img->qp])-MIN_QP)%6; - q_bits = Q_BITS+qp_per; - qp_const=(1<<q_bits)/6; // inter + int qpChroma = currMB->qpc[uv] + img->bitdepth_chroma_qp_scale; + int qpChromaSP = iClip3(-img->bitdepth_chroma_qp_scale, 51, currMB->qpsp + active_pps->chroma_qp_index_offset); + + int qp_per = qp_per_matrix[qpChroma]; + int qp_rem = qp_rem_matrix[qpChroma]; - qp_per_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)/6; - qp_rem_sp = ((img->qpsp<0?img->qpsp:QP_SCALE_CR[img->qpsp])-MIN_QP)%6; - q_bits_sp = Q_BITS+qp_per_sp; - qp_const2 = (1<<q_bits_sp)/2; //sp_pred + int qp_per_sp = qp_per_matrix[qpChromaSP]; + int qp_rem_sp = qp_rem_matrix[qpChromaSP]; + int q_bits_sp = Q_BITS + qp_per; + int qp_const2 = (1 << q_bits_sp)/2; //sp_pred + + levelscale = LevelScale4x4Comp[uv + 1][intra][qp_rem]; + invlevelscale = InvLevelScale4x4Comp[uv + 1][intra][qp_rem]; + leveloffset = ptLevelOffset4x4[intra][qpChroma]; + + levelscale_sp = LevelScale4x4Comp[uv + 1][intra][qp_rem_sp]; + invlevelscale_sp = InvLevelScale4x4Comp[uv + 1][intra][qp_rem_sp]; + leveloffset_sp = ptLevelOffset4x4[intra][qpChromaSP]; for (j=0; j < MB_BLOCK_SIZE>>1; j++) + { for (i=0; i < MB_BLOCK_SIZE>>1; i++) { - M1[j][i]=curr_mpr[j][i]; - curr_res[j][i]=lrec_uv[uv][img->pix_c_y+j][img->pix_c_x+i]; + M1[j][i]=mb_pred[j][i]; + mb_rres[j][i]=lrec_uv[uv][img->pix_c_y+j][img->pix_c_x+i]; } + } + - for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE) { for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE) @@ -2497,24 +2612,21 @@ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) } // DC coefficients already transformed and quantized - m1[0]= curr_res[0][0]; - m1[1]= curr_res[0][4]; - m1[2]= curr_res[4][0]; - m1[3]= curr_res[4][4]; + m1[0]= mb_rres[0][0]; + m1[1]= mb_rres[0][4]; + m1[2]= mb_rres[4][0]; + m1[3]= mb_rres[4][4]; // 2X2 transform of predicted DC coeffs. hadamard2x2(M1, mp1); - run=-1; - scan_pos=0; - for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) { run++; ilev=0; //quantization of predicted DC coeff - level1 = (iabs (mp1[coeff_ctr]) * quant_coef[qp_rem_sp][0][0] + 2 * qp_const2) >> (q_bits_sp + 1); + level1 = (iabs (mp1[coeff_ctr]) * levelscale_sp[0][0] + 2 * qp_const2) >> (q_bits_sp + 1); //substratcted from lrecUV c_err = m1[coeff_ctr] - isignab(level1, mp1[coeff_ctr]); level = iabs(c_err); @@ -2532,18 +2644,18 @@ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) //from now on decoder world ilev = c_err + isignab(level1,mp1[coeff_ctr]) ; // we have perfect reconstruction here - m1[coeff_ctr]= ilev * dequant_coef[qp_rem_sp][0][0] << qp_per_sp; + m1[coeff_ctr]= ilev * invlevelscale_sp[0][0] << qp_per_sp; } DCLevel[scan_pos] = 0; - // Invers transform of 2x2 DC levels + // Inverse transform of 2x2 DC levels ihadamard2x2(m1, m1); - curr_res[0][0]=m1[0]/2; - curr_res[0][4]=m1[1]/2; - curr_res[4][0]=m1[2]/2; - curr_res[4][4]=m1[3]/2; + mb_rres[0][0]=m1[0]/2; + mb_rres[0][4]=m1[1]/2; + mb_rres[4][0]=m1[2]/2; + mb_rres[4][4]=m1[3]/2; // Quant of chroma AC-coeffs. coeff_cost=0; @@ -2569,9 +2681,9 @@ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) ++run; ilev=0; // quantization on prediction - level1 = (iabs(M1[n2+j][n1+i]) * quant_coef[qp_rem_sp][j][i] + qp_const2) >> q_bits_sp; + level1 = (iabs(M1[n2+j][n1+i]) * levelscale_sp[j][i] + qp_const2) >> q_bits_sp; //substracted from lrec - c_err = curr_res[n2+j][n1+i] - isignab(level1, M1[n2+j][n1+i]); + c_err = mb_rres[n2+j][n1+i] - isignab(level1, M1[n2+j][n1+i]); level = iabs(c_err) ; if (level != 0) @@ -2589,7 +2701,7 @@ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) //from now on decoder land ilev=c_err + isignab(level1,M1[n2+j][n1+i]); - curr_res[n2+j][n1+i] = ilev * dequant_coef[qp_rem_sp][j][i] << qp_per_sp; + mb_rres[n2+j][n1+i] = ilev * invlevelscale_sp[j][i] << qp_per_sp; } ACLevel[scan_pos] = 0; } @@ -2597,22 +2709,22 @@ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) // * reset chroma coeffs if(cr_cbp_tmp==2) - cr_cbp=2; + cr_cbp=2; // IDCT. - // Horizontal. + // Horizontal. for (n2=0; n2 <= BLOCK_SIZE; n2 += BLOCK_SIZE) { for (n1=0; n1 <= BLOCK_SIZE; n1 += BLOCK_SIZE) { - inverse4x4(curr_res, curr_res, n2, n1); + inverse4x4(mb_rres, mb_rres, n2, n1); // Vertical. for (j=0; j < BLOCK_SIZE; j++) { for (i=0; i < BLOCK_SIZE; i++) { - enc_picture->imgUV[uv][img->pix_c_y+j+n2][img->pix_c_x+i +n1 ] = iClip3 (0, img->max_imgpel_value,rshift_rnd_sf(curr_res[n2+j][n1+i], DQ_BITS)); + enc_picture->imgUV[uv][img->pix_c_y+j+n2][img->pix_c_x+i +n1 ] = iClip3 (0, img->max_imgpel_value,rshift_rnd_sf(mb_rres[n2+j][n1+i], DQ_BITS)); } } } @@ -2622,7 +2734,7 @@ int dct_chroma_sp2(Macroblock *currMB, int uv,int cr_cbp) } -void select_dct(Macroblock *currMB) +void select_dct(ImageParameters *img, Macroblock *currMB) { if (img->type!=SP_SLICE) { @@ -2645,14 +2757,14 @@ void select_dct(Macroblock *currMB) dct_cr_4x4[0] = dct_chroma; dct_cr_4x4[1] = dct_chroma; } - + if (currMB->qp_scaled[1] == 0) { - dct_cr_4x4[0] = dct_chroma_ls; + dct_cr_4x4[0] = dct_chroma_ls; } if (currMB->qp_scaled[2] == 0) { - dct_cr_4x4[1] = dct_chroma_ls; + dct_cr_4x4[1] = dct_chroma_ls; } } else diff --git a/lencod/src/cabac.c b/lencod/src/cabac.c index 8496df1..159773d 100644 --- a/lencod/src/cabac.c +++ b/lencod/src/cabac.c @@ -19,7 +19,7 @@ #include "mb_access.h" #if TRACE -#define CABAC_TRACE if (dp->bitstream->trace_enabled) trace2out_cabac (se) + #define CABAC_TRACE if (dp->bitstream->trace_enabled) trace2out_cabac (se) #else #define CABAC_TRACE #endif @@ -106,9 +106,7 @@ MotionInfoContexts* create_contexts_MotionInfo(void) */ TextureInfoContexts* create_contexts_TextureInfo(void) { - TextureInfoContexts* enco_ctx; - - enco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) ); + TextureInfoContexts* enco_ctx = (TextureInfoContexts*) calloc(1, sizeof(TextureInfoContexts) ); if( enco_ctx == NULL ) no_mem_exit("create_contexts_TextureInfo: enco_ctx"); @@ -131,8 +129,6 @@ void delete_contexts_MotionInfo(MotionInfoContexts *enco_ctx) return; free( enco_ctx ); - - return; } /*! @@ -148,8 +144,6 @@ void delete_contexts_TextureInfo(TextureInfoContexts *enco_ctx) return; free( enco_ctx ); - - return; } @@ -164,15 +158,14 @@ void writeFieldModeInfo_CABAC(SyntaxElement *se, DataPartition *dp) { EncodingEnvironmentPtr eep_dp = &(dp->ee_cabac); int curr_len = arienco_bits_written(eep_dp); - int a,b,act_ctx; - MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; - Macroblock *currMB = &img->mb_data[img->current_mb_nr]; - int mb_field = se->value1; + MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; + Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + int mb_field = se->value1; - a = currMB->mbAvailA ? img->mb_data[currMB->mbAddrA].mb_field : 0; - b = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0; + int a = currMB->mbAvailA ? img->mb_data[currMB->mbAddrA].mb_field : 0; + int b = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0; - act_ctx = a + b; + int act_ctx = a + b; biari_encode_symbol(eep_dp, (signed short) (mb_field != 0),&ctx->mb_aff_contexts[act_ctx]); @@ -181,7 +174,6 @@ void writeFieldModeInfo_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -194,51 +186,31 @@ void writeMB_skip_flagInfo_CABAC(Macroblock *currMB, SyntaxElement *se, DataPart { EncodingEnvironmentPtr eep_dp = &(dp->ee_cabac); int curr_len = arienco_bits_written(eep_dp); - int a,b,act_ctx; - int bframe = (img->type==B_SLICE); - MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; - int curr_mb_type = se->value1; + MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; + int curr_mb_type = se->value1; + int a = (currMB->mb_available_left != NULL && (currMB->mb_available_left->skip_flag == 0)) ? 1 : 0; + int b = (currMB->mb_available_up != NULL && (currMB->mb_available_up ->skip_flag == 0)) ? 1 : 0; + int act_ctx = a + b; - if (bframe) + if (img->type == B_SLICE) { - if (currMB->mb_available_up == NULL) - b = 0; - else - b = (currMB->mb_available_up->skip_flag==0 ? 1 : 0); - - if (currMB->mb_available_left == NULL) - a = 0; - else - a = (currMB->mb_available_left->skip_flag==0 ? 1 : 0); - - act_ctx = 7 + a + b; + act_ctx += 7; if (se->value1==0 && se->value2==0) // DIRECT mode, no coefficients biari_encode_symbol (eep_dp, 1, &ctx->mb_type_contexts[2][act_ctx]); else biari_encode_symbol (eep_dp, 0, &ctx->mb_type_contexts[2][act_ctx]); - currMB->skip_flag = (se->value1==0 && se->value2==0)?1:0; + currMB->skip_flag = (se->value1==0 && se->value2==0) ? 1 : 0; } else { - if (currMB->mb_available_up == NULL) - b = 0; - else - b = (( (currMB->mb_available_up)->skip_flag == 0) ? 1 : 0 ); - if (currMB->mb_available_left == NULL) - a = 0; - else - a = (( (currMB->mb_available_left)->skip_flag == 0) ? 1 : 0 ); - - act_ctx = a + b; - if (curr_mb_type==0) // SKIP biari_encode_symbol(eep_dp, 1,&ctx->mb_type_contexts[1][act_ctx]); else biari_encode_symbol(eep_dp, 0,&ctx->mb_type_contexts[1][act_ctx]); - currMB->skip_flag = (curr_mb_type==0)?1:0; + currMB->skip_flag = (curr_mb_type==0) ? 1 : 0; } se->context = act_ctx; se->value1 = 1 - currMB->skip_flag; @@ -246,7 +218,6 @@ void writeMB_skip_flagInfo_CABAC(Macroblock *currMB, SyntaxElement *se, DataPart dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -260,27 +231,23 @@ void writeMB_skip_flagInfo_CABAC(Macroblock *currMB, SyntaxElement *se, DataPart void writeMB_transform_size_CABAC(SyntaxElement *se, DataPartition *dp) { EncodingEnvironmentPtr eep_dp = &(dp->ee_cabac); - int curr_len = arienco_bits_written(eep_dp); - int a, b; - int act_ctx = 0; - int act_sym; - MotionInfoContexts *ctx = (img->currentSlice)->mot_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + int curr_len = arienco_bits_written(eep_dp); + int act_sym = currMB->luma_transform_size_8x8_flag; + - b = (currMB->mb_available_up == NULL) ? 0 : currMB->mb_available_up->luma_transform_size_8x8_flag; - a = (currMB->mb_available_left == NULL) ? 0 :currMB->mb_available_left->luma_transform_size_8x8_flag; + int b = (currMB->mb_available_up == NULL) ? 0 : currMB->mb_available_up->luma_transform_size_8x8_flag; + int a = (currMB->mb_available_left == NULL) ? 0 :currMB->mb_available_left->luma_transform_size_8x8_flag; + int act_ctx = a + b; - act_ctx = a + b; - act_sym = currMB->luma_transform_size_8x8_flag; se->context = act_ctx; // store context biari_encode_symbol(eep_dp, (signed short) (act_sym != 0), ctx->transform_size_contexts + act_ctx ); dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -523,7 +490,6 @@ void writeMB_typeInfo_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } @@ -586,37 +552,38 @@ void writeB8_typeInfo_CABAC(SyntaxElement *se, DataPartition *dp) biari_encode_symbol (eep_dp, 1, &b8_type_contexts[1][0]); act_sym--; } - if (act_sym<2) + + if (act_sym < 2) { biari_encode_symbol (eep_dp, 0, &b8_type_contexts[1][1]); biari_encode_symbol (eep_dp, (signed short) (act_sym!=0), &b8_type_contexts[1][3]); } - else if (act_sym<6) + else if (act_sym < 6) { biari_encode_symbol (eep_dp, 1, &b8_type_contexts[1][1]); biari_encode_symbol (eep_dp, 0, &b8_type_contexts[1][2]); - csym=(((act_sym-2)>>1)&0x01) != 0; + csym=(((act_sym - 2) >> 1) & 0x01) != 0; biari_encode_symbol (eep_dp, csym, &b8_type_contexts[1][3]); - csym=((act_sym-2)&0x01) != 0; + csym=((act_sym - 2) & 0x01) != 0; biari_encode_symbol (eep_dp, csym, &b8_type_contexts[1][3]); } else { biari_encode_symbol (eep_dp, 1, &b8_type_contexts[1][1]); biari_encode_symbol (eep_dp, 1, &b8_type_contexts[1][2]); - csym=(((act_sym-6)>>2)&0x01); + csym=(((act_sym - 6)>> 2) & 0x01); if (csym) { biari_encode_symbol (eep_dp, 1, &b8_type_contexts[1][3]); - csym=((act_sym-6)&0x01) != 0; + csym=((act_sym - 6) & 0x01) != 0; biari_encode_symbol (eep_dp, csym, &b8_type_contexts[1][3]); } else { biari_encode_symbol (eep_dp, 0, &b8_type_contexts[1][3]); - csym=(((act_sym-6)>>1)&0x01) != 0; + csym=(((act_sym - 6) >> 1) & 0x01) != 0; biari_encode_symbol (eep_dp, csym, &b8_type_contexts[1][3]); - csym=((act_sym-6)&0x01) != 0; + csym=((act_sym - 6) & 0x01) != 0; biari_encode_symbol (eep_dp, csym, &b8_type_contexts[1][3]); } } @@ -625,7 +592,6 @@ void writeB8_typeInfo_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -657,7 +623,6 @@ void writeIntraPredMode_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -679,7 +644,7 @@ void writeRefFrame_CABAC(SyntaxElement *se, DataPartition *dp) int a, b; int act_ctx; int act_sym; - char** refframe_array = enc_picture->ref_idx[se->value2]; + char** refframe_array = enc_picture->motion.ref_idx[se->value2]; int bslice = (img->type==B_SLICE); @@ -740,7 +705,6 @@ void writeRefFrame_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -778,7 +742,6 @@ void writeDquant_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } /*! @@ -871,7 +834,6 @@ void writeMVD_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } @@ -888,23 +850,15 @@ void writeCIPredMode_CABAC(SyntaxElement *se, DataPartition *dp) int curr_len = arienco_bits_written(eep_dp); TextureInfoContexts *ctx = img->currentSlice->tex_ctx; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; - int act_ctx,a,b; int act_sym = se->value1; Macroblock *MbUp = currMB->mb_available_up; Macroblock *MbLeft = currMB->mb_available_left; - if (MbUp == NULL) - b = 0; - else - b = ((MbUp->c_ipred_mode != 0) && (MbUp->mb_type != IPCM)) ? 1 : 0; + int b = (MbUp != NULL) ? (((MbUp->c_ipred_mode != 0) && (MbUp->mb_type != IPCM)) ? 1 : 0) : 0; + int a = (MbLeft != NULL) ? (((MbLeft->c_ipred_mode != 0) && (MbLeft->mb_type != IPCM)) ? 1 : 0) : 0; - if (MbLeft == NULL) - a = 0; - else - a = ((MbLeft->c_ipred_mode != 0) && (MbLeft->mb_type != IPCM)) ? 1 : 0; - - act_ctx = a+b; + int act_ctx = a + b; if (act_sym==0) biari_encode_symbol(eep_dp, 0, ctx->cipr_contexts + act_ctx ); @@ -917,7 +871,6 @@ void writeCIPredMode_CABAC(SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } @@ -931,39 +884,30 @@ void writeCIPredMode_CABAC(SyntaxElement *se, DataPartition *dp) void writeCBP_BIT_CABAC (Macroblock* currMB, int b8, int bit, int cbp, int inter, EncodingEnvironmentPtr eep_dp, TextureInfoContexts *ctx) { PixelPos block_a; - int a, b; + int a = 0, b = 0; int mb_x=(b8 & 0x01)<<1; int mb_y=(b8 >> 1)<<1; if (mb_y == 0) { - if ((currMB->mb_available_up == NULL) || ((currMB->mb_available_up)->mb_type==IPCM)) - b = 0; - else + if (!((currMB->mb_available_up == NULL) || ((currMB->mb_available_up)->mb_type==IPCM))) { b = (( ((currMB->mb_available_up)->cbp & (1<<(2+(mb_x>>1)))) == 0) ? 1 : 0); //VG-ADD } } else - b = ( ((cbp & (1<<(mb_x/2))) == 0) ? 1: 0); + b = ( ((cbp & (1<<(mb_x >> 1))) == 0) ? 1: 0); if (mb_x == 0) { get4x4Neighbour(currMB, (mb_x << 2) - 1, (mb_y << 2), img->mb_size[IS_LUMA], &block_a); - if (block_a.available) - { - { - if(img->mb_data[block_a.mb_addr].mb_type==IPCM) - a=0; - else - a = (( (img->mb_data[block_a.mb_addr].cbp & (1<<(2*(block_a.y>>1)+1))) == 0) ? 1 : 0); //VG-ADD - } - } - else - a=0; + if (block_a.available && (!(img->mb_data[block_a.mb_addr].mb_type==IPCM))) + { + a = (( (img->mb_data[block_a.mb_addr].cbp & (1<<(2*(block_a.y>>1)+1))) == 0) ? 1 : 0); //VG-ADD + } } else a = ( ((cbp & (1<<mb_y)) == 0) ? 1: 0); @@ -1041,22 +985,8 @@ void writeCBP_CABAC(Macroblock *currMB, SyntaxElement *se, DataPartition *dp) dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } - - - -//static const int maxpos [] = {15, 14, 63, 31, 31, 15, 3, 14, 7, 15, 15, 14, 63, 31, 31, 15, 15, 14, 63, 31, 31, 15}; -//static const int c1isdc [] = { 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1}; -// -//static const int type2ctx_bcbp[] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 10, 11, 12, 13, 13, 14, 16, 17, 18, 19, 19, 20}; -//static const int type2ctx_map [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; // 8 -//static const int type2ctx_last[] = { 0, 1, 2, 3, 4, 5, 6, 7, 6, 6, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; // 8 -//static const int type2ctx_one [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 10, 11, 12, 13, 13, 14, 16, 17, 18, 19, 19, 20}; // 7 -//static const int type2ctx_abs [] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 10, 11, 12, 13, 13, 14, 16, 17, 18, 19, 19, 20}; // 7 -//static const int max_c2 [] = { 4, 4, 4, 4, 4, 4, 3, 4, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; // 9 - const int maxpos [] = {15, 14, 63, 31, 31, 15, 3, 14, 7, 15, 15, 14, 63, 31, 31, 15, 15, 14, 63, 31, 31, 15}; const int c1isdc [] = { 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1}; @@ -1077,7 +1007,6 @@ void write_and_store_CBP_block_bit (Macroblock* currMB, EncodingEnvironmentPtr e { #define BIT_SET(x,n) ((int)(((x)&((int64)1<<(n)))>>(n))) - int y_ac = (type==LUMA_16AC || type==LUMA_8x8 || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4 || type==CB_16AC || type==CB_8x8 || type==CB_8x4 || type==CB_4x8 || type==CB_4x4 || type==CR_16AC || type==CR_8x8 || type==CR_8x4 || type==CR_4x8 || type==CR_4x4); @@ -1119,9 +1048,9 @@ void write_and_store_CBP_block_bit (Macroblock* currMB, EncodingEnvironmentPtr e if (u_ac||v_ac) { if (block_a.available) - bit_pos_a = 4*block_a.y + block_a.x; + bit_pos_a = (block_a.y << 2) + block_a.x; if (block_b.available) - bit_pos_b = 4*block_b.y + block_b.x; + bit_pos_b = (block_b.y << 2) + block_b.x; } } @@ -1268,21 +1197,21 @@ void write_and_store_CBP_block_bit (Macroblock* currMB, EncodingEnvironmentPtr e if (block_a.available) { if(img->mb_data[block_a.mb_addr].mb_type==IPCM) - left_bit=1; + left_bit = 1; else { if(type==LUMA_8x8) - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[0],bit+bit_pos_a); + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[0],bit + bit_pos_a); else if (type==CB_8x8) - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[1],bit+bit_pos_a); + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[1],bit + bit_pos_a); else if (type==CR_8x8) - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[2],bit+bit_pos_a); + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[2],bit + bit_pos_a); else if ((type==CB_4x4)||(type==CB_4x8)||(type==CB_8x4)||(type==CB_16AC)||(type==CB_16DC)) - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[1],bit+bit_pos_a); + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[1],bit + bit_pos_a); else if ((type==CR_4x4)||(type==CR_4x8)||(type==CR_8x4)||(type==CR_16AC)||(type==CR_16DC)) - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[2],bit+bit_pos_a); + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[2],bit + bit_pos_a); else - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[0],bit+bit_pos_a); + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[0],bit + bit_pos_a); } } @@ -1298,24 +1227,6 @@ void write_and_store_CBP_block_bit (Macroblock* currMB, EncodingEnvironmentPtr e //===== position -> ctx for MAP ===== //--- zig-zag scan ---- -//static const int pos2ctx_map8x8 [] = { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, -// 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9, 10, 9, 8, 7, -// 7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10, 9, 8, 6, 11, -// 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11 ,14, 10, 12, 14}; // 15 CTX -//static const int pos2ctx_map8x4 [] = { 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 9, 8, 6, 7, 8, -// 9, 10, 11, 9, 8, 6, 12, 8, 9, 10, 11, 9, 13, 13, 14, 14}; // 15 CTX -//static const int pos2ctx_map4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14}; // 15 CTX -//static const int pos2ctx_map2x4c[] = { 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX -//static const int pos2ctx_map4x4c[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX -//static const int* pos2ctx_map [] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8, pos2ctx_map8x4, -// pos2ctx_map8x4, pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map4x4, -// pos2ctx_map2x4c, pos2ctx_map4x4c, -// -// pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8,pos2ctx_map8x4, -// pos2ctx_map8x4, pos2ctx_map4x4, //Cb component -// pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_map8x8,pos2ctx_map8x4, -// pos2ctx_map8x4,pos2ctx_map4x4}; //Cr component - const int pos2ctx_map8x8 [] = { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9, 10, 9, 8, 7, 7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10, 9, 8, 6, 11, @@ -1356,22 +1267,6 @@ static const int* pos2ctx_map_int[] = {pos2ctx_map4x4, pos2ctx_map4x4, pos2ctx_m //===== position -> ctx for LAST ===== -//static const int pos2ctx_last8x8 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -// 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, -// 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8}; // 9 CTX -//static const int pos2ctx_last8x4 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, -// 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}; // 9 CTX -//static const int pos2ctx_last4x4 [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; // 15 CTX -//static const int pos2ctx_last2x4c[] = { 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX -//static const int pos2ctx_last4x4c[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2}; // 15 CTX -//static const int* pos2ctx_last [] = {pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8, pos2ctx_last8x4, -// pos2ctx_last8x4, pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last4x4, -// pos2ctx_last2x4c, pos2ctx_last4x4c, -// pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8,pos2ctx_last8x4, -// pos2ctx_last8x4, pos2ctx_last4x4, //Cb component -// pos2ctx_last4x4, pos2ctx_last4x4, pos2ctx_last8x8,pos2ctx_last8x4, -// pos2ctx_last8x4, pos2ctx_last4x4}; //Cr component const int pos2ctx_last8x8 [] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, @@ -1430,7 +1325,8 @@ void write_significance_map (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, last = (--coeff_ctr == 0); biari_encode_symbol(eep_dp, last, last_ctx + pos2ctx_last[type][k]); - if (last) return; + if (last) + return; } } return; @@ -1447,7 +1343,8 @@ void write_significance_map (Macroblock* currMB, EncodingEnvironmentPtr eep_dp, last = (--coeff_ctr == 0); biari_encode_symbol(eep_dp, last, last_ctx + pos2ctx_last[type][k]); - if (last) return; + if (last) + return; } } } @@ -1476,7 +1373,7 @@ void write_significant_coefficients (Macroblock* currMB, EncodingEnvironmentPtr { if (coeff[i]!=0) { - if (coeff[i]>0) + if (coeff[i] > 0) { absLevel = coeff[i]; sign = 0; @@ -1490,7 +1387,7 @@ void write_significant_coefficients (Macroblock* currMB, EncodingEnvironmentPtr greater_one = (absLevel > 1); //--- if coefficient is one --- - ctx = imin(c1,4); + ctx = imin(c1, 4); biari_encode_symbol (eep_dp, greater_one, one_contexts + ctx); if (greater_one) @@ -1530,13 +1427,12 @@ void writeRunLevel_CABAC (Macroblock* currMB, SyntaxElement *se, DataPartition * pos += se->value2; coeff[pos++] = se->value1; coeff_ctr++; - //return; } else { TextureInfoContexts *tex_ctx = img->currentSlice->tex_ctx; //===== encode CBP-BIT ===== - if (coeff_ctr>0) + if (coeff_ctr > 0) { write_and_store_CBP_block_bit (currMB, eep_dp, se->context, 1, tex_ctx); //===== encode significance map ===== @@ -1555,7 +1451,6 @@ void writeRunLevel_CABAC (Macroblock* currMB, SyntaxElement *se, DataPartition * dp->bitstream->write_flag = 1; se->len = (arienco_bits_written(eep_dp) - curr_len); CABAC_TRACE; - return; } @@ -1574,9 +1469,7 @@ void unary_bin_encode(EncodingEnvironmentPtr eep_dp, BiContextTypePtr ctx, int ctx_offset) { - unsigned int l; - BiContextTypePtr ictx; - + if (symbol==0) { biari_encode_symbol(eep_dp, 0, ctx ); @@ -1585,13 +1478,11 @@ void unary_bin_encode(EncodingEnvironmentPtr eep_dp, else { biari_encode_symbol(eep_dp, 1, ctx ); - l = symbol; - ictx = ctx+ctx_offset; - while ((--l)>0) - biari_encode_symbol(eep_dp, 1, ictx); - biari_encode_symbol(eep_dp, 0, ictx); + ctx += ctx_offset; + while ((--symbol) > 0) + biari_encode_symbol(eep_dp, 1, ctx); + biari_encode_symbol(eep_dp, 0, ctx); } - return; } /*! @@ -1609,9 +1500,6 @@ void unary_bin_max_encode(EncodingEnvironmentPtr eep_dp, int ctx_offset, unsigned int max_symbol) { - unsigned int l; - BiContextTypePtr ictx; - if (symbol==0) { biari_encode_symbol(eep_dp, 0, ctx ); @@ -1619,15 +1507,15 @@ void unary_bin_max_encode(EncodingEnvironmentPtr eep_dp, } else { + unsigned int l = symbol; biari_encode_symbol(eep_dp, 1, ctx ); - l=symbol; - ictx=ctx+ctx_offset; + + ctx += ctx_offset; while ((--l)>0) - biari_encode_symbol(eep_dp, 1, ictx); - if (symbol<max_symbol) - biari_encode_symbol(eep_dp, 0, ictx); + biari_encode_symbol(eep_dp, 1, ctx); + if (symbol < max_symbol) + biari_encode_symbol(eep_dp, 0, ctx); } - return; } @@ -1658,8 +1546,6 @@ void exp_golomb_encode_eq_prob( EncodingEnvironmentPtr eep_dp, break; } } - - return; } /*! @@ -1672,9 +1558,6 @@ void unary_exp_golomb_level_encode( EncodingEnvironmentPtr eep_dp, unsigned int symbol, BiContextTypePtr ctx) { - unsigned int l,k; - unsigned int exp_start = 13; // 15-2 : 0,1 level decision always sent - if (symbol==0) { biari_encode_symbol(eep_dp, 0, ctx ); @@ -1682,17 +1565,18 @@ void unary_exp_golomb_level_encode( EncodingEnvironmentPtr eep_dp, } else { + unsigned int exp_start = 13; // 15-2 : 0,1 level decision always sent + unsigned int l=symbol; + unsigned int k = 1; + biari_encode_symbol(eep_dp, 1, ctx ); - l=symbol; - k=1; while (((--l)>0) && (++k <= exp_start)) biari_encode_symbol(eep_dp, 1, ctx); if (symbol < exp_start) biari_encode_symbol(eep_dp, 0, ctx); else - exp_golomb_encode_eq_prob(eep_dp,symbol-exp_start,0); + exp_golomb_encode_eq_prob(eep_dp,symbol - exp_start, 0); } - return; } @@ -1707,36 +1591,31 @@ void unary_exp_golomb_mv_encode(EncodingEnvironmentPtr eep_dp, unsigned int symbol, BiContextTypePtr ctx, unsigned int max_bin) -{ - unsigned int l,k; - unsigned int bin=1; - BiContextTypePtr ictx=ctx; - unsigned int exp_start = 8; // 9-1 : 0 mvd decision always sent - +{ if (symbol==0) { - biari_encode_symbol(eep_dp, 0, ictx ); + biari_encode_symbol(eep_dp, 0, ctx ); return; } else { - biari_encode_symbol(eep_dp, 1, ictx ); - l=symbol; - k=1; - ictx++; + unsigned int bin=1; + unsigned int exp_start = 8; // 9-1 : 0 mvd decision always sent + unsigned int l = symbol, k = 1; + biari_encode_symbol(eep_dp, 1, ctx++ ); + while (((--l)>0) && (++k <= exp_start)) { - biari_encode_symbol(eep_dp, 1, ictx ); - if ((++bin)==2) - ictx++; - if (bin==max_bin) - ictx++; + biari_encode_symbol(eep_dp, 1, ctx ); + if ((++bin) == 2) + ctx++; + if (bin == max_bin) + ctx++; } if (symbol < exp_start) - biari_encode_symbol(eep_dp, 0, ictx); + biari_encode_symbol(eep_dp, 0, ctx); else - exp_golomb_encode_eq_prob(eep_dp,symbol-exp_start,3); + exp_golomb_encode_eq_prob(eep_dp, symbol - exp_start, 3); } - return; } diff --git a/lencod/src/cconv_yuv2rgb.c b/lencod/src/cconv_yuv2rgb.c new file mode 100644 index 0000000..975a375 --- /dev/null +++ b/lencod/src/cconv_yuv2rgb.c @@ -0,0 +1,122 @@ + +/*! + ************************************************************************************* + * \file img_distortion.c + * + * \brief + * YUV to RGB color conversion + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + ************************************************************************************* + */ +#include "contributors.h" +#include "global.h" +#include "img_distortion.h" + +#define YUV2RGB_YOFFSET + +//YUV to RGB conversion +#ifdef YUV2RGB_YOFFSET +#define OFFSET_Y 16 +static const float K0 = 1.164f; +static const float K1 = 1.596f; +static const float K2 = 0.391f; +static const float K3 = 0.813f; +static const float K4 = 2.018f; +static int offset_y, offset_cr; +#else +static const float K0 = 1.000f; +static const float K1 = 1.402f; +static const float K2 = 0.34414f; +static const float K3 = 0.71414f; +static const float K4 = 1.772f; +#endif +static int wk0, wk1, wk2, wk3, wk4; + +ImageStructure imgRGB_src, imgRGB_ref; + +void init_YUVtoRGB(void) +{ + float conv_scale = (float) (65536.0f); + + wk0 = float2int( conv_scale * K0); + wk1 = float2int( conv_scale * K1); + wk2 = float2int( -conv_scale * K2); + wk3 = float2int( -conv_scale * K3); + wk4 = float2int( conv_scale * K4); + +#ifdef YUV2RGB_YOFFSET + offset_y = OFFSET_Y << (params->output.bit_depth[0] - 8); + offset_cr = 1 << (params->output.bit_depth[0] - 1); +#endif +} + +/*! +************************************************************************************* +* \brief +* YUV to RGB conversion +* ITU 601 with and without offset consideration +* Upsampling by repetition of chroma samples in case of 4:2:0 and 4:2:2 +* Method not support for 4:0:0 content +************************************************************************************* +*/ +void YUVtoRGB(ImageStructure *YUV, ImageStructure *RGB) +{ + static int i, j, j_cr, i_cr; + static int sy, su, sv; + static int wbuv, wguv, wruv; + static imgpel *Y, *U, *V, *R, *G, *B; + FrameFormat format = YUV->format; + int width = format.width; + int height = format.height; + int max_value = format.max_value[0]; + + // Color conversion + for (j = 0; j < height; j++) + { + j_cr = j >> shift_cr_y; + Y = YUV->data[0][j]; + U = YUV->data[1][j_cr]; + V = YUV->data[2][j_cr]; + R = RGB->data[0][j]; + G = RGB->data[1][j]; + B = RGB->data[2][j]; + + for (i = 0; i < width; i++) + { + i_cr = i >> shift_cr_x; + + su = U[i_cr] - offset_cr; + sv = V[i_cr] - offset_cr; + + wruv = wk1 * sv; + wguv = wk2 * su + wk3 * sv; + wbuv = wk4 * su; + +#ifdef YUV2RGB_YOFFSET // Y offset value of 16 is considered + sy = wk0 * (Y[i] - offset_y); +#else + sy = wk0 * Y[i]; +#endif + + R[i] = iClip1( max_value, rshift_rnd(sy + wruv, 16)); + G[i] = iClip1( max_value, rshift_rnd(sy + wguv, 16)); + B[i] = iClip1( max_value, rshift_rnd(sy + wbuv, 16)); + } + } + // Setting RGB FrameFormat + RGB->format = format; // copy format information from YUV to RGB + RGB->format.yuv_format = 3; + RGB->format.rgb_format = 1; + RGB->format.height_cr = format.height; + RGB->format.width_cr = format.width; + for (i = 1; i < 3; i++) + { + RGB->format.size_cmp[i] = format.size_cmp[0]; + RGB->format.bit_depth[i] = format.bit_depth[0]; + RGB->format.max_value[i] = max_value; + RGB->format.max_value_sq[i] = format.max_value_sq[0]; + } +} diff --git a/lencod/src/configfile.c b/lencod/src/configfile.c index 38fbdb0..0d82084 100644 --- a/lencod/src/configfile.c +++ b/lencod/src/configfile.c @@ -149,6 +149,23 @@ static void getNumberOfFrames (void) params->no_frames = (int) (((fsize - params->infile_header)/ isize) - params->start_frame - 1) / (1 + params->jumpd) + 1; } +/*! + ************************************************************************ + * \brief + * Updates images max values + * + ************************************************************************ + */ +static void updateMaxValue(FrameFormat *format) +{ + format->max_value[0] = (1 << format->bit_depth[0]) - 1; + format->max_value_sq[0] = format->max_value[0] * format->max_value[0]; + format->max_value[1] = (1 << format->bit_depth[1]) - 1; + format->max_value_sq[1] = format->max_value[1] * format->max_value[1]; + format->max_value[2] = (1 << format->bit_depth[2]) - 1; + format->max_value_sq[2] = format->max_value[2] * format->max_value[2]; +} + /*! ************************************************************************ * \brief @@ -159,6 +176,9 @@ static void getNumberOfFrames (void) static void updateOutFormat(InputParameters *params) { + params->output.yuv_format = params->yuv_format; + params->source.yuv_format = params->yuv_format; + if (params->src_resize == 0) { params->output.width = params->source.width; @@ -167,8 +187,8 @@ static void updateOutFormat(InputParameters *params) if (params->yuv_format == YUV400) // reset bitdepth of chroma for 400 content { - params->source.bit_depth[1] = 0; - params->output.bit_depth[1] = 0; + params->source.bit_depth[1] = 8; + params->output.bit_depth[1] = 8; params->source.width_cr = 0; params->source.height_cr = 0; params->output.width_cr = 0; @@ -177,22 +197,28 @@ static void updateOutFormat(InputParameters *params) else { params->source.width_cr = (params->source.width * mb_width_cr [params->yuv_format]) >> 4; - params->source.height_cr = (params->source.height * mb_width_cr [params->yuv_format]) >> 4; + params->source.height_cr = (params->source.height * mb_height_cr[params->yuv_format]) >> 4; params->output.width_cr = (params->output.width * mb_width_cr [params->yuv_format]) >> 4; params->output.height_cr = (params->output.height * mb_height_cr[params->yuv_format]) >> 4; } // source size - params->source.size_cmp[0] = params->source.width * params->source.height; + params->source.size_cmp[0] = params->source.width * params->source.height; params->source.size_cmp[1] = params->source.width_cr * params->source.height_cr; params->source.size_cmp[2] = params->source.size_cmp[1]; - params->source.size = params->source.size_cmp[0] + params->source.size_cmp[1] + params->source.size_cmp[2]; + params->source.size = params->source.size_cmp[0] + params->source.size_cmp[1] + params->source.size_cmp[2]; + params->source.mb_width = params->source.width / MB_BLOCK_SIZE; + params->source.mb_height = params->source.height / MB_BLOCK_SIZE; + // output size (excluding padding) params->output.size_cmp[0] = params->output.width * params->source.height; params->output.size_cmp[1] = params->output.width_cr * params->source.height_cr; params->output.size_cmp[2] = params->output.size_cmp[1]; - params->source.size = params->output.size_cmp[0] + params->output.size_cmp[1] + params->output.size_cmp[2]; + params->output.size = params->output.size_cmp[0] + params->output.size_cmp[1] + params->output.size_cmp[2]; + params->output.mb_width = params->output.width / MB_BLOCK_SIZE; + params->output.mb_height = params->output.height / MB_BLOCK_SIZE; + // both chroma components have the same bitdepth params->source.bit_depth[2] = params->source.bit_depth[1]; @@ -205,6 +231,9 @@ static void updateOutFormat(InputParameters *params) params->output.bit_depth[1] = params->source.bit_depth[1]; params->output.bit_depth[2] = params->source.bit_depth[2]; } + + updateMaxValue(¶ms->source); + updateMaxValue(¶ms->output); } @@ -367,7 +396,7 @@ char *GetConfigFileContent (char *Filename) } FileSize = ftell (f); - if (FileSize < 0 || FileSize > 60000) + if (FileSize < 0 || FileSize > 100000) { snprintf (errortext, ET_SIZE, "Unreasonable Filesize %ld reported by ftell for configuration file %s.", FileSize, Filename); return NULL; @@ -1064,45 +1093,51 @@ static void PatchInp (void) read_slice_group_info(); } - if (params->ReferenceReorder && (params->PicInterlace || params->MbInterlace)) + if (params->WPMCPrecision && (params->RDPictureDecision != 1 || params->GenerateMultiplePPS != 1) ) { - snprintf(errortext, ET_SIZE, "ReferenceReorder Not supported with Interlace encoding methods\n"); + snprintf(errortext, ET_SIZE, "WPMCPrecision requires both RDPictureDecision=1 and GenerateMultiplePPS=1.\n"); error (errortext, 400); } - - if (params->PocMemoryManagement && (params->PicInterlace || params->MbInterlace)) + if (params->WPMCPrecision && params->WPMCPrecFullRef && params->num_ref_frames < 16 ) { - snprintf(errortext, ET_SIZE, "PocMemoryManagement not supported with Interlace encoding methods\n"); + params->num_ref_frames++; + if ( params->P_List0_refs ) + params->P_List0_refs++; + else + params->P_List0_refs = params->num_ref_frames; + if ( params->B_List0_refs ) + params->B_List0_refs++; + else + params->B_List0_refs = params->num_ref_frames; + if ( params->B_List1_refs ) + params->B_List1_refs++; + else + params->B_List1_refs = params->num_ref_frames; + } + else if ( params->WPMCPrecision && params->WPMCPrecFullRef ) + { + snprintf(errortext, ET_SIZE, "WPMCPrecFullRef requires NumberReferenceFrames < 16.\n"); error (errortext, 400); } - // frame/field consistency check - if (params->PicInterlace != FRAME_CODING && params->PicInterlace != ADAPTIVE_CODING && params->PicInterlace != FIELD_CODING) + if (params->ReferenceReorder && params->MbInterlace ) { - snprintf (errortext, ET_SIZE, "Unsupported PicInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2",params->PicInterlace); + snprintf(errortext, ET_SIZE, "ReferenceReorder not supported with MBAFF\n"); error (errortext, 400); } - // frame/field consistency check - if (params->MbInterlace != FRAME_CODING && params->MbInterlace != ADAPTIVE_CODING && params->MbInterlace != FIELD_CODING && params->MbInterlace != FRAME_MB_PAIR_CODING) + if (params->PocMemoryManagement && params->MbInterlace ) { - snprintf (errortext, ET_SIZE, "Unsupported MbInterlace=%d, use frame based coding=0 or field based coding=1 or adaptive=2 or frame MB pair only=3",params->MbInterlace); + snprintf(errortext, ET_SIZE, "PocMemoryManagement not supported with MBAFF\n"); error (errortext, 400); } - if ((!params->rdopt)&&(params->MbInterlace)) { snprintf(errortext, ET_SIZE, "MB AFF is not compatible with non-rd-optimized coding."); error (errortext, 500); } - /*if (params->rdopt>2) - { - snprintf(errortext, ET_SIZE, "RDOptimization=3 mode has been deactivated do to diverging of real and simulated decoders."); - error (errortext, 500); - }*/ - // check RDoptimization mode and profile. FMD does not support Frex Profiles. if (params->rdopt==2 && ( params->ProfileIDC>=FREXT_HP || params->ProfileIDC==FREXT_CAVLC444 )) { @@ -1167,35 +1202,35 @@ static void PatchInp (void) // Rate control if(params->RCEnable) { + if (params->basicunit == 0) + params->basicunit = (params->output.height + img->auto_crop_bottom)*(params->output.width + img->auto_crop_right)/256; + if ( ((params->output.height + img->auto_crop_bottom)*(params->output.width + img->auto_crop_right)/256) % params->basicunit != 0) { snprintf(errortext, ET_SIZE, "Frame size in macroblocks must be a multiple of BasicUnit."); error (errortext, 500); } - // input basicunit represents the number of BUs in a frame - // internal basicunit is the number of MBs in a BU - params->basicunit = ((params->output.height + img->auto_crop_bottom)*(params->output.width + img->auto_crop_right)/256) / params->basicunit; - if ( params->RCEnable && params->RCUpdateMode == RC_MODE_1 && + if ( params->RCUpdateMode == RC_MODE_1 && !( (params->intra_period == 1 || params->idr_period == 1 || params->BRefPictures == 2 ) && !params->successive_Bframe ) ) { snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 1 only for all intra or all B-slice coding."); error (errortext, 500); } - if ( params->RCEnable && params->BRefPictures == 2 && params->intra_period == 0 && params->RCUpdateMode != RC_MODE_1 ) + if ( params->BRefPictures == 2 && params->intra_period == 0 && params->RCUpdateMode != RC_MODE_1 ) { snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 1 for all B-slice coding."); error (errortext, 500); } - if ( params->RCEnable && params->HierarchicalCoding && params->RCUpdateMode != RC_MODE_2 && params->RCUpdateMode != RC_MODE_3 ) + if ( params->HierarchicalCoding && params->RCUpdateMode != RC_MODE_2 && params->RCUpdateMode != RC_MODE_3 ) { snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 2 or 3 for hierarchical B-picture coding."); error (errortext, 500); } - if ( params->RCEnable && (params->RCUpdateMode != RC_MODE_1) && (params->intra_period == 1) ) + if ( (params->RCUpdateMode != RC_MODE_1) && (params->intra_period == 1) ) { snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 1 for all intra coding."); error (errortext, 500); @@ -1278,24 +1313,18 @@ static void PatchInp (void) params->ChromaMEEnable = 0; } - if ( (0 == params->ChromaMCBuffer) && (( params->yuv_format == YUV444) && (!params->separate_colour_plane_flag)) ) + if ( (params->ChromaMCBuffer == 0) && (( params->yuv_format == YUV444) && (!params->separate_colour_plane_flag)) ) { fprintf(stderr, "Warning: Enabling ChromaMCBuffer for YUV444 combined color coding.\n"); params->ChromaMCBuffer = 1; } - if (params->EnableOpenGOP && params->PicInterlace) - { - snprintf(errortext, ET_SIZE, "Open GOP currently not supported for Field coded pictures."); - error (errortext, 500); - } if (params->EnableOpenGOP) params->ReferenceReorder = 1; - if (params->SearchMode != EPZS) - params->EPZSSubPelGrid = 0; + params->EPZSSubPelGrid = 0; params->EPZSGrid = params->EPZSSubPelGrid << 1; @@ -1362,6 +1391,9 @@ static void PatchInp (void) { printf("RDO Quantization currently not supported with MBAFF. Option disabled.\n"); params->UseRDOQuant = 0; + params->RDOQ_QP_Num = 1; + params->RDOQ_CP_MV = 0; + params->RDOQ_CP_Mode = 0; } else { diff --git a/lencod/src/conformance.c b/lencod/src/conformance.c index 7d81624..dffbb6d 100644 --- a/lencod/src/conformance.c +++ b/lencod/src/conformance.c @@ -199,11 +199,6 @@ void ProfileCheck(void) snprintf(errortext, ET_SIZE, "CABAC is not allowed in Extended profile (ProfileIDC = 88)."); error (errortext, 500); } - if ((params->PicInterlace) ||(params->MbInterlace)) - { - snprintf(errortext, ET_SIZE, "Interlace tools are not allowed in Extended profile (ProfileIDC = 88)."); - error (errortext, 500); - } } //FRExt diff --git a/lencod/src/context_ini.c b/lencod/src/context_ini.c index 96a7348..a7ed4cc 100644 --- a/lencod/src/context_ini.c +++ b/lencod/src/context_ini.c @@ -239,7 +239,7 @@ double XRate (BiContextTypePtr ctx, const int* model) { int ctx_state, mod_state; double weight, xr = 0.0; - int qp = imax(0,img->qp); + int qp = imax(0, img->qp); weight = dmin (1.0, (double)ctx->count/(double)RELIABLE_COUNT); diff --git a/lencod/src/decoder.c b/lencod/src/decoder.c deleted file mode 100644 index e0f68ed..0000000 --- a/lencod/src/decoder.c +++ /dev/null @@ -1,669 +0,0 @@ - -/*! - ************************************************************************************* - * \file decoder.c - * - * \brief - * Contains functions that implement the "decoders in the encoder" concept for the - * rate-distortion optimization with losses. - * \date - * October 22nd, 2001 - * - * \author - * Main contributors (see contributors.h for copyright, address and - * affiliation details) - * - Dimitrios Kontopodis <dkonto@eikon.tum.de> - ************************************************************************************* - */ - -#include "global.h" -#include "refbuf.h" -#include "image.h" - -static void Get_Reference_Block(imgpel **imY, int block_y, int block_x, int mvhor, int mvver, imgpel **out); -static byte Get_Reference_Pixel(imgpel **imY, int y, int x); -static void DecOneForthPix(imgpel **dY, imgpel ***dref); -static void Build_Status_Map(byte **s_map); -static void Error_Concealment(imgpel **inY, byte **s_map, imgpel ***refY); -static void Conceal_Error(imgpel **inY, int mb_y, int mb_x, imgpel ***refY, byte **s_map); -/*! - ************************************************************************************* - * \brief - * decodes one 8x8 partition - * - * \note - * Gives the expected value in the decoder of one 8x8 block. This is done based on the - * stored reconstructed residue decs->resY[][], the reconstructed values imgY[][] - * and the motion vectors. The decoded 8x8 block is moved to decs->decY[][]. - ************************************************************************************* - */ -void decode_one_b8block (int decoder, int mbmode, int b8block, short b8mode, short b8ref) -{ - int i,j,block_y,block_x,bx,by; - int ref_inx = (IMG_NUMBER-1)%img->num_ref_frames; - - int mv[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE]; - int resY_tmp[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; - - int i0 = (b8block%2)<<3, i1 = i0+8, bx0 = i0>>2, bx1 = bx0+2; - int j0 = (b8block/2)<<3, j1 = j0+8, by0 = j0>>2, by1 = by0+2; - - if (img->type==I_SLICE) - { - for(i=i0;i<i1;i++) - for(j=j0;j<j1;j++) - { - decs->decY[decoder][img->pix_y+j][img->pix_x+i]=enc_picture->imgY[img->pix_y+j][img->pix_x+i]; - } - } - else - { - if (mbmode==0 && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0))) - { - for(i=i0;i<i1;i++) - for(j=j0;j<j1;j++) - { - resY_tmp[j][i]=0; - } - for (by=by0; by<by1; by++) - for (bx=bx0; bx<bx1; bx++) - { - mv[0][by][bx] = mv[1][by][bx] = 0; - } - } - else - { - if (b8mode>=1 && b8mode<=7) - { - for (by=by0; by<by1; by++) - for (bx=bx0; bx<bx1; bx++) - { - mv[0][by][bx] = img->all_mv[LIST_0][b8ref][b8mode][by][bx][0]; - mv[1][by][bx] = img->all_mv[LIST_0][b8ref][b8mode][by][bx][1]; - } - } - else - { - for (by=by0; by<by1; by++) - for (bx=bx0; bx<bx1; bx++) - { - mv[0][by][bx] = mv[1][by][bx] = 0; - } - } - - for(i=i0;i<i1;i++) - for(j=j0;j<j1;j++) - { - resY_tmp[j][i]=decs->resY[j][i]; - } - } - - // Decode Luminance - if ((b8mode>=1 && b8mode<=7) || (mbmode==0 && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0)))) - { - for (by=by0; by<by1; by++) - for (bx=bx0; bx<bx1; bx++) - { - block_x = img->block_x+bx; - block_y = img->block_y+by; - if (img->type == B_SLICE && enc_picture != enc_frame_picture[0]) - ref_inx = (IMG_NUMBER - b8ref - 2)%img->num_ref_frames; - - Get_Reference_Block (decs->decref[decoder][ref_inx], block_y, block_x, mv[0][by][bx], mv[1][by][bx], decs->RefBlock); - - for (j=0; j<4; j++) - for (i=0; i<4; i++) - { - decs->decY[decoder][block_y*4+j][block_x*4+i] = iClip3 (0, img->max_imgpel_value, resY_tmp[by*4+j][bx*4+i] + decs->RefBlock[j][i]); - } - } - } - else - { - // Intra Refresh - Assume no spatial prediction - for(i=i0;i<i1;i++) - for(j=j0;j<j1;j++) - { - decs->decY[decoder][img->pix_y+j][img->pix_x+i] = enc_picture->imgY[img->pix_y+j][img->pix_x+i]; - } - } - } -} - - -/*! - ************************************************************************************* - * \brief - * decodes one macroblock - ************************************************************************************* - */ -void decode_one_mb (int decoder, Macroblock* currMB) -{ - decode_one_b8block (decoder, currMB->mb_type, 0, currMB->b8mode[0], enc_picture->ref_idx[LIST_0][img->block_y+0][img->block_x+0]);//refFrArr[img->block_y+0][img->block_x+0]); - decode_one_b8block (decoder, currMB->mb_type, 1, currMB->b8mode[1], enc_picture->ref_idx[LIST_0][img->block_y+0][img->block_x+2]);//refFrArr[img->block_y+0][img->block_x+2]); - decode_one_b8block (decoder, currMB->mb_type, 2, currMB->b8mode[2], enc_picture->ref_idx[LIST_0][img->block_y+2][img->block_x+0]);//refFrArr[img->block_y+2][img->block_x+0]); - decode_one_b8block (decoder, currMB->mb_type, 3, currMB->b8mode[3], enc_picture->ref_idx[LIST_0][img->block_y+2][img->block_x+2]);//refFrArr[img->block_y+2][img->block_x+2]); -} - -/*! - ************************************************************************************* - * \brief - * Finds the reference MB given the decoded reference frame - * \note - * This is based on the function UnifiedOneForthPix, only it is modified to - * be used at the "many decoders in the encoder" RD optimization. In this case - * we dont want to keep full upsampled reference frames for all decoders, so - * we just upsample when it is necessary. - * \param imY - * The frame to be upsampled - * \param block_y - * The row of the block, whose prediction we want to find - * \param block_x - * The column of the block, whose prediction we want to track - * \param mvhor - * Motion vector, horizontal part - * \param mvver - * Motion vector, vertical part - * \param out - * Output: The prediction for the block (block_y, block_x) - ************************************************************************************* - */ -static void Get_Reference_Block(imgpel **imY, - int block_y, - int block_x, - int mvhor, - int mvver, - imgpel **out) -{ - int i,j,y,x; - - y = block_y * BLOCK_SIZE * 4 + mvver; - x = block_x * BLOCK_SIZE * 4 + mvhor; - - for (j=0; j<BLOCK_SIZE; j++) - for (i=0; i<BLOCK_SIZE; i++) - out[j][i] = Get_Reference_Pixel(imY, y+j*4, x+i*4); -} - -/*! - ************************************************************************************* - * \brief - * Finds a pixel (y,x) of the upsampled reference frame - * \note - * This is based on the function UnifiedOneForthPix, only it is modified to - * be used at the "many decoders in the encoder" RD optimization. In this case - * we dont want to keep full upsampled reference frames for all decoders, so - * we just upsample when it is necessary. - ************************************************************************************* - */ -static byte Get_Reference_Pixel(imgpel **imY, int y_pos, int x_pos) -{ - - int dx, x; - int dy, y; - int maxold_x,maxold_y; - - int result = 0, result1, result2; - int pres_x; - int pres_y; - - int tmp_res[6]; - - static const int COEF[6] = { 1, -5, 20, 20, -5, 1 }; - - - dx = x_pos&3; - dy = y_pos&3; - x_pos = (x_pos-dx)/4; - y_pos = (y_pos-dy)/4; - maxold_x = img->width-1; - maxold_y = img->height-1; - - if (dx == 0 && dy == 0) - { /* fullpel position */ - result = imY[iClip3(0,maxold_y,y_pos)][iClip3(0,maxold_x,x_pos)]; - } - else { /* other positions */ - - if (dy == 0) - { - pres_y = iClip3(0,maxold_y,y_pos); - for(x=-2;x<4;x++) - { - pres_x = iClip3(0,maxold_x,x_pos+x); - result += imY[pres_y][pres_x]*COEF[x+2]; - } - - result = iClip1( img->max_imgpel_value, (result+16)/32); - - if (dx == 1) - { - result = (result + imY[pres_y][iClip3(0,maxold_x,x_pos)])/2; - } - else if (dx == 3) - { - result = (result + imY[pres_y][iClip3(0,maxold_x,x_pos+1)])/2; - } - } - else if (dx == 0) - { - pres_x = iClip3(0,maxold_x,x_pos); - for(y=-2;y<4;y++) - { - pres_y = iClip3(0,maxold_y,y_pos+y); - result += imY[pres_y][pres_x]*COEF[y+2]; - } - - result = iClip1( img->max_imgpel_value, (result+16)/32); - - if (dy == 1) - { - result = (result + imY[iClip3(0,maxold_y,y_pos)][pres_x])/2; - } - else if (dy == 3) - { - result = (result + imY[iClip3(0,maxold_y,y_pos+1)][pres_x])/2; - } - } - else if (dx == 2) - { - - for(y=-2;y<4;y++) - { - result = 0; - pres_y = iClip3(0,maxold_y,y_pos+y); - for(x=-2;x<4;x++) - { - pres_x = iClip3(0,maxold_x,x_pos+x); - result += imY[pres_y][pres_x]*COEF[x+2]; - } - tmp_res[y+2] = result; - } - - result = 0; - for(y=-2;y<4;y++) - { - result += tmp_res[y+2]*COEF[y+2]; - } - - result = iClip1(img->max_imgpel_value, (result+512)/1024); - - if (dy == 1) - { - result = (result + iClip1(img->max_imgpel_value, (tmp_res[2]+16)/32))/2; - } - else if (dy == 3) - { - result = (result + iClip1(img->max_imgpel_value, (tmp_res[3]+16)/32))/2; - } - } - else if (dy == 2) - { - - for(x=-2;x<4;x++) - { - result = 0; - pres_x = iClip3(0,maxold_x,x_pos+x); - for(y=-2;y<4;y++) - { - pres_y = iClip3(0,maxold_y,y_pos+y); - result += imY[pres_y][pres_x]*COEF[y+2]; - } - tmp_res[x+2] = result; - } - - result = 0; - for(x=-2;x<4;x++) - { - result += tmp_res[x+2]*COEF[x+2]; - } - - result = iClip1(img->max_imgpel_value, (result+512)/1024); - - if (dx == 1) - { - result = (result + iClip1( img->max_imgpel_value, (tmp_res[2]+16)/32))/2; - } - else { - result = (result + iClip1( img->max_imgpel_value, (tmp_res[3]+16)/32))/2; - } - } - else { - - result = 0; - pres_y = dy == 1 ? y_pos : y_pos+1; - pres_y = iClip3(0,maxold_y,pres_y); - - for(x=-2;x<4;x++) - { - pres_x = iClip3(0,maxold_x,x_pos+x); - result += imY[pres_y][pres_x]*COEF[x+2]; - } - - result1 = iClip1( img->max_imgpel_value, (result+16)/32); - - result = 0; - pres_x = dx == 1 ? x_pos : x_pos+1; - pres_x = iClip3(0,maxold_x,pres_x); - - for(y=-2;y<4;y++) - { - pres_y = iClip3(0,maxold_y,y_pos+y); - result += imY[pres_y][pres_x]*COEF[y+2]; - } - - result2 = iClip1( img->max_imgpel_value, (result+16)/32); - result = (result1+result2)/2; - } - } - - return result; -} - -/*! - ************************************************************************************* - * \brief - * Performs the simulation of the packet losses, calls the error concealment funcs - * and copies the decoded images to the reference frame buffers of the decoders - * - ************************************************************************************* - */ -void UpdateDecoders() -{ - int k; - for (k=0; k<params->NoOfDecoders; k++) - { - Build_Status_Map(decs->status_map); // simulates the packet losses - Error_Concealment(decs->decY_best[k], decs->status_map, decs->decref[k]); // for the moment error concealment is just a "copy" - // Move decoded frames to reference buffers: (at the decoders this is done - // without interpolation (upsampling) - upsampling is done while decoding - DecOneForthPix(decs->decY_best[k], decs->decref[k]); - } -} -/*! - ************************************************************************************* - * \brief - * Copies one (reconstructed) image to the respective reference frame buffer - * - * \note - * This is used at the "many decoders in the encoder" - * \param dY - * The reconstructed image - * \param dref - * The reference buffer - ************************************************************************************* - */ -static void DecOneForthPix(imgpel **dY, imgpel ***dref) -{ - int j, ref=IMG_NUMBER%img->buf_cycle; - - for (j=0; j<img->height; j++) - memcpy(dref[ref][j], dY[j], img->width * sizeof(imgpel)); -} - -/*! - ************************************************************************************* - * \brief - * Gives the prediction residue for a 8x8 block - ************************************************************************************* - */ -void compute_residue_b8block (int b8block, int i16mode) // if not INTRA16x16 it has to be -1 -{ - int i,j; - int i0 = (b8block%2)<<3, i1 = i0+8; - int j0 = (b8block/2)<<3, j1 = j0+8; - imgpel (*curr_mpr_16x16)[16][16] = img->mpr_16x16[0]; - imgpel (*curr_mpr)[16] = img->mpr[0]; - - - if (i16mode>=0) - { - for (i=i0; i<i1; i++) - for (j=j0; j<j1; j++) - { - decs->resY[j][i] = enc_picture->imgY[img->pix_y+j][img->pix_x+i] - curr_mpr_16x16[i16mode][j][i]; - } - } - else - { - for (i=i0; i<i1; i++) - for (j=j0; j<j1; j++) - { - decs->resY[j][i] = enc_picture->imgY[img->pix_y+j][img->pix_x+i] - curr_mpr[j][i]; - } - } -} - -/*! - ************************************************************************************* - * \brief - * Gives the prediction residue for a macroblock - ************************************************************************************* - */ -void compute_residue_mb (int i16mode) -{ - compute_residue_b8block (0, i16mode); - compute_residue_b8block (1, i16mode); - compute_residue_b8block (2, i16mode); - compute_residue_b8block (3, i16mode); -} - - -/*! - ************************************************************************************* - * \brief - * Builds a random status map showing whether each MB is received or lost, based - * on the packet loss rate and the slice structure. - * - * \param s_map - * The status map to be filled - ************************************************************************************* - */ -static void Build_Status_Map(byte **s_map) -{ - int i,j,slice=-1,mb=0,jj,ii,packet_lost=0; - - jj = img->height/MB_BLOCK_SIZE; - ii = img->width/MB_BLOCK_SIZE; - - for (j=0 ; j<jj; j++) - for (i=0 ; i<ii; i++) - { - if (!params->slice_mode || img->mb_data[mb].slice_nr != slice) /* new slice */ - { - packet_lost=0; - if ((double)rand()/(double)RAND_MAX*100 < params->LossRateC) packet_lost += 3; - if ((double)rand()/(double)RAND_MAX*100 < params->LossRateB) packet_lost += 2; - if ((double)rand()/(double)RAND_MAX*100 < params->LossRateA) packet_lost = 1; - slice++; - } - if (!packet_lost) - { - s_map[j][i]=0; //! Packet OK - } - else - { - s_map[j][i]=packet_lost; - if(params->partition_mode == 0) s_map[j][i]=1; - } - mb++; - } -} - -/*! - ************************************************************************************* - * \brief - * Performs some sort of error concealment for the areas that are lost according - * to the status_map - * - * \param inY - * Error concealment is performed on this frame imY[][] - * \param s_map - * The status map shows which areas are lost. - * \param refY - * The set of reference frames - may be used for the error concealment. - ************************************************************************************* - */ -static void Error_Concealment(imgpel **inY, byte **s_map, imgpel ***refY) -{ - int mb_y, mb_x, mb_h, mb_w; - mb_h = img->height/MB_BLOCK_SIZE; - mb_w = img->width/MB_BLOCK_SIZE; - - for (mb_y=0; mb_y < mb_h; mb_y++) - for (mb_x=0; mb_x < mb_w; mb_x++) - { - if (s_map[mb_y][mb_x]) - Conceal_Error(inY, mb_y, mb_x, refY, s_map); - } -} - -/*! - ************************************************************************************* - * \brief - * Copies a certain MB (mb_y,mb_x) of the frame inY[][] from the previous frame. - * For the time there is no better EC... - ************************************************************************************* - */ -static void Conceal_Error(imgpel **inY, int mb_y, int mb_x, imgpel ***refY, byte **s_map) -{ - int i,j,block_x, block_y; - int ref_inx = (IMG_NUMBER-1)%img->num_ref_frames; - int pos_y = mb_y*MB_BLOCK_SIZE, pos_x = mb_x*MB_BLOCK_SIZE; - int mv[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE]; - int resY[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; - int copy = (decs->dec_mb_mode[mb_y][mb_x]==0 && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0))); - int inter = (((decs->dec_mb_mode[mb_y][mb_x]>=1 && decs->dec_mb_mode[mb_y][mb_x]<=3) || decs->dec_mb_mode[mb_y][mb_x]==P8x8) && (img->type==P_SLICE || (img->type==B_SLICE && img->nal_reference_idc>0))); - short ***tmp_mv = enc_picture->mv[LIST_0]; - - switch(s_map[mb_y][mb_x]) - { - case 1: //! whole slice lost (at least partition A lost) - if (img->type!=I_SLICE) - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i]; - } - else - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = 127; - } - break; - case 5: //! partition B and partition C lost - - //! Copy motion vectors - for (block_y=0; block_y<BLOCK_MULTIPLE; block_y++) - for (block_x=0; block_x<BLOCK_MULTIPLE; block_x++) - for (i=0;i<2;i++) - mv[i][block_y][block_x]=tmp_mv[mb_y*BLOCK_SIZE+block_y][mb_x*BLOCK_SIZE+block_x+4][i]; - - //! Residue ist set to zero - for(i=0;i<MB_BLOCK_SIZE;i++) - for(j=0;j<MB_BLOCK_SIZE;j++) - resY[j][i]=0; - - //! not first frame - if (img->type!=I_SLICE) - { - //! if copy mb - if (copy) - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i]; - } - //! if inter mb - else if (inter) - { - for (block_y = mb_y*BLOCK_SIZE ; block_y < (mb_y*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_y++) - for (block_x = mb_x*BLOCK_SIZE ; block_x < (mb_x*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_x++) - { - Get_Reference_Block(refY[ref_inx], - block_y, block_x, - mv[0][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE], - mv[1][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE], - decs->RefBlock); - for (j=0;j<BLOCK_SIZE;j++) - for (i=0;i<BLOCK_SIZE;i++) - { - inY[block_y*BLOCK_SIZE + j][block_x*BLOCK_SIZE + i] = decs->RefBlock[j][i]; - } - } - } - else //intra; up to now only copy mb, may integrate nokia EC - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i]; - } - } - else //! first frame; up to now set value to grey, may integrate nokia EC - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = 127; - } - break; - case 3: //! Partition C lost - if(img->type!=I_SLICE) - { - //! Copy motion vectors - for (block_y=0; block_y<BLOCK_MULTIPLE; block_y++) - for (block_x=0; block_x<BLOCK_MULTIPLE; block_x++) - for (i=0;i<2;i++) - mv[i][block_y][block_x]=tmp_mv[mb_y*BLOCK_SIZE+block_y][mb_x*BLOCK_SIZE+block_x+4][i]; - - //! Residue ist set to zero - for(i=0;i<MB_BLOCK_SIZE;i++) - for(j=0;j<MB_BLOCK_SIZE;j++) - resY[j][i]=0; - - //! if copy mb - if (copy) - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i]; - } - //! if inter mb - else if (inter) - { - for (block_y = mb_y*BLOCK_SIZE ; block_y < (mb_y*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_y++) - for (block_x = mb_x*BLOCK_SIZE ; block_x < (mb_x*BLOCK_SIZE + BLOCK_MULTIPLE) ; block_x++) - { - Get_Reference_Block(refY[ref_inx], - block_y, block_x, - mv[0][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE], - mv[1][block_y - mb_y*BLOCK_SIZE][block_x - mb_x*BLOCK_SIZE], - decs->RefBlock); - for (j=0;j<BLOCK_SIZE;j++) - for (i=0;i<BLOCK_SIZE;i++) - { - inY[block_y*BLOCK_SIZE + j][block_x*BLOCK_SIZE + i] = decs->RefBlock[j][i]; - } - } - } - } - break; - case 2: //! Partition B lost - if(img->type!=I_SLICE) - { - if(!inter) - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = refY[ref_inx][pos_y+j][pos_x+i]; - } - } - else //! first frame; up to now set value to grey, may integrate nokia EC - { - for (j=0;j<MB_BLOCK_SIZE;j++) - for (i=0;i<MB_BLOCK_SIZE;i++) - inY[pos_y+j][pos_x+i] = 127; - } - break; - } //! End Switch -} diff --git a/lencod/src/errdo.c b/lencod/src/errdo.c new file mode 100644 index 0000000..4e51bec --- /dev/null +++ b/lencod/src/errdo.c @@ -0,0 +1,580 @@ + +/*! + ************************************************************************************* + * \file errdo.c + * + * \brief + * Contains functions that implement the "decoders in the encoder" concept for the + * rate-distortion optimization with losses. + * \date + * October 22nd, 2001 + * + * \author + * Main contributors (see contributors.h for copyright, address and + * affiliation details) + * - Dimitrios Kontopodis <dkonto@eikon.tum.de> + * Code revamped July 2008 by: + * - Peshala Pahalawatta (ppaha@dolby.com) + ************************************************************************************* + */ + +#include "global.h" +#include "refbuf.h" +#include "image.h" +#include "errdo.h" +#include "errdo_mc_prediction.h" + +static StorablePicture* find_nearest_ref_picture(int poc); +static void copy_conceal_mb (StorablePicture *enc_pic, ImageParameters* image, int decoder, int mb_error, Macroblock* currMB, StorablePicture* refPic); +static void get_predicted_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, Macroblock* currMB); +static void add_residue (StorablePicture *enc_pic, int decoder, int pl, int block8x8, int x_size, int y_size); +static void Build_Status_Map(byte **s_map); + +extern void DeblockFrame(ImageParameters *img, imgpel **, imgpel ***); + +/*! +************************************************************************************** +* \brief +* Decodes one macroblock for error resilient RDO. +* Currently does not support: +* 1) B coded pictures +* 2) Chroma components +* 3) Potential error propagation due to intra prediction +* 4) Field coding +************************************************************************************** +*/ +void decode_one_mb (ImageParameters *image, StorablePicture *enc_pic, int decoder, Macroblock* currMB) +{ + int i0, j; + static imgpel** curComp; + static imgpel** oldComp; + + if (currMB->mb_type > P8x8) //Intra MB + { + curComp = &enc_pic->p_dec_img[0][decoder][image->pix_y]; + oldComp = &enc_pic->p_curr_img[image->pix_y]; + i0 = image->pix_x; + for (j = 0; j < MB_BLOCK_SIZE; j++) + { + memcpy(&(curComp[j][i0]), &(oldComp[j][i0]), MB_BLOCK_SIZE*sizeof(imgpel)); + } + } + else if (currMB->mb_type == 0) + { + get_predicted_mb(enc_pic, image, decoder, currMB); + curComp = &enc_pic->p_dec_img[0][decoder][image->pix_y]; + for(j = 0; j < image->mb_size[0][1]; j++) + { + memcpy(&(curComp[j][image->pix_x]), &(image->mb_pred[0][j][0]), image->mb_size[0][0] * sizeof(imgpel)); + } + } + else + { + get_predicted_mb(enc_pic, image, decoder, currMB); + add_residue(enc_pic, decoder, PLANE_Y, 0, MB_BLOCK_SIZE, MB_BLOCK_SIZE); + } +} + +/*! +************************************************************************************** +* \brief +* Finds predicted macroblock values +* and copies them to img->mb_pred[0][][] +* Requires img->all_mv, enc_picture->motion.ref_idx to be correct for current +* macroblock. +************************************************************************************** +*/ +static void get_predicted_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, Macroblock* currMB) +{ + int i,j,k; + int block_size_x, block_size_y; + int mv_mode, pred_dir; + int list_offset = 0; //For now + int curr_mb_field = 0; //For now + static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; + int block8x8; + int k_start, k_end, k_inc; + + if (!currMB->mb_type) + { + block_size_x = MB_BLOCK_SIZE; + block_size_y = MB_BLOCK_SIZE; + pred_dir = LIST_0; + + perform_mc(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, 0, 0, 0, list_offset, block_size_x, block_size_y, curr_mb_field); + } + else if (currMB->mb_type == 1) + { + block_size_x = MB_BLOCK_SIZE; + block_size_y = MB_BLOCK_SIZE; + pred_dir = currMB->b8pdir[0]; + + perform_mc(decoder, PLANE_Y, enc_pic, image, pred_dir, 1, 0, 0, 0, list_offset, block_size_x, block_size_y, curr_mb_field); + } + else if (currMB->mb_type == 2) + { + block_size_x = MB_BLOCK_SIZE; + block_size_y = 8; + + for (block8x8 = 0; block8x8 < 4; block8x8 += 2) + { + pred_dir = currMB->b8pdir[block8x8]; + perform_mc(decoder, PLANE_Y, enc_pic, image, pred_dir, 2, 0, 0, block8x8, list_offset, block_size_x, block_size_y, curr_mb_field); + } + } + else if (currMB->mb_type == 3) + { + block_size_x = 8; + block_size_y = 16; + + for (block8x8 = 0; block8x8 < 2; block8x8++) + { + i = block8x8<<1; + j = 0; + pred_dir = currMB->b8pdir[block8x8]; + assert (pred_dir<=2); + perform_mc(decoder, PLANE_Y, enc_pic, image, pred_dir, 3, 0, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + } + else //Need to change to support B slices. + { + for (block8x8 = 0; block8x8 < 4; block8x8++) + { + mv_mode = currMB->b8mode[block8x8]; + pred_dir = currMB->b8pdir[block8x8]; + + if ( mv_mode != 0 ) + { + k_start = (block8x8 << 2); + k_inc = (mv_mode == 5) ? 2 : 1; + k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1); + + block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4; + block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4; + + for (k = k_start; k < k_end; k += k_inc) + { + i = (decode_block_scan[k] & 3); + j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(decoder, PLANE_Y, enc_pic, image, pred_dir, mv_mode, 0, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + } + } + } +} + + +/*! +************************************************************************************** +* \brief +* Decodes one 8x8 partition for error resilient RDO. +* Currently does not support: +* 1) B coded pictures +* 2) Chroma components +* 3) Potential error propagation due to intra prediction +* 4) Field coding +************************************************************************************** +*/ +void decode_one_b8block (ImageParameters *image, StorablePicture *enc_pic, int decoder, int mbmode, int block8x8, short mv_mode, short b8ref) //b8ref may not be necessary any more. +{ + int i,j,k; + int block_size_x, block_size_y; + int i0 = (block8x8 & 0x01)<<3; + int j0 = (block8x8 >> 1)<<3, j1 = j0+8; + int list_offset = 0; + int curr_mb_field = 0; + imgpel **curComp; + imgpel **oldComp; + int pred_dir; + int k_start, k_end, k_inc; + static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; + + if (mv_mode > 8) //Intra + { + for(j = j0; j < j1; j++) + { + curComp = &enc_pic->p_dec_img[0][decoder][image->pix_y]; + oldComp = &enc_pic->p_curr_img[image->pix_y]; + memcpy(&(curComp[j][i0]), &(oldComp[j][i0]), sizeof(imgpel)*8); + } + } + else + { + pred_dir = 0; + + k_start = (block8x8 << 2); + k_inc = (mv_mode == 5) ? 2 : 1; + k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1); + + block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4; + block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4; + + for (k = k_start; k < k_end; k += k_inc) + { + i = (decode_block_scan[k] & 3); + j = ((decode_block_scan[k] >> 2) & 3); + perform_mc(decoder, PLANE_Y, enc_pic, image, pred_dir, mv_mode, 0, i, j, list_offset, block_size_x, block_size_y, curr_mb_field); + } + + add_residue(enc_pic, decoder, PLANE_Y, block8x8, 8, 8); + } +} + +/*! +************************************************************************************** +* \brief +* Add residual to motion predicted block +************************************************************************************** +*/ +static void add_residue (StorablePicture *enc_pic, int decoder, int pl, int block8x8, int x_size, int y_size) +{ + int i,j; + int i0 = (block8x8 & 0x01)<<3, i1 = i0 + x_size; + int j0 = (block8x8 >> 1)<<3, j1 = j0 + y_size; + + imgpel **p_dec_img = &enc_pic->p_dec_img[pl][decoder][img->pix_y]; + int (*res_img)[16] = decs->res_img[0]; + imgpel (*mpr)[16] = img->mb_pred[pl]; + + + for (j = j0; j < j1; j++) + { + for (i = i0; i < i1; i++) + { + p_dec_img[j][img->pix_x+i] = iClip3(0, img->max_imgpel_value_comp[pl], (mpr[j][i] + res_img[j][i])); + } + } +} + +/*! + ************************************************************************************* + * \brief + * Performs the simulation of the packet losses, calls the error concealment funcs + * and copies the decoded images to the reference frame buffers of the decoders + * + ************************************************************************************* + */ +void UpdateDecoders(InputParameters *params, ImageParameters *image, StorablePicture *enc_pic) +{ + int k; + for (k = 0; k < params->NoOfDecoders; k++) + { + Build_Status_Map(enc_pic->mb_error_map[k]); // simulates the packet losses + error_conceal_picture(image, enc_pic, k); + DeblockFrame (image, enc_pic->p_dec_img[0][k], NULL); + } +} + +/*! + ************************************************************************************* + * \brief + * Initialize error concealment function + * (Currently only copy concealment is implemented. Can extend to other concealment + * types when available.) + * + ************************************************************************************* + */ +void init_error_conceal(int concealment_type) +{ + error_conceal_picture = copy_conceal_picture; +} + +/*! +************************************************************************************** +* \brief +* Finds predicted macroblock values for error concealment +* and copies them to img->mb_pred[0][][] +* Requires enc_picture->motion.mv and enc_picture->motion.ref_idx to be correct for +* current picture. +************************************************************************************** +*/ +static void get_predicted_concealment_mb(StorablePicture* enc_pic, ImageParameters* image, int decoder, Macroblock* currMB) +{ + int i,j,k; + int block_size_x, block_size_y; + int mv_mode, pred_dir; + static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; + int block8x8; + int k_start, k_end, k_inc; + + if (!currMB->mb_type) + { + block_size_x = MB_BLOCK_SIZE; + block_size_y = MB_BLOCK_SIZE; + pred_dir = LIST_0; + + perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, 0, block_size_x, block_size_y); + } + else if (currMB->mb_type == 1) + { + block_size_x = MB_BLOCK_SIZE; + block_size_y = MB_BLOCK_SIZE; + pred_dir = currMB->b8pdir[0]; + + perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, 0, block_size_x, block_size_y); + } + else if (currMB->mb_type == 2) + { + block_size_x = MB_BLOCK_SIZE; + block_size_y = 8; + + for (block8x8 = 0; block8x8 < 4; block8x8 += 2) + { + pred_dir = currMB->b8pdir[block8x8]; + perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, block8x8, block_size_x, block_size_y); + } + } + else if (currMB->mb_type == 3) + { + block_size_x = 8; + block_size_y = 16; + + for (block8x8 = 0; block8x8 < 2; block8x8++) + { + i = block8x8<<1; + j = 0; + pred_dir = currMB->b8pdir[block8x8]; + assert (pred_dir<=2); + perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, i, j, block_size_x, block_size_y); + } + } + else //Need to change to support B slices. + { + for (block8x8 = 0; block8x8 < 4; block8x8++) + { + mv_mode = currMB->b8mode[block8x8]; + pred_dir = currMB->b8pdir[block8x8]; + + if ( mv_mode != 0 ) + { + k_start = (block8x8 << 2); + k_inc = (mv_mode == 5) ? 2 : 1; + k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1); + + block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4; + block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4; + + for (k = k_start; k < k_end; k += k_inc) + { + i = (decode_block_scan[k] & 3); + j = ((decode_block_scan[k] >> 2) & 3); + perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, i, j, block_size_x, block_size_y); + } + } + } + } +} + +/*! + ************************************************************************************* + * \brief + * Performs copy error concealment for macroblocks with errors. + * Note: Currently assumes that the reference picture lists remain the same for all + * slices of a picture. + * + ************************************************************************************* + */ +void copy_conceal_picture(ImageParameters *image, StorablePicture *enc_pic, int decoder) +{ + unsigned int mb; + Macroblock* currMB; + int mb_error; + byte** mb_error_map = enc_pic->mb_error_map[decoder]; + StorablePicture* refPic; + + refPic = find_nearest_ref_picture(enc_pic->poc); //Used for concealment if actual reference pic is not known. + + for (mb = 0; mb < image->PicSizeInMbs; mb++) + { + image->mb_x = PicPos[mb][0]; + image->mb_y = PicPos[mb][1]; + mb_error = mb_error_map[image->mb_y][image->mb_x]; + if (mb_error) + { + currMB = &image->mb_data[mb]; + image->block_x = image->mb_x << 2; + image->block_y = image->mb_y << 2; + image->pix_x = image->block_x << 2; + image->pix_y = image->block_y << 2; + copy_conceal_mb(enc_pic, image, decoder, mb_error, currMB, refPic); + } + } +} + +/****************************************************************************************** +* +* Perform copy error concealment for macroblock. +* +******************************************************************************************* +*/ +static void copy_conceal_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, int mb_error, Macroblock* currMB, StorablePicture* refPic) +{ + int j, i0 = img->pix_x; + imgpel** concealed_img = &(enc_pic->p_dec_img[0][decoder][image->pix_y]); + imgpel** ref_img; + + if (mb_error == 1 || (mb_error != 3 && currMB->mb_type > P8x8)) //All partitions lost, or intra mb lost + { + if (refPic != NULL) //Use nearest reference picture for concealment + { + ref_img = &(refPic->p_dec_img[0][decoder][img->pix_y]); + for (j = 0; j < MB_BLOCK_SIZE; j++) + { + memcpy(&(concealed_img[j][i0]), &(ref_img[j][i0]), sizeof(imgpel)*MB_BLOCK_SIZE); + } + } + else //No ref picture available + { + for (j = 0; j < MB_BLOCK_SIZE; j++) + { + memset(&(concealed_img[j][i0]), 128, sizeof(imgpel)*MB_BLOCK_SIZE); //Only reliable if sizeof(imgpel) = 1 + } + } + } + else if (mb_error != 2 && image->type == P_SLICE && currMB->mb_type && currMB->mb_type < P8x8) //Only partition 3 lost, and P macroblock and not skip + { + get_predicted_concealment_mb(enc_pic, image, decoder, currMB); + for(j = 0; j < MB_BLOCK_SIZE; j++) + { + memcpy(&(concealed_img[j][i0]), &(image->mb_pred[j][0]), MB_BLOCK_SIZE * sizeof(imgpel)); + } + } +} + +/****************************************************************************************** +* +* Finds reference picture with nearest POC to current picture to use for error concealment +* +******************************************************************************************* +*/ +static StorablePicture* find_nearest_ref_picture(int poc) +{ + unsigned int i; + int min_poc_diff = 1000; + int poc_diff; + StorablePicture* refPic = NULL; + + for (i = 0; i < dpb.ref_frames_in_buffer; i++) + { + if (dpb.fs_ref[i]->is_used==3) + { + if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term)) + { + poc_diff = iabs(dpb.fs_ref[i]->frame->poc - poc); + if (poc_diff < min_poc_diff) + { + refPic = dpb.fs_ref[i]->frame; + min_poc_diff = poc_diff; + } + } + } + } + return refPic; +} + +/*! + ************************************************************************************* + * \brief + * Gives the prediction residue for a block + ************************************************************************************* + */ +void compute_residue_block (ImageParameters *image, imgpel **imgY, int res_img[16][16], imgpel mb_pred[16][16], int b8block, int block_size) +{ + int i,j; + int i0 = (b8block & 0x01)<<3, i1 = i0+block_size; + int j0 = (b8block >> 1)<<3, j1 = j0+block_size; + //imgpel (*mb_pred)[16] = (i16mode >= 0) ? image->mpr_16x16[0][i16mode] : image->mb_pred[0];; + + for (i = i0; i < i1; i++) + { + for (j = j0; j < j1; j++) + { + res_img[j][i] = (int)imgY[j][image->pix_x + i] - mb_pred[j][i]; + } + } +} + +/*! + ************************************************************************************* + * \brief + * Stores the pel values for the current best mode. + ************************************************************************************* + */ +void errdo_store_best_block(ImageParameters* image, imgpel*** mbY, imgpel*** dec_img, int i0, int j0, int block_size) +{ + int j, k; + int i = image->pix_x + i0; + int j1 = j0 + block_size; + + for (k = 0; k < params->NoOfDecoders; k++) + { + for (j = j0; j < j1; j++) + { + memcpy(&mbY[k][j][i0], &dec_img[k][image->pix_y + j][i], block_size * sizeof(imgpel)); + } + } +} + +/*! + ************************************************************************************* + * \brief + * Restores the pel values from the current best 8x8 mode. + ************************************************************************************* + */ +void errdo_get_best_block(ImageParameters* image, imgpel*** dec_img, imgpel*** mbY, int j0, int block_size) +{ + int j, k; + int j1 = j0 + block_size; + + for (k = 0; k < params->NoOfDecoders; k++) + { + for (j = j0; j < j1; j++) + { + memcpy(&dec_img[k][image->pix_y + j][image->pix_x], mbY[k][j], block_size * sizeof(imgpel)); + } + } +} + +/*! + ************************************************************************************* + * \brief + * Builds a random status map showing whether each MB is received or lost, based + * on the packet loss rate and the slice structure. + * + * \param s_map + * The status map to be filled + ************************************************************************************* + */ +static void Build_Status_Map(byte **s_map) +{ + int i,j,slice=-1,mb=0,jj,ii,packet_lost=0; + + jj = img->height/MB_BLOCK_SIZE; + ii = img->width/MB_BLOCK_SIZE; + + for (j = 0; j < jj; j++) + { + for (i = 0; i < ii; i++) + { + if (!params->slice_mode || img->mb_data[mb].slice_nr != slice) /* new slice */ + { + packet_lost=0; + if ((double)rand()/(double)RAND_MAX*100 < params->LossRateC) packet_lost += 3; + if ((double)rand()/(double)RAND_MAX*100 < params->LossRateB) packet_lost += 2; + if ((double)rand()/(double)RAND_MAX*100 < params->LossRateA) packet_lost = 1; + slice++; + } + if (!packet_lost) + { + s_map[j][i]=0; //! Packet OK + } + else + { + s_map[j][i]=packet_lost; + if(params->partition_mode == 0) s_map[j][i]=1; + } + mb++; + } + } +} + diff --git a/lencod/src/errdo_mc_prediction.c b/lencod/src/errdo_mc_prediction.c new file mode 100644 index 0000000..5064a94 --- /dev/null +++ b/lencod/src/errdo_mc_prediction.c @@ -0,0 +1,1295 @@ +/*! + ************************************************************************************* + * \file decoder_mc_prediction.c + * + * \brief + * Functions for motion compensated prediction + * + * \author + * Main contributors (see contributors.h for copyright, + * address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Modified for encoder from ldecod/src/mc_prediction.c + * by Peshala V. Pahalawatta <pesh@ieee.org> + ************************************************************************************* + */ +#include "global.h" +#include "mbuffer.h" +#include "mb_access.h" +#include "macroblock.h" +#include "errdo_mc_prediction.h" + +//extern StorablePicture *no_reference_picture; + +#if defined(USEMMX) +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) // ICC +__declspec(align(16)) imgpel tmp_block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; +__declspec(align(16)) imgpel tmp_block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; +# else +imgpel tmp_block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE] __attribute__ ((aligned (16))); +imgpel tmp_block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE] __attribute__ ((aligned (16))); +# endif +#else +imgpel tmp_block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; //!< l0 prediction +imgpel tmp_block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE]; //!< l1 prediction +#endif + +static const int COEF[6] = { 1, -5, 20, 20, -5, 1 }; +/*! + ************************************************************************ + * \brief + * block single list prediction + ************************************************************************ + */ +static inline void mc_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + int ver_block_size, + int hor_block_size, + int ioff, + imgpel block[MB_BLOCK_SIZE][MB_BLOCK_SIZE]) +{ + static int jj; + + if (hor_block_size == MB_BLOCK_SIZE) + { + memcpy(&(mb_pred[0][ioff]), &(block[0][0]), hor_block_size * ver_block_size * sizeof(imgpel)); + } + else + { + for(jj = 0; jj < ver_block_size; jj++) + { + memcpy(&(mb_pred[jj][ioff]), &(block[jj][0]), hor_block_size * sizeof(imgpel)); + } + } +} + +/*! + ************************************************************************ + * \brief + * block single list weighted prediction + ************************************************************************ + */ +static inline void weighted_mc_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + int ver_block_size, + int hor_block_size, + int ioff, + imgpel block[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + int wp_scale, + int wp_offset, + int weight_denom, + int color_clip) +{ + static int ii, jj; + static imgpel *mpr, *b0; + + for(jj=0;jj<ver_block_size;jj++) + { + mpr = &mb_pred[jj][ioff]; + b0 = block[jj]; + for(ii=0;ii<hor_block_size;ii++) + *(mpr++) = (imgpel) iClip1(color_clip, (rshift_rnd((wp_scale * *(b0++)), weight_denom) + wp_offset )); + } +} + + +/*! + ************************************************************************ + * \brief + * block biprediction + ************************************************************************ + */ +static inline void bi_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + imgpel block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + imgpel block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + int ver_block_size, + int hor_block_size, + int ioff) +{ + static int ii, jj; + static imgpel *mpr, *b0, *b1; + + for(jj = 0;jj < ver_block_size;jj++) + { + mpr = &mb_pred[jj][ioff]; + b0 = block_l0[jj]; + b1 = block_l1[jj]; + for(ii = 0; ii < hor_block_size;ii++) + *(mpr++) = (imgpel) rshift_rnd_sf((*(b0++) + *(b1++)), 1); + } +} + +/*! + ************************************************************************ + * \brief + * block weighted biprediction + ************************************************************************ + */ +static inline void weighted_bi_prediction(imgpel mb_pred[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + imgpel block_l0[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + imgpel block_l1[MB_BLOCK_SIZE][MB_BLOCK_SIZE], + int ver_block_size, + int hor_block_size, + int ioff, + int wp_scale_l0, + int wp_scale_l1, + int wp_offset, + int weight_denom, + int color_clip) +{ + static int ii, jj; + static imgpel *mpr, *b0, *b1; + + for(jj = 0; jj < ver_block_size; jj++) + { + mpr = &mb_pred[jj][ioff]; + b0 = block_l0[jj]; + b1 = block_l1[jj]; + + for(ii=0;ii<hor_block_size;ii++) + *(mpr++) = (imgpel) iClip1(color_clip, (rshift_rnd((wp_scale_l0 * *(b0++) + wp_scale_l1 * *(b1++)), weight_denom) + wp_offset)); + } +} + +void get_block_luma(int decoder, ColorPlane pl, StorablePicture* dec_picture, StorablePicture *curr_ref, int x_pos, int y_pos, int hor_block_size, int ver_block_size, ImageParameters *img, imgpel block[MB_BLOCK_SIZE][MB_BLOCK_SIZE]) +{ + static int tmp_res[21][21]; + static int *tmp_line; + static imgpel *p0, *p1, *p2, *p3, *p4, *p5; + static int *x0, *x1, *x2, *x3, *x4, *x5; + + static imgpel **cur_imgY, *cur_lineY; + static int ipos_m2, ipos_m1, ipos, ipos_p1, ipos_p2, ipos_p3; + static imgpel *orig_line; + int tmp_pos; + + int dx = (x_pos & 3), dy = (y_pos & 3); + int i, j, jj; + int shift_x = dec_picture->size_x; + int maxold_x = dec_picture->size_x - 1; + int maxold_y = (dec_picture->motion.mb_field[img->current_mb_nr]) ? (dec_picture->size_y >> 1) - 1 : dec_picture->size_y - 1; + int result; + int pres_x; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; + + + if( IS_INDEPENDENT(params) ) + { + cur_imgY = curr_ref->p_dec_img[img->colour_plane_id][decoder]; + } + else + { + cur_imgY = curr_ref->p_dec_img[pl][decoder]; + } + + x_pos = x_pos >> 2; + y_pos = y_pos >> 2; + + if ( (y_pos > 1) && (y_pos < maxold_y - 2 - ver_block_size) && (x_pos > 1) && (x_pos < maxold_x - 2 - hor_block_size)) + { + cur_imgY = &cur_imgY[ y_pos]; + if (dx == 0 && dy == 0) + { /* fullpel position */ + for (j = 0; j < ver_block_size; j++) + { + memcpy(&(block[j][0]), &(cur_imgY[j][x_pos]), hor_block_size * sizeof(imgpel)); + } + } + else + { /* other positions */ + + if (dy == 0) + { /* No vertical interpolation */ + for (j = 0; j < ver_block_size; j++) + { + p0 = &cur_imgY[j][x_pos - 2]; + p1 = p0 + 1; + p2 = p1 + 1; + p3 = p2 + 1; + p4 = p3 + 1; + p5 = p4 + 1; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (*(p0++) + *(p5++)) * COEF[0] + + (*(p1++) + *(p4++)) * COEF[1] + + (*(p2++) + *(p3++)) * COEF[2]; + + *orig_line++ = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); + } + } + + if ((dx&1) == 1) + { + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = &(cur_imgY[j][x_pos + (dx >> 1)]); + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + *(cur_lineY++) + 1 ) >> 1); + orig_line++; + } + } + } + } + else if (dx == 0) + { /* No horizontal interpolation */ + p0 = &(cur_imgY[ - 2][x_pos]); + for (j = 0; j < ver_block_size; j++) + { + p1 = p0 + shift_x; + p2 = p1 + shift_x; + p3 = p2 + shift_x; + p4 = p3 + shift_x; + p5 = p4 + shift_x; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (*(p0++) + *(p5++)) * COEF[0] + + (*(p1++) + *(p4++)) * COEF[1] + + (*(p2++) + *(p3++)) * COEF[2]; + + *orig_line++ = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); + } + p0 = p1 - hor_block_size; + } + + if ((dy&1) == 1) + { + jj = (dy >> 1); + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = &(cur_imgY[jj++][x_pos]); + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + *(cur_lineY++) + 1 ) >> 1); + orig_line++; + } + } + } + } + else if (dx == 2) + { /* Vertical & horizontal interpolation */ + jj = - 2; + for (j = 0; j < ver_block_size + 5; j++) + { + p0 = &cur_imgY[jj++][x_pos - 2]; + p1 = p0 + 1; + p2 = p1 + 1; + p3 = p2 + 1; + p4 = p3 + 1; + p5 = p4 + 1; + orig_line = block[j]; + tmp_line = tmp_res[j]; + + for (i = 0; i < hor_block_size; i++) + { + *(tmp_line++) = (*(p0++) + *(p5++)) * COEF[0] + + (*(p1++) + *(p4++)) * COEF[1] + + (*(p2++) + *(p3++)) * COEF[2]; + } + } + + for (j = 0; j < ver_block_size; j++) + { + x0 = tmp_res[j ]; + x1 = tmp_res[j + 1]; + x2 = tmp_res[j + 2]; + x3 = tmp_res[j + 3]; + x4 = tmp_res[j + 4]; + x5 = tmp_res[j + 5]; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (*x0++ + *x5++) * COEF[0] + + (*x1++ + *x4++) * COEF[1] + + (*x2++ + *x3++) * COEF[2]; + + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result+512)>>10)); + } + } + + if ((dy&1) == 1) + { + jj = 2 + (dy>>1); + for (j = 0; j < ver_block_size; j++) + { + tmp_line = tmp_res[jj++]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16) >> 5)) + 1 )>> 1); + orig_line++; + } + } + } + } + else if (dy == 2) + { /* Horizontal & vertical interpolation */ + p0 = &(cur_imgY[ -2][x_pos - 2]); + for (j = 0; j < ver_block_size; j++) + { + p1 = p0 + shift_x; + p2 = p1 + shift_x; + p3 = p2 + shift_x; + p4 = p3 + shift_x; + p5 = p4 + shift_x; + tmp_line = tmp_res[j]; + + for (i = 0; i < hor_block_size + 5; i++) + { + *(tmp_line++) = (*(p0++) + *(p5++)) * COEF[0] + + (*(p1++) + *(p4++)) * COEF[1] + + (*(p2++) + *(p3++)) * COEF[2]; + } + p0 = p1 - (hor_block_size + 5); + } + + for (j = 0; j < ver_block_size; j++) + { + orig_line = block[j]; + x0 = tmp_res[j]; + x1 = x0 + 1; + x2 = x1 + 1; + x3 = x2 + 1; + x4 = x3 + 1; + x5 = x4 + 1; + + for (i = 0; i < hor_block_size; i++) + { + result = (*(x0++) + *(x5++)) * COEF[0] + + (*(x1++) + *(x4++)) * COEF[1] + + (*(x2++) + *(x3++)) * COEF[2]; + + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result + 512)>>10)); + } + } + + if ((dx&1) == 1) + { + for (j = 0; j < ver_block_size; j++) + { + tmp_line = &tmp_res[j][2 + (dx>>1)]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16)>>5))+1)>>1); + orig_line ++; + } + } + } + } + else + { /* Diagonal interpolation */ + jj = (dy == 1 ? 0 : 1); + + for (j = 0; j < ver_block_size; j++) + { + p0 = &cur_imgY[jj++][x_pos - 2]; + p1 = p0 + 1; + p2 = p1 + 1; + p3 = p2 + 1; + p4 = p3 + 1; + p5 = p4 + 1; + + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (*(p0++) + *(p5++)) * COEF[0] + + (*(p1++) + *(p4++)) * COEF[1] + + (*(p2++) + *(p3++)) * COEF[2]; + + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); + } + } + + p0 = &(cur_imgY[-2][(dx == 1 ? x_pos : x_pos + 1)]); + for (j = 0; j < ver_block_size; j++) + { + p1 = p0 + shift_x; + p2 = p1 + shift_x; + p3 = p2 + shift_x; + p4 = p3 + shift_x; + p5 = p4 + shift_x; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (*(p0++) + *(p5++)) * COEF[0] + + (*(p1++) + *(p4++)) * COEF[1] + + (*(p2++) + *(p3++)) * COEF[2]; + + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((result + 16) >> 5)) + 1) >> 1); + orig_line++; + } + p0 = p1 - hor_block_size ; + } + } + } + } + else // unsafe positions + { + if (dx == 0 && dy == 0) + { /* fullpel position */ + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = cur_imgY[iClip3(0, maxold_y, y_pos + j)]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *(orig_line++) = cur_lineY[iClip3(0, maxold_x, x_pos + i )]; + } + } + } + else + { /* other positions */ + + if (dy == 0) + { /* No vertical interpolation */ + tmp_pos = x_pos - 2; + for (i = 0; i < hor_block_size; i++) + { + ipos_m2 = iClip3(0, maxold_x, tmp_pos++); + ipos_m1 = iClip3(0, maxold_x, tmp_pos++); + ipos = iClip3(0, maxold_x, tmp_pos++); + ipos_p1 = iClip3(0, maxold_x, tmp_pos++); + ipos_p2 = iClip3(0, maxold_x, tmp_pos++); + ipos_p3 = iClip3(0, maxold_x, tmp_pos ); + tmp_pos -= 4; + + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)]; + + result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0]; + result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1]; + result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2]; + + block[j][i] = (imgpel) iClip1(max_imgpel_value, ((result + 16)>>5)); + } + } + + if ((dx&1) == 1) + { + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + cur_lineY[iClip3(0, maxold_x, x_pos + i + (dx >> 1))] + 1 ) >> 1); + orig_line++; + } + } + } + } + else if (dx == 0) + { /* No horizontal interpolation */ + tmp_pos = y_pos - 2; + for (j = 0; j < ver_block_size; j++) + { + p0 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p1 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p2 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p3 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p4 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p5 = cur_imgY[iClip3(0, maxold_y, tmp_pos )]; + + tmp_pos -= 4; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + pres_x = iClip3(0,maxold_x,x_pos+i); + + result = (p0[pres_x] + p5[pres_x]) * COEF[0]; + result += (p1[pres_x] + p4[pres_x]) * COEF[1]; + result += (p2[pres_x] + p3[pres_x]) * COEF[2]; + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result+16)>>5)); + } + } + + if ((dy&1) == 1) + { + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j+(dy>>1))]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + cur_lineY[iClip3(0, maxold_x, x_pos + i)] + 1 ) >> 1); + orig_line++; + } + } + } + } + else if (dx == 2) + { /* Vertical & horizontal interpolation */ + tmp_pos = x_pos - 2; + for (i = 0; i < hor_block_size; i++) + { + ipos_m2 = iClip3(0, maxold_x, tmp_pos++); + ipos_m1 = iClip3(0, maxold_x, tmp_pos++); + ipos = iClip3(0, maxold_x, tmp_pos++); + ipos_p1 = iClip3(0, maxold_x, tmp_pos++); + ipos_p2 = iClip3(0, maxold_x, tmp_pos++); + ipos_p3 = iClip3(0, maxold_x, tmp_pos ); + tmp_pos -= 4; + + for (j = 0; j < ver_block_size + 5; j++) + { + cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos + j - 2)]; + + tmp_res[j][i] = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0]; + tmp_res[j][i] += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1]; + tmp_res[j][i] += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2]; + } + } + + for (j = 0; j < ver_block_size; j++) + { + x0 = tmp_res[j ]; + x1 = tmp_res[j + 1]; + x2 = tmp_res[j + 2]; + x3 = tmp_res[j + 3]; + x4 = tmp_res[j + 4]; + x5 = tmp_res[j + 5]; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (*x0++ + *x5++) * COEF[0] + + (*x1++ + *x4++) * COEF[1] + + (*x2++ + *x3++) * COEF[2]; + + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result+512)>>10)); + } + } + + if ((dy&1) == 1) + { + for (j = 0; j < ver_block_size; j++) + { + tmp_line = tmp_res[j + 2 + (dy>>1)]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16) >> 5)) + 1 )>>1); + orig_line++; + } + } + } + } + else if (dy == 2) + { /* Horizontal & vertical interpolation */ + + tmp_pos = y_pos - 2; + for (j = 0; j < ver_block_size; j++) + { + p0 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p1 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p2 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p3 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p4 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p5 = cur_imgY[iClip3(0, maxold_y, tmp_pos )]; + + tmp_pos -= 4; + + for (i = 0; i < hor_block_size + 5; i++) + { + pres_x = iClip3(0,maxold_x, x_pos + i - 2); + result = (p0[pres_x] + p5[pres_x])*COEF[0] + + (p1[pres_x] + p4[pres_x])*COEF[1] + + (p2[pres_x] + p3[pres_x])*COEF[2]; + tmp_res[j][i] = result; + } + } + + for (j = 0; j < ver_block_size; j++) + { + orig_line = block[j]; + tmp_line = tmp_res[j]; + x0 = tmp_res[j]; + x1 = x0 + 1; + x2 = x1 + 1; + x3 = x2 + 1; + x4 = x3 + 1; + x5 = x4 + 1; + + for (i = 0; i < hor_block_size; i++) + { + result = (*(x0++) + *(x5++)) * COEF[0] + + (*(x1++) + *(x4++)) * COEF[1] + + (*(x2++) + *(x3++)) * COEF[2]; + + *(orig_line++) = (imgpel) iClip1(max_imgpel_value, ((result + 512)>>10)); + } + } + + if ((dx&1) == 1) + { + for (j = 0; j < ver_block_size; j++) + { + tmp_line = &tmp_res[j][2 + (dx>>1)]; + orig_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((*(tmp_line++) + 16)>>5)) + 1)>> 1); + orig_line++; + } + } + } + } + else + { /* Diagonal interpolation */ + tmp_pos = x_pos - 2; + for (i = 0; i < hor_block_size; i++) + { + ipos_m2 = iClip3(0, maxold_x, tmp_pos++); + ipos_m1 = iClip3(0, maxold_x, tmp_pos++); + ipos = iClip3(0, maxold_x, tmp_pos++); + ipos_p1 = iClip3(0, maxold_x, tmp_pos++); + ipos_p2 = iClip3(0, maxold_x, tmp_pos++); + ipos_p3 = iClip3(0, maxold_x, tmp_pos ); + tmp_pos -= 4; + + for (j = 0; j < ver_block_size; j++) + { + cur_lineY = cur_imgY[iClip3(0,maxold_y,(dy == 1 ? y_pos+j : y_pos+j+1))]; + + result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0]; + result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1]; + result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2]; + + block[j][i] = (imgpel) iClip1(max_imgpel_value, ((result+16)>>5)); + } + } + + tmp_pos = y_pos - 2; + for (j = 0; j < ver_block_size; j++) + { + p0 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p1 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p2 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p3 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p4 = cur_imgY[iClip3(0, maxold_y, tmp_pos++)]; + p5 = cur_imgY[iClip3(0, maxold_y, tmp_pos )]; + + tmp_pos -= 4; + orig_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + pres_x = dx == 1 ? x_pos+i : x_pos+i+1; + pres_x = iClip3(0, maxold_x, pres_x); + + result = (p0[pres_x] + p5[pres_x]) * COEF[0]; + result += (p1[pres_x] + p4[pres_x]) * COEF[1]; + result += (p2[pres_x] + p3[pres_x]) * COEF[2]; + + *orig_line = (imgpel) ((*orig_line + iClip1(max_imgpel_value, ((result+16)>>5)) + 1 ) >> 1); + orig_line++; + } + } + } + } + } +} + +void get_block_chroma(int decoder, int uv, StorablePicture* dec_picture, StorablePicture *curr_ref, int x_pos, int y_pos, int hor_block_size, int ver_block_size, ImageParameters *img, imgpel block[MB_BLOCK_SIZE][MB_BLOCK_SIZE]) +{ + int subpel_x = img->mb_cr_size_x == 8 ? 7 : 3; + int subpel_y = img->mb_cr_size_y == 8 ? 7 : 3; + int shiftpel_x = img->mb_cr_size_x == 8 ? 3 : 2; + int shiftpel_y = img->mb_cr_size_y == 8 ? 3 : 2; + int total_scale = shiftpel_x + shiftpel_y; + + int dx = (x_pos & subpel_x); + int dy = (y_pos & subpel_y); + int dxcur = (subpel_x + 1 - dx); + int dycur = (subpel_y + 1 - dy); + + int w00 = dxcur * dycur; + int w01 = dxcur * dy; + int w10 = dx * dycur; + int w11 = dx * dy; + + int i, j; + int maxold_x = dec_picture->size_x_cr - 1; + int maxold_y = (dec_picture->motion.mb_field[img->current_mb_nr]) ? (dec_picture->size_y_cr >> 1) - 1 : dec_picture->size_y_cr - 1; + int result; + + static imgpel **cur_img, *blk_line; + static imgpel *cur_line, *cur_line_p1; + int tmp_pos; + static int ipos, ipos_p1; + int max_imgpel_value = img->max_imgpel_value_comp[uv + 1]; + +#if 0 + if (curr_ref == no_reference_picture && img->framepoc < img->recovery_poc) + { + printf("list[ref_frame] is equal to 'no reference picture' before RAP\n"); + + /* fill the block with sample value 128 */ + for (j = 0; j < ver_block_size; j++) + for (i = 0; i < hor_block_size; i++) + block[j][i] = 128; + return; + } +#endif + + cur_img = curr_ref->p_dec_img[uv+1][decoder]; + + x_pos = x_pos >> shiftpel_x; + y_pos = y_pos >> shiftpel_y; + + if ((y_pos >= 0) && (y_pos < maxold_y - ver_block_size) && (x_pos >= 0) && (x_pos < maxold_x - hor_block_size)) + { + if (dx == 0 && dy == 0) + { /* fullpel position */ + for (j = 0; j < ver_block_size; j++) + { + memcpy(&(block[j][0]), &(cur_img[ y_pos + j ][x_pos]), hor_block_size * sizeof(imgpel)); + } + } + else if (dx == 0) + { + for (j = 0; j < ver_block_size; j++) + { + cur_line = &cur_img[y_pos + j ][x_pos]; + cur_line_p1 = &cur_img[y_pos + j + 1][x_pos]; + blk_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (w00 * *cur_line++ + w01 * *cur_line_p1++); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); + } + } + } + else if (dy == 0) + { + for (j = 0; j < ver_block_size; j++) + { + cur_line = &cur_img[y_pos + j][x_pos]; + cur_line_p1 = cur_line + 1; + blk_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (w00 * *cur_line++ + w10 * *cur_line_p1++); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); + } + } + } + else + { /* other positions */ + for (j = 0; j < ver_block_size; j++) + { + cur_line = &cur_img[y_pos + j ][x_pos]; + cur_line_p1 = &cur_img[y_pos + j + 1][x_pos]; + blk_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + result = (w00 * *(cur_line++) + w01 * *(cur_line_p1++)); + result += (w10 * *(cur_line ) + w11 * *(cur_line_p1 )); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); + } + } + } + } + else // unsafe positions + { + if (dx == 0 && dy == 0) + { /* fullpel position */ + for (j = 0; j < ver_block_size; j++) + { + cur_line = cur_img[iClip3(0, maxold_y, y_pos + j)]; + blk_line = block[j]; + for (i = 0; i < hor_block_size; i++) + { + *(blk_line++) = cur_line[iClip3(0, maxold_x, x_pos + i )]; + } + } + } + else if (dx == 0) + { + for (j = 0; j < ver_block_size; j++) + { + cur_line = cur_img[iClip3(0, maxold_y, y_pos + j)]; + cur_line_p1 = cur_img[iClip3(0, maxold_y, y_pos + j + 1)]; + tmp_pos = x_pos; + blk_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + ipos = iClip3(0, maxold_x, tmp_pos++); + + result = (w00 * cur_line[ipos] + w01 * cur_line_p1[ipos]); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); + } + } + } + else if (dy == 0) + { + for (j = 0; j < ver_block_size; j++) + { + cur_line = cur_img[iClip3(0, maxold_y, y_pos + j)]; + tmp_pos = x_pos; + blk_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + ipos = iClip3(0, maxold_x, tmp_pos++); + ipos_p1 = iClip3(0, maxold_x, tmp_pos ); + + result = (w00 * cur_line[ipos ] + w10 * cur_line[ipos_p1]); + *(blk_line++) = (imgpel)iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); + } + } + } + else + { /* other positions */ + for (j = 0; j < ver_block_size; j++) + { + cur_line = cur_img[iClip3(0, maxold_y, y_pos + j)]; + cur_line_p1 = cur_img[iClip3(0, maxold_y, y_pos + j + 1)]; + tmp_pos = x_pos; + blk_line = block[j]; + + for (i = 0; i < hor_block_size; i++) + { + ipos = iClip3(0, maxold_x, tmp_pos++); + ipos_p1 = iClip3(0, maxold_x, tmp_pos ); + + result = ( + w00 * cur_line [ipos ] + + w10 * cur_line [ipos_p1] + + w01 * cur_line_p1[ipos ] + + w11 * cur_line_p1[ipos_p1]); + *(blk_line++) = (imgpel) iClip1(max_imgpel_value, rshift_rnd_sf(result, total_scale)); + } + } + } + } +} + +#if 0 +void intra_cr_decoding(Macroblock *currMB, int yuv, ImageParameters *img, int smb) +{ + imgpel **curUV, *cur_img; + int (*m7UV)[16], *m7; + int uv; + int b8,b4; + int ioff, joff, ii, jj; + + for(uv = 0; uv < 2; uv++) + { + Boolean lossless_qpprime = (Boolean) ((img->lossless_qpprime_flag == 1) &&((img->qp + dec_picture->chroma_qp_offset[uv] + img->bitdepth_chroma_qp_scale) == 0)); + itrans_4x4 = (!lossless_qpprime) ? itrans4x4 : itrans4x4_ls; + + curUV = dec_picture->imgUV[uv]; + m7UV = img->mb_rres[uv+1]; + intrapred_chroma(img, currMB, uv); + + if (!smb && (currMB->cbp >> 4)) + { + for (b8 = 0; b8 < (img->num_uv_blocks); b8++) + { + for(b4 = 0; b4 < 4; b4++) + { + joff = subblk_offset_y[yuv][b8][b4]; + ioff = subblk_offset_x[yuv][b8][b4]; + + itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff); + + for(jj=joff; jj<joff + 4;jj++) + { + cur_img = &curUV[img->pix_c_y+jj][img->pix_c_x + ioff]; + m7 = &m7UV[jj][ioff]; + + for(ii=0; ii<4;ii++) + { + *cur_img++ = (imgpel) *m7++; + } + } + } + } + } + else if ((currMB->cbp >> 4) == 0) + { + for (b8 = 0; b8 < (img->num_uv_blocks); b8++) + { + for(b4 = 0; b4 < 4; b4++) + { + joff = subblk_offset_y[yuv][b8][b4]; + ioff = subblk_offset_x[yuv][b8][b4]; + + for(jj = joff; jj < 4 + joff;jj++) + memcpy(&(curUV[img->pix_c_y + jj][img->pix_c_x + ioff]), &(img->mb_pred[uv + 1][jj][ioff]), BLOCK_SIZE * sizeof(imgpel)); + } + } + } + else + { + itrans_sp_cr(img, uv); + + for (joff = 0; joff < 8; joff += 4) + { + for(ioff = 0; ioff < 8;ioff+=4) + { + itrans_4x4(img, (ColorPlane) (uv + 1), ioff, joff); + + for(jj = joff; jj < joff + 4; jj++) + for(ii = ioff; ii < ioff + 4; ii++) + { + curUV[img->pix_c_y+jj][ii + img->pix_c_x] = (imgpel) img->mb_rres[uv+1][jj][ii]; + } + } + } + } + } +} + +void prepare_direct_params(Macroblock *currMB, StorablePicture *dec_picture, ImageParameters *img, short pmvl0[2], short pmvl1[2],char *l0_rFrame, char *l1_rFrame) +{ + char l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR; + char l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR; + + PixelPos mb_left, mb_up, mb_upleft, mb_upright; + + get4x4Neighbour(currMB, -1, 0, img->mb_size[IS_LUMA], &mb_left); + get4x4Neighbour(currMB, 0, -1, img->mb_size[IS_LUMA], &mb_up); + get4x4Neighbour(currMB, 16, -1, img->mb_size[IS_LUMA], &mb_upright); + get4x4Neighbour(currMB, -1, -1, img->mb_size[IS_LUMA], &mb_upleft); + + if (!img->MbaffFrameFlag) + { + l0_rFrameL = (char) (mb_left.available ? dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1); + l0_rFrameU = (char) (mb_up.available ? dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1); + l0_rFrameUL = (char) (mb_upleft.available ? dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + l0_rFrameUR = (char) (mb_upright.available ? dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL); + + l1_rFrameL = (char) (mb_left.available ? dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1); + l1_rFrameU = (char) (mb_up.available ? dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1); + l1_rFrameUL = (char) (mb_upleft.available ? dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + l1_rFrameUR = (char) (mb_upright.available ? dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL); + } + else + { + if (currMB->mb_field) + { + l0_rFrameL = (char) (mb_left.available + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1); + + l0_rFrameU = (char) (mb_up.available + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1); + + l0_rFrameUL = (char) (mb_upleft.available + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1); + + l0_rFrameUR = (char) (mb_upright.available + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] + : dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL); + + l1_rFrameL = (char) (mb_left.available + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1); + + l1_rFrameU = (char) (mb_up.available + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1); + + l1_rFrameUL = (char) (mb_upleft.available + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2 : -1); + + l1_rFrameUR = (char) (mb_upright.available + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] + : dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL); + } + else + { + l0_rFrameL = (char) (mb_left.available + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1); + + l0_rFrameU = (char) (mb_up.available + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1); + + l0_rFrameUL = (char) (mb_upleft.available + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + + l0_rFrameUR = (char) (mb_upright.available + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL); + + l1_rFrameL = (char) (mb_left.available + ? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1); + + l1_rFrameU = (char) (mb_up.available + ? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1); + + l1_rFrameUL = (char) (mb_upleft.available + ? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1); + + l1_rFrameUR = (char) (mb_upright.available + ? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 + ? dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1 + : dec_picture->motion.ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL); + } + } + + *l0_rFrame = (char) ((l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU) : imax(l0_rFrameL,l0_rFrameU)); + *l0_rFrame = (char) ((*l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(*l0_rFrame,l0_rFrameUR): imax(*l0_rFrame,l0_rFrameUR)); + + *l1_rFrame = (char) ((l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU) : imax(l1_rFrameL,l1_rFrameU)); + *l1_rFrame = (char) ((*l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(*l1_rFrame,l1_rFrameUR): imax(*l1_rFrame,l1_rFrameUR)); + + if (*l0_rFrame >=0) + SetMotionVectorPredictor (img, currMB, pmvl0, *l0_rFrame, LIST_0, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16); + + if (*l1_rFrame >=0) + SetMotionVectorPredictor (img, currMB, pmvl1, *l1_rFrame, LIST_1, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16); +} + +void check_motion_vector_range(ImageParameters *img, short mv_x, short mv_y) +{ + if (mv_x > 8191 || mv_x < -8192) + { + fprintf(stderr,"ERROR! Horizontal motion vector %d is out of allowed range {-8192, 8191} in picture %d, macroblock %d\n", mv_x, img->number, img->current_mb_nr); + error("invalid stream: too big horizontal motion vector", 500); + } + + if (mv_y > (img->max_mb_vmv_r - 1) || mv_y < (-img->max_mb_vmv_r)) + { + fprintf(stderr,"ERROR! Vertical motion vector %d is out of allowed range {%d, %d} in picture %d, macroblock %d\n", mv_y, (-img->max_mb_vmv_r), (img->max_mb_vmv_r - 1), img->number, img->current_mb_nr); + error("invalid stream: too big vertical motion vector", 500); + } +} +#endif + +void perform_mc(int decoder, ColorPlane pl, StorablePicture *dec_picture, ImageParameters *img, int pred_dir, int l0_mode, int l1_mode, int i, int j, int list_offset, int block_size_x, int block_size_y, int curr_mb_field) +{ + static int vec1_x=0, vec1_y=0; +#if 0 + static int vec2_x=0, vec2_y=0; + static int vec1_y_cr = 0, vec2_y_cr = 0; + static int alpha_l0, alpha_l1, wp_offset; + int max_imgpel_value = img->max_imgpel_value_comp[pl]; +#endif + static const int mv_mul = 16; // 4 * 4 + + + int i4 = img->block_x + i; + int j4 = img->block_y + j; + int ioff = (i << 2); + int joff = (j << 2); + + assert (pred_dir<=2); + + if (pred_dir != 2) + { + //===== Single List Prediction ===== + short ref_idx = dec_picture->motion.ref_idx[pred_dir][j4][i4]; + //short ref_idx_wp = ref_idx; + short ***mv_array = img->all_mv[pred_dir][ref_idx][l0_mode]; + StorablePicture **list = listX[list_offset + pred_dir]; + + //check_motion_vector_range(img, mv_array[j4][i4][0], mv_array[j4][i4][1]); + + vec1_x = i4 * mv_mul + mv_array[j][i][0]; + //vec1_y = (img->block_y_aff + j) * mv_mul + mv_array[j4][i4][1]; + vec1_y = j4 * mv_mul + mv_array[j][i][1]; + + get_block_luma (decoder, pl, dec_picture, list[ref_idx], vec1_x, vec1_y, block_size_x, block_size_y, img, tmp_block_l0); + +#if 0 //Currently not used + if (img->apply_weights) + { + if (curr_mb_field && ((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))|| + (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE)))) + { + ref_idx_wp >>=1; + } + + alpha_l0 = img->wp_weight[pred_dir][ref_idx_wp][0]; + wp_offset = img->wp_offset[pred_dir][ref_idx_wp][0]; + + weighted_mc_prediction(&img->mb_pred[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0, alpha_l0, wp_offset, img->luma_log2_weight_denom, max_imgpel_value); + } + else +#endif + { + mc_prediction(&img->mb_pred[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0); + } + +#if 0 + if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444) ) + { + int uv; + + int ioff_cr = (img->mb_cr_size_x == MB_BLOCK_SIZE) ? ioff : ioff >> 1; + int joff_cr = (img->mb_cr_size_y == MB_BLOCK_SIZE) ? joff : joff >> 1; + int block_size_x_cr = img->mb_cr_size_x == MB_BLOCK_SIZE ? block_size_x : block_size_x >> 1; + int block_size_y_cr = img->mb_cr_size_y == MB_BLOCK_SIZE ? block_size_y : block_size_y >> 1; + + vec1_y_cr = vec1_y + ((active_sps->chroma_format_idc == 1)? list[ref_idx]->chroma_vector_adjustment : 0); + + for(uv=0;uv<2;uv++) + { + get_block_chroma (uv, list[ref_idx], vec1_x, vec1_y_cr, block_size_x_cr, block_size_y_cr, img, tmp_block_l0); + + if (img->apply_weights) + { + alpha_l0 = img->wp_weight[pred_dir][ref_idx_wp][uv + 1]; + wp_offset = img->wp_offset[pred_dir][ref_idx_wp][uv + 1]; + + weighted_mc_prediction(&img->mb_pred[uv + 1][joff_cr], block_size_y_cr, block_size_x_cr, ioff_cr, tmp_block_l0, alpha_l0, wp_offset, img->chroma_log2_weight_denom, img->max_imgpel_value_comp[uv + 1]); + } + else + { + mc_prediction(&img->mb_pred[uv + 1][joff_cr], block_size_y_cr, block_size_x_cr, ioff_cr, tmp_block_l0); + } + } + } +#endif + } + else + { +#if 0 + //===== BI-PREDICTION ===== + short ***l0_mv_array = dec_picture->motion.mv[LIST_0]; + short ***l1_mv_array = dec_picture->motion.mv[LIST_1]; + + short l0_refframe = dec_picture->motion.ref_idx[LIST_0][j4][i4]; + short l1_refframe = dec_picture->motion.ref_idx[LIST_1][j4][i4]; + short l0_ref_idx = l0_refframe; + short l1_ref_idx = l1_refframe; + + check_motion_vector_range(img, l0_mv_array[j4][i4][0], l0_mv_array[j4][i4][1]); + check_motion_vector_range(img, l1_mv_array[j4][i4][0], l1_mv_array[j4][i4][1]); + vec1_x = i4 * mv_mul + l0_mv_array[j4][i4][0]; + vec2_x = i4 * mv_mul + l1_mv_array[j4][i4][0]; + + vec1_y = (img->block_y_aff + j) * mv_mul + l0_mv_array[j4][i4][1]; + vec2_y = (img->block_y_aff + j) * mv_mul + l1_mv_array[j4][i4][1]; + + get_block_luma(pl, listX[LIST_0 + list_offset][l0_refframe], vec1_x, vec1_y, block_size_x, block_size_y, img, tmp_block_l0); + get_block_luma(pl, listX[LIST_1 + list_offset][l1_refframe], vec2_x, vec2_y, block_size_x, block_size_y, img, tmp_block_l1); + + if(img->apply_weights) + { + int wt_list_offset = (active_pps->weighted_bipred_idc==2)? list_offset : 0; + + // This code existed in the original. Seems pointless but copying it here for reference and in case temporal direct breaks. + // if (mv_mode==0 && img->direct_spatial_mv_pred_flag==0 ) l1_ref_idx=0; + if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))|| + (active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field) + { + l0_ref_idx >>=1; + l1_ref_idx >>=1; + } + + alpha_l0 = img->wbp_weight[LIST_0 + wt_list_offset][l0_ref_idx][l1_ref_idx][0]; + alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][0]; + wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][0] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][0] + 1) >>1); + + weighted_bi_prediction(&img->mb_pred[pl][joff], tmp_block_l0, tmp_block_l1, block_size_y, block_size_x, ioff, alpha_l0, alpha_l1, wp_offset, (img->luma_log2_weight_denom + 1), max_imgpel_value); + } + else + { + bi_prediction(&img->mb_pred[pl][joff], tmp_block_l0, tmp_block_l1, block_size_y, block_size_x, ioff); + } + + if ((dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444) ) + { + int uv; + + int ioff_cr = img->mb_cr_size_x == MB_BLOCK_SIZE ? ioff : ioff >> 1; + int joff_cr = img->mb_cr_size_y == MB_BLOCK_SIZE ? joff : joff >> 1; + int block_size_x_cr = img->mb_cr_size_x == MB_BLOCK_SIZE ? block_size_x : block_size_x >> 1; + int block_size_y_cr = img->mb_cr_size_y == MB_BLOCK_SIZE ? block_size_y : block_size_y >> 1; + + vec1_y_cr = vec1_y + ((active_sps->chroma_format_idc == 1)? listX[LIST_0 + list_offset][l0_refframe]->chroma_vector_adjustment : 0); + vec2_y_cr = vec2_y + ((active_sps->chroma_format_idc == 1)? listX[LIST_1 + list_offset][l1_refframe]->chroma_vector_adjustment : 0); + + for(uv=0;uv<2;uv++) + { + get_block_chroma (uv, listX[LIST_0 + list_offset][l0_refframe], vec1_x, vec1_y_cr, block_size_x_cr, block_size_y_cr, img, tmp_block_l0); + get_block_chroma (uv, listX[LIST_1 + list_offset][l1_refframe], vec2_x, vec2_y_cr, block_size_x_cr, block_size_y_cr, img, tmp_block_l1); + + if(img->apply_weights) + { + int wt_list_offset = (active_pps->weighted_bipred_idc==2)? list_offset : 0; + + alpha_l0 = img->wbp_weight[LIST_0 + wt_list_offset][l0_ref_idx][l1_ref_idx][uv + 1]; + alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][uv + 1]; + wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][uv + 1] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][uv + 1] + 1) >>1); + + weighted_bi_prediction(&img->mb_pred[uv+1][joff_cr], tmp_block_l0, tmp_block_l1, block_size_y_cr, block_size_x_cr, ioff_cr, alpha_l0, alpha_l1, wp_offset, (img->chroma_log2_weight_denom + 1), img->max_imgpel_value_comp[uv + 1]); + } + else + { + bi_prediction(&img->mb_pred[uv + 1][joff_cr], tmp_block_l0, tmp_block_l1, block_size_y_cr, block_size_x_cr, ioff_cr); + } + } + } +#endif + } +} + +void perform_mc_concealment(int decoder, ColorPlane pl, StorablePicture *dec_picture, ImageParameters *img, int pred_dir, int i, int j, int block_size_x, int block_size_y) +{ + static int vec1_x=0, vec1_y=0; + static const int mv_mul = 16; // 4 * 4 + + int i4 = img->block_x + i; + int j4 = img->block_y + j; + int ioff = (i << 2); + int joff = (j << 2); + + assert (pred_dir<=2); + + if (pred_dir != 2) + { + //===== Single List Prediction ===== + short ref_idx = dec_picture->motion.ref_idx[pred_dir][j4][i4]; + short ***mv_array = dec_picture->motion.mv[pred_dir]; + StorablePicture **list = listX[pred_dir]; + + vec1_x = i4 * mv_mul + mv_array[j4][i4][0]; + vec1_y = j4 * mv_mul + mv_array[j4][i4][1]; + + get_block_luma (decoder, pl, dec_picture, list[ref_idx], vec1_x, vec1_y, block_size_x, block_size_y, img, tmp_block_l0); + mc_prediction(&img->mb_pred[pl][joff], block_size_y, block_size_x, ioff, tmp_block_l0); + } +} diff --git a/lencod/src/explicit_gop.c b/lencod/src/explicit_gop.c index 92d8b40..bdc443f 100644 --- a/lencod/src/explicit_gop.c +++ b/lencod/src/explicit_gop.c @@ -1,4 +1,3 @@ - /*! ************************************************************************************* * \file explicit_gop.c @@ -12,14 +11,16 @@ ************************************************************************************* */ +#include "contributors.h" + #include <ctype.h> #include <limits.h> #include "global.h" -#include "contributors.h" + #include "explicit_gop.h" #include "image.h" #include "nalucommon.h" - +#include "report.h" /*! ************************************************************************ @@ -445,8 +446,14 @@ void encode_enhancement_layer() img->b_frame_to_code = 0; } +/*! +************************************************************************ +* \brief +* POC-based reference management (FRAME) +************************************************************************ +*/ -void poc_based_ref_management(int current_pic_num) +void poc_based_ref_management_frame_pic(int current_pic_num) { unsigned i, pic_num = 0; @@ -456,7 +463,7 @@ void poc_based_ref_management(int current_pic_num) if (img->dec_ref_pic_marking_buffer!=NULL) return; - if ((dpb.ref_frames_in_buffer+dpb.ltref_frames_in_buffer)==0) + if ((dpb.ref_frames_in_buffer + dpb.ltref_frames_in_buffer)==0) return; for (i=0; i<dpb.used_size;i++) @@ -481,3 +488,60 @@ void poc_based_ref_management(int current_pic_num) img->dec_ref_pic_marking_buffer = tmp_drpm2; } + +/*! +************************************************************************ +* \brief +* POC-based reference management (FIELD) +************************************************************************ +*/ + +void poc_based_ref_management_field_pic(int current_pic_num) +{ + unsigned int i, pic_num1 = 0, pic_num2 = 0; + + int min_poc=INT_MAX; + DecRefPicMarking_t *tmp_drpm,*tmp_drpm2, *tmp_drpm3; + + if (img->dec_ref_pic_marking_buffer!=NULL) + return; + + if ((dpb.ref_frames_in_buffer+dpb.ltref_frames_in_buffer)==0) + return; + + if ( img->structure == TOP_FIELD ) + { + for (i=0; i<dpb.used_size;i++) + { + if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)) && dpb.fs[i]->poc < min_poc) + { + min_poc = dpb.fs[i]->poc; + pic_num1 = dpb.fs[i]->top_field->pic_num; + pic_num2 = dpb.fs[i]->bottom_field->pic_num; + } + } + } + + if (NULL==(tmp_drpm=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management_field_pic: tmp_drpm"); + tmp_drpm->Next=NULL; + tmp_drpm->memory_management_control_operation = 0; + + if ( img->structure == BOTTOM_FIELD ) + { + img->dec_ref_pic_marking_buffer = tmp_drpm; + return; + } + + if (NULL==(tmp_drpm2=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management_field_pic: tmp_drpm2"); + tmp_drpm2->Next=tmp_drpm; + tmp_drpm2->memory_management_control_operation = 1; + tmp_drpm2->difference_of_pic_nums_minus1 = current_pic_num - pic_num1 - 1; + + if (NULL==(tmp_drpm3=(DecRefPicMarking_t*)calloc (1,sizeof (DecRefPicMarking_t)))) no_mem_exit("poc_based_ref_management_field_pic: tmp_drpm3"); + tmp_drpm3->Next=tmp_drpm2; + tmp_drpm3->memory_management_control_operation = 1; + tmp_drpm3->difference_of_pic_nums_minus1 = current_pic_num - pic_num2 - 1; + + img->dec_ref_pic_marking_buffer = tmp_drpm3; +} + diff --git a/lencod/src/filehandle.c b/lencod/src/filehandle.c index a58ee6e..56079d3 100644 --- a/lencod/src/filehandle.c +++ b/lencod/src/filehandle.c @@ -15,6 +15,7 @@ #include "contributors.h" #include "global.h" +#include "enc_statistics.h" #include "rtp.h" #include "annexb.h" diff --git a/lencod/src/header.c b/lencod/src/header.c index ebf8c83..1c29343 100644 --- a/lencod/src/header.c +++ b/lencod/src/header.c @@ -41,7 +41,7 @@ int assignSE2partition_DP[SE_MAX_ELEMENTS] = static int ref_pic_list_reordering(Bitstream *bitstream); static int dec_ref_pic_marking (Bitstream *bitstream); static int pred_weight_table (Bitstream *bitstream); - +static int get_picture_type(void); /*! ******************************************************************************************** * \brief @@ -67,7 +67,7 @@ int SliceHeader(void) else len = ue_v("SH: first_mb_in_slice", img->current_mb_nr, bitstream); - len += ue_v("SH: slice_type", get_picture_type (), bitstream); + len += ue_v("SH: slice_type", get_picture_type (), bitstream); len += ue_v("SH: pic_parameter_set_id" , active_pps->pic_parameter_set_id ,bitstream); @@ -198,14 +198,13 @@ int SliceHeader(void) if (img->DFDisableIdc!=1) { len += se_v ("SH: slice_alpha_c0_offset_div2", img->DFAlphaC0Offset / 2, bitstream); - - len += se_v ("SH: slice_beta_offset_div2", img->DFBetaOffset / 2, bitstream); + len += se_v ("SH: slice_beta_offset_div2 ", img->DFBetaOffset / 2, bitstream); } } - if ( active_pps->num_slice_groups_minus1>0 && - active_pps->slice_group_map_type>=3 && active_pps->slice_group_map_type<=5) + if ( active_pps->num_slice_groups_minus1 > 0 && + active_pps->slice_group_map_type >= 3 && active_pps->slice_group_map_type <= 5) { numtmp=img->PicHeightInMapUnits*img->PicWidthInMbs/(float)(active_pps->slice_group_change_rate_minus1+1)+1; num_bits_slice_group_change_cycle = (int)ceil(log(numtmp)/log(2)); @@ -477,7 +476,7 @@ static int pred_weight_table(Bitstream *bitstream) * symbol value for picture type ************************************************************************ */ -int get_picture_type() +static int get_picture_type() { // set this value to zero for transmission without signaling // that the whole picture has the same slice type diff --git a/lencod/src/image.c b/lencod/src/image.c index 34ca638..a9e130d 100644 --- a/lencod/src/image.c +++ b/lencod/src/image.c @@ -32,10 +32,11 @@ #include "global.h" -#include "refbuf.h" +#include "filehandle.h" #include "mbuffer.h" #include "img_luma.h" #include "img_chroma.h" +#include "img_distortion.h" #include "intrarefresh.h" #include "fmo.h" #include "sei.h" @@ -43,50 +44,41 @@ #include "nalu.h" #include "ratectl.h" #include "mb_access.h" -#include "output.h" #include "cabac.h" #include "context_ini.h" +#include "enc_statistics.h" #include "conformance.h" #include "q_matrix.h" #include "q_offsets.h" #include "quant4x4.h" #include "quant8x8.h" +#include "quantChroma.h" #include "wp.h" #include "input.h" +#include "image.h" +#include "errdo.h" + extern pic_parameter_set_rbsp_t *PicParSet[MAXPPS]; -void code_a_picture(Picture *pic); -void frame_picture (Picture *frame, int rd_pass); -void field_picture(Picture *top, Picture *bottom); -void prepare_enc_frame_picture (StorablePicture **stored_pic); +extern void DeblockFrame(ImageParameters *img, imgpel **, imgpel ***); +static void code_a_picture(Picture *pic); +static void field_picture(Picture *top, Picture *bottom); +static void prepare_enc_frame_picture (StorablePicture **stored_pic); static int writeout_picture(Picture *pic); - static int picture_structure_decision(Picture *frame, Picture *top, Picture *bot); -static void distortion_fld (float *dis_fld_y, float *dis_fld_u, float *dis_fld_v); - -static void find_snr(void); -static void find_distortion(void); - - - -static void field_mode_buffer(int bit_field, float snr_field_y, float snr_field_u, float snr_field_v); -static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v); - -static void init_frame(void); -static void init_field(void); - -static void put_buffer_frame(void); -static void put_buffer_top(void); -static void put_buffer_bot(void); - -static void copy_motion_vectors_MB(void); - +static void distortion_fld (Picture *field_pic); +static void field_mode_buffer (ImageParameters *img, InputParameters *params); +static void frame_mode_buffer (ImageParameters *img, InputParameters *params); +static void init_frame(ImageParameters *img); +static void init_field(ImageParameters *img); +static void put_buffer_frame(ImageParameters *img); +static void put_buffer_top(ImageParameters *img); +static void put_buffer_bot(ImageParameters *img); static void PaddAutoCropBorders (FrameFormat output, int img_size_x, int img_size_y, int img_size_x_cr, int img_size_y_cr); - -static void writeUnit(Bitstream* currStream ,int partition); +static void writeUnit(Bitstream* currStream, int partition); static void rdPictureCoding(void); #ifdef _ADAPT_LAST_GROUP_ @@ -120,7 +112,7 @@ void MbAffPostProc(void) { for (i=0; i<(int)img->PicSizeInMbs; i+=2) { - if (enc_picture->mb_field[i]) + if (enc_picture->motion.mb_field[i]) { get_mb_pos(i, img->mb_size[IS_LUMA], &x0, &y0); for (y=0; y<(2*MB_BLOCK_SIZE);y++) @@ -153,7 +145,7 @@ void MbAffPostProc(void) { for (i=0; i<(int)img->PicSizeInMbs; i+=2) { - if (enc_picture->mb_field[i]) + if (enc_picture->motion.mb_field[i]) { get_mb_pos(i, img->mb_size[IS_LUMA], &x0, &y0); for (y=0; y<(2*MB_BLOCK_SIZE);y++) @@ -178,11 +170,53 @@ void MbAffPostProc(void) */ void set_slice_type(int slice_type) { - img->type = slice_type; // set slice type - img->RCMinQP = params->RCMinQP[img->type]; - img->RCMaxQP = params->RCMaxQP[img->type]; + img->type = slice_type; // set slice type + img->RCMinQP = params->RCMinQP[img->type]; + img->RCMaxQP = params->RCMaxQP[img->type]; } +void code_a_plane(ImageParameters *img, Picture *pic) +{ + unsigned int NumberOfCodedMBs = 0; + int SliceGroup = 0; + // The slice_group_change_cycle can be changed here. + // FmoInit() is called before coding each picture, frame or field + img->slice_group_change_cycle=1; + FmoInit(img, active_pps, active_sps); + FmoStartPicture (); //! picture level initialization of FMO + + CalculateQuantParam(); + CalculateOffsetParam(); + + if(params->Transform8x8Mode) + { + CalculateQuant8Param(); + CalculateOffset8Param(); + } + + reset_pic_bin_count(); + img->bytes_in_picture = 0; + + while (NumberOfCodedMBs < img->PicSizeInMbs) // loop over slices + { + // Encode one SLice Group + while (!FmoSliceGroupCompletelyCoded (SliceGroup)) + { + // Encode the current slice + NumberOfCodedMBs += encode_one_slice (SliceGroup, pic, NumberOfCodedMBs); + FmoSetLastMacroblockInSlice (img->current_mb_nr); + // Proceed to next slice + img->current_slice_nr++; + stats->bit_slice = 0; + } + // Proceed to next SliceGroup + SliceGroup++; + } + FmoEndPicture (); + + if ((params->SkipDeBlockNonRef == 0) || (img->nal_reference_idc != 0)) + DeblockFrame (img, enc_picture->imgY, enc_picture->imgUV); //comment out to disable deblocking filter +} /*! ************************************************************************ * \brief @@ -194,13 +228,8 @@ void set_slice_type(int slice_type) * coding ************************************************************************ */ -void code_a_picture(Picture *pic) +static void code_a_picture(Picture *pic) { - unsigned int NumberOfCodedMBs = 0; - int SliceGroup = 0; - int j; - - int nplane; int pl; int idr_refresh; @@ -218,122 +247,39 @@ void code_a_picture(Picture *pic) || (idr_refresh && (img->type == I_SLICE || img->type==SI_SLICE)&& (!(img->structure==BOTTOM_FIELD))); pic->no_slices = 0; - pic->distortion_u = pic->distortion_v = pic->distortion_y = 0.0; RandomIntraNewPicture (); //! Allocates forced INTRA MBs (even for fields!) if( IS_INDEPENDENT( params ) ) { - for( pl=0; pl<MAX_PLANE; pl++ ){ + for( pl=0; pl<MAX_PLANE; pl++ ) + { img->current_mb_nr = 0; img->current_slice_nr = 0; img->SumFrameQP = 0; - SliceGroup = 0; - NumberOfCodedMBs = 0; img->colour_plane_id = pl; - - // The slice_group_change_cycle can be changed here. - // FmoInit() is called before coding each picture, frame or field - img->slice_group_change_cycle=1; - FmoInit(img, active_pps, active_sps); - FmoStartPicture (); //! picture level initialization of FMO - - CalculateQuantParam(); - CalculateOffsetParam(); - - if(params->Transform8x8Mode) - { - CalculateQuant8Param(); - CalculateOffset8Param(); - } - - reset_pic_bin_count(); - img->bytes_in_picture = 0; - - while (NumberOfCodedMBs < img->PicSizeInMbs) // loop over slices - { - // Encode one SLice Group - while (!FmoSliceGroupCompletelyCoded (SliceGroup)) - { - // Encode the current slice - NumberOfCodedMBs += encode_one_slice (SliceGroup, pic, NumberOfCodedMBs); - FmoSetLastMacroblockInSlice (img->current_mb_nr); - // Proceed to next slice - img->current_slice_nr++; - stats->bit_slice = 0; - } - // Proceed to next SliceGroup - SliceGroup++; - } - FmoEndPicture (); - } - } - else - { - // The slice_group_change_cycle can be changed here. - // FmoInit() is called before coding each picture, frame or field - img->slice_group_change_cycle=1; - FmoInit(img, active_pps, active_sps); - FmoStartPicture (); //! picture level initialization of FMO - - CalculateQuantParam(); - CalculateOffsetParam(); - - if(params->Transform8x8Mode) - { - CalculateQuant8Param(); - CalculateOffset8Param(); - } - - reset_pic_bin_count(); - img->bytes_in_picture = 0; - - while (NumberOfCodedMBs < img->PicSizeInMbs) // loop over slices - { - // Encode one SLice Group - while (!FmoSliceGroupCompletelyCoded (SliceGroup)) - { - // Encode the current slice - NumberOfCodedMBs += encode_one_slice (SliceGroup, pic, NumberOfCodedMBs); - FmoSetLastMacroblockInSlice (img->current_mb_nr); - // Proceed to next slice - img->current_slice_nr++; - stats->bit_slice = 0; - } - // Proceed to next SliceGroup - SliceGroup++; + + code_a_plane(img, pic); } - FmoEndPicture (); } - - if( IS_INDEPENDENT(params) ) - { - for( nplane=0; nplane<MAX_PLANE; nplane++ ) - { - change_plane_JV( nplane ); - // Modified for Fast Mode Decision. Inchoon Choi, SungKyunKwan Univ. - if (params->rdopt == 3 && (img->nal_reference_idc != 0)) - for (j = 0; j < params->NoOfDecoders; j++) - DeblockFrame (img, decs->decY_best[j], NULL); - - DeblockFrame (img, enc_picture->imgY, enc_picture->imgUV); //comment out to disable deblocking filter - } - } else { - // Modified for Fast Mode Decision. Inchoon Choi, SungKyunKwan Univ. - if ((params->rdopt == 3) && (img->nal_reference_idc != 0)) - for (j = 0; j < params->NoOfDecoders; j++) - DeblockFrame (img, decs->decY_best[j], NULL); - - DeblockFrame (img, enc_picture->imgY, enc_picture->imgUV); //comment out to disable deblocking filter + code_a_plane(img, pic); } if (img->MbaffFrameFlag) MbAffPostProc(); } - +void free_pictures(int stored_pic) +{ + int i; + for (i = 0; i < 6; i++) + { + if (i != stored_pic) + free_storable_picture(enc_frame_picture[i]); + } +} /*! ************************************************************************ @@ -350,7 +296,6 @@ int encode_one_frame (void) //Rate control int bits = 0; - int bits_frm = 0, bits_fld = 0; #ifdef _LEAKYBUCKET_ //extern long Bit_Buffer[20000]; @@ -360,9 +305,6 @@ int encode_one_frame (void) time_t ltime1, ltime2, tmp_time; struct TIMEB tstruct1, tstruct2; - float dis_frm = 0.0, dis_frm_y = 0.0, dis_frm_u = 0.0, dis_frm_v = 0.0; - float dis_fld = 0.0, dis_fld_y = 0.0, dis_fld_u = 0.0, dis_fld_v = 0.0; - me_time=0; img->rd_pass = 0; @@ -393,21 +335,18 @@ int encode_one_frame (void) UpdateRandomAccess (); */ - if ((params->ResendPPS) && (img->frm_number !=0)) { - stats->bit_ctr_parametersets_n=write_PPS(0, 0); - stats->bit_ctr_parametersets += stats->bit_ctr_parametersets_n; + stats->bit_ctr_parametersets_n = write_PPS(0, 0); + stats->bit_ctr_parametersets += stats->bit_ctr_parametersets_n; } - put_buffer_frame (); // sets the pointers to the frame structures + put_buffer_frame (img); // sets the pointers to the frame structures // (and not to one of the field structures) - init_frame (); - //FrameNumberInFile = CalculateFrameNumber(); + init_frame (img); ReadOneFrame (FrameNumberInFile, params->infile_header, ¶ms->source, ¶ms->output); - - PaddAutoCropBorders (params->output, img->width, img->height,img->width_cr, img->height_cr); + PaddAutoCropBorders (params->output, img->width, img->height, img->width_cr, img->height_cr); // set parameters for direct mode and deblocking filter img->direct_spatial_mv_pred_flag = params->direct_spatial_mv_pred_flag; @@ -419,13 +358,14 @@ int encode_one_frame (void) img->AdaptiveRounding = params->AdaptiveRounding; // Initialize quantization functions based on rounding/quantization method // Done here since we may wish to disable adaptive rounding on occasional intervals (even at a frame or gop level). - init_quant_4x4(img); - init_quant_8x8(img); + init_quant_4x4(params, img); + init_quant_8x8(params, img); + init_quant_Chroma(params, img); // Following code should consider optimal coding mode. Currently also does not support // multiple slices per frame. - frame_ctr[img->type]++; - snr->frame_ctr++; + + dist->frame_ctr++; if(img->type == SP_SLICE) { @@ -439,12 +379,19 @@ int encode_one_frame (void) { sp2_frame_indicator=0; } + if ( params->WPMCPrecision ) + { + wpxInitWPXPasses(params); + pWPX->curr_wp_rd_pass = pWPX->wp_rd_passes; + pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR; + } + if (params->PicInterlace == FIELD_CODING) { //Rate control if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE ) - generic_RC->FieldControl=1; + generic_RC->FieldControl = 1; img->field_picture = 1; // we encode fields field_picture (field_pic[0], field_pic[1]); @@ -455,7 +402,7 @@ int encode_one_frame (void) int tmpFrameQP; //Rate control if ( params->RCEnable && params->RCUpdateMode <= MAX_RC_MODE ) - generic_RC->FieldControl=0; + generic_RC->FieldControl = 0; // For frame coding, turn MB level field/frame coding flag on if (params->MbInterlace) @@ -465,7 +412,7 @@ int encode_one_frame (void) //Rate control if(params->RCEnable) - rc_init_frame(FrameNumberInFile); + rc_init_frame(FrameNumberInFile); if (params->GenerateMultiplePPS) active_pps = PicParSet[0]; @@ -476,6 +423,7 @@ int encode_one_frame (void) { rdPictureCoding(); } + tmpFrameQP = img->SumFrameQP; // call it here since rdPictureCoding buffers it and may modify it if ((img->type==SP_SLICE) && (si_frame_indicator==0) && (params->si_frame_indicator)) @@ -489,6 +437,7 @@ int encode_one_frame (void) // output the transformed and quantized coefficients (useful for switching SP frames) output_SP_coefficients(); } + // For field coding, turn MB level field/frame coding flag off if (params->MbInterlace) mb_adaptive = 0; @@ -504,11 +453,6 @@ int encode_one_frame (void) img->field_picture = 1; // we encode fields field_picture (field_pic[0], field_pic[1]); - //! Note: the distortion for a field coded picture is stored in the top field - //! the distortion values in the bottom field are dummies - dis_fld = field_pic[0]->distortion_y + field_pic[0]->distortion_u + field_pic[0]->distortion_v; - dis_frm = frame_pic[0]->distortion_y + frame_pic[0]->distortion_u + frame_pic[0]->distortion_v; - if(img->rd_pass == 0) img->fld_flag = picture_structure_decision (frame_pic[0], field_pic[0], field_pic[1]); else if(img->rd_pass == 1) @@ -527,31 +471,30 @@ int encode_one_frame (void) } else img->fld_flag = 0; + img->SumFrameQP = tmpFrameQP; } + stats->frame_counter++; + stats->frame_ctr[img->type]++; + if (img->fld_flag) stats->bit_ctr_emulationprevention += stats->em_prev_bits_fld; else stats->bit_ctr_emulationprevention += stats->em_prev_bits_frm; - if (img->type != B_SLICE) - { - img->pstruct_next_P = img->fld_flag; - } - // Here, img->structure may be either FRAME or BOTTOM FIELD depending on whether AFF coding is used // The picture structure decision changes really only the fld_flag if (img->fld_flag) // field mode (use field when fld_flag=1 only) { - field_mode_buffer (bits_fld, dis_fld_y, dis_fld_u, dis_fld_v); + field_mode_buffer (img, params); writeout_picture (field_pic[0]); writeout_picture (field_pic[1]); } else //frame mode { - frame_mode_buffer (bits_frm, dis_frm_y, dis_frm_u, dis_frm_v); + frame_mode_buffer (img, params); if (img->type==SP_SLICE && si_frame_indicator == 1) { @@ -601,71 +544,54 @@ int encode_one_frame (void) if (params->PicInterlace == FRAME_CODING) { if ((params->rdopt == 3) && (img->nal_reference_idc != 0)) - UpdateDecoders (); // simulate packet losses and move decoded image to reference buffers + { + UpdateDecoders (params, img, enc_picture); // simulate packet losses and move decoded image to reference buffers + } if (params->RestrictRef) UpdatePixelMap (); } - if (params->Verbose != 0) - { - find_snr (); - } - else - { - snr->snr_y = 0.0; - snr->snr_u = 0.0; - snr->snr_v = 0.0; - snr->sse_y = 0.0; - snr->sse_u = 0.0; - snr->sse_v = 0.0; - } + compute_distortion(); // redundant pictures: save reconstruction to calculate SNR and replace reference picture - if(params->redundant_pic_flag && key_frame) + + if(params->redundant_pic_flag) { - for(i=0; i<img->width; i++) + int k; + if(key_frame) { for(j=0; j<img->height; j++) { - imgY_tmp[j][i] = enc_frame_picture[0]->imgY[j][i]; + memcpy(imgY_tmp[j], enc_frame_picture[0]->imgY[j], img->width * sizeof(imgpel)); } - } - for(i=0; i<img->width_cr; i++) - { - for(j=0; j<img->height_cr; j++) + + for (k = 0; k < 2; k++) { - imgUV_tmp[0][j][i] = enc_frame_picture[0]->imgUV[0][j][i]; - imgUV_tmp[1][j][i] = enc_frame_picture[0]->imgUV[1][j][i]; + for(j=0; j<img->height_cr; j++) + { + memcpy(imgUV_tmp[k][j], enc_frame_picture[0]->imgUV[k][j], img->width_cr * sizeof(imgpel)); + } } } - } - if(params->redundant_pic_flag && redundant_coding) - { - for(i=0; i<img->width; i++) + if(redundant_coding) { for(j=0; j<img->height; j++) { - enc_frame_picture[0]->imgY[j][i] = imgY_tmp[j][i]; + memcpy(enc_frame_picture[0]->imgY[j], imgY_tmp[j], img->width * sizeof(imgpel)); } - } - for(i=0; i<img->width_cr; i++) - { - for(j=0; j<img->height_cr; j++) + for (k = 0; k < 2; k++) { - enc_frame_picture[0]->imgUV[0][j][i] = imgUV_tmp[0][j][i]; - enc_frame_picture[0]->imgUV[1][j][i] = imgUV_tmp[1][j][i]; + for(j=0; j<img->height_cr; j++) + { + memcpy(enc_frame_picture[0]->imgUV[k][j], imgUV_tmp[k][j], img->width_cr * sizeof(imgpel)); + } } } } - time (<ime2); // end time sec - ftime (&tstruct2); // end time ms - - tmp_time = (ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm); - tot_time = tot_time + tmp_time; - + if (params->PicInterlace == ADAPTIVE_CODING) { if (img->fld_flag) @@ -673,52 +599,48 @@ int encode_one_frame (void) // store bottom field store_picture_in_dpb(enc_field_picture[1]); free_storable_picture(enc_frame_picture[0]); + free_storable_picture(enc_frame_picture[1]); + free_storable_picture(enc_frame_picture[2]); } else { // replace top with frame - replace_top_pic_with_frame(enc_frame_picture[0]); - free_storable_picture(enc_field_picture[1]); - } - } - else - { - if (img->fld_flag) - { - store_picture_in_dpb(enc_field_picture[1]); - } - else - { if (img->rd_pass==2) { - store_picture_in_dpb(enc_frame_picture[2]); + replace_top_pic_with_frame(enc_frame_picture[2]); free_storable_picture(enc_frame_picture[0]); free_storable_picture(enc_frame_picture[1]); } else if (img->rd_pass==1) { - store_picture_in_dpb(enc_frame_picture[1]); + replace_top_pic_with_frame(enc_frame_picture[1]); free_storable_picture(enc_frame_picture[0]); free_storable_picture(enc_frame_picture[2]); } else { - if(params->redundant_pic_flag==0) + if(params->redundant_pic_flag==0 || (key_frame==0)) { - store_picture_in_dpb(enc_frame_picture[0]); + replace_top_pic_with_frame(enc_frame_picture[0]); free_storable_picture(enc_frame_picture[1]); free_storable_picture(enc_frame_picture[2]); } - else - { - // key picture will be stored in dpb after redundant picture is coded - if(key_frame==0) - { - store_picture_in_dpb(enc_frame_picture[0]); - free_storable_picture(enc_frame_picture[1]); - free_storable_picture(enc_frame_picture[2]); - } - } + } + free_storable_picture(enc_field_picture[1]); + } + } + else + { + if (img->fld_flag) + { + store_picture_in_dpb(enc_field_picture[1]); + } + else + { + if ((params->redundant_pic_flag != 1) || (key_frame == 0)) + { + store_picture_in_dpb (enc_frame_picture[img->rd_pass]); + free_pictures(img->rd_pass); } } } @@ -746,6 +668,12 @@ int encode_one_frame (void) prev_frame_no = frame_no; } + time (<ime2); // end time sec + ftime (&tstruct2); // end time ms + + tmp_time = (ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm); + tot_time = tot_time + tmp_time; + if (stats->bit_ctr_parametersets_n!=0) ReportNALNonVLCBits(tmp_time, me_time); @@ -768,19 +696,19 @@ int encode_one_frame (void) switch (img->type) { case I_SLICE: - stats->bit_ctr_I += stats->bit_ctr - stats->bit_ctr_n; + stats->bit_counter[I_SLICE] += stats->bit_ctr - stats->bit_ctr_n; ReportIntra(tmp_time,me_time); break; case SP_SLICE: - stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n; + stats->bit_counter[P_SLICE] += stats->bit_ctr - stats->bit_ctr_n; ReportSP(tmp_time,me_time); break; case B_SLICE: - stats->bit_ctr_B += stats->bit_ctr - stats->bit_ctr_n; + stats->bit_counter[B_SLICE] += stats->bit_ctr - stats->bit_ctr_n; ReportB(tmp_time,me_time); break; default: // P - stats->bit_ctr_P += stats->bit_ctr - stats->bit_ctr_n; + stats->bit_counter[P_SLICE] += stats->bit_ctr - stats->bit_ctr_n; ReportP(tmp_time,me_time); } } @@ -800,7 +728,7 @@ int encode_one_frame (void) rc_update_picture_ptr( bits ); stats->bit_ctr_n = stats->bit_ctr; - stats->bit_ctr_parametersets_n=0; + stats->bit_ctr_parametersets_n = 0; if ( img->type == I_SLICE && img->nal_reference_idc) { @@ -886,7 +814,7 @@ void copy_params(void) * Prepare and allocate an encoded frame picture structure ************************************************************************ */ -void prepare_enc_frame_picture (StorablePicture **stored_pic) +static void prepare_enc_frame_picture (StorablePicture **stored_pic) { (*stored_pic) = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr); @@ -907,6 +835,21 @@ void prepare_enc_frame_picture (StorablePicture **stored_pic) copy_params(); } +static void calc_picture_bits(Picture *frame) +{ + int i, j; + Slice *thisSlice = NULL; + + frame->bits_per_picture = 0; + + for ( i = 0; i < frame->no_slices; i++ ) + { + thisSlice = frame->slices[i]; + + for ( j = 0; j < thisSlice->max_part_nr; j++ ) + frame->bits_per_picture += 8 * ((thisSlice->partArr[j]).bitstream)->byte_pos; + } +} /*! ************************************************************************ * \brief @@ -922,39 +865,18 @@ void frame_picture (Picture *frame, int rd_pass) //set mv limits to frame type update_mv_limits(img, 0); - if ( rd_pass == 2 ) - prepare_enc_frame_picture( &enc_frame_picture[2] ); - else if ( rd_pass == 1 ) - prepare_enc_frame_picture( &enc_frame_picture[1] ); - else + if( IS_INDEPENDENT(params) ) { - if( IS_INDEPENDENT(params) ) + for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - for( nplane=0; nplane<MAX_PLANE; nplane++ ) - { - enc_frame_picture_JV[nplane] = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr); - img->ThisPOC=enc_frame_picture_JV[nplane]->poc=img->framepoc; - enc_frame_picture_JV[nplane]->top_poc = img->toppoc; - enc_frame_picture_JV[nplane]->bottom_poc = img->bottompoc; - enc_frame_picture_JV[nplane]->frame_poc = img->framepoc; - - enc_frame_picture_JV[nplane]->pic_num = img->frame_num; - enc_frame_picture_JV[nplane]->frame_num = img->frame_num; - enc_frame_picture_JV[nplane]->coded_frame = 1; - - enc_frame_picture_JV[nplane]->MbaffFrameFlag = img->MbaffFrameFlag = (params->MbInterlace != FRAME_CODING); - get_mb_block_pos = img->MbaffFrameFlag ? get_mb_block_pos_mbaff : get_mb_block_pos_normal; - getNeighbour = img->MbaffFrameFlag ? getAffNeighbour : getNonAffNeighbour; - - enc_picture=enc_frame_picture_JV[nplane]; - copy_params(); - } + prepare_enc_frame_picture( &enc_frame_picture_JV[nplane] ); } - else - { - prepare_enc_frame_picture( &enc_frame_picture[0] ); - } } + else + { + prepare_enc_frame_picture( &enc_frame_picture[rd_pass] ); + } + stats->em_prev_bits_frm = 0; stats->em_prev_bits = &stats->em_prev_bits_frm; @@ -967,14 +889,12 @@ void frame_picture (Picture *frame, int rd_pass) make_frame_picture_JV(); } - frame->bits_per_picture = 8 * ((((img->currentSlice)->partArr[0]).bitstream)->byte_pos); + calc_picture_bits(frame); if (img->structure==FRAME) { find_distortion (); - frame->distortion_y = snr->snr_y; - frame->distortion_u = snr->snr_u; - frame->distortion_v = snr->snr_v; + frame->distortion = dist->metric[SSE]; } } @@ -985,7 +905,7 @@ void frame_picture (Picture *frame, int rd_pass) * Encodes a field picture, consisting of top and bottom field ************************************************************************ */ -void field_picture (Picture *top, Picture *bottom) +static void field_picture (Picture *top, Picture *bottom) { //Rate control int old_pic_type; // picture type of top field used for rate control @@ -1022,8 +942,8 @@ void field_picture (Picture *top, Picture *bottom) enc_picture = enc_field_picture[0]; copy_params(); - put_buffer_top (); - init_field (); + put_buffer_top (img); + init_field (img); if (img->type == B_SLICE) //all I- and P-frames nextP_tr_fld--; @@ -1039,7 +959,7 @@ void field_picture (Picture *top, Picture *bottom) store_picture_in_dpb(enc_field_picture[0]); - top->bits_per_picture = 8 * ((((img->currentSlice)->partArr[0]).bitstream)->byte_pos); + calc_picture_bits(top); //Rate control TopFieldBits=top->bits_per_picture; @@ -1059,10 +979,10 @@ void field_picture (Picture *top, Picture *bottom) img->structure = BOTTOM_FIELD; enc_picture = enc_field_picture[1]; copy_params(); - put_buffer_bot (); + put_buffer_bot (img); img->number++; - init_field (); + init_field (img); if (img->type == B_SLICE) //all I- and P-frames nextP_tr_fld++; //check once coding B field @@ -1079,12 +999,11 @@ void field_picture (Picture *top, Picture *bottom) enc_picture->structure = (PictureStructure) 2; code_a_picture(field_pic[1]); - bottom->bits_per_picture = 8 * ((((img->currentSlice)->partArr[0]).bitstream)->byte_pos); + calc_picture_bits(bottom); // the distortion for a field coded frame (consisting of top and bottom field) // lives in the top->distortion variables, the bottom-> are dummies - distortion_fld (&top->distortion_y, &top->distortion_u, &top->distortion_v); - + distortion_fld (top); } @@ -1094,7 +1013,7 @@ void field_picture (Picture *top, Picture *bottom) * Distortion Field ************************************************************************ */ -static void distortion_fld (float *dis_fld_y, float *dis_fld_u, float *dis_fld_v) +static void distortion_fld (Picture *field_pic) { img->number /= 2; @@ -1104,21 +1023,17 @@ static void distortion_fld (float *dis_fld_y, float *dis_fld_u, float *dis_fld_v combine_field (); - pCurImg = imgY_org_frm; - imgUV_org = imgUV_org_frm; + pCurImg = img_org_frm[0]; + pImgOrg[0] = img_org_frm[0]; - pImgOrg[0] = imgY_org_frm; if (params->yuv_format != YUV400) { - pImgOrg[1] = imgUV_org_frm[0]; - pImgOrg[2] = imgUV_org_frm[1]; + pImgOrg[1] = img_org_frm[1]; + pImgOrg[2] = img_org_frm[2]; } find_distortion (); // find snr from original frame picture - - *dis_fld_y = snr->snr_y; - *dis_fld_u = snr->snr_u; - *dis_fld_v = snr->snr_v; + field_pic->distortion = dist->metric[SSE]; } @@ -1132,17 +1047,18 @@ static int picture_structure_decision (Picture *frame, Picture *top, Picture *bo { double lambda_picture; int bframe = (img->type == B_SLICE); - float snr_frame, snr_field; + float sse_frame, sse_field; int bit_frame, bit_field; lambda_picture = 0.68 * pow (2, img->bitdepth_lambda_scale + ((img->qp - SHIFT_QP) / 3.0)) * (bframe ? 1 : 1); - snr_frame = frame->distortion_y + frame->distortion_u + frame->distortion_v; + sse_frame = frame->distortion.value[0] + frame->distortion.value[1] + frame->distortion.value[2]; //! all distrortions of a field picture are accumulated in the top field - snr_field = top->distortion_y + top->distortion_u + top->distortion_v; + sse_field = top->distortion.value[0] + top->distortion.value[1] + top->distortion.value[2]; + bit_field = top->bits_per_picture + bot->bits_per_picture; bit_frame = frame->bits_per_picture; - return decide_fld_frame (snr_frame, snr_field, bit_field, bit_frame, lambda_picture); + return decide_fld_frame (sse_frame, sse_field, bit_field, bit_frame, lambda_picture); } @@ -1152,13 +1068,9 @@ static int picture_structure_decision (Picture *frame, Picture *top, Picture *bo * Field Mode Buffer ************************************************************************ */ -static void field_mode_buffer (int bit_field, float snr_field_y, float snr_field_u, float snr_field_v) +static void field_mode_buffer (ImageParameters *img, InputParameters *params) { - put_buffer_frame (); - - snr->snr_y = snr_field_y; - snr->snr_u = snr_field_u; - snr->snr_v = snr_field_v; + put_buffer_frame (img); } @@ -1168,9 +1080,9 @@ static void field_mode_buffer (int bit_field, float snr_field_y, float snr_field * Frame Mode Buffer ************************************************************************ */ -static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v) +static void frame_mode_buffer (ImageParameters *img, InputParameters *params) { - put_buffer_frame (); + put_buffer_frame (img); if ((params->PicInterlace != FRAME_CODING)||(params->MbInterlace != FRAME_CODING)) { @@ -1178,20 +1090,16 @@ static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame img->height_cr = img->height_cr / 2; img->number *= 2; - put_buffer_top (); + put_buffer_top (img); img->number++; - put_buffer_bot (); + put_buffer_bot (img); img->number /= 2; // reset the img->number to field img->height = (params->output.height + img->auto_crop_bottom); img->height_cr = img->height_cr_frame; - snr->snr_y = snr_frame_y; - snr->snr_u = snr_frame_u; - snr->snr_v = snr_frame_v; - put_buffer_frame (); - + put_buffer_frame (img); } } @@ -1214,7 +1122,7 @@ static void init_dec_ref_pic_marking_buffer(void) * Initializes the parameters for a new frame ************************************************************************ */ -static void init_frame (void) +static void init_frame (ImageParameters *img) { int i, j; int prevP_no, nextP_no; @@ -1242,16 +1150,13 @@ static void init_frame (void) else { for(i=0;i< ((int) (img->FrameSizeInMbs));i++) - img->mb_data[i].slice_nr=-1; + img->mb_data[i].slice_nr = -1; } if (img->b_frame_to_code == 0) { img->tr = start_tr_in_this_IGOP + IMG_NUMBER * (params->jumpd + 1); - img->imgtr_last_P_frm = img->imgtr_next_P_frm; - img->imgtr_next_P_frm = img->tr; - #ifdef _ADAPT_LAST_GROUP_ if (params->last_frame && img->frm_number + 1 == params->no_frames) img->tr = params->last_frame; @@ -1405,7 +1310,7 @@ static void init_frame (void) * Initializes the parameters for a new field ************************************************************************ */ -static void init_field (void) +static void init_field (ImageParameters *img) { int i; int prevP_no, nextP_no; @@ -1429,12 +1334,6 @@ static void init_field (void) { img->tr = img->number * (params->jumpd + 2) + img->fld_type; - if (!img->fld_type) - { - img->imgtr_last_P_fld = img->imgtr_next_P_fld; - img->imgtr_next_P_fld = img->tr; - } - #ifdef _ADAPT_LAST_GROUP_ if (params->last_frame && img->number + 1 == params->no_frames) img->tr = params->last_frame; @@ -1494,6 +1393,7 @@ static void init_field (void) img->p_interval = params->jumpd + 2; prevP_no = (img->number - 1) * img->p_interval + img->fld_type; nextP_no = img->number * img->p_interval + img->fld_type; + #ifdef _ADAPT_LAST_GROUP_ if (!img->fld_type) // top field { @@ -1522,6 +1422,7 @@ static void init_field (void) img->p_interval = nextP_no - prevP_no; } #endif + img->b_interval = ((double) (params->jumpd + 1) / (params->successive_Bframe + 1.0) ); @@ -1551,6 +1452,7 @@ static void init_field (void) img->qp = params->qpB; if (img->nal_reference_idc) { + #ifdef _CHANGE_QP_ //QP oscillation for secondary SP frames if ((params->qp2start > 0 && img->tr >= params->qp2start && params->sp2_frame_indicator==0)|| @@ -1711,203 +1613,6 @@ void UnifiedOneForthPix_JV (int nplane, StorablePicture *s) getSubImagesLuma ( s ); } -/*! - ************************************************************************ - * \brief - * Find SNR for all three components - ************************************************************************ - */ -static void find_snr (void) -{ - int i; - imgpel **curCmp = pCurImg, **curRef = imgY_com; - - int64 diff_cmp[3] = {0}; - int impix = params->output.size_cmp[0]; - int impix_cr = params->output.size_cmp[1]; - unsigned int max_pix_value_sqd = img->max_imgpel_value_comp[0] * img->max_imgpel_value_comp[0]; - unsigned int max_pix_value_sqd_uv = img->max_imgpel_value_comp[1] * img->max_imgpel_value_comp[1]; - - // Calculate PSNR for Y, U and V. - // Luma. - if (img->fld_flag != 0) - { - diff_cmp[0] += compute_SSE(curCmp, curRef, 0, 0, params->output.height, params->output.width); - - if (img->yuv_format != YUV400) - { - // Chroma. - diff_cmp[1] += compute_SSE(imgUV_org[0], imgUV_com[0], 0, 0, params->output.height_cr, params->output.width_cr); - diff_cmp[2] += compute_SSE(imgUV_org[1], imgUV_com[1], 0, 0, params->output.height_cr, params->output.width_cr); - } - } - else - { - if( IS_INDEPENDENT(params) ) - { - pCurImg = imgY_org_frm_JV[0]; - } - else - { - pCurImg = imgY_org_frm; - imgUV_org = imgUV_org_frm; - pImgOrg[0] = imgY_org_frm; - } - - curCmp = pCurImg; - if(params->PicInterlace==ADAPTIVE_CODING || IS_INDEPENDENT(params)) - { - enc_picture = enc_frame_picture[0]; - } - curRef = enc_picture->imgY; - - diff_cmp[0] += compute_SSE(curCmp, curRef, 0, 0, params->output.height, params->output.width); - - if (img->yuv_format != YUV400) - { - // Chroma. - if( !IS_INDEPENDENT(params) ) - { - pImgOrg[1] = imgUV_org_frm[0]; - pImgOrg[2] = imgUV_org_frm[1]; - } - diff_cmp[1] += compute_SSE(pImgOrg[1], enc_picture->imgUV[0], 0, 0, params->output.height_cr, params->output.width_cr); - diff_cmp[2] += compute_SSE(pImgOrg[2], enc_picture->imgUV[1], 0, 0, params->output.height_cr, params->output.width_cr); - } - } - snr->sse_y = (float)diff_cmp[0]; - snr->sse_u = (float)diff_cmp[1]; - snr->sse_v = (float)diff_cmp[2]; - -#if ZEROSNR - if (diff_cmp[0] == 0) - diff_cmp[0] = 1; - if (diff_cmp[1] == 0) - diff_cmp[1] = 1; - if (diff_cmp[2] == 0) - diff_cmp[2] = 1; -#endif - - // Collecting SNR statistics - if (diff_cmp[0] != 0) - { - snr->snr_y = (float) (10 * log10 (max_pix_value_sqd * (double)((double) impix / diff_cmp[0]))); // luma snr for current frame - if (img->yuv_format != YUV400) - { - snr->snr_u = (float) (10 * log10 (max_pix_value_sqd_uv * (double)((double) impix_cr / diff_cmp[1]))); // u croma snr for current frame, 1/4 of luma samples - snr->snr_v = (float) (10 * log10 (max_pix_value_sqd_uv * (double)((double) impix_cr / diff_cmp[2]))); // v croma snr for current frame, 1/4 of luma samples - } - else - { - snr->snr_u = 0.0; - snr->snr_v = 0.0; - } - } - - - if (img->number == 0) - { - snr->snr_y1 = snr->snr_y; // keep luma snr for first frame - snr->snr_u1 = snr->snr_u; // keep croma u snr for first frame - snr->snr_v1 = snr->snr_v; // keep croma v snr for first frame - snr->snr_ya = snr->snr_y1; - snr->snr_ua = snr->snr_u1; - snr->snr_va = snr->snr_v1; - // sse stats - snr->msse_y = snr->sse_y; - snr->msse_u = snr->sse_u; - snr->msse_v = snr->sse_v; - for (i=0; i<5; i++) - { - snr->snr_yt[i] = 0.0; - snr->snr_ut[i] = 0.0; - snr->snr_vt[i] = 0.0; - } - } - else - { - //int total_frames = img->number + frame_ctr[B_SLICE]; - int total_frames = snr->frame_ctr - 1; - - snr->snr_ya = (float) (snr->snr_ya * total_frames + snr->snr_y) / (total_frames + 1); // average snr luma for all frames inc. first - snr->snr_ua = (float) (snr->snr_ua * total_frames + snr->snr_u) / (total_frames + 1); // average snr u croma for all frames inc. first - snr->snr_va = (float) (snr->snr_va * total_frames + snr->snr_v) / (total_frames + 1); // average snr v croma for all frames inc. first - snr->msse_y = (float) (snr->msse_y * total_frames + snr->sse_y) / (total_frames + 1); // average sse luma for all frames inc. first - snr->msse_u = (float) (snr->msse_u * total_frames + snr->sse_u) / (total_frames + 1); // average sse u croma for all frames inc. first - snr->msse_v = (float) (snr->msse_v * total_frames + snr->sse_v) / (total_frames + 1); // average sse v croma for all frames inc. first - } - - snr->snr_yt[img->type] = (float) (snr->snr_yt[img->type] * (frame_ctr[img->type] - 1) + snr->snr_y) / ( frame_ctr[img->type] ); // average luma snr for img->type coded frames - snr->snr_ut[img->type] = (float) (snr->snr_ut[img->type] * (frame_ctr[img->type] - 1) + snr->snr_u) / ( frame_ctr[img->type] ); // average chroma u snr for img->type coded frames - snr->snr_vt[img->type] = (float) (snr->snr_vt[img->type] * (frame_ctr[img->type] - 1) + snr->snr_v) / ( frame_ctr[img->type] ); // average chroma v snr for img->type coded frames -} - - - -/*! - ************************************************************************ - * \brief - * Find distortion for all three components - ************************************************************************ - */ -static void find_distortion (void) -{ - int64 diff_cmp[3] = {0}; - - // Calculate PSNR for Y, U and V. - - // Luma. - if (img->structure!=FRAME) - { - diff_cmp[0] += compute_SSE(pCurImg, imgY_com, 0, 0, params->output.height, params->output.width); - - if (img->yuv_format != YUV400) - { - // Chroma. - diff_cmp[1] += compute_SSE(imgUV_org[0], imgUV_com[0], 0, 0, params->output.height_cr, params->output.width_cr); - diff_cmp[2] += compute_SSE(imgUV_org[1], imgUV_com[1], 0, 0, params->output.height_cr, params->output.width_cr); - } - } - else - { - if( IS_INDEPENDENT(params) ) - { - pCurImg = imgY_org_frm_JV[0]; - enc_picture = enc_frame_picture[0]; - pImgOrg[0] = imgY_org_frm_JV[0]; - } - else - { - pCurImg = imgY_org_frm; - imgUV_org = imgUV_org_frm; - pImgOrg[0] = imgY_org_frm; - } - - diff_cmp[0] += compute_SSE(pCurImg, enc_picture->imgY, 0, 0, params->output.height, params->output.width); - - if (img->yuv_format != YUV400) - { - // Chroma. - if( IS_INDEPENDENT(params) ) - { - pImgOrg[1] = imgY_org_frm_JV[1]; - pImgOrg[2] = imgY_org_frm_JV[2]; - } - else - { - pImgOrg[1] = imgUV_org_frm[0]; - pImgOrg[2] = imgUV_org_frm[1]; - } - - diff_cmp[1] += compute_SSE(pImgOrg[1], enc_picture->imgUV[0], 0, 0, params->output.height_cr, params->output.width_cr); - diff_cmp[2] += compute_SSE(pImgOrg[2], enc_picture->imgUV[1], 0, 0, params->output.height_cr, params->output.width_cr); - } - } - // Calculate real PSNR at find_snr_avg() - snr->snr_y = (float) diff_cmp[0]; - snr->snr_u = (float) diff_cmp[1]; - snr->snr_v = (float) diff_cmp[2]; -} /*! @@ -1922,6 +1627,13 @@ Boolean dummy_slice_too_big (int bits_slice) } +static inline void copy_motion_vectors_MB (ImageParameters *img, RD_DATA *rdopt) +{ + memcpy(&img->all_mv [LIST_0][0][0][0][0][0], &rdopt->all_mv [LIST_0][0][0][0][0][0], 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short)); + memcpy(&img->pred_mv[LIST_0][0][0][0][0][0], &rdopt->pred_mv[LIST_0][0][0][0][0][0], 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short)); +} + + /*! *************************************************************************** // For MB level field/frame coding @@ -1942,7 +1654,6 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) currMB->mb_type = rdopt->mb_type; // copy mb_type currMB->cbp = rdopt->cbp; // copy cbp currMB->cbp_blk = rdopt->cbp_blk; // copy cbp_blk - currMB->bi_pred_me = rdopt->bi_pred_me; // copy biprediction img->i16offset = rdopt->i16offset; currMB->prev_qp = rdopt->prev_qp; @@ -1950,7 +1661,7 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) currMB->prev_cbp = rdopt->prev_cbp; currMB->delta_qp = rdopt->delta_qp; currMB->qp = rdopt->qp; - update_qp(currMB); + update_qp (img, currMB); currMB->c_ipred_mode = rdopt->c_ipred_mode; @@ -1960,20 +1671,20 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) for (j = 0; j < BLOCK_MULTIPLE; j++) { block_y = img->block_y + j; - memcpy(&enc_picture->ref_idx[LIST_0][block_y][img->block_x], rdopt->refar[LIST_0][j], BLOCK_MULTIPLE * sizeof(char)); + memcpy(&enc_picture->motion.ref_idx[LIST_0][block_y][img->block_x], rdopt->refar[LIST_0][j], BLOCK_MULTIPLE * sizeof(char)); for (i = 0; i < BLOCK_MULTIPLE; i++) - enc_picture->ref_pic_id [LIST_0][block_y][img->block_x + i] = - enc_picture->ref_pic_num[LIST_0 + list_offset][(short)enc_picture->ref_idx[LIST_0][block_y][img->block_x+i]]; + enc_picture->motion.ref_pic_id [LIST_0][block_y][img->block_x + i] = + enc_picture->ref_pic_num[LIST_0 + list_offset][(short)enc_picture->motion.ref_idx[LIST_0][block_y][img->block_x+i]]; } if (bframe) { for (j = 0; j < BLOCK_MULTIPLE; j++) { block_y = img->block_y + j; - memcpy(&enc_picture->ref_idx[LIST_1][block_y][img->block_x], rdopt->refar[LIST_1][j], BLOCK_MULTIPLE * sizeof(char)); + memcpy(&enc_picture->motion.ref_idx[LIST_1][block_y][img->block_x], rdopt->refar[LIST_1][j], BLOCK_MULTIPLE * sizeof(char)); for (i = 0; i < BLOCK_MULTIPLE; i++) - enc_picture->ref_pic_id [LIST_1][block_y][img->block_x + i] = - enc_picture->ref_pic_num[LIST_1 + list_offset][(short)enc_picture->ref_idx[LIST_1][block_y][img->block_x+i]]; + enc_picture->motion.ref_pic_id [LIST_1][block_y][img->block_x + i] = + enc_picture->ref_pic_num[LIST_1 + list_offset][(short)enc_picture->motion.ref_idx[LIST_1][block_y][img->block_x + i]]; } } @@ -1985,13 +1696,13 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) { for (j = 0; j < img->mb_cr_size_y; j++) { - memcpy(&enc_picture->imgUV[0][img->pix_c_y + j][img->pix_c_x],rdopt->rec_mb_cr[0][j], img->mb_cr_size_x * sizeof(imgpel)); - memcpy(&enc_picture->imgUV[1][img->pix_c_y + j][img->pix_c_x],rdopt->rec_mb_cr[1][j], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[0][img->pix_c_y + j][img->pix_c_x], rdopt->rec_mb_cr[0][j], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[1][img->pix_c_y + j][img->pix_c_x], rdopt->rec_mb_cr[1][j], img->mb_cr_size_x * sizeof(imgpel)); } } - memcpy(currMB->b8mode,rdopt->b8mode, 4 * sizeof(short)); - memcpy(currMB->b8pdir,rdopt->b8pdir, 4 * sizeof(short)); + memcpy(currMB->b8mode, rdopt->b8mode, 4 * sizeof(short)); + memcpy(currMB->b8pdir, rdopt->b8pdir, 4 * sizeof(short)); currMB->luma_transform_size_8x8_flag = rdopt->luma_transform_size_8x8_flag; @@ -2022,7 +1733,7 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) { // motion vectors - copy_motion_vectors_MB (); + copy_motion_vectors_MB (img, rdopt); if (!IS_INTRA(currMB)) { @@ -2034,25 +1745,25 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) if (b8pdir!=1) { - enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][0] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i][0]; - enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][1] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i][1]; + enc_picture->motion.mv[LIST_0][j+img->block_y][i+img->block_x][0] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i][0]; + enc_picture->motion.mv[LIST_0][j+img->block_y][i+img->block_x][1] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i][1]; } else { - enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][0] = 0; - enc_picture->mv[LIST_0][j+img->block_y][i+img->block_x][1] = 0; + enc_picture->motion.mv[LIST_0][j+img->block_y][i+img->block_x][0] = 0; + enc_picture->motion.mv[LIST_0][j+img->block_y][i+img->block_x][1] = 0; } if (bframe) { if (b8pdir!=0) { - enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][0] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i][0]; - enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][1] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i][1]; + enc_picture->motion.mv[LIST_1][j+img->block_y][i+img->block_x][0] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i][0]; + enc_picture->motion.mv[LIST_1][j+img->block_y][i+img->block_x][1] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i][1]; } else { - enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][0] = 0; - enc_picture->mv[LIST_1][j+img->block_y][i+img->block_x][1] = 0; + enc_picture->motion.mv[LIST_1][j+img->block_y][i+img->block_x][0] = 0; + enc_picture->motion.mv[LIST_1][j+img->block_y][i+img->block_x][1] = 0; } } } @@ -2060,26 +1771,19 @@ void copy_rdopt_data (Macroblock *currMB, int bot_block) else { for (j = 0; j < 4; j++) - memset(enc_picture->mv[LIST_0][j+img->block_y][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short)); + memset(enc_picture->motion.mv[LIST_0][j+img->block_y][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short)); if (bframe) { for (j = 0; j < 4; j++) - memset(enc_picture->mv[LIST_1][j+img->block_y][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short)); + memset(enc_picture->motion.mv[LIST_1][j+img->block_y][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short)); } } } -} // end of copy_rdopt_data +} // end of copy_rdopt_data -static void copy_motion_vectors_MB (void) -{ - memcpy(&img->all_mv[LIST_0][0][0][0][0][0], &rdopt->all_mv[LIST_0][0][0][0][0][0], 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short)); - - memcpy(&img->pred_mv[LIST_0][0][0][0][0][0], &rdopt->pred_mv[LIST_0][0][0][0][0][0], 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short)); -} static void ReportNALNonVLCBits(time_t tmp_time, time_t me_time) { - //! Need to add type (i.e. SPS, PPS, SEI etc). if (params->Verbose != 0) printf ("%04d(NVB)%8d \n", frame_no, stats->bit_ctr_parametersets_n); @@ -2091,19 +1795,25 @@ static void ReportFirstframe(time_t tmp_time, time_t me_time) { printf ("%04d(IDR)%8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } else if (params->Verbose == 2) { int lambda = (int) img->lambda_me[I_SLICE][img->AverageFrameQP][0]; - printf ("%04d(IDR)%8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", + if (params->Distortion[SSIM] == 1) + printf ("%04d(IDR)%8d %1d %2d %2d %7.3f %7.3f %7.3f %7.4f %7.4f %7.4f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no,(int) (stats->bit_ctr - stats->bit_ctr_n),0, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], dist->metric[SSIM].value[0], dist->metric[SSIM].value[1], dist->metric[SSIM].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + else + printf ("%04d(IDR)%8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", frame_no,(int) (stats->bit_ctr - stats->bit_ctr_n),0, - img->AverageFrameQP, lambda, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); } - stats->bit_ctr_I = stats->bit_ctr; + stats->bit_counter[I_SLICE] = stats->bit_ctr; stats->bit_ctr = 0; } @@ -2111,31 +1821,48 @@ static void ReportIntra(time_t tmp_time, time_t me_time) { if (params->Verbose == 1) { - if (img->currentPicture->idr_flag == 1) + if (img->currentPicture->idr_flag == 1) printf ("%04d(IDR)%8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); else printf ("%04d(I) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } else if (params->Verbose == 2) { int lambda = (int) img->lambda_me[I_SLICE][img->AverageFrameQP][0]; - if (img->currentPicture->idr_flag == 1) - printf ("%04d(IDR)%8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", - frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), 0, - img->AverageFrameQP, lambda, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, - img->fld_flag ? "FLD" : "FRM", intras, - img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + if (params->Distortion[SSIM] == 1) + { + if (img->currentPicture->idr_flag == 1) + printf ("%04d(IDR)%8d %1d %2d %2d %7.3f %7.3f %7.3f %7.4f %7.4f %7.4f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), 0, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], dist->metric[SSIM].value[0], dist->metric[SSIM].value[1], dist->metric[SSIM].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, + img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + else + printf ("%04d(I) %8d %1d %2d %2d %7.3f %7.3f %7.3f %7.4f %7.4f %7.4f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), 0, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], dist->metric[SSIM].value[0], dist->metric[SSIM].value[1], dist->metric[SSIM].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + } else - printf ("%04d(I) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", - frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), 0, - img->AverageFrameQP, lambda, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, - img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + { + if (img->currentPicture->idr_flag == 1) + printf ("%04d(IDR)%8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), 0, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, + img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + else + printf ("%04d(I) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), 0, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + } } } @@ -2145,15 +1872,21 @@ static void ReportSP(time_t tmp_time, time_t me_time) { printf ("%04d(SP) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } else if (params->Verbose == 2) { int lambda = (int) img->lambda_me[SP_SLICE][img->AverageFrameQP][0]; - printf ("%04d(SP) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", + if (params->Distortion[SSIM] == 1) + printf ("%04d(SP) %8d %1d %2d %2d %7.3f %7.3f %7.3f %7.4f %7.4f %7.4f %9d %7d %3s %5d %2d %2d %d %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_pred_flag, - img->AverageFrameQP, lambda, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], dist->metric[SSIM].value[0], dist->metric[SSIM].value[1], dist->metric[SSIM].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + else + printf ("%04d(SP) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_pred_flag, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); } } @@ -2163,18 +1896,26 @@ static void ReportB(time_t tmp_time, time_t me_time) if (params->Verbose == 1) { printf ("%04d(B) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", - frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, - img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } else if (params->Verbose == 2) { int lambda = (int) img->lambda_me[img->nal_reference_idc ? 5 : B_SLICE][img->AverageFrameQP][0]; - printf ("%04d(B) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %1d %2d %2d %d %d\n", - frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_bipred_idc, - img->AverageFrameQP, lambda, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, - img->fld_flag ? "FLD" : "FRM",intras,img->direct_spatial_mv_pred_flag, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active,img->rd_pass, img->nal_reference_idc); + if (params->Distortion[SSIM] == 1) + printf ("%04d(B) %8d %1d %2d %2d %7.3f %7.3f %7.3f %7.4f %7.4f %7.4f %9d %7d %3s %5d %1d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_bipred_idc, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], dist->metric[SSIM].value[0], dist->metric[SSIM].value[1], dist->metric[SSIM].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->direct_spatial_mv_pred_flag, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active, img->rd_pass, img->nal_reference_idc); + else + printf ("%04d(B) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %1d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_bipred_idc, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->direct_spatial_mv_pred_flag, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active, img->rd_pass, img->nal_reference_idc); } + + } @@ -2186,7 +1927,7 @@ static void ReportP(time_t tmp_time, time_t me_time) { printf ("%04d(P) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } else @@ -2195,14 +1936,14 @@ static void ReportP(time_t tmp_time, time_t me_time) { printf ("%04d(P) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } else { // report a redundant picture. printf (" (R) %8d %2d %7.3f %7.3f %7.3f %9d %7d %3s %d\n", (int) (stats->bit_ctr - stats->bit_ctr_n), - img->AverageFrameQP, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", img->nal_reference_idc); } } @@ -2210,9 +1951,15 @@ static void ReportP(time_t tmp_time, time_t me_time) else if (params->Verbose == 2) { int lambda = (int) img->lambda_me[P_SLICE][img->AverageFrameQP][0]; - printf ("%04d(P) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", + if (params->Distortion[SSIM] == 1) + printf ("%04d(P) %8d %1d %2d %2d %7.3f %7.3f %7.3f %7.4f %7.4f %7.4f %9d %7d %3s %5d %2d %2d %d %d\n", + frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_pred_flag, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], dist->metric[SSIM].value[0], dist->metric[SSIM].value[1], dist->metric[SSIM].value[2], (int)tmp_time, (int)me_time, + img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active, img->rd_pass, img->nal_reference_idc); + else + printf ("%04d(P) %8d %1d %2d %2d %7.3f %7.3f %7.3f %9d %7d %3s %5d %2d %2d %d %d\n", frame_no, (int) (stats->bit_ctr - stats->bit_ctr_n), active_pps->weighted_pred_flag, - img->AverageFrameQP, lambda, snr->snr_y, snr->snr_u, snr->snr_v, (int)tmp_time, (int)me_time, + img->AverageFrameQP, lambda, dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2], (int)tmp_time, (int)me_time, img->fld_flag ? "FLD" : "FRM", intras, img->num_ref_idx_l0_active, img->num_ref_idx_l1_active, img->rd_pass, img->nal_reference_idc); } } @@ -2223,18 +1970,12 @@ static void ReportP(time_t tmp_time, time_t me_time) * Padding of automatically added border for picture sizes that are not * multiples of macroblock/macroblock pair size * - * \param org_size_x - * original image horizontal size (luma) - * \param org_size_y - * original image vertical size (luma) + * \param output + * Image dimensions * \param img_size_x * coded image horizontal size (luma) * \param img_size_y * code image vertical size (luma) - * \param org_size_x_cr - * original image horizontal size (chroma) - * \param org_size_y_cr - * original image vertical size (chroma) * \param img_size_x_cr * coded image horizontal size (chroma) * \param img_size_y_cr @@ -2255,8 +1996,7 @@ static void PaddAutoCropBorders (FrameFormat output, int img_size_x, int img_siz //padding bottom border if (output.height < img_size_y) for (y = output.height; y<img_size_y; y++) - for (x=0; x<img_size_x; x++) - pImgOrg[0] [y][x] = pImgOrg[0] [y-1][x]; + memcpy(pImgOrg[0][y], pImgOrg[0][y - 1], img_size_x * sizeof(imgpel)); // Chroma or all other components if (img->yuv_format != YUV400) @@ -2274,8 +2014,7 @@ static void PaddAutoCropBorders (FrameFormat output, int img_size_x, int img_siz //padding bottom border if (output.height_cr < img_size_y_cr) for (y = output.height_cr; y<img_size_y_cr; y++) - for (x=0; x<img_size_x_cr; x++) - pImgOrg[k][y][x] = pImgOrg[k][y-1][x]; + memcpy(pImgOrg[k][y], pImgOrg[k][y - 1], img_size_x_cr * sizeof(imgpel)); } } } @@ -2329,7 +2068,7 @@ int CalculateFrameNumber(void) frame_no = start_tr_in_this_IGOP + (frm_sign * IMG_NUMBER + delay) * (params->jumpd + 1); #ifdef _ADAPT_LAST_GROUP_ - if (params->last_frame && img->frm_number + 1 == params->no_frames) + if (params->last_frame && (img->frm_number + 1) == params->no_frames) frame_no = params->last_frame; #endif } @@ -2346,28 +2085,14 @@ int CalculateFrameNumber(void) * point to frame coding variables ************************************************************************ */ -static void put_buffer_frame(void) +static void put_buffer_frame(ImageParameters *img) { - if( IS_INDEPENDENT(params) ) - { - pImgOrg[0] = imgY_org_frm_JV[0]; - pCurImg = pImgOrg[0]; - if (img->yuv_format != YUV400) - { - pImgOrg[1] = imgY_org_frm_JV[1]; - pImgOrg[2] = imgY_org_frm_JV[2]; - } - } - else + pCurImg = img_org_frm[0]; + pImgOrg[0] = img_org_frm[0]; + if (img->yuv_format != YUV400) { - pCurImg = imgY_org_frm; - imgUV_org = imgUV_org_frm; - pImgOrg[0] = imgY_org_frm; - if (img->yuv_format != YUV400) - { - pImgOrg[1] = imgUV_org_frm[0]; - pImgOrg[2] = imgUV_org_frm[1]; - } + pImgOrg[1] = img_org_frm[1]; + pImgOrg[2] = img_org_frm[2]; } } @@ -2377,17 +2102,16 @@ static void put_buffer_frame(void) * point to top field coding variables ************************************************************************ */ -static void put_buffer_top(void) +static void put_buffer_top(ImageParameters *img) { img->fld_type = 0; - pCurImg = imgY_org_top; - imgUV_org = imgUV_org_top; - pImgOrg[0] = imgY_org_top; + pCurImg = img_org_top[0]; + pImgOrg[0] = img_org_top[0]; if (img->yuv_format != YUV400) { - pImgOrg[1] = imgUV_org_top[0]; - pImgOrg[2] = imgUV_org_top[1]; + pImgOrg[1] = img_org_top[1]; + pImgOrg[2] = img_org_top[2]; } } @@ -2397,17 +2121,16 @@ static void put_buffer_top(void) * point to bottom field coding variables ************************************************************************ */ -static void put_buffer_bot(void) +static void put_buffer_bot(ImageParameters *img) { img->fld_type = 1; - pCurImg = imgY_org_bot; - imgUV_org = imgUV_org_bot; - pImgOrg[0] = imgY_org_bot; + pCurImg = img_org_bot[0]; + pImgOrg[0] = img_org_bot[0]; if (img->yuv_format != YUV400) { - pImgOrg[1] = imgUV_org_bot[0]; - pImgOrg[2] = imgUV_org_bot[1]; + pImgOrg[1] = img_org_bot[1]; + pImgOrg[2] = img_org_bot[2]; } } @@ -2502,15 +2225,21 @@ static void rdPictureCoding(void) if ( params->RCEnable ) rc_save_state(); + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass = pWPX->wp_rd_passes + 1; if (img->type!=I_SLICE && params->GenerateMultiplePPS) { if (img->type==P_SLICE) { - if ((params->RDPSliceWeightOnly != 2) && (TestWPPSlice(0) == 1)) + if ((params->RDPSliceWeightOnly != 2) && (TestWPPSlice(img, params, 0) == 1)) { active_pps = PicParSet[1]; + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR; } + else if ( params->WPMCPrecision ) + active_pps = PicParSet[1]; else { skip_encode = params->RDPSliceWeightOnly; @@ -2526,6 +2255,8 @@ static void rdPictureCoding(void) else { active_pps = PicParSet[2]; + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR; } } else @@ -2564,12 +2295,12 @@ static void rdPictureCoding(void) enc_picture=enc_frame_picture[0]; if (img->type!=I_SLICE && params->GenerateMultiplePPS) { - img->qp=rd_qp; + img->qp = rd_qp; active_pps = PicParSet[0]; } else { - img->qp=rd_qp; + img->qp = rd_qp; } intras = previntras; p_frame_pic = frame_pic[0]; @@ -2588,7 +2319,9 @@ static void rdPictureCoding(void) if ( params->RCEnable ) rateRatio = 1.0F; - if (img->type!=I_SLICE ) + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass = pWPX->wp_rd_passes + 2; + if (img->type != I_SLICE ) { skip_encode = 0; img->qp = rd_qp; @@ -2602,10 +2335,14 @@ static void rdPictureCoding(void) { if (params->GenerateMultiplePPS) { - if ((params->RDPSliceWeightOnly != 2) && (TestWPPSlice(0) == 1)) + if ((params->RDPSliceWeightOnly != 2) && (TestWPPSlice(img, params, 0) == 1)) { active_pps = PicParSet[1]; + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR; } + else if ( params->WPMCPrecision == 2 ) + active_pps = PicParSet[1]; else if (params->RDPSliceBTest && active_sps->profile_idc != 66) { set_slice_type( B_SLICE ); @@ -2626,16 +2363,22 @@ static void rdPictureCoding(void) } else { - if (params->GenerateMultiplePPS && (params->RDBSliceWeightOnly != 2) && TestWPBSlice(0) == 1) + if (params->GenerateMultiplePPS && (params->RDBSliceWeightOnly != 2) && TestWPBSlice(img, params, 0) == 1) { active_pps = PicParSet[1]; + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR; } + else if ( params->WPMCPrecision == 2 && (params->WPMCPrecBSlice == 2 || (params->WPMCPrecBSlice == 1 && img->nal_reference_idc) ) ) + active_pps = PicParSet[1]; else { skip_encode = (params->RDBSliceWeightOnly == 1); img->qp = rd_qp + (img->nal_reference_idc ? - 1 : 1); if ( params->RCEnable ) rateRatio = img->nal_reference_idc ? 1.15F : 0.85F; + if ( params->WPMCPrecision ) + pWPX->curr_wp_rd_pass->algorithm = WP_REGULAR; } } } @@ -2809,7 +2552,7 @@ void select_plane(ColorPlane color_plane) enc_picture->p_curr_img_sub = enc_picture->p_img_sub[color_plane]; img->max_imgpel_value = img->max_imgpel_value_comp[color_plane]; img->dc_pred_value = img->dc_pred_value_comp[color_plane]; - img->curr_res = img->m7[color_plane]; - img->curr_prd = img->mpr[color_plane]; + img->curr_res = img->mb_rres [color_plane]; + img->curr_prd = img->mb_pred [color_plane]; } diff --git a/lencod/src/img_dist_ms_ssim.c b/lencod/src/img_dist_ms_ssim.c new file mode 100644 index 0000000..8ef6ac1 --- /dev/null +++ b/lencod/src/img_dist_ms_ssim.c @@ -0,0 +1,353 @@ + +/*! + ************************************************************************************* + * \file img_dist_ms_ssim.c + * + * \brief + * Compute structural similarity (SSIM) index using the encoded image and the reference image + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * - Peshala Pahalawatta <ppaha@dolby.com> + * - Zhen Li <zli@dolby.com> + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ +#include "contributors.h" +#include "global.h" +#include "img_distortion.h" +#include "enc_statistics.h" +#include "memalloc.h" +#include "math.h" + +#ifndef UNBIASED_VARIANCE + #define UNBIASED_VARIANCE // unbiased estimation of the variance +#endif + +#define MS_SSIM_PAD 6 +#define MS_SSIM_PAD2 3 + +#define MS_SSIM_BETA0 0.0448 +#define MS_SSIM_BETA1 0.2856 +#define MS_SSIM_BETA2 0.3001 +#define MS_SSIM_BETA3 0.2363 +#define MS_SSIM_BETA4 0.1333 + +#define MAX_SSIM_LEVELS 5 + +//Computes the product of the contrast and structure componenents of the structural similarity metric. +float compute_structural_components (imgpel **refImg, imgpel **encImg, int height, int width, int win_height, int win_width, int comp) +{ + static const float K2 = 0.03f; + static float max_pix_value_sqd; + float C2; + float win_pixels = (float) (win_width * win_height); +#ifdef UNBIASED_VARIANCE + float win_pixels_bias = win_pixels - 1; +#else + float win_pixels_bias = win_pixels; +#endif + float mb_ssim, meanOrg, meanEnc; + float varOrg, varEnc, covOrgEnc; + int imeanOrg, imeanEnc, ivarOrg, ivarEnc, icovOrgEnc; + float cur_distortion = 0.0; + int i, j, n, m, win_cnt = 0; + int overlapSize = params->SSIMOverlapSize; + + max_pix_value_sqd = (float) (img->max_imgpel_value_comp[comp] * img->max_imgpel_value_comp[comp]); + C2 = K2 * K2 * max_pix_value_sqd; + + for (j = 0; j <= height - win_height; j += overlapSize) + { + for (i = 0; i <= width - win_width; i += overlapSize) + { + imeanOrg = 0; + imeanEnc = 0; + ivarOrg = 0; + ivarEnc = 0; + icovOrgEnc = 0; + + for ( n = j;n < j + win_height;n ++) + { + for (m = i;m < i + win_width;m ++) + { + imeanOrg += refImg[n][m]; + imeanEnc += encImg[n][m]; + ivarOrg += refImg[n][m] * refImg[n][m]; + ivarEnc += encImg[n][m] * encImg[n][m]; + icovOrgEnc += refImg[n][m] * encImg[n][m]; + } + } + + meanOrg = (float) imeanOrg / win_pixels; + meanEnc = (float) imeanEnc / win_pixels; + + varOrg = ((float) ivarOrg - ((float) imeanOrg) * meanOrg) / win_pixels_bias; + varEnc = ((float) ivarEnc - ((float) imeanEnc) * meanEnc) / win_pixels_bias; + covOrgEnc = ((float) icovOrgEnc - ((float) imeanOrg) * meanEnc) / win_pixels_bias; + + mb_ssim = (float) (2.0 * covOrgEnc + C2); + mb_ssim /= (float) (varOrg + varEnc + C2); + + cur_distortion += mb_ssim; + win_cnt++; + } + } + + cur_distortion /= (float) win_cnt; + + if (cur_distortion >= 1.0 && cur_distortion < 1.01) // avoid float accuracy problem at very low QP(e.g.2) + cur_distortion = 1.0; + + return cur_distortion; +} + +float compute_luminance_component (imgpel **refImg, imgpel **encImg, int height, int width, int win_height, int win_width, int comp) +{ + static const float K1 = 0.01f; + static float max_pix_value_sqd; + float C1; + float win_pixels = (float) (win_width * win_height); + float mb_ssim, meanOrg, meanEnc; + int imeanOrg, imeanEnc; + float cur_distortion = 0.0; + int i, j, n, m, win_cnt = 0; + int overlapSize = params->SSIMOverlapSize; + + max_pix_value_sqd = (float) (img->max_imgpel_value_comp[comp] * img->max_imgpel_value_comp[comp]); + C1 = K1 * K1 * max_pix_value_sqd; + + for (j = 0; j <= height - win_height; j += overlapSize) + { + for (i = 0; i <= width - win_width; i += overlapSize) + { + imeanOrg = 0; + imeanEnc = 0; + + for ( n = j;n < j + win_height;n ++) + { + for (m = i;m < i + win_width;m ++) + { + imeanOrg += refImg[n][m]; + imeanEnc += encImg[n][m]; + } + } + + meanOrg = (float) imeanOrg / win_pixels; + meanEnc = (float) imeanEnc / win_pixels; + + mb_ssim = (float) (2.0 * meanOrg * meanEnc + C1); + mb_ssim /= (float) (meanOrg * meanOrg + meanEnc * meanEnc + C1); + + cur_distortion += mb_ssim; + win_cnt++; + } + } + + cur_distortion /= (float) win_cnt; + + if (cur_distortion >= 1.0 && cur_distortion < 1.01) // avoid float accuracy problem at very low QP(e.g.2) + cur_distortion = 1.0; + + return cur_distortion; +} + +void horizontal_symmetric_extension(int **buffer, int width, int height ) +{ + int j; + int* buf; + + int height_plus_pad2 = height + MS_SSIM_PAD2; + int width_plus_pad2_minus_one = width + MS_SSIM_PAD2 - 1; + + // horizontal PSE + for (j = MS_SSIM_PAD2; j < height_plus_pad2; j++ ) { + // left column + buf = &buffer[j][MS_SSIM_PAD2]; + buf[-1] = buf[1]; + buf[-2] = buf[2]; + + // right column + buf = &buffer[j][width_plus_pad2_minus_one]; + buf[1] = buf[-1]; + buf[2] = buf[-2]; + buf[3] = buf[-3]; + } +} + +void vertical_symmetric_extension(int **buffer, int width, int height) +{ + int i; + int* bufminus1; + int* bufminus2; + int* bufminus3; + int* bufplus1; + int* bufplus2; + int* bufplus3; + + bufminus1 = &buffer[MS_SSIM_PAD2-1][MS_SSIM_PAD2]; + bufminus2 = &buffer[MS_SSIM_PAD2-2][MS_SSIM_PAD2]; + bufplus1 = &buffer[MS_SSIM_PAD2+1][MS_SSIM_PAD2]; + bufplus2 = &buffer[MS_SSIM_PAD2+2][MS_SSIM_PAD2]; + + for (i = 0; i < width; i++) + { + bufminus1[i] = bufplus1[i]; + bufminus2[i] = bufplus2[i]; + } + + bufminus1 = &buffer[height + MS_SSIM_PAD2-2][MS_SSIM_PAD2]; + bufminus2 = &buffer[height + MS_SSIM_PAD2-3][MS_SSIM_PAD2]; + bufminus3 = &buffer[height + MS_SSIM_PAD2-4][MS_SSIM_PAD2]; + bufplus1 = &buffer[height + MS_SSIM_PAD2][MS_SSIM_PAD2]; + bufplus2 = &buffer[height + MS_SSIM_PAD2+1][MS_SSIM_PAD2]; + bufplus3 = &buffer[height + MS_SSIM_PAD2+2][MS_SSIM_PAD2]; + for (i = 0; i < width; i++) + { + bufplus1[i] = bufminus1[i]; + bufplus2[i] = bufminus2[i]; + bufplus3[i] = bufminus3[i]; + } +} + +static void imgpel_to_padded_int(imgpel** src, int **buffer, int width, int height) +{ + int i, j; + int* tmpDst; + imgpel* tmpSrc; + + tmpDst = buffer[MS_SSIM_PAD2]; + for (j = 0; j < height; j++) + { + tmpSrc = src[j]; + tmpDst = &buffer[j + MS_SSIM_PAD2][MS_SSIM_PAD2]; + for (i = 0; i < width; i++) + { + tmpDst[i] = (int)tmpSrc[i]; + } + } +} + +void downsample(imgpel** src, imgpel** out, int height, int width) +{ + int height2 = height >> 1; + int width2 = width >> 1; + int i, j; + int ii, jj; + int iDst; + int tmp, tmp1, tmp2; + int* tmpDst; + int* tmpSrc; + + int** itemp; + int** dest; + + get_mem2Dint(&itemp, height + MS_SSIM_PAD, width + MS_SSIM_PAD); + get_mem2Dint(&dest, height + MS_SSIM_PAD, width2 + MS_SSIM_PAD); + + imgpel_to_padded_int(src, itemp, width, height); + horizontal_symmetric_extension(itemp, width, height); + + for (j = 0; j < height; j++) + { + tmpDst = dest[j+MS_SSIM_PAD2]; + tmpSrc = itemp[j+MS_SSIM_PAD2]; + iDst = MS_SSIM_PAD2; + for (i = 0; i < width2; i++, iDst++) + { + ii = (i << 1) + MS_SSIM_PAD2; + tmp1 = tmpSrc[ii-1] + tmpSrc[ii+2]; + tmp2 = tmpSrc[ii] + tmpSrc[ii+1]; + tmpDst[iDst] = tmpSrc[ii-2] + tmpSrc[ii+3] + (tmp1 << 1) + tmp1 + (tmp2 << 5) - (tmp2 << 2); + tmpDst[iDst] >>= 6; + } + } + + //Periodic extension + vertical_symmetric_extension(dest, width2, height); + + for (i = 0; i < width2; i++) + { + ii = i + MS_SSIM_PAD2; + for (j = 0; j < height2; j++) + { + jj = (j << 1) + MS_SSIM_PAD2; + tmp1 = dest[jj-1][ii] + dest[jj+2][ii]; + tmp2 = dest[jj][ii] + dest[jj+1][ii]; + tmp = dest[jj-2][ii] + dest[jj+3][ii] + (tmp1 << 1) + tmp1 + (tmp2 << 5) - (tmp2 << 2); + out[j][i] = (unsigned char) (tmp >> 6); //Note: Should change for different bit depths + } + } + free_mem2Dint(itemp); + free_mem2Dint(dest); +} + +float compute_ms_ssim(imgpel **refImg, imgpel **encImg, int height, int width, int win_height, int win_width, int comp) +{ + float structural[MAX_SSIM_LEVELS]; + float cur_distortion; + float luminance; + imgpel** dsRef; + imgpel** dsEnc; + int m; + static int max_ssim_levels_minus_one = MAX_SSIM_LEVELS - 1; + static float exponent[5] = {(float)MS_SSIM_BETA0, (float)MS_SSIM_BETA1, (float)MS_SSIM_BETA2, (float)MS_SSIM_BETA3, (float)MS_SSIM_BETA4}; + + dsRef = NULL; + dsEnc = NULL; + get_mem2Dpel(&dsRef, height>>1, width>>1); + get_mem2Dpel(&dsEnc, height>>1, width>>1); + + structural[0] = compute_structural_components(refImg, encImg, height, width, win_height, win_width, comp); + cur_distortion = (float)pow(structural[0], exponent[0]); + + downsample(refImg, dsRef, height, width); + downsample(encImg, dsEnc, height, width); + + for (m = 1; m < MAX_SSIM_LEVELS; m++) + { + height >>= 1; + width >>= 1; + structural[m] = compute_structural_components(dsRef, dsEnc, height, width, imin(win_height,height), imin(win_width,width), comp); + cur_distortion *= (float)pow(structural[m], exponent[m]); + if (m < max_ssim_levels_minus_one) + { + downsample(dsRef, dsRef, height, width); + downsample(dsEnc, dsEnc, height, width); + } + else + { + luminance = compute_luminance_component(dsRef, dsEnc, height, width, imin(win_height,height), imin(win_width,width), comp); + cur_distortion *= (float)pow(luminance, exponent[m]); + } + } + free_mem2Dpel(dsRef); + free_mem2Dpel(dsEnc); + dsRef = NULL; + dsEnc = NULL; + + return cur_distortion; +} + +/*! + ************************************************************************ + * \brief + * Find MS-SSIM for all three components + ************************************************************************ + */ +void find_ms_ssim (ImageStructure *ref, ImageStructure *src, DistMetric *metricSSIM) +{ + FrameFormat *format = &ref->format; + + metricSSIM->value[0] = compute_ms_ssim (ref->data[0], src->data[0], format->height, format->width, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, 0); + // Chroma. + if (format->yuv_format != YUV400) + { + metricSSIM->value[1] = compute_ms_ssim (ref->data[1], src->data[1], format->height_cr, format->width_cr, img->mb_cr_size_y, img->mb_cr_size_x, 1); + metricSSIM->value[2] = compute_ms_ssim (ref->data[2], src->data[2], format->height_cr, format->width_cr, img->mb_cr_size_y, img->mb_cr_size_x, 2); + } + + accumulate_average(metricSSIM, dist->frame_ctr); + accumulate_avslice(metricSSIM, img->type, stats->frame_ctr[img->type]); +} diff --git a/lencod/src/img_dist_snr.c b/lencod/src/img_dist_snr.c new file mode 100644 index 0000000..766ea97 --- /dev/null +++ b/lencod/src/img_dist_snr.c @@ -0,0 +1,52 @@ + +/*! + ************************************************************************************* + * \file img_dist_snr.c + * + * \brief + * Compute signal to noise ratio (SNR) between the encoded image and the reference image + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ +#include "contributors.h" + +#include <math.h> + +#include "global.h" +#include "img_distortion.h" +#include "enc_statistics.h" + +/*! + ************************************************************************ + * \brief + * Find SNR for all three components + ************************************************************************ + */ +void find_snr(ImageStructure *imgREF, ImageStructure *imgSRC, DistMetric *metricSSE, DistMetric *metricPSNR) +{ + FrameFormat *format = &imgREF->format; + // Luma. + metricSSE ->value[0] = (float) compute_SSE(imgREF->data[0], imgSRC->data[0], 0, 0, format->height, format->width); + metricPSNR->value[0] = psnr(format->max_value_sq[0], format->size_cmp[0], metricSSE->value[0]); + + // Chroma. + if (format->yuv_format != YUV400) + { + metricSSE ->value[1] = (float) compute_SSE(imgREF->data[1], imgSRC->data[1], 0, 0, format->height_cr, format->width_cr); + metricPSNR->value[1] = psnr(format->max_value_sq[1], format->size_cmp[1], metricSSE->value[1]); + metricSSE ->value[2] = (float) compute_SSE(imgREF->data[2], imgSRC->data[2], 0, 0, format->height_cr, format->width_cr); + metricPSNR->value[2] = psnr(format->max_value_sq[2], format->size_cmp[2], metricSSE->value[2]); + } + + { + accumulate_average(metricSSE, dist->frame_ctr); + accumulate_average(metricPSNR, dist->frame_ctr); + + accumulate_avslice(metricSSE, img->type, stats->frame_ctr[img->type]); + accumulate_avslice(metricPSNR, img->type, stats->frame_ctr[img->type]); + } +} diff --git a/lencod/src/img_dist_ssim.c b/lencod/src/img_dist_ssim.c new file mode 100644 index 0000000..b8bbc6f --- /dev/null +++ b/lencod/src/img_dist_ssim.c @@ -0,0 +1,113 @@ + +/*! + ************************************************************************************* + * \file img_dist_ssim.c + * + * \brief + * Compute structural similarity (SSIM) index using the encoded image and the reference image + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * - Zhen Li <zli@dolby.com> + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ +#include "contributors.h" +#include "global.h" +#include "img_distortion.h" +#include "enc_statistics.h" + +//#define UNBIASED_VARIANCE // unbiased estimation of the variance + +float compute_ssim (imgpel **refImg, imgpel **encImg, int height, int width, int win_height, int win_width, int comp) +{ + static const float K1 = 0.01f, K2 = 0.03f; + static float max_pix_value_sqd; + float C1, C2; + float win_pixels = (float) (win_width * win_height); +#ifdef UNBIASED_VARIANCE + float win_pixels_bias = win_pixels - 1; +#else + float win_pixels_bias = win_pixels; +#endif + float mb_ssim, meanOrg, meanEnc; + float varOrg, varEnc, covOrgEnc; + int imeanOrg, imeanEnc, ivarOrg, ivarEnc, icovOrgEnc; + float cur_distortion = 0.0; + int i, j, n, m, win_cnt = 0; + int overlapSize = params->SSIMOverlapSize; + + max_pix_value_sqd = (float) (img->max_imgpel_value_comp[comp] * img->max_imgpel_value_comp[comp]); + C1 = K1 * K1 * max_pix_value_sqd; + C2 = K2 * K2 * max_pix_value_sqd; + + for (j = 0; j <= height - win_height; j += overlapSize) + { + for (i = 0; i <= width - win_width; i += overlapSize) + { + imeanOrg = 0; + imeanEnc = 0; + ivarOrg = 0; + ivarEnc = 0; + icovOrgEnc = 0; + + for ( n = j;n < j + win_height;n ++) + { + for (m = i;m < i + win_width;m ++) + { + imeanOrg += refImg[n][m]; + imeanEnc += encImg[n][m]; + ivarOrg += refImg[n][m] * refImg[n][m]; + ivarEnc += encImg[n][m] * encImg[n][m]; + icovOrgEnc += refImg[n][m] * encImg[n][m]; + } + } + + meanOrg = (float) imeanOrg / win_pixels; + meanEnc = (float) imeanEnc / win_pixels; + + varOrg = ((float) ivarOrg - ((float) imeanOrg) * meanOrg) / win_pixels_bias; + varEnc = ((float) ivarEnc - ((float) imeanEnc) * meanEnc) / win_pixels_bias; + covOrgEnc = ((float) icovOrgEnc - ((float) imeanOrg) * meanEnc) / win_pixels_bias; + + mb_ssim = (float) ((2.0 * meanOrg * meanEnc + C1) * (2.0 * covOrgEnc + C2)); + mb_ssim /= (float) (meanOrg * meanOrg + meanEnc * meanEnc + C1) * (varOrg + varEnc + C2); + + cur_distortion += mb_ssim; + win_cnt++; + } + } + + cur_distortion /= (float) win_cnt; + + if (cur_distortion >= 1.0 && cur_distortion < 1.01) // avoid float accuracy problem at very low QP(e.g.2) + cur_distortion = 1.0; + + return cur_distortion; +} + +/*! + ************************************************************************ + * \brief + * Find SSIM for all three components + ************************************************************************ + */ +void find_ssim (ImageStructure *ref, ImageStructure *src, DistMetric *metricSSIM) +{ + FrameFormat *format = &ref->format; + + metricSSIM->value[0] = compute_ssim (ref->data[0], src->data[0], format->height, format->width, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, 0); + // Chroma. + if (format->yuv_format != YUV400) + { + metricSSIM->value[1] = compute_ssim (ref->data[1], src->data[1], format->height_cr, format->width_cr, img->mb_cr_size_y, img->mb_cr_size_x, 1); + metricSSIM->value[2] = compute_ssim (ref->data[2], src->data[2], format->height_cr, format->width_cr, img->mb_cr_size_y, img->mb_cr_size_x, 2); + } + + { + accumulate_average(metricSSIM, dist->frame_ctr); + accumulate_avslice(metricSSIM, img->type, stats->frame_ctr[img->type]); + } +} + diff --git a/lencod/src/img_distortion.c b/lencod/src/img_distortion.c new file mode 100644 index 0000000..5e0db25 --- /dev/null +++ b/lencod/src/img_distortion.c @@ -0,0 +1,210 @@ + +/*! + ************************************************************************************* + * \file img_distortion.c + * + * \brief + * Compute distortion for encoded image + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Woo-Shik Kim <wooshik.kim@usc.edu> + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ + +#include <math.h> +#include <time.h> +#include <sys/timeb.h> + +#include "global.h" + +#include "refbuf.h" +#include "mbuffer.h" +#include "img_luma.h" +#include "img_chroma.h" +#include "intrarefresh.h" +#include "fmo.h" +#include "sei.h" +#include "memalloc.h" +#include "nalu.h" +#include "ratectl.h" +#include "mb_access.h" +#include "output.h" +#include "cabac.h" +#include "context_ini.h" +#include "conformance.h" +#include "enc_statistics.h" + +#include "q_matrix.h" +#include "q_offsets.h" +#include "quant4x4.h" +#include "quant8x8.h" +#include "wp.h" +#include "input.h" +#include "image.h" +#include "img_distortion.h" +#include "img_dist_snr.h" +#include "img_dist_ssim.h" +#include "img_dist_ms_ssim.h" +#include "cconv_yuv2rgb.h" + +// images for distortion calculation +ImageStructure imgSRC, imgREF; +extern ImageStructure imgRGB_src, imgRGB_ref; + +/*! + ************************************************************************ + * \brief + * Metric accumulator + ************************************************************************ + */ +void accumulate_metric(float *ave_metric, float cur_metric, int frames) +{ + *ave_metric = (float) (*ave_metric * (frames - 1) + cur_metric) / frames; +} + +/*! + ************************************************************************ + * \brief + * Accumulate distortion for all components + ************************************************************************ + */ +void accumulate_average(DistMetric *metric, int frames) +{ + accumulate_metric(&metric->average[0], metric->value[0], frames); + accumulate_metric(&metric->average[1], metric->value[1], frames); + accumulate_metric(&metric->average[2], metric->value[2], frames); +} + +/*! + ************************************************************************ + * \brief + * Accumulate distortion for all components for slice_type + ************************************************************************ + */ +void accumulate_avslice(DistMetric *metric, int slice_type, int frames) +{ + accumulate_metric(&metric->avslice[slice_type][0], metric->value[0], frames); + accumulate_metric(&metric->avslice[slice_type][1], metric->value[1], frames); + accumulate_metric(&metric->avslice[slice_type][2], metric->value[2], frames); +} + +/*! + ************************************************************************ + * \brief + * Find distortion for all three components + ************************************************************************ + */ +void find_distortion (void) +{ + int64 diff_cmp[3] = {0}; + + // Calculate SSE for Y, U and V. + if (img->structure!=FRAME) + { + // Luma. + diff_cmp[0] += compute_SSE(pCurImg, imgY_com, 0, 0, params->output.height, params->output.width); + + // Chroma. + if (img->yuv_format != YUV400) + { + diff_cmp[1] += compute_SSE(pImgOrg[1], imgUV_com[0], 0, 0, params->output.height_cr, params->output.width_cr); + diff_cmp[2] += compute_SSE(pImgOrg[2], imgUV_com[1], 0, 0, params->output.height_cr, params->output.width_cr); + } + } + else + { + if( IS_INDEPENDENT(params) ) + { + enc_picture = enc_frame_picture[0]; + } + pCurImg = img_org_frm[0]; + pImgOrg[0] = img_org_frm[0]; + + // Luma. + diff_cmp[0] += compute_SSE(pImgOrg[0], enc_picture->imgY, 0, 0, params->output.height, params->output.width); + + // Chroma. + if (img->yuv_format != YUV400) + { + pImgOrg[1] = img_org_frm[1]; + pImgOrg[2] = img_org_frm[2]; + + diff_cmp[1] += compute_SSE(pImgOrg[1], enc_picture->imgUV[0], 0, 0, params->output.height_cr, params->output.width_cr); + diff_cmp[2] += compute_SSE(pImgOrg[2], enc_picture->imgUV[1], 0, 0, params->output.height_cr, params->output.width_cr); + } + } + + // This should be assigned to the SSE structure. Should double check code. + dist->metric[SSE].value[0] = (float) diff_cmp[0]; + dist->metric[SSE].value[1] = (float) diff_cmp[1]; + dist->metric[SSE].value[2] = (float) diff_cmp[2]; +} + +void select_img(ImageStructure *imgSRC, ImageStructure *imgREF) +{ + if (img->fld_flag != 0) + { + imgSRC->format = params->output; + imgREF->format = params->output; + + imgREF->data[0] = pCurImg; + imgSRC->data[0] = imgY_com; + + if (img->yuv_format != YUV400) + { + imgREF->data[1] = pImgOrg[1]; + imgREF->data[2] = pImgOrg[2]; + imgSRC->data[1] = imgUV_com[0]; + imgSRC->data[2] = imgUV_com[1]; + } + } + else + { + imgSRC->format = params->output; + imgREF->format = params->output; + + imgREF->data[0] = img_org_frm[0]; + + if ((params->PicInterlace == ADAPTIVE_CODING) || IS_INDEPENDENT(params)) + { + enc_picture = enc_frame_picture[0]; + } + imgSRC->data[0] = enc_picture->imgY; + + if (img->yuv_format != YUV400) + { + imgREF->data[1] = img_org_frm[1]; + imgREF->data[2] = img_org_frm[2]; + + imgSRC->data[1] = enc_picture->imgUV[0]; + imgSRC->data[2] = enc_picture->imgUV[1]; + } + } +} + +void compute_distortion(void) +{ + if (params->Verbose != 0) + { + select_img(&imgSRC, &imgREF); + + find_snr (&imgREF, &imgSRC, &dist->metric[SSE], &dist->metric[PSNR]); + if (params->Distortion[SSIM] == 1) + find_ssim (&imgREF, &imgSRC, &dist->metric[SSIM]); + if (params->Distortion[MS_SSIM] == 1) + find_ms_ssim(&imgREF, &imgSRC, &dist->metric[MS_SSIM]); + // RGB Distortion + if(params->DistortionYUVtoRGB == 1) + { + YUVtoRGB(&imgREF, &imgRGB_ref); + YUVtoRGB(&imgSRC, &imgRGB_src); + find_snr (&imgRGB_ref, &imgRGB_src, &dist->metric[SSE_RGB], &dist->metric[PSNR_RGB]); + if (params->Distortion[SSIM] == 1) + find_ssim (&imgRGB_ref, &imgRGB_src, &dist->metric[SSIM_RGB]); + if (params->Distortion[MS_SSIM] == 1) + find_ms_ssim(&imgRGB_ref, &imgRGB_src, &dist->metric[MS_SSIM_RGB]); + } + } +} diff --git a/lencod/src/input.c b/lencod/src/input.c index a1ee97b..345fa0a 100644 --- a/lencod/src/input.c +++ b/lencod/src/input.c @@ -21,6 +21,7 @@ #include "global.h" #include "input.h" +#include "report.h" unsigned char *buf; @@ -501,7 +502,7 @@ void ReadOneFrame (int FrameNoInFile, int HeaderSize, FrameFormat *source, Frame if (read(p_in, buf, (int) framesize_in_bytes) != (int) framesize_in_bytes) { - printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", (int) framesize_in_bytes); + printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF, exiting...\n", (int) framesize_in_bytes); report_stats_on_error(); } diff --git a/lencod/src/lencod.c b/lencod/src/lencod.c index 90db6c4..d27f81d 100644 --- a/lencod/src/lencod.c +++ b/lencod/src/lencod.c @@ -14,7 +14,7 @@ * The main contributors are listed in contributors.h * * \version - * JM 14.0 (FRExt) + * JM 14.1 (FRExt) * * \note * tags are used for document system "doxygen" @@ -49,40 +49,33 @@ #include <sys/timeb.h> #include "global.h" +#include "cconv_yuv2rgb.h" #include "configfile.h" -#include "leaky_bucket.h" -#include "memalloc.h" -#include "intrarefresh.h" -#include "fmo.h" -#include "sei.h" -#include "parset.h" +#include "context_ini.h" +#include "explicit_gop.h" +#include "filehandle.h" #include "image.h" #include "input.h" -#include "output.h" - +#include "intrarefresh.h" +#include "leaky_bucket.h" +#include "memalloc.h" #include "me_epzs.h" #include "me_umhex.h" #include "me_umhexsmp.h" - -#include "ratectl.h" -#include "explicit_gop.h" -#include "context_ini.h" - +#include "output.h" +#include "parset.h" #include "q_matrix.h" #include "q_offsets.h" +#include "ratectl.h" +#include "report.h" #include "rdo_quant.h" +#include "errdo.h" +#include "rdopt.h" +#include "wp_mcprec.h" -#define JM "14 (FRExt)" -#define VERSION "14.0" -#define EXT_VERSION "(FRExt)" - -InputParameters inputs, *params = &inputs; -ImageParameters images, *img = &images; -StatParameters statistics, *stats = &statistics; -SNRParameters snrs, *snr = &snrs; -Decoders decoders, *decs=&decoders; - -static void information_init(void); +InputParameters inputs, *params = &inputs; +ImageParameters images, *img = &images; +Decoders decoders, *decs = &decoders; #ifdef _ADAPT_LAST_GROUP_ int initial_Bframes = 0; @@ -98,36 +91,33 @@ extern ColocatedParams *Co_located; extern ColocatedParams *Co_located_JV[MAX_PLANE]; //!< Co_located to be used during 4:4:4 independent mode encoding extern double *mb16x16_cost_frame; extern int FrameNumberInFile; -static char DistortionType[3][20] = {"SAD", "SSE", "Hadamard SAD"}; -void Init_Motion_Search_Module (void); -void Clear_Motion_Search_Module (void); -void report_frame_statistic(void); +extern ImageStructure imgRGB_src, imgRGB_ref; // RGB Distortion Metric + + +extern void Init_Motion_Search_Module (void); +extern void Clear_Motion_Search_Module (void); + +static void SetImgType(void); void SetLevelIndices(void); void chroma_mc_setup(void); - -void init_stats (void) +int get_mem_mv (short*******); +int get_mem_bipred_mv (short********); +void free_mem_bipred_mv (short*******); +void free_mem_mv (short******); +static void init_img( ImageParameters *img, InputParameters *params); +static void init_poc(void); + +void init_stats (StatParameters *stats, DistortionParams *dist) { stats->successive_Bframe = params->successive_Bframe; - stats->bit_ctr_I = 0; - stats->bit_ctr_P = 0; - stats->bit_ctr_B = 0; - snr->snr_y = 0.0; - snr->snr_u = 0.0; - snr->snr_v = 0.0; - snr->snr_y1 = 0.0; - snr->snr_u1 = 0.0; - snr->snr_v1 = 0.0; - snr->snr_ya = 0.0; - snr->snr_ua = 0.0; - snr->snr_va = 0.0; - snr->sse_y = 0.0; - snr->sse_u = 0.0; - snr->sse_v = 0.0; - snr->msse_y = 0.0; - snr->msse_u = 0.0; - snr->msse_v = 0.0; - snr->frame_ctr = 0; + stats->frame_counter = 0; + memset(stats->frame_ctr, 0, NUM_SLICE_TYPES * sizeof(int)); + memset(stats->bit_counter, 0, NUM_SLICE_TYPES * sizeof(int64)); + + // Distortion + dist->frame_ctr = 0; + memset(dist->metric, 0, TOTAL_DIST_TYPES * sizeof(DistMetric)); } /*! @@ -144,6 +134,7 @@ void init_frame_params() { if (!params->adaptive_idr_period && ( img->frm_number - img->lastIDRnumber ) % params->idr_period == 0 ) img->nal_reference_idc = NALU_PRIORITY_HIGHEST; + if (params->adaptive_idr_period == 1 && ( img->frm_number - imax(img->lastIntraNumber, img->lastIDRnumber) ) % params->idr_period == 0 ) img->nal_reference_idc = NALU_PRIORITY_HIGHEST; else @@ -205,13 +196,12 @@ void init_frame_params() */ int main(int argc,char **argv) { - int nplane; int primary_disp = 0; giRDOpt_B8OnlyFlag = 0; p_dec = p_in = -1; - p_stat = p_log = p_trace = NULL; + p_log = p_trace = NULL; frame_statistic_start = 1; @@ -226,9 +216,15 @@ int main(int argc,char **argv) GenerateParameterSets(); SetLevelIndices(); - init_img(); + init_img(img, params); + + init_rdopt(params); + + if (params->rdopt == 3) + { + init_error_conceal(params->ErrorConcealment); + } - init_rdopt (); #ifdef _LEAKYBUCKET_ Bit_Buffer = malloc((params->no_frames * (params->successive_Bframe + 1) + 1) * sizeof(long)); #endif @@ -247,28 +243,30 @@ int main(int argc,char **argv) dpb.init_done = 0; init_dpb(); init_out_buffer(); - init_stats(); + init_stats(stats, dist); enc_picture = NULL; init_global_buffers(); + if ( params->WPMCPrecision ) + { + wpxInitWPXPasses(params); + } + create_context_memory (); Init_Motion_Search_Module (); - information_init(); + information_init(img, params, stats); + + if(params->DistortionYUVtoRGB) + init_YUVtoRGB(); //Rate control if (params->RCEnable) rc_init_sequence(); - if (params->SearchMode == UM_HEX) - UMHEX_DefineThreshold(); - - // Init frame type counter. Only supports single slice per frame. - memset(frame_ctr, 0, 5 * sizeof(int)); - img->last_valid_reference = 0; - tot_time=0; // time for total encoding session + tot_time = 0; // time for total encoding session #ifdef _ADAPT_LAST_GROUP_ if (params->last_frame > 0) @@ -284,7 +282,6 @@ int main(int argc,char **argv) stats->bit_ctr_parametersets += stats->bit_ctr_parametersets_n; start_frame_no_in_this_IGOP = 0; - if (params->UseRDOQuant) precalculate_unary_exp_golomb_level(); @@ -316,9 +313,9 @@ int main(int argc,char **argv) } #ifdef _ADAPT_LAST_GROUP_ - if (params->successive_Bframe && params->last_frame && IMG_NUMBER+1 == params->no_frames) + if (params->successive_Bframe && params->last_frame && (IMG_NUMBER + 1) == params->no_frames) { - int bi = (int)((float)(params->jumpd+1)/(params->successive_Bframe + 1.0) + 0.499999); + int bi = (int)((float)(params->jumpd + 1)/(params->successive_Bframe + 1.0) + 0.499999); params->successive_Bframe = ((params->last_frame - (img->frm_number - 1)*(params->jumpd + 1)) / bi) - 1; @@ -363,16 +360,11 @@ int main(int argc,char **argv) if (img->nal_reference_idc == 0) { primary_disp ++; - //img->frame_num -= 1; - //img->frame_num %= max_frame_num; } if (img->currentPicture->idr_flag) { img->idr_gop_number = 0; - //start_frame_no_in_this_IGOP = img->frm_number; - //start_tr_in_this_IGOP = img->toppoc; - // start_tr_in_this_IGOP = (img->frm_number - 1 ) * (params->jumpd + 1) +1; } else img->idr_gop_number ++; @@ -380,74 +372,15 @@ int main(int argc,char **argv) encode_enhancement_layer(); } // terminate sequence - terminate_sequence(); - - flush_dpb(); - - close(p_in); - if (-1 != p_dec) - close(p_dec); - if (p_trace) - fclose(p_trace); - - Clear_Motion_Search_Module (); - - RandomIntraUninit(); - FmoUninit(); - - if (params->HierarchicalCoding) - clear_gop_structure (); - - // free structure for rd-opt. mode decision - clear_rdopt (); - -#ifdef _LEAKYBUCKET_ - calc_buffer(); -#endif - - // report everything - report(); - -#ifdef _LEAKYBUCKET_ - if (Bit_Buffer) - free(Bit_Buffer); -#endif - - free_dpb(); - if( IS_INDEPENDENT(params) ) - { - for( nplane=0; nplane<MAX_PLANE; nplane++ ) - { - free_colocated(Co_located_JV[nplane]); - } - } - else - { - free_colocated(Co_located); - } - uninit_out_buffer(); - - free_global_buffers(); - - // free image mem - free_img (); - free_context_memory (); - FreeNalPayloadBuffer(); - FreeParameterSets(); + free_encoder_memory(img); return 0; } -/*! - *********************************************************************** - * \brief - * Terminates and reports statistics on error. - * - *********************************************************************** - */ -void report_stats_on_error(void) + + +void free_encoder_memory(ImageParameters *img) { int nplane; - params->no_frames = img->frm_number; terminate_sequence(); flush_dpb(); @@ -455,7 +388,6 @@ void report_stats_on_error(void) close(p_in); if (-1 != p_dec) close(p_dec); - if (p_trace) fclose(p_trace); @@ -468,19 +400,22 @@ void report_stats_on_error(void) clear_gop_structure (); // free structure for rd-opt. mode decision - clear_rdopt (); + clear_rdopt (params); #ifdef _LEAKYBUCKET_ calc_buffer(); #endif - if (params->ReportFrameStats) - report_frame_statistic(); - // report everything - report(); + report(img, params, stats); + +#ifdef _LEAKYBUCKET_ + if (Bit_Buffer) + free(Bit_Buffer); +#endif free_dpb(); + if( IS_INDEPENDENT(params) ) { for( nplane=0; nplane<MAX_PLANE; nplane++ ) @@ -492,6 +427,7 @@ void report_stats_on_error(void) { free_colocated(Co_located); } + uninit_out_buffer(); free_global_buffers(); @@ -501,7 +437,6 @@ void report_stats_on_error(void) free_context_memory (); FreeNalPayloadBuffer(); FreeParameterSets(); - exit (-1); } /*! @@ -523,27 +458,24 @@ void init_poc() if (params->BRefPictures == 1) { - img->offset_for_non_ref_pic = 0; - img->offset_for_ref_frame[0] = 2; + img->offset_for_non_ref_pic = 0; + img->offset_for_ref_frame[0] = 2; } else { - img->offset_for_non_ref_pic = -2*(params->successive_Bframe); - img->offset_for_ref_frame[0] = 2*(params->successive_Bframe+1); + img->offset_for_non_ref_pic = -2*(params->successive_Bframe); + img->offset_for_ref_frame[0] = 2*(params->successive_Bframe + 1); } - if ((params->PicInterlace==FRAME_CODING) && (params->MbInterlace==FRAME_CODING)) - img->offset_for_top_to_bottom_field=0; - else - img->offset_for_top_to_bottom_field=1; - if ((params->PicInterlace==FRAME_CODING) && (params->MbInterlace==FRAME_CODING)) { + img->offset_for_top_to_bottom_field = 0; img->pic_order_present_flag = FALSE; img->delta_pic_order_cnt_bottom = 0; } else { + img->offset_for_top_to_bottom_field = 1; img->pic_order_present_flag = TRUE; img->delta_pic_order_cnt_bottom = 1; } @@ -583,7 +515,7 @@ void CAVLC_init(void) * Image Parameters ImageParameters *img *********************************************************************** */ -void init_img() +static void init_img( ImageParameters *img, InputParameters *params) { int i, j; int byte_abs_range; @@ -602,10 +534,10 @@ void init_img() img->bitdepth_luma_qp_scale = 3 * img->bitdepth_lambda_scale; img->dc_pred_value_comp[0] = 1<<(img->bitdepth_luma - 1); img->max_imgpel_value_comp[0] = (1<<img->bitdepth_luma) - 1; + img->max_imgpel_value_comp_sq[0] = img->max_imgpel_value_comp[0] * img->max_imgpel_value_comp[0]; - img->dc_pred_value = img->dc_pred_value_comp[0]; // set defaults + img->dc_pred_value = img->dc_pred_value_comp[0]; // set defaults img->max_imgpel_value = img->max_imgpel_value_comp[0]; - img->mb_size[0][0] = img->mb_size[0][1] = MB_BLOCK_SIZE; // Initialization for RC QP parameters (could be placed in ratectl.c) @@ -613,8 +545,8 @@ void init_img() img->RCMaxQP = params->RCMaxQP[P_SLICE]; // Set current residue & prediction array pointers - img->curr_res = img->m7[0]; - img->curr_prd = img->mpr[0]; + img->curr_res = img->mb_rres[0]; + img->curr_prd = img->mb_pred[0]; if (img->yuv_format != YUV400) { @@ -624,8 +556,11 @@ void init_img() img->dc_pred_value_comp[2] = img->dc_pred_value_comp[1]; img->max_imgpel_value_comp[1] = (1<<img->bitdepth_chroma) - 1; img->max_imgpel_value_comp[2] = img->max_imgpel_value_comp[1]; + img->max_imgpel_value_comp_sq[1] = img->max_imgpel_value_comp[1] * img->max_imgpel_value_comp[1]; + img->max_imgpel_value_comp_sq[2] = img->max_imgpel_value_comp[2] * img->max_imgpel_value_comp[2]; img->num_blk8x8_uv = (1<<img->yuv_format)&(~(0x1)); img->num_cdc_coeff = img->num_blk8x8_uv << 1; + img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = (img->yuv_format == YUV420 || img->yuv_format == YUV422) ? 8 : 16; img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y = (img->yuv_format == YUV444 || img->yuv_format == YUV422) ? 16 : 8; @@ -640,6 +575,8 @@ void init_img() img->bitdepth_scale[1] = 0; img->max_imgpel_value_comp[1] = 0; img->max_imgpel_value_comp[2] = img->max_imgpel_value_comp[1]; + img->max_imgpel_value_comp_sq[1] = img->max_imgpel_value_comp[1] * img->max_imgpel_value_comp[1]; + img->max_imgpel_value_comp_sq[2] = img->max_imgpel_value_comp[2] * img->max_imgpel_value_comp[2]; img->num_blk8x8_uv = 0; img->num_cdc_coeff = 0; img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x = 0; @@ -651,7 +588,7 @@ void init_img() img->chroma_qp_offset[0] = 0; img->chroma_qp_offset[1] = 0; } - + //img->pic_unit_size_on_disk = (imax(img->bitdepth_luma , img->bitdepth_chroma) > 8) ? 16 : 8; img->pic_unit_size_on_disk = (imax(params->source.bit_depth[0], params->source.bit_depth[1]) > 8) ? 16 : 8; img->out_unit_size_on_disk = (imax(params->output.bit_depth[0], params->output.bit_depth[1]) > 8) ? 16 : 8; @@ -688,8 +625,7 @@ void init_img() if (params->BiPredMotionEstimation) { - get_mem_mv (&(img->bipred_mv1)); - get_mem_mv (&(img->bipred_mv2)); + get_mem_bipred_mv(&(img->bipred_mv)); } } @@ -751,7 +687,7 @@ void init_img() get_mem_ACcoeff (&(rddata_trellis_best.cofAC)); get_mem_DCcoeff (&(rddata_trellis_best.cofDC)); - + if (!params->IntraProfile) { get_mem_mv (&(rddata_trellis_curr.pred_mv)); @@ -768,7 +704,7 @@ void init_img() } } - byte_abs_range = (imax(img->max_imgpel_value_comp[0],img->max_imgpel_value_comp[1]) + 1) * 2; + byte_abs_range = (imax(img->max_imgpel_value_comp[0], img->max_imgpel_value_comp[1]) + 1) * 2; if ((img->quad = (int*)calloc (byte_abs_range, sizeof(int))) == NULL) no_mem_exit ("init_img: img->quad"); @@ -788,7 +724,7 @@ void init_img() if (img->yuv_format != YUV400) { - img->width_cr = img->width * mb_width_cr[img->yuv_format] / 16; + img->width_cr = img->width * mb_width_cr [img->yuv_format] / 16; img->height_cr= img->height * mb_height_cr[img->yuv_format] / 16; } else @@ -796,20 +732,24 @@ void init_img() img->width_cr = 0; img->height_cr= 0; } + img->height_cr_frame = img->height_cr; img->size = img->width * img->height; img->size_cr = img->width_cr * img->height_cr; - img->PicWidthInMbs = img->width/MB_BLOCK_SIZE; - img->FrameHeightInMbs = img->height/MB_BLOCK_SIZE; + img->PicWidthInMbs = img->width / MB_BLOCK_SIZE; + img->FrameHeightInMbs = img->height / MB_BLOCK_SIZE; img->FrameSizeInMbs = img->PicWidthInMbs * img->FrameHeightInMbs; img->PicHeightInMapUnits = ( active_sps->frame_mbs_only_flag ? img->FrameHeightInMbs : img->FrameHeightInMbs/2 ); + + if ((img->b8x8info = (Block8x8Info *) calloc(1, sizeof(Block8x8Info))) == NULL) + no_mem_exit("init_img: img->block8x8info"); if( IS_INDEPENDENT(params) ) { - for( i=0; i<MAX_PLANE; i++ ){ + for( i = 0; i < MAX_PLANE; i++ ){ if ((img->mb_data_JV[i] = (Macroblock *) calloc(img->FrameSizeInMbs,sizeof(Macroblock))) == NULL) no_mem_exit("init_img: img->mb_data_JV"); } @@ -836,7 +776,7 @@ void init_img() } get_mem2D((byte***)&(img->ipredmode), img->height_blk, img->width_blk); //need two extra rows at right and bottom get_mem2D((byte***)&(img->ipredmode8x8), img->height_blk, img->width_blk); // help storage for ipredmode 8x8, inserted by YV - memset(&(img->ipredmode[0][0]), -1, img->height_blk * img->width_blk *sizeof(char)); + memset(&(img->ipredmode[0][0]) , -1, img->height_blk * img->width_blk *sizeof(char)); memset(&(img->ipredmode8x8[0][0]), -1, img->height_blk * img->width_blk *sizeof(char)); get_mem2D((byte***)&(rddata_top_frame_mb.ipredmode), img->height_blk, img->width_blk); @@ -849,34 +789,35 @@ void init_img() get_mem2D((byte***)&(rddata_top_field_mb.ipredmode), img->height_blk, img->width_blk); get_mem2D((byte***)&(rddata_bot_field_mb.ipredmode), img->height_blk, img->width_blk); } + // CAVLC mem get_mem3Dint(&(img->nz_coeff), img->FrameSizeInMbs, 4, 4+img->num_blk8x8_uv); - - - get_mem2Ddb_offset(&(img->lambda_md), 10, 52 + img->bitdepth_luma_qp_scale,img->bitdepth_luma_qp_scale); - get_mem3Ddb_offset (&(img->lambda_me), 10, 52 + img->bitdepth_luma_qp_scale, 3, img->bitdepth_luma_qp_scale); - get_mem3Dint_offset(&(img->lambda_mf), 10, 52 + img->bitdepth_luma_qp_scale, 3, img->bitdepth_luma_qp_scale); + CAVLC_init(); + + get_mem2Dolm (&(img->lambda), 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); + get_mem2Dodouble (&(img->lambda_md), 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); + get_mem3Dodouble (&(img->lambda_me), 10, 52 + img->bitdepth_luma_qp_scale, 3, img->bitdepth_luma_qp_scale); + get_mem3Doint (&(img->lambda_mf), 10, 52 + img->bitdepth_luma_qp_scale, 3, img->bitdepth_luma_qp_scale); if (params->CtxAdptLagrangeMult == 1) { - get_mem2Ddb_offset(&(img->lambda_mf_factor), 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); + get_mem2Dodouble(&(img->lambda_mf_factor), 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); } - CAVLC_init(); - img->b_frame_to_code = 0; img->GopLevels = (params->successive_Bframe) ? 1 : 0; img->mb_y_upd=0; RandomIntraInit (img->PicWidthInMbs, img->FrameHeightInMbs, params->RandomIntraMBRefresh); - InitSEIMessages(); // Tian Dong (Sept 2002) + InitSEIMessages(); initInput(¶ms->source, ¶ms->output); // Allocate I/O Frame memory if (AllocateFrameMemory(img, params->source.size)) no_mem_exit("AllocateFrameMemory: buf"); + // Initialize filtering parameters. If sending parameters, the offsets are // multiplied by 2 since inputs are taken in "div 2" format. // If not sending parameters, all fields are cleared @@ -884,7 +825,7 @@ void init_img() { for (j = 0; j < 2; j++) { - for (i = 0; i < 5; i++) + for (i = 0; i < NUM_SLICE_TYPES; i++) { params->DFAlpha[j][i] <<= 1; params->DFBeta [j][i] <<= 1; @@ -895,23 +836,16 @@ void init_img() { for (j = 0; j < 2; j++) { - for (i = 0; i < 5; i++) + for (i = 0; i < NUM_SLICE_TYPES; i++) { params->DFDisableIdc[j][i] = 0; - params->DFAlpha[j][i] = 0; - params->DFBeta[j][i] = 0; + params->DFAlpha [j][i] = 0; + params->DFBeta [j][i] = 0; } } } - if( params->separate_colour_plane_flag ) - { - img->ChromaArrayType = 0; - } - else - { - img->ChromaArrayType = params->yuv_format; - } + img->ChromaArrayType = params->separate_colour_plane_flag ? 0 : params->yuv_format; if (params->RDPictureDecision) { @@ -943,8 +877,7 @@ void free_img () if (params->BiPredMotionEstimation) { - free_mem_mv (img->bipred_mv1); - free_mem_mv (img->bipred_mv2); + free_mem_bipred_mv (img->bipred_mv); } } @@ -1027,9 +960,9 @@ void free_img () if (params->MbInterlace) { - free_mem2D((byte**)rddata_bot_frame_mb.ipredmode); - free_mem2D((byte**)rddata_top_field_mb.ipredmode); - free_mem2D((byte**)rddata_bot_field_mb.ipredmode); + free_mem2D((byte**) rddata_bot_frame_mb.ipredmode); + free_mem2D((byte**) rddata_top_field_mb.ipredmode); + free_mem2D((byte**) rddata_bot_field_mb.ipredmode); } } @@ -1072,956 +1005,6 @@ void free_picture(Picture *pic) } -/*! - ************************************************************************ - * \brief - * Reports frame statistical data to a stats file - ************************************************************************ - */ -void report_frame_statistic() -{ - FILE *p_stat_frm = NULL; - static int64 last_mode_use[NUM_PIC_TYPE][MAXMODE]; - static int last_b8_mode_0[NUM_PIC_TYPE][2]; - static int last_mode_chroma_use[4]; - static int64 last_bit_ctr_n = 0; - int i; - char name[30]; - int bitcounter; - -#ifndef WIN32 - time_t now; - struct tm *l_time; - char string[1000]; -#else - char timebuf[128]; -#endif - - - // write to log file - if ((p_stat_frm = fopen("stat_frame.dat", "r")) == 0) // check if file exists - { - if ((p_stat_frm = fopen("stat_frame.dat", "a")) == NULL) // append new statistic at the end - { - snprintf(errortext, ET_SIZE, "Error open file %s \n", "stat_frame.dat.dat"); - error(errortext, 500); - } - else // Create header for new log file - { - fprintf(p_stat_frm, " --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); - fprintf(p_stat_frm, "| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n"); - fprintf(p_stat_frm, " --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); - } - } - else - { - fclose (p_stat_frm); - if ((p_stat_frm = fopen("stat_frame.dat", "a")) == NULL) // File exists, just open for appending - { - snprintf(errortext, ET_SIZE, "Error open file %s \n", "stat_frame.dat.dat"); - error(errortext, 500); - } - } - - if (frame_statistic_start) - { - fprintf(p_stat_frm, "| ver | Date | Time | Sequence |Frm | QP |P/MbInt| Bits | SNRY | SNRU | SNRV | I4 | I8 | I16 | IC0 | IC1 | IC2 | IC3 | PI4 | PI8 | PI16 | P0 | P1 | P2 | P3 | P1*8*| P1*4*| P2*8*| P2*4*| P3*8*| P3*4*| P8 | P8:4 | P4*8*| P4*4*| P8:5 | P8:6 | P8:7 | BI4 | BI8 | BI16 | B0 | B1 | B2 | B3 | B0*8*| B0*4*| B1*8*| B1*4*| B2*8*| B2*4*| B3*8*| B3*4*| B8 | B8:0 |B80*8*|B80*4*| B8:4 | B4*8*| B4*4*| B8:5 | B8:6 | B8:7 |\n"); - fprintf(p_stat_frm, " ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); - } - - //report - fprintf(p_stat_frm, "|%4s/%s", VERSION, EXT_VERSION); - -#ifdef WIN32 - _strdate( timebuf ); - fprintf(p_stat_frm, "| %1.5s |", timebuf); - - _strtime( timebuf); - fprintf(p_stat_frm, " % 1.5s |", timebuf); -#else - now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time' - time (&now); - l_time = localtime (&now); - strftime (string, sizeof string, "%d-%b-%Y", l_time); - fprintf(p_stat_frm, "| %1.5s |", string ); - - strftime (string, sizeof string, "%H:%M:%S", l_time); - fprintf(p_stat_frm, " %1.5s |", string); -#endif - - for (i=0;i<30;i++) - name[i]=params->infile[i + imax(0,(int) (strlen(params->infile)- 30))]; // write last part of path, max 30 chars - - fprintf(p_stat_frm, "%30.30s|", name); - - fprintf(p_stat_frm, "%3d |", frame_no); - - fprintf(p_stat_frm, "%3d |", img->qp); - - fprintf(p_stat_frm, " %d/%d |", params->PicInterlace, params->MbInterlace); - - - if (img->frm_number == 0 && img->frame_num == 0) - { - bitcounter = (int) stats->bit_ctr_I; - } - else - { - bitcounter = (int) (stats->bit_ctr_n - last_bit_ctr_n); - last_bit_ctr_n = stats->bit_ctr_n; - } - - //report bitrate - fprintf(p_stat_frm, " %9d|", bitcounter); - - //report snr's - fprintf(p_stat_frm, " %2.4f| %2.4f| %2.4f|", snr->snr_y, snr->snr_u, snr->snr_v); - - //report modes - //I-Modes - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I4MB] - last_mode_use[I_SLICE][I4MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I8MB] - last_mode_use[I_SLICE][I8MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I16MB] - last_mode_use[I_SLICE][I16MB]); - - //chroma intra mode - fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[0] - last_mode_chroma_use[0]); - fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[1] - last_mode_chroma_use[1]); - fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[2] - last_mode_chroma_use[2]); - fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[3] - last_mode_chroma_use[3]); - - //P-Modes - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I4MB] - last_mode_use[P_SLICE][I4MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I8MB] - last_mode_use[P_SLICE][I8MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I16MB] - last_mode_use[P_SLICE][I16MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][0 ] - last_mode_use[P_SLICE][0 ]); - - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][1 ] - last_mode_use[P_SLICE][1 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][2 ] - last_mode_use[P_SLICE][2 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][3 ] - last_mode_use[P_SLICE][3 ]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][0][1]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][0][1]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][0][2]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][0][2]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][0][3]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][0][3]); - - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][P8x8] - last_mode_use[P_SLICE][P8x8]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][4 ] - last_mode_use[P_SLICE][4 ]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][0][4]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][0][4]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][5 ] - last_mode_use[P_SLICE][5 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][6 ] - last_mode_use[P_SLICE][6 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][7 ] - last_mode_use[P_SLICE][7 ]); - - //B-Modes - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I4MB] - last_mode_use[B_SLICE][I4MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I8MB] - last_mode_use[B_SLICE][I8MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I16MB] - last_mode_use[B_SLICE][I16MB]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][0 ] - last_mode_use[B_SLICE][0 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][1 ] - last_mode_use[B_SLICE][1 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][2 ] - last_mode_use[B_SLICE][2 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][3 ] - last_mode_use[B_SLICE][3 ]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][1][0]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][1][0]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][1][1]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][1][1]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][1][2]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][1][2]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][1][3]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][1][3]); - - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][P8x8] - last_mode_use[B_SLICE][P8x8]); - fprintf(p_stat_frm, " %d|", (stats->b8_mode_0_use [B_SLICE][0]+stats->b8_mode_0_use [B_SLICE][1]) - (last_b8_mode_0[B_SLICE][0]+last_b8_mode_0[B_SLICE][1])); - fprintf(p_stat_frm, " %5d|", stats->b8_mode_0_use [B_SLICE][1] - last_b8_mode_0[B_SLICE][1]); - fprintf(p_stat_frm, " %5d|", stats->b8_mode_0_use [B_SLICE][0] - last_b8_mode_0[B_SLICE][0]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][4 ] - last_mode_use[B_SLICE][4 ]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[1][1][4]); - fprintf(p_stat_frm, " %5d|", stats->mode_use_transform[0][1][4]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][5 ] - last_mode_use[B_SLICE][5 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][6 ] - last_mode_use[B_SLICE][6 ]); - fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][7 ] - last_mode_use[B_SLICE][7 ]); - - fprintf(p_stat_frm, "\n"); - - //save the last results - memcpy(last_mode_use[I_SLICE], stats->mode_use[I_SLICE], MAXMODE * sizeof(int64)); - memcpy(last_mode_use[P_SLICE], stats->mode_use[P_SLICE], MAXMODE * sizeof(int64)); - memcpy(last_mode_use[B_SLICE], stats->mode_use[B_SLICE], MAXMODE * sizeof(int64)); - memset(stats->mode_use_transform[1], 0, 2 * MAXMODE * sizeof(int)); - memset(stats->mode_use_transform[0], 0, 2 * MAXMODE * sizeof(int)); - memcpy(last_b8_mode_0[B_SLICE], stats->b8_mode_0_use[B_SLICE], 2 * sizeof(int)); - memcpy(last_mode_chroma_use, stats->intra_chroma_mode, 4 * sizeof(int)); - - frame_statistic_start = 0; - fclose(p_stat_frm); -} - - -/*! - ************************************************************************ - * \brief - * Reports the gathered information to appropriate outputs - * \par Input: - * struct inp_par *inp, \n - * ImageParameters *img, \n - * struct stat_par *stats, \n - * struct stat_par *stats \n - * - * \par Output: - * None - ************************************************************************ - */ -void report() -{ - int64 bit_use[NUM_PIC_TYPE][2] ; - int i,j; - char name[40]; - int64 total_bits; - float frame_rate; - double mean_motion_info_bit_use[2] = {0.0}; - -#ifndef WIN32 - time_t now; - struct tm *l_time; - char string[1000]; -#else - char timebuf[128]; -#endif - bit_use[I_SLICE][0] = frame_ctr[I_SLICE]; - bit_use[P_SLICE][0] = imax(frame_ctr[P_SLICE] + frame_ctr[SP_SLICE],1); - bit_use[B_SLICE][0] = frame_ctr[B_SLICE]; - - // Accumulate bit usage for inter and intra frames - for (j=0; j < NUM_PIC_TYPE; j++) - { - bit_use[j][1] = 0; - } - - for (j=0; j < NUM_PIC_TYPE; j++) - { - for(i=0; i < MAXMODE; i++) - bit_use[j][1] += stats->bit_use_mode[j][i]; - - bit_use[j][1] += stats->bit_use_header[j]; - bit_use[j][1] += stats->bit_use_mb_type[j]; - bit_use[j][1] += stats->tmp_bit_use_cbp[j]; - bit_use[j][1] += stats->bit_use_coeffC[j]; - bit_use[j][1] += stats->bit_use_coeff[0][j]; - bit_use[j][1] += stats->bit_use_coeff[1][j]; - bit_use[j][1] += stats->bit_use_coeff[2][j]; - bit_use[j][1] += stats->bit_use_delta_quant[j]; - bit_use[j][1] += stats->bit_use_stuffingBits[j]; - } - - frame_rate = (img->framerate *(float)(stats->successive_Bframe + 1)) / (float) (params->jumpd+1); - - //! Currently adding NVB bits on P rate. Maybe additional stats info should be created instead and added in log file - stats->bitrate_I = (stats->bit_ctr_I)*(frame_rate)/(float) (params->no_frames + frame_ctr[B_SLICE]); - stats->bitrate_P = (stats->bit_ctr_P)*(frame_rate)/(float) (params->no_frames + frame_ctr[B_SLICE]); - stats->bitrate_B = (stats->bit_ctr_B)*(frame_rate)/(float) (params->no_frames + frame_ctr[B_SLICE]); - - switch (params->Verbose) - { - case 0: - case 1: - default: - fprintf(stdout,"------------------ Average data all frames -----------------------------------\n\n"); - break; - case 2: - fprintf(stdout,"------------------------------------ Average data all frames ---------------------------------\n\n"); - break; - } - - if (params->Verbose != 0) - { - int impix = params->output.size_cmp[0]; - int impix_cr = params->output.size_cmp[1]; - unsigned int max_pix_value_sqd = img->max_imgpel_value_comp[0] * img->max_imgpel_value_comp[0]; - unsigned int max_pix_value_sqd_uv = img->max_imgpel_value_comp[1] * img->max_imgpel_value_comp[1]; - float csnr_y = (float) (10 * log10 (max_pix_value_sqd * - (double)((double) impix / (snr->msse_y == 0.0? 1.0 : snr->msse_y)))); - float csnr_u = (float) (10 * log10 (max_pix_value_sqd_uv * - (double)((double) impix_cr / (snr->msse_u == 0.0? 1.0 : snr->msse_u)))); - float csnr_v = (float) (10 * log10 (max_pix_value_sqd_uv * - (double)((double) impix_cr / (snr->msse_v == 0.0? 1.0 : snr->msse_v)))); - fprintf(stdout, " Total encoding time for the seq. : %.3f sec (%.2f fps)\n", tot_time*0.001, 1000.0*(params->no_frames + frame_ctr[B_SLICE])/tot_time); - fprintf(stdout, " Total ME time for sequence : %.3f sec \n\n", me_tot_time*0.001); - - fprintf(stdout," PSNR Y(dB) : %5.2f\n", snr->snr_ya); - fprintf(stdout," PSNR U(dB) : %5.2f\n", snr->snr_ua); - fprintf(stdout," PSNR V(dB) : %5.2f\n", snr->snr_va); - fprintf(stdout," cSNR Y(dB) : %5.2f (%5.2f)\n", csnr_y,snr->msse_y/impix); - fprintf(stdout," cSNR U(dB) : %5.2f (%5.2f)\n", csnr_u,snr->msse_u/impix_cr); - fprintf(stdout," cSNR V(dB) : %5.2f (%5.2f)\n\n", csnr_v,snr->msse_v/impix_cr); - } - else - fprintf(stdout, " Total encoding time for the seq. : %.3f sec (%.2f fps)\n\n", tot_time*0.001, 1000.0*(params->no_frames + frame_ctr[B_SLICE])/tot_time); - - if (frame_ctr[B_SLICE] != 0) - { - fprintf(stdout, " Total bits : %" FORMAT_OFF_T " (I %" FORMAT_OFF_T ", P %" FORMAT_OFF_T ", B %" FORMAT_OFF_T " NVB %d) \n", - total_bits=stats->bit_ctr_P + stats->bit_ctr_I + stats->bit_ctr_B + stats->bit_ctr_parametersets, - stats->bit_ctr_I, stats->bit_ctr_P, stats->bit_ctr_B, stats->bit_ctr_parametersets); - - frame_rate = (img->framerate *(float)(stats->successive_Bframe + 1)) / (float) (params->jumpd+1); - // stats->bitrate= ((float) total_bits * frame_rate)/((float) (params->no_frames + frame_ctr[B_SLICE])); - stats->bitrate= ((float) total_bits * frame_rate) / ((float)(frame_ctr[I_SLICE] + frame_ctr[P_SLICE] + frame_ctr[B_SLICE])); - - fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate/1000); - - } - else if (params->sp_periodicity == 0) - { - fprintf(stdout, " Total bits : %" FORMAT_OFF_T " (I %" FORMAT_OFF_T ", P %" FORMAT_OFF_T ", NVB %d) \n", - total_bits=stats->bit_ctr_P + stats->bit_ctr_I + stats->bit_ctr_parametersets, stats->bit_ctr_I, stats->bit_ctr_P, stats->bit_ctr_parametersets); - - - frame_rate = img->framerate / ( (float) (params->jumpd + 1) ); - stats->bitrate= ((float) total_bits * frame_rate) / ((float) params->no_frames ); - - fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate/1000); - } - else - { - fprintf(stdout, " Total bits : %" FORMAT_OFF_T " (I %" FORMAT_OFF_T ", P %" FORMAT_OFF_T ", NVB %d) \n", - total_bits=stats->bit_ctr_P + stats->bit_ctr_I + stats->bit_ctr_parametersets, stats->bit_ctr_I, stats->bit_ctr_P, stats->bit_ctr_parametersets); - - - frame_rate = img->framerate / ( (float) (params->jumpd + 1) ); - stats->bitrate= ((float) total_bits * frame_rate)/((float) params->no_frames ); - - fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate/1000); - } - - fprintf(stdout, " Bits to avoid Startcode Emulation : %d \n", stats->bit_ctr_emulationprevention); - fprintf(stdout, " Bits for parameter sets : %d \n\n", stats->bit_ctr_parametersets); - - switch (params->Verbose) - { - case 0: - case 1: - default: - fprintf(stdout,"-------------------------------------------------------------------------------\n"); - break; - case 2: - fprintf(stdout,"------------------------------------------------------------------------------------------------\n"); - break; - } - fprintf(stdout,"Exit JM %s encoder ver %s ", JM, VERSION); - fprintf(stdout,"\n"); - - // status file - if (strlen(params->StatsFile) == 0) - strcpy (params->StatsFile,"stats.dat"); - - if ((p_stat = fopen(params->StatsFile, "wt")) == 0) - { - snprintf(errortext, ET_SIZE, "Error open file %s", params->StatsFile); - error(errortext, 500); - } - - fprintf(p_stat," -------------------------------------------------------------- \n"); - fprintf(p_stat," This file contains statistics for the last encoded sequence \n"); - fprintf(p_stat," -------------------------------------------------------------- \n"); - fprintf(p_stat, " Sequence : %s\n", params->infile); - fprintf(p_stat, " No.of coded pictures : %4d\n", params->no_frames+frame_ctr[B_SLICE]); - fprintf(p_stat, " Freq. for encoded bitstream : %4.0f\n", frame_rate); - - fprintf(p_stat, " I Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_I/1000); - fprintf(p_stat, " P Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_P/1000); - // B pictures - if (stats->successive_Bframe != 0) - fprintf(p_stat, " B Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_B/1000); - fprintf(p_stat, " Total Bitrate(kb/s) : %6.2f\n", stats->bitrate/1000); - - for (i = 0; i < 3; i++) - { - fprintf(p_stat," ME Metric for Refinement Level %1d : %s\n", i, DistortionType[params->MEErrorMetric[i]]); - } - fprintf(p_stat," Mode Decision Metric : %s\n", DistortionType[params->ModeDecisionMetric]); - - switch ( params->ChromaMEEnable ) - { - case 1: - fprintf(p_stat," Motion Estimation for components : YCbCr\n"); - break; - default: - fprintf(p_stat," Motion Estimation for components : Y\n"); - break; - } - - fprintf(p_stat, " Image format : %dx%d\n", params->output.width, params->output.height); - - if (params->intra_upd) - fprintf(p_stat," Error robustness : On\n"); - else - fprintf(p_stat," Error robustness : Off\n"); - - fprintf(p_stat, " Search range : %d\n", params->search_range); - - fprintf(p_stat, " Total number of references : %d\n", params->num_ref_frames); - fprintf(p_stat, " References for P slices : %d\n", params->P_List0_refs ? params->P_List0_refs : params->num_ref_frames); - if (stats->successive_Bframe != 0) - { - fprintf(p_stat, " List0 refs for B slices : %d\n", params->B_List0_refs ? params->B_List0_refs : params->num_ref_frames); - fprintf(p_stat, " List1 refs for B slices : %d\n", params->B_List1_refs ? params->B_List1_refs : params->num_ref_frames); - } - - if (params->symbol_mode == CAVLC) - fprintf(p_stat, " Entropy coding method : CAVLC\n"); - else - fprintf(p_stat, " Entropy coding method : CABAC\n"); - - fprintf(p_stat, " Profile/Level IDC : (%d,%d)\n", params->ProfileIDC, params->LevelIDC); - if (params->MbInterlace) - fprintf(p_stat, " MB Field Coding : On \n"); - - if (params->SearchMode == EPZS) - EPZSOutputStats(p_stat, 1); - - if (params->full_search == 2) - fprintf(p_stat," Search range restrictions : none\n"); - else if (params->full_search == 1) - fprintf(p_stat," Search range restrictions : older reference frames\n"); - else - fprintf(p_stat," Search range restrictions : smaller blocks and older reference frames\n"); - - if (params->rdopt) - fprintf(p_stat," RD-optimized mode decision : used\n"); - else - fprintf(p_stat," RD-optimized mode decision : not used\n"); - - fprintf(p_stat," ---------------------|----------------|---------------|\n"); - fprintf(p_stat," Item | Intra | All frames |\n"); - fprintf(p_stat," ---------------------|----------------|---------------|\n"); - fprintf(p_stat," SNR Y(dB) |"); - fprintf(p_stat," %5.2f |", snr->snr_y1); - fprintf(p_stat," %5.2f |\n", snr->snr_ya); - fprintf(p_stat," SNR U/V (dB) |"); - fprintf(p_stat," %5.2f/%5.2f |", snr->snr_u1, snr->snr_v1); - fprintf(p_stat," %5.2f/%5.2f |\n", snr->snr_ua, snr->snr_va); - - // QUANT. - fprintf(p_stat," Average quant |"); - fprintf(p_stat," %5d |", iabs(params->qp0)); - fprintf(p_stat," %5.2f |\n", (float)stats->quant1/dmax(1.0,(float)stats->quant0)); - - fprintf(p_stat,"\n ---------------------|----------------|---------------|---------------|\n"); - fprintf(p_stat," SNR | I | P | B |\n"); - fprintf(p_stat," ---------------------|----------------|---------------|---------------|\n"); - fprintf(p_stat," SNR Y(dB) | %5.3f | %5.3f | %5.3f |\n", - snr->snr_yt[I_SLICE], snr->snr_yt[P_SLICE], snr->snr_yt[B_SLICE]); - fprintf(p_stat," SNR U(dB) | %5.3f | %5.3f | %5.3f |\n", - snr->snr_ut[I_SLICE], snr->snr_ut[P_SLICE], snr->snr_ut[B_SLICE]); - fprintf(p_stat," SNR V(dB) | %5.3f | %5.3f | %5.3f |\n", - snr->snr_vt[I_SLICE], snr->snr_vt[P_SLICE], snr->snr_vt[B_SLICE]); - - - // MODE - fprintf(p_stat,"\n ---------------------|----------------|\n"); - fprintf(p_stat," Intra | Mode used |\n"); - fprintf(p_stat," ---------------------|----------------|\n"); - - fprintf(p_stat," Mode 0 intra 4x4 | %5" FORMAT_OFF_T " |\n", stats->mode_use[I_SLICE][I4MB ]); - fprintf(p_stat," Mode 1 intra 8x8 | %5" FORMAT_OFF_T " |\n", stats->mode_use[I_SLICE][I8MB ]); - fprintf(p_stat," Mode 2+ intra 16x16 | %5" FORMAT_OFF_T " |\n", stats->mode_use[I_SLICE][I16MB]); - fprintf(p_stat," Mode intra IPCM | %5" FORMAT_OFF_T " |\n", stats->mode_use[I_SLICE][IPCM ]); - - fprintf(p_stat,"\n ---------------------|----------------|-----------------|\n"); - fprintf(p_stat," Inter | Mode used | MotionInfo bits |\n"); - fprintf(p_stat," ---------------------|----------------|-----------------|"); - fprintf(p_stat,"\n Mode 0 (copy) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[P_SLICE][0 ], (double)stats->bit_use_mode[P_SLICE][0 ]/(double)bit_use[P_SLICE][0]); - fprintf(p_stat,"\n Mode 1 (16x16) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[P_SLICE][1 ], (double)stats->bit_use_mode[P_SLICE][1 ]/(double)bit_use[P_SLICE][0]); - fprintf(p_stat,"\n Mode 2 (16x8) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[P_SLICE][2 ], (double)stats->bit_use_mode[P_SLICE][2 ]/(double)bit_use[P_SLICE][0]); - fprintf(p_stat,"\n Mode 3 (8x16) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[P_SLICE][3 ], (double)stats->bit_use_mode[P_SLICE][3 ]/(double)bit_use[P_SLICE][0]); - fprintf(p_stat,"\n Mode 4 (8x8) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[P_SLICE][P8x8], (double)stats->bit_use_mode[P_SLICE][P8x8]/(double)bit_use[P_SLICE][0]); - fprintf(p_stat,"\n Mode 5 intra 4x4 | %5" FORMAT_OFF_T " |-----------------|", stats->mode_use[P_SLICE][I4MB]); - fprintf(p_stat,"\n Mode 6 intra 8x8 | %5" FORMAT_OFF_T " |", stats->mode_use[P_SLICE][I8MB]); - fprintf(p_stat,"\n Mode 7+ intra 16x16 | %5" FORMAT_OFF_T " |", stats->mode_use[P_SLICE][I16MB]); - fprintf(p_stat,"\n Mode intra IPCM | %5" FORMAT_OFF_T " |", stats->mode_use[P_SLICE][IPCM ]); - mean_motion_info_bit_use[0] = (double)(stats->bit_use_mode[P_SLICE][0] + stats->bit_use_mode[P_SLICE][1] + stats->bit_use_mode[P_SLICE][2] - + stats->bit_use_mode[P_SLICE][3] + stats->bit_use_mode[P_SLICE][P8x8])/(double) bit_use[P_SLICE][0]; - - // B pictures - if ((stats->successive_Bframe!=0) && (frame_ctr[B_SLICE]!=0)) - { - - fprintf(p_stat,"\n\n ---------------------|----------------|-----------------|\n"); - fprintf(p_stat," B frame | Mode used | MotionInfo bits |\n"); - fprintf(p_stat," ---------------------|----------------|-----------------|"); - fprintf(p_stat,"\n Mode 0 (copy) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[B_SLICE][0 ], (double)stats->bit_use_mode[B_SLICE][0 ]/(double)frame_ctr[B_SLICE]); - fprintf(p_stat,"\n Mode 1 (16x16) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[B_SLICE][1 ], (double)stats->bit_use_mode[B_SLICE][1 ]/(double)frame_ctr[B_SLICE]); - fprintf(p_stat,"\n Mode 2 (16x8) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[B_SLICE][2 ], (double)stats->bit_use_mode[B_SLICE][2 ]/(double)frame_ctr[B_SLICE]); - fprintf(p_stat,"\n Mode 3 (8x16) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[B_SLICE][3 ], (double)stats->bit_use_mode[B_SLICE][3 ]/(double)frame_ctr[B_SLICE]); - fprintf(p_stat,"\n Mode 4 (8x8) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[B_SLICE][P8x8], (double)stats->bit_use_mode[B_SLICE][P8x8]/(double)frame_ctr[B_SLICE]); - fprintf(p_stat,"\n Mode 5 intra 4x4 | %5" FORMAT_OFF_T " |-----------------|", stats->mode_use[B_SLICE][I4MB]); - fprintf(p_stat,"\n Mode 6 intra 8x8 | %5" FORMAT_OFF_T " |", stats->mode_use[B_SLICE][I8MB]); - fprintf(p_stat,"\n Mode 7+ intra 16x16 | %5" FORMAT_OFF_T " |", stats->mode_use[B_SLICE][I16MB]); - fprintf(p_stat,"\n Mode intra IPCM | %5" FORMAT_OFF_T " |", stats->mode_use[B_SLICE][IPCM ]); - mean_motion_info_bit_use[1] = (double)(stats->bit_use_mode[B_SLICE][0] + stats->bit_use_mode[B_SLICE][1] + stats->bit_use_mode[B_SLICE][2] - + stats->bit_use_mode[B_SLICE][3] + stats->bit_use_mode[B_SLICE][P8x8])/(double) frame_ctr[B_SLICE]; - } - - fprintf(p_stat,"\n\n ---------------------|----------------|----------------|----------------|\n"); - fprintf(p_stat," Bit usage: | Intra | Inter | B frame |\n"); - fprintf(p_stat," ---------------------|----------------|----------------|----------------|\n"); - - fprintf(p_stat," Header |"); - fprintf(p_stat," %10.2f |", (float) stats->bit_use_header[I_SLICE]/bit_use[I_SLICE][0]); - fprintf(p_stat," %10.2f |", (float) stats->bit_use_header[P_SLICE]/bit_use[P_SLICE][0]); - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) - fprintf(p_stat," %10.2f |", (float) stats->bit_use_header[B_SLICE]/frame_ctr[B_SLICE]); - else fprintf(p_stat," %10.2f |", 0.); - fprintf(p_stat,"\n"); - - fprintf(p_stat," Mode |"); - fprintf(p_stat," %10.2f |", (float)stats->bit_use_mb_type[I_SLICE]/bit_use[I_SLICE][0]); - fprintf(p_stat," %10.2f |", (float)stats->bit_use_mb_type[P_SLICE]/bit_use[P_SLICE][0]); - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) - fprintf(p_stat," %10.2f |", (float)stats->bit_use_mb_type[B_SLICE]/frame_ctr[B_SLICE]); - else fprintf(p_stat," %10.2f |", 0.); - fprintf(p_stat,"\n"); - - fprintf(p_stat," Motion Info |"); - fprintf(p_stat," ./. |"); - fprintf(p_stat," %10.2f |", mean_motion_info_bit_use[0]); - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) - fprintf(p_stat," %10.2f |", mean_motion_info_bit_use[1]); - else fprintf(p_stat," %10.2f |", 0.); - fprintf(p_stat,"\n"); - - fprintf(p_stat," CBP Y/C |"); - fprintf(p_stat," %10.2f |", (float)stats->tmp_bit_use_cbp[I_SLICE]/bit_use[I_SLICE][0]); - fprintf(p_stat," %10.2f |", (float)stats->tmp_bit_use_cbp[P_SLICE]/bit_use[P_SLICE][0]); - if ((stats->successive_Bframe != 0) && (bit_use[B_SLICE][0] != 0)) - fprintf(p_stat," %10.2f |", (float)stats->tmp_bit_use_cbp[B_SLICE]/bit_use[B_SLICE][0]); - else fprintf(p_stat," %10.2f |", 0.); - fprintf(p_stat,"\n"); - - if (stats->successive_Bframe != 0 && frame_ctr[B_SLICE] != 0) - fprintf(p_stat," Coeffs. Y | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeff[0][I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeff[0][P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_coeff[0][B_SLICE]/frame_ctr[B_SLICE]); - else - fprintf(p_stat," Coeffs. Y | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeff[0][I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeff[0][P_SLICE]/(float)bit_use[P_SLICE][0], 0.); - - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) - fprintf(p_stat," Coeffs. C | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeffC[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeffC[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_coeffC[B_SLICE]/frame_ctr[B_SLICE]); - else - fprintf(p_stat," Coeffs. C | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeffC[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeffC[P_SLICE]/bit_use[P_SLICE][0], 0.); - if(img->P444_joined) - { - if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0) - fprintf(p_stat," Coeffs. CB | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeff[1][I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeff[1][P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_coeff[1][B_SLICE]/frame_ctr[B_SLICE]); - else - fprintf(p_stat," Coeffs. CB | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeff[1][I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeff[1][P_SLICE]/bit_use[P_SLICE][0], 0.); - - if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0) - fprintf(p_stat," Coeffs. CR | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeff[2][I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeff[2][P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_coeff[2][B_SLICE]/frame_ctr[B_SLICE]); - else - fprintf(p_stat," Coeffs. CR | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_coeff[2][I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_coeff[2][P_SLICE]/bit_use[P_SLICE][0], 0.); - } - - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) - fprintf(p_stat," Delta quant | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_delta_quant[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_delta_quant[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_delta_quant[B_SLICE]/frame_ctr[B_SLICE]); - else - fprintf(p_stat," Delta quant | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_delta_quant[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_delta_quant[P_SLICE]/bit_use[P_SLICE][0], 0.); - - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) - fprintf(p_stat," Stuffing Bits | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_stuffingBits[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_stuffingBits[P_SLICE]/bit_use[P_SLICE][0], (float)stats->bit_use_stuffingBits[B_SLICE]/frame_ctr[B_SLICE]); - else - fprintf(p_stat," Stuffing Bits | %10.2f | %10.2f | %10.2f |\n", - (float)stats->bit_use_stuffingBits[I_SLICE]/bit_use[I_SLICE][0], (float)stats->bit_use_stuffingBits[P_SLICE]/bit_use[P_SLICE][0], 0.); - - - - fprintf(p_stat," ---------------------|----------------|----------------|----------------|\n"); - - fprintf(p_stat," average bits/frame |"); - - fprintf(p_stat," %10.2f |", (float) bit_use[I_SLICE][1]/(float) bit_use[I_SLICE][0] ); - fprintf(p_stat," %10.2f |", (float) bit_use[P_SLICE][1]/(float) bit_use[P_SLICE][0] ); - - if(stats->successive_Bframe!=0 && frame_ctr[B_SLICE]!=0) - fprintf(p_stat," %10.2f |", (float) bit_use[B_SLICE][1]/ (float) frame_ctr[B_SLICE] ); - else fprintf(p_stat," %10.2f |", 0.); - - fprintf(p_stat,"\n"); - fprintf(p_stat," ---------------------|----------------|----------------|----------------|\n"); - - fclose(p_stat); - - // write to log file - if ((p_log = fopen("log.dat", "r")) == 0) // check if file exists - { - if ((p_log = fopen("log.dat", "a")) == NULL) // append new statistic at the end - { - snprintf(errortext, ET_SIZE, "Error open file %s \n", "log.dat"); - error(errortext, 500); - } - else // Create header for new log file - { - fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); - fprintf(p_log,"| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n"); - fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); - fprintf(p_log,"| ver | Date | Time | Sequence | #Img |P/MbInt| QPI| QPP| QPB| Format |Iperiod| #B | FMES | Hdmd | S.R |#Ref | Freq |Coding|RD-opt|Intra upd|8x8Tr| SNRY 1| SNRU 1| SNRV 1| SNRY N| SNRU N| SNRV N|#Bitr I|#Bitr P|#Bitr B|#Bitr IPB| Total Time | Me Time |\n"); - fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); - - } - } - else - { - fclose (p_log); - if ((p_log = fopen("log.dat", "a")) == NULL) // File exists, just open for appending - { - snprintf(errortext, ET_SIZE, "Error open file %s \n", "log.dat"); - error(errortext, 500); - } - } - fprintf(p_log,"|%5s/%-5s", VERSION, EXT_VERSION); - -#ifdef WIN32 - _strdate( timebuf ); - fprintf(p_log,"| %1.5s |", timebuf ); - - _strtime( timebuf); - fprintf(p_log," % 1.5s |", timebuf); -#else - now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time' - time (&now); - l_time = localtime (&now); - strftime (string, sizeof string, "%d-%b-%Y", l_time); - fprintf(p_log,"| %1.5s |", string ); - - strftime (string, sizeof string, "%H:%M:%S", l_time); - fprintf(p_log," %1.5s |", string ); -#endif - - for (i=0; i < 40; i++) - name[i] = params->infile[i + imax(0, ((int) strlen(params->infile)) - 40)]; // write last part of path, max 40 chars - fprintf(p_log,"%40.40s|",name); - - fprintf(p_log,"%5d | %d/%d |", params->no_frames, params->PicInterlace, params->MbInterlace); - fprintf(p_log," %-3d| %-3d| %-3d|", params->qp0, params->qpN, params->qpB); - - fprintf(p_log,"%4dx%-4d|", params->output.width, params->output.height); - fprintf(p_log," %3d |%3d |", params->intra_period, stats->successive_Bframe); - - - switch( params->SearchMode ) - { - case UM_HEX: - fprintf(p_log," HEX |"); - break; - case UM_HEX_SIMPLE: - fprintf(p_log," SHEX |"); - break; - case EPZS: - fprintf(p_log," EPZS |"); - break; - case FAST_FULL_SEARCH: - fprintf(p_log," FFS |"); - break; - default: - fprintf(p_log," FS |"); - break; - } - - fprintf(p_log," %1d%1d%1d |", params->MEErrorMetric[F_PEL], params->MEErrorMetric[H_PEL], params->MEErrorMetric[Q_PEL]); - - fprintf(p_log," %3d | %2d |", params->search_range, params->num_ref_frames ); - - fprintf(p_log," %5.2f|", (img->framerate *(float) (stats->successive_Bframe + 1)) / (float)(params->jumpd + 1)); - - if (params->symbol_mode == CAVLC) - fprintf(p_log," CAVLC|"); - else - fprintf(p_log," CABAC|"); - - fprintf(p_log," %d |", params->rdopt); - - if (params->intra_upd == 1) - fprintf(p_log," ON |"); - else - fprintf(p_log," OFF |"); - - fprintf(p_log," %d |", params->Transform8x8Mode); - - fprintf(p_log,"%7.3f|%7.3f|%7.3f|", snr->snr_y1,snr->snr_u1,snr->snr_v1); - fprintf(p_log,"%7.3f|%7.3f|%7.3f|", snr->snr_ya,snr->snr_ua,snr->snr_va); - /* - fprintf(p_log,"%-5.3f|%-5.3f|%-5.3f|", snr->snr_yt[I_SLICE], snr->snr_ut[I_SLICE], snr->snr_vt[I_SLICE]); - fprintf(p_log,"%-5.3f|%-5.3f|%-5.3f|", snr->snr_yt[P_SLICE], snr->snr_ut[P_SLICE], snr->snr_vt[P_SLICE]); - fprintf(p_log,"%-5.3f|%-5.3f|%-5.3f|", snr->snr_yt[B_SLICE], snr->snr_ut[B_SLICE], snr->snr_vt[B_SLICE]); - */ - fprintf(p_log,"%7.0f|%7.0f|%7.0f|%9.0f|", stats->bitrate_I,stats->bitrate_P,stats->bitrate_B, stats->bitrate); - - fprintf(p_log," %12d | %12d |", (int)tot_time,(int)me_tot_time); - - - fprintf(p_log,"\n"); - - fclose(p_log); - - p_log = fopen("data.txt", "a"); - - if ((stats->successive_Bframe != 0) && (frame_ctr[B_SLICE] != 0)) // B picture used - { - fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5" FORMAT_OFF_T " " - "%2.2f %2.2f %2.2f %5d " - "%2.2f %2.2f %2.2f %5" FORMAT_OFF_T " %5" FORMAT_OFF_T " %.3f\n", - params->no_frames, params->qp0, params->qpN, - snr->snr_y1, - snr->snr_u1, - snr->snr_v1, - stats->bit_ctr_I, - 0.0, - 0.0, - 0.0, - 0, - snr->snr_ya, - snr->snr_ua, - snr->snr_va, - (stats->bit_ctr_I+stats->bit_ctr)/(params->no_frames+frame_ctr[B_SLICE]), - stats->bit_ctr_B/frame_ctr[B_SLICE], - (double)0.001*tot_time/(params->no_frames+frame_ctr[B_SLICE])); - } - else - { - if (params->no_frames != 0) - fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5" FORMAT_OFF_T " " - "%2.2f %2.2f %2.2f %5d " - "%2.2f %2.2f %2.2f %5" FORMAT_OFF_T " %5d %.3f\n", - params->no_frames, params->qp0, params->qpN, - snr->snr_y1, - snr->snr_u1, - snr->snr_v1, - stats->bit_ctr_I, - 0.0, - 0.0, - 0.0, - 0, - snr->snr_ya, - snr->snr_ua, - snr->snr_va, - (stats->bit_ctr_I+stats->bit_ctr)/params->no_frames, - 0, - (double)0.001*tot_time/params->no_frames); - } - - fclose(p_log); - - if (params->ReportFrameStats) - { - if ((p_log = fopen("stat_frame.dat", "a")) == NULL) // append new statistic at the end - { - snprintf(errortext, ET_SIZE, "Error open file %s \n", "stat_frame.dat.dat"); - // error(errortext, 500); - } - else - { - fprintf(p_log," --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); - fclose(p_log); - } - } -} - - -/*! - ************************************************************************ - * \brief - * Prints the header of the protocol. - * \par Input: - * struct inp_par *inp - * \par Output: - * none - ************************************************************************ - */ -void information_init(void) -{ - int i; - static char yuv_types[4][10] = {"YUV 4:0:0", "YUV 4:2:0", "YUV 4:2:2", "YUV 4:4:4"}; - switch (params->Verbose) - { - case 0: - case 1: - default: - printf("------------------------------- JM %4.4s %7.7s -------------------------------\n", VERSION, EXT_VERSION); - break; - case 2: - printf("--------------------------------------- JM %4.4s %7.7s ----------------------------------------\n", VERSION, EXT_VERSION); - break; - } - - fprintf(stdout, " Input YUV file : %s \n", params->infile); - fprintf(stdout, " Output H.264 bitstream : %s \n", params->outfile); - if (p_dec != -1) - fprintf(stdout, " Output YUV file : %s \n", params->ReconFile); - fprintf(stdout, " YUV Format : %s \n", &yuv_types[img->yuv_format][0]);//img->yuv_format==YUV422?"YUV 4:2:2":(img->yuv_format==YUV444)?"YUV 4:4:4":"YUV 4:2:0"); - fprintf(stdout, " Frames to be encoded I-P/B : %d/%d\n", params->no_frames, (params->successive_Bframe*(params->no_frames-1))); - if (params->Verbose != 0) - { - fprintf(stdout, " Freq. for encoded bitstream : %1.0f\n", img->framerate/(float)(params->jumpd+1)); - fprintf(stdout, " PicInterlace / MbInterlace : %d/%d\n", params->PicInterlace, params->MbInterlace); - fprintf(stdout, " Transform8x8Mode : %d\n", params->Transform8x8Mode); - - for (i=0; i<3; i++) - { - fprintf(stdout," ME Metric for Refinement Level %1d : %s\n", i, DistortionType[params->MEErrorMetric[i]]); - } - fprintf(stdout, " Mode Decision Metric : %s\n", DistortionType[params->ModeDecisionMetric]); - - switch ( params->ChromaMEEnable ) - { - case 1: - fprintf(stdout," Motion Estimation for components : YCbCr\n"); - break; - default: - fprintf(stdout," Motion Estimation for components : Y\n"); - break; - } - - fprintf(stdout, " Image format : %dx%d (%dx%d)\n", params->output.width, params->output.height, img->width,img->height); - - if (params->intra_upd) - fprintf(stdout," Error robustness : On\n"); - else - fprintf(stdout," Error robustness : Off\n"); - fprintf(stdout, " Search range : %d\n", params->search_range); - - fprintf(stdout, " Total number of references : %d\n", params->num_ref_frames); - fprintf(stdout, " References for P slices : %d\n", params->P_List0_refs? params->P_List0_refs:params->num_ref_frames); - if (stats->successive_Bframe != 0) - { - fprintf(stdout," List0 references for B slices : %d\n", params->B_List0_refs? params->B_List0_refs:params->num_ref_frames); - fprintf(stdout," List1 references for B slices : %d\n", params->B_List1_refs? params->B_List1_refs:params->num_ref_frames); - } - - // B pictures - fprintf(stdout, " Sequence type :"); - - if (stats->successive_Bframe > 0 && params->HierarchicalCoding) - { - fprintf(stdout, " Hierarchy (QP: I %d, P %d, B %d) \n", - params->qp0, params->qpN, params->qpB); - } - else if (stats->successive_Bframe > 0) - { - char seqtype[80]; - int i,j; - - strcpy (seqtype,"I"); - - for (j=0; j < 2; j++) - { - for (i=0; i < stats->successive_Bframe; i++) - { - if (params->BRefPictures) - strncat(seqtype,"-RB", imax(0, (int) (79-strlen(seqtype)))); - else - strncat(seqtype,"-B", imax(0, (int) (79-strlen(seqtype)))); - } - strncat(seqtype,"-P", imax(0, (int) (79-strlen(seqtype)))); - } - if (params->BRefPictures) - fprintf(stdout, " %s (QP: I %d, P %d, RB %d) \n", seqtype, params->qp0, params->qpN, iClip3(0, 51, params->qpB + params->qpBRSOffset)); - else - fprintf(stdout, " %s (QP: I %d, P %d, B %d) \n", seqtype, params->qp0, params->qpN, params->qpB); - } - else if (stats->successive_Bframe == 0 && params->sp_periodicity == 0) fprintf(stdout, " IPPP (QP: I %d, P %d) \n", params->qp0, params->qpN); - - else fprintf(stdout, " I-P-P-SP-P (QP: I %d, P %d, SP (%d, %d)) \n", params->qp0, params->qpN, params->qpsp, params->qpsp_pred); - - // report on entropy coding method - if (params->symbol_mode == CAVLC) - fprintf(stdout," Entropy coding method : CAVLC\n"); - else - fprintf(stdout," Entropy coding method : CABAC\n"); - - fprintf(stdout, " Profile/Level IDC : (%d,%d)\n", params->ProfileIDC, params->LevelIDC); - - if (params->SearchMode == UM_HEX) - fprintf(stdout, " Motion Estimation Scheme : HEX\n"); - else if (params->SearchMode == UM_HEX_SIMPLE) - fprintf(stdout, " Motion Estimation Scheme : SHEX\n"); - else if (params->SearchMode == EPZS) - { - fprintf(stdout, " Motion Estimation Scheme : EPZS\n"); - EPZSOutputStats(stdout, 0); - } - else if (params->SearchMode == FAST_FULL_SEARCH) - fprintf(stdout, " Motion Estimation Scheme : Fast Full Search\n"); - else - fprintf(stdout, " Motion Estimation Scheme : Full Search\n"); - - if (params->full_search == 2) - fprintf(stdout," Search range restrictions : none\n"); - else if (params->full_search == 1) - fprintf(stdout," Search range restrictions : older reference frames\n"); - else - fprintf(stdout," Search range restrictions : smaller blocks and older reference frames\n"); - - if (params->rdopt) - fprintf(stdout," RD-optimized mode decision : used\n"); - else - fprintf(stdout," RD-optimized mode decision : not used\n"); - - switch(params->partition_mode) - { - case PAR_DP_1: - fprintf(stdout," Data Partitioning Mode : 1 partition \n"); - break; - case PAR_DP_3: - fprintf(stdout," Data Partitioning Mode : 3 partitions \n"); - break; - default: - fprintf(stdout," Data Partitioning Mode : not supported\n"); - break; - } - - switch(params->of_mode) - { - case PAR_OF_ANNEXB: - fprintf(stdout," Output File Format : H.264/AVC Annex B Byte Stream Format \n"); - break; - case PAR_OF_RTP: - fprintf(stdout," Output File Format : RTP Packet File Format \n"); - break; - default: - fprintf(stdout," Output File Format : not supported\n"); - break; - } - } - - - switch (params->Verbose) - { - case 0: - default: - printf("-------------------------------------------------------------------------------\n"); - printf("\nEncoding. Please Wait.\n\n"); - break; - case 1: - printf("-------------------------------------------------------------------------------\n"); - printf(" Frame Bit/pic QP SnrY SnrU SnrV Time(ms) MET(ms) Frm/Fld Ref \n"); - printf("-------------------------------------------------------------------------------\n"); - break; - case 2: - printf("------------------------------------------------------------------------------------------------\n"); - printf(" Frame Bit/pic WP QP QL SnrY SnrU SnrV Time(ms) MET(ms) Frm/Fld I D L0 L1 RDP Ref\n"); - printf("------------------------------------------------------------------------------------------------\n"); - break; - } -} /*! ************************************************************************ @@ -2034,46 +1017,41 @@ int init_orig_buffers(void) int memory_size = 0; int nplane; - // allocate memory for reference frame buffers: imgY_org_frm, imgUV_org_frm + // allocate memory for reference frame buffers: img_org_frm if( IS_INDEPENDENT(params) ) { for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - memory_size += get_mem2Dpel(&imgY_org_frm_JV[nplane], img->height, img->width); + memory_size += get_mem2Dpel(&img_org_frm[nplane], img->height, img->width); } } else { - memory_size += get_mem2Dpel(&imgY_org_frm, img->height, img->width); - } - - if (img->yuv_format != YUV400) - { - int i, j, k; - memory_size += get_mem3Dpel(&imgUV_org_frm, 2, img->height_cr, img->width_cr); - for (k = 0; k < 2; k++) - for (j = 0; j < img->height_cr; j++) - for (i = 0; i < img->width_cr; i++) - imgUV_org_frm[k][j][i] = 128; + memory_size += get_mem2Dpel(&img_org_frm[0], img->height, img->width); + if (img->yuv_format != YUV400) + { + int i, j, k; + memory_size += get_mem2Dpel(&img_org_frm[1], img->height_cr, img->width_cr); + memory_size += get_mem2Dpel(&img_org_frm[2], img->height_cr, img->width_cr); + for (k = 1; k < 3; k++) + for (j = 0; j < img->height_cr; j++) + for (i = 0; i < img->width_cr; i++) + img_org_frm[k][j][i] = 128; + } } - if (!active_sps->frame_mbs_only_flag) { - // allocate memory for reference frame buffers: imgY_org, imgUV_org - init_top_bot_planes(imgY_org_frm, img->height, img->width, &imgY_org_top, &imgY_org_bot); + // allocate memory for field reference frame buffers + init_top_bot_planes(img_org_frm[0], img->height, img->width, &img_org_top[0], &img_org_bot[0]); if (img->yuv_format != YUV400) { - if ((imgUV_org_top = (imgpel***)calloc(2, sizeof(imgpel**))) == NULL) - no_mem_exit("init_global_buffers: imgUV_org_top"); - if ((imgUV_org_bot = (imgpel***)calloc(2, sizeof(imgpel**))) == NULL) - no_mem_exit("init_global_buffers: imgUV_org_bot"); memory_size += 4*(sizeof(imgpel**)); - memory_size += init_top_bot_planes(imgUV_org_frm[0], img->height_cr, img->width_cr, &(imgUV_org_top[0]), &(imgUV_org_bot[0])); - memory_size += init_top_bot_planes(imgUV_org_frm[1], img->height_cr, img->width_cr, &(imgUV_org_top[1]), &(imgUV_org_bot[1])); + memory_size += init_top_bot_planes(img_org_frm[1], img->height_cr, img->width_cr, &(img_org_top[1]), &(img_org_bot[1])); + memory_size += init_top_bot_planes(img_org_frm[2], img->height_cr, img->width_cr, &(img_org_top[2]), &(img_org_bot[2])); } } return memory_size; @@ -2175,18 +1153,10 @@ int init_global_buffers(void) if (params->rdopt == 3) { - memory_size += get_mem2Dint(&decs->resY, MB_BLOCK_SIZE, MB_BLOCK_SIZE); - if ((decs->decref = (imgpel****) calloc(params->NoOfDecoders, sizeof(imgpel***))) == NULL) - no_mem_exit("init_global_buffers: decref"); - for (j = 0; j < params->NoOfDecoders; j++) - { - memory_size += get_mem3Dpel(&decs->decref[j], img->max_num_references+1, img->height, img->width); - } - memory_size += get_mem2Dpel(&decs->RefBlock, BLOCK_SIZE, BLOCK_SIZE); - memory_size += get_mem3Dpel(&decs->decY, params->NoOfDecoders, img->height, img->width); - memory_size += get_mem3Dpel(&decs->decY_best, params->NoOfDecoders, img->height, img->width); - memory_size += get_mem2D(&decs->status_map, img->FrameHeightInMbs, img->PicWidthInMbs); - memory_size += get_mem2D(&decs->dec_mb_mode, img->FrameHeightInMbs, img->PicWidthInMbs); + decs->dec_mbY = NULL; + decs->dec_mbY8x8 = NULL; + memory_size += get_mem3Dpel(&decs->dec_mbY, params->NoOfDecoders, 16, 16); + memory_size += get_mem3Dpel(&decs->dec_mbY8x8, params->NoOfDecoders, 16, 16); } if (params->RestrictRef) { @@ -2217,7 +1187,7 @@ int init_global_buffers(void) memory_size += smpUMHEX_get_mem(); } else if (params->SearchMode == EPZS) - memory_size += EPZSInit(); + memory_size += EPZSInit(params, img); } if (params->RCEnable) @@ -2245,6 +1215,25 @@ int init_global_buffers(void) img_cr_padded_size_x2 = (img_cr_padded_size_x << 1); img_cr_padded_size_x4 = (img_cr_padded_size_x << 2); img_cr_padded_size_x_m8 = (img_cr_padded_size_x - 8); + + // RGB images for distortion calculation + // Recommended to do this allocation (and de-allocation) in + // the appropriate file instead of here. + if(params->DistortionYUVtoRGB) + { + for( j = 0; j < 3; j++ ) + { + memory_size += get_mem2Dpel (&imgRGB_src.data[j], img->height, img->width); + memory_size += get_mem2Dpel (&imgRGB_ref.data[j], img->height, img->width); + } + } + + pWPX = NULL; + if ( params->WPMCPrecision ) + { + wpxInitWPXObject(); + } + return memory_size; } @@ -2262,28 +1251,27 @@ void free_orig_planes(void) int nplane; for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - free_mem2Dpel(imgY_org_frm_JV[nplane]); // free ref frame buffers + free_mem2Dpel(img_org_frm[nplane]); // free ref frame buffers } } else { - free_mem2Dpel(imgY_org_frm); // free ref frame buffers + free_mem2Dpel(img_org_frm[0]); // free ref frame buffers + if (img->yuv_format != YUV400) + { + free_mem2Dpel(img_org_frm[1]); + free_mem2Dpel(img_org_frm[2]); + } } - if (img->yuv_format != YUV400) - free_mem3Dpel(imgUV_org_frm); - - if (!active_sps->frame_mbs_only_flag) { - free_top_bot_planes(imgY_org_top, imgY_org_bot); + free_top_bot_planes(img_org_top[0], img_org_bot[0]); if (img->yuv_format != YUV400) { - free_top_bot_planes(imgUV_org_top[0], imgUV_org_bot[0]); - free_top_bot_planes(imgUV_org_top[1], imgUV_org_bot[1]); - free (imgUV_org_top); - free (imgUV_org_bot); + free_top_bot_planes(img_org_top[1], img_org_bot[1]); + free_top_bot_planes(img_org_top[2], img_org_bot[2]); } } } @@ -2353,6 +1341,11 @@ void free_global_buffers(void) free_QMatrix(); free_QOffsets(); + if ( params->WPMCPrecision ) + { + wpxFreeWPXObject(); + } + if (params->WeightedPrediction || params->WeightedBiprediction || params->GenerateMultiplePPS) { free_mem3Dint(wp_weight ); @@ -2376,7 +1369,8 @@ void free_global_buffers(void) // free intra pred mode buffer for blocks free_mem2D((byte**)img->ipredmode); free_mem2D((byte**)img->ipredmode8x8); - + free(img->b8x8info); + if( IS_INDEPENDENT(params) ) { for( i=0; i<MAX_PLANE; i++ ){ @@ -2404,37 +1398,16 @@ void free_global_buffers(void) if (params->rdopt == 3) { - free(decs->resY[0]); - free(decs->resY); - - free(decs->RefBlock[0]); - free(decs->RefBlock); - - for (j=0; j < params->NoOfDecoders; j++) + if (decs->dec_mbY) { - free(decs->decY[j][0]); - free(decs->decY[j]); - - free(decs->decY_best[j][0]); - free(decs->decY_best[j]); - - for (i=0; i < img->max_num_references+1; i++) - { - free(decs->decref[j][i][0]); - free(decs->decref[j][i]); - } - free(decs->decref[j]); + free_mem3Dpel(decs->dec_mbY); + } + if (decs->dec_mbY8x8) + { + free_mem3Dpel(decs->dec_mbY8x8); } - free(decs->decY); - free(decs->decY_best); - free(decs->decref); - - free(decs->status_map[0]); - free(decs->status_map); - - free(decs->dec_mb_mode[0]); - free(decs->dec_mb_mode); } + if (params->RestrictRef) { free(pixel_map[0]); @@ -2454,13 +1427,14 @@ void free_global_buffers(void) free_mem3Dint(img->nz_coeff); - free_mem2Ddb_offset (img->lambda_md, img->bitdepth_luma_qp_scale); - free_mem3Ddb_offset (img->lambda_me, 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); - free_mem3Dint_offset(img->lambda_mf, 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); + free_mem2Dolm (img->lambda, img->bitdepth_luma_qp_scale); + free_mem2Dodouble (img->lambda_md, img->bitdepth_luma_qp_scale); + free_mem3Dodouble (img->lambda_me, 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); + free_mem3Doint (img->lambda_mf, 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale); if (params->CtxAdptLagrangeMult == 1) { - free_mem2Ddb_offset(img->lambda_mf_factor, img->bitdepth_luma_qp_scale); + free_mem2Dodouble(img->lambda_mf_factor, img->bitdepth_luma_qp_scale); } if (!params->IntraProfile) @@ -2475,7 +1449,7 @@ void free_global_buffers(void) } else if (params->SearchMode == EPZS) { - EPZSDelete(); + EPZSDelete(params); } } @@ -2489,6 +1463,17 @@ void free_global_buffers(void) free_mem2Dpel(imgUV_tmp[0]); free_mem2Dpel(imgUV_tmp[1]); } + + // Again process should be moved into cconv_yuv2rgb.c file for cleanliness + // These should not be globals but instead only be visible through that code. + if(params->DistortionYUVtoRGB) + { + for( i = 0; i < 3; i++ ) + { + free_mem2Dpel(imgRGB_src.data[i]); + free_mem2Dpel(imgRGB_ref.data[i]); + } + } } /*! @@ -2509,6 +1494,27 @@ int get_mem_mv (short ******* mv) return 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short); } +/*! + ************************************************************************ + * \brief + * Allocate memory for bipredictive mv + * \par Input: + * Image Parameters ImageParameters *img \n + * int****** mv + * \return memory size in bytes + ************************************************************************ + */ +int get_mem_bipred_mv (short******** bipred_mv) +{ + if(((*bipred_mv) = (short*******)calloc(2, sizeof(short******))) == NULL) + no_mem_exit("get_mem_bipred_mv: bipred_mv"); + + get_mem6Dshort(*bipred_mv, 2 * 2, img->max_num_references, 9, 4, 4, 2); + (*bipred_mv)[1] = (*bipred_mv)[0] + 2; + + return 2 * 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short); +} + /*! ************************************************************************ * \brief @@ -2523,6 +1529,27 @@ void free_mem_mv (short****** mv) } +/*! + ************************************************************************ + * \brief + * Free memory from mv + * \par Input: + * int****** mv + ************************************************************************ + */ +void free_mem_bipred_mv (short******* bipred_mv) +{ + if (bipred_mv) + { + free_mem6Dshort(*bipred_mv); + free (bipred_mv); + } + else + { + error ("free_mem_bipred_mv: trying to free unused memory",100); + } +} + /*! ************************************************************************ * \brief @@ -2626,7 +1653,7 @@ int decide_fld_frame(float snr_frame_Y, float snr_field_Y, int bit_field, int bi * Set the image type for I,P and SP pictures (not B!) ************************************************************************ */ -void SetImgType(void) +static void SetImgType(void) { int intra_refresh = (params->intra_period == 0) ? (IMG_NUMBER == 0) : (( ( img->frm_number - img->lastIntraNumber) % params->intra_period ) == 0); int idr_refresh; diff --git a/lencod/src/loopFilter.c b/lencod/src/loopFilter.c index d4adbda..0473c9e 100644 --- a/lencod/src/loopFilter.c +++ b/lencod/src/loopFilter.c @@ -292,12 +292,12 @@ void GetStrengthNormal(byte Strength[MB_BLOCK_SIZE],ImageParameters *img,int MbQ if (!ANY_INTRA) { - list0_refPicIdArr = enc_picture->ref_pic_id[LIST_0]; - list1_refPicIdArr = enc_picture->ref_pic_id[LIST_1]; - list0_mv = enc_picture->mv[LIST_0]; - list1_mv = enc_picture->mv[LIST_1]; - list0_refIdxArr = enc_picture->ref_idx[LIST_0]; - list1_refIdxArr = enc_picture->ref_idx[LIST_1]; + list0_refPicIdArr = enc_picture->motion.ref_pic_id[LIST_0]; + list1_refPicIdArr = enc_picture->motion.ref_pic_id[LIST_1]; + list0_mv = enc_picture->motion.mv[LIST_0]; + list1_mv = enc_picture->motion.mv[LIST_1]; + list0_refIdxArr = enc_picture->motion.ref_idx[LIST_0]; + list1_refIdxArr = enc_picture->motion.ref_idx[LIST_1]; get_mb_block_pos (MbQAddr, &mb_x, &mb_y); mb_x <<= 2; @@ -413,12 +413,12 @@ void GetStrengthMBAff(byte Strength[16],ImageParameters *img,int MbQAddr,int dir int *mb_size = img->mb_size[IS_LUMA]; MbQ = &(img->mb_data[MbQAddr]); - list0_mv = enc_picture->mv[LIST_0]; - list1_mv = enc_picture->mv[LIST_1]; - list0_refIdxArr = enc_picture->ref_idx[LIST_0]; - list1_refIdxArr = enc_picture->ref_idx[LIST_1]; - list0_refPicIdArr = enc_picture->ref_pic_id[LIST_0]; - list1_refPicIdArr = enc_picture->ref_pic_id[LIST_1]; + list0_mv = enc_picture->motion.mv[LIST_0]; + list1_mv = enc_picture->motion.mv[LIST_1]; + list0_refIdxArr = enc_picture->motion.ref_idx[LIST_0]; + list1_refIdxArr = enc_picture->motion.ref_idx[LIST_1]; + list0_refPicIdArr = enc_picture->motion.ref_pic_id[LIST_0]; + list1_refPicIdArr = enc_picture->motion.ref_pic_id[LIST_1]; for( idx=0 ; idx<16 ; idx++ ) { diff --git a/lencod/src/macroblock.c b/lencod/src/macroblock.c index bb9cd98..eddaa0d 100644 --- a/lencod/src/macroblock.c +++ b/lencod/src/macroblock.c @@ -25,6 +25,7 @@ #include <math.h> #include "global.h" +#include "enc_statistics.h" #include "elements.h" #include "macroblock.h" @@ -39,6 +40,7 @@ #include "transform8x8.h" #include "transform.h" #include "me_fullsearch.h" +#include "me_fullfast.h" #include "symbol.h" #include "rdo_quant.h" @@ -48,11 +50,32 @@ #define TRACE_SE(trace,str) #endif -extern const byte QP_SCALE_CR[52] ; +const byte QP_SCALE_CR[52]= +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, + 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37, + 37,38,38,38,39,39,39,39 +}; -//Rate control -extern int delta_qp_mbaff[2][2],delta_qp_mbaff[2][2]; -extern int qp_mbaff[2][2],qp_mbaff[2][2]; +static const int block8x8_idx[3][4][4] = +{ + { {0, 1, 0, 0}, + {2, 3, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { {0, 1, 0, 0}, + {0, 1, 0, 0}, + {2, 3, 0, 0}, + {2, 3, 0, 0}, + }, + { {0, 0, 1, 1}, + {0, 0, 1, 1}, + {2, 2, 3, 3}, + {2, 2, 3, 3} + } +}; static int slice_too_big(int rlc_bits); @@ -63,14 +86,10 @@ static int writeCBPandDquant (Macroblock* currMB); extern int *mvbits; -extern int QP2QUANT[40]; -extern int ver_offset[4][8][4]; -extern int hor_offset[4][8][4]; - static int diff [16]; static int diff64[64]; -static const unsigned char subblk_offset_x[3][8][4] = +const unsigned char subblk_offset_x[3][8][4] = { { {0, 4, 0, 4}, @@ -104,7 +123,7 @@ static const unsigned char subblk_offset_x[3][8][4] = } }; -static const unsigned char subblk_offset_y[3][8][4] = +const unsigned char subblk_offset_y[3][8][4] = { { {0, 0, 4, 4}, @@ -166,13 +185,20 @@ void set_MB_parameters (int mb_addr) { if (img->mb_data[mb_addr].mb_field) { - pCurImg = (mb_addr & 0x01) ? imgY_org_bot : imgY_org_top; + pCurImg = (mb_addr & 0x01) ? img_org_bot[0] : img_org_top[0]; pImgOrg[0] = pCurImg; if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params)) { - imgUV_org = (mb_addr & 0x01) ? imgUV_org_bot : imgUV_org_top; - pImgOrg[1] = imgUV_org[0]; - pImgOrg[2] = imgUV_org[1]; + if (mb_addr & 0x01) + { + pImgOrg[1] = img_org_bot[1]; + pImgOrg[2] = img_org_bot[2]; + } + else + { + pImgOrg[1] = img_org_top[1]; + pImgOrg[2] = img_org_top[2]; + } } img->opix_y = (img->mb_y >> 1 ) << 4; @@ -180,14 +206,15 @@ void set_MB_parameters (int mb_addr) } else { - pCurImg = imgY_org_frm; - pImgOrg[0] = imgY_org_frm; + pCurImg = img_org_frm[0]; + pImgOrg[0] = img_org_frm[0]; + if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params)) { - imgUV_org = imgUV_org_frm; - pImgOrg[1] = imgUV_org_frm[0]; - pImgOrg[2] = imgUV_org_frm[1]; + pImgOrg[1] = img_org_frm[1]; + pImgOrg[2] = img_org_frm[2]; } + img->opix_y = img->block_y << 2; img->mb_data[mb_addr].list_offset = 0; } @@ -244,12 +271,12 @@ void proceed2nextMacroblock(Macroblock *currMB) if ((currMB->cbp&15) != 0) { - ++stats->mode_use_transform[currMB->luma_transform_size_8x8_flag][img->type][currMB->mb_type]; + ++stats->mode_use_transform[img->type][currMB->mb_type][currMB->luma_transform_size_8x8_flag]; } } ++stats->mode_use[img->type][currMB->mb_type]; - stats->bit_use_mode[img->type][currMB->mb_type]+= bitCount[BITS_INTER_MB]; + stats->bit_use_mode[img->type][currMB->mb_type] += bitCount[BITS_INTER_MB]; if (img->type != I_SLICE) { @@ -265,45 +292,49 @@ void proceed2nextMacroblock(Macroblock *currMB) if (currMB->b8mode[i]==4) { if ((currMB->luma_transform_size_8x8_flag && (currMB->cbp&15) != 0) || params->Transform8x8Mode == 2) - ++stats->mode_use_transform[1][img->type][4]; + ++stats->mode_use_transform[img->type][4][1]; else - ++stats->mode_use_transform[0][img->type][4]; + ++stats->mode_use_transform[img->type][4][0]; } } } else if (currMB->mb_type >= 0 && currMB->mb_type <=3 && ((currMB->cbp&15) != 0)) { - ++stats->mode_use_transform[currMB->luma_transform_size_8x8_flag][img->type][currMB->mb_type]; + ++stats->mode_use_transform[img->type][currMB->mb_type][currMB->luma_transform_size_8x8_flag]; } } // Statistics - if ((img->type == P_SLICE)||(img->type==SP_SLICE) ) + if ((img->type == P_SLICE) || (img->type==SP_SLICE) ) { ++stats->quant0; stats->quant1 += currMB->qp; // to find average quant for inter frames } } +void set_chroma_qp(ImageParameters *img, Macroblock* currMB) +{ + int i; + for (i=0; i<2; i++) + { + currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + img->chroma_qp_offset[i] ); + currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]]; + currMB->qp_scaled[i + 1] = currMB->qpc[i] + img->bitdepth_chroma_qp_scale; + } +} + /*! ************************************************************************ * \brief * updates chroma QP according to luma QP and bit depth ************************************************************************ */ -void update_qp(Macroblock *currMB) +void update_qp(ImageParameters *img, Macroblock *currMB) { - int i; - for (i=0; i<2; i++) - { - currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + img->chroma_qp_offset[i] ); - currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]]; - } - currMB->qp_scaled[0] = currMB->qp + img->bitdepth_luma_qp_scale - MIN_QP; - currMB->qp_scaled[1] = currMB->qpc[0] + img->bitdepth_chroma_qp_scale; - currMB->qp_scaled[2] = currMB->qpc[1] + img->bitdepth_chroma_qp_scale; + currMB->qp_scaled[0] = currMB->qp + img->bitdepth_luma_qp_scale; + set_chroma_qp(img, currMB); - select_dct(currMB); + select_dct(img, currMB); } /*! @@ -326,10 +357,10 @@ void reset_macroblock(Macroblock *currMB, int prev_mb) { for (j=img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++) { - memset(&enc_picture->ref_idx[l][j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char)); - memset(enc_picture->mv [l][j][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short)); + memset(&enc_picture->motion.ref_idx[l][j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char)); + memset(enc_picture->motion.mv [l][j][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short)); for (i=img->block_x; i < img->block_x + BLOCK_MULTIPLE; i++) - enc_picture->ref_pic_id[l][j][i]= -1; + enc_picture->motion.ref_pic_id[l][j][i]= -1; } } @@ -394,7 +425,7 @@ void reset_macroblock(Macroblock *currMB, int prev_mb) */ void start_macroblock(Macroblock **currMB, int mb_addr, int mb_field) { - int i; + int i, mb_qp; int use_bitstream_backing = (params->slice_mode == FIXED_RATE || params->slice_mode == CALL_BACK); Slice *curr_slice = img->currentSlice; DataPartition *dataPart; @@ -407,7 +438,7 @@ void start_macroblock(Macroblock **currMB, int mb_addr, int mb_field) (*currMB)->mb_field = mb_field; - enc_picture->mb_field[mb_addr] = mb_field; + enc_picture->motion.mb_field[mb_addr] = mb_field; (*currMB)->is_field_mode = (img->field_picture || ( img->MbaffFrameFlag && (*currMB)->mb_field)); set_MB_parameters (mb_addr); @@ -451,60 +482,31 @@ void start_macroblock(Macroblock **currMB, int mb_addr, int mb_field) // Initialize delta qp change from last macroblock. Feature may be used for future rate control // Rate control (*currMB)->qpsp = img->qpsp; - if(params->RCEnable) - rc_handle_mb( prev_mb, *currMB, curr_slice ); + + if (prev_mb > -1 && (img->mb_data[prev_mb].slice_nr == img->current_slice_nr)) + { + (*currMB)->prev_qp = img->mb_data[prev_mb].qp; + (*currMB)->prev_dqp = img->mb_data[prev_mb].delta_qp; + } else { - Slice* currSlice = img->currentSlice; - int new_qp = img->qp; - - if (prev_mb > -1) - { - (*currMB)->prev_qp = img->mb_data[prev_mb].qp; - (*currMB)->prev_dqp = (img->mb_data[prev_mb].slice_nr == img->current_slice_nr) ? img->mb_data[prev_mb].delta_qp : 0; - } - else - { - (*currMB)->prev_qp = currSlice->qp; - (*currMB)->prev_dqp = 0; - } + (*currMB)->prev_qp = curr_slice->qp; + (*currMB)->prev_dqp = 0; + } - if (prev_mb < 0) //first macroblock (of slice) - { - (*currMB)->qp = img->qp; - (*currMB)->delta_qp = (*currMB)->qp - (*currMB)->prev_qp; - } - else - { - if (!((params->MbInterlace) && img->bot_MB)) //top macroblock - { - if (img->mb_data[prev_mb].prev_cbp == 1) - { - (*currMB)->qp = img->qp; - (*currMB)->delta_qp = (*currMB)->qp - (*currMB)->prev_qp; - } - else - { - (*currMB)->qp = img->mb_data[prev_mb].prev_qp; - (*currMB)->delta_qp = (*currMB)->qp - img->mb_data[prev_mb].qp; - img->qp = (*currMB)->qp; - } - } - else //bottom macroblock - { - (*currMB)->qp = img->qp; - (*currMB)->delta_qp = (*currMB)->qp - (*currMB)->prev_qp; - } - } + if(params->RCEnable) + mb_qp = rc_handle_mb( prev_mb, *currMB, curr_slice ); + else + { + mb_qp = img->qp; - (*currMB)->qp = img->qp = new_qp; - (*currMB)->delta_qp = (*currMB)->qp - (*currMB)->prev_qp; } - delta_qp_mbaff[(*currMB)->mb_field][img->bot_MB] = (*currMB)->delta_qp; - qp_mbaff [(*currMB)->mb_field][img->bot_MB] = (*currMB)->qp; + mb_qp = iClip3(-img->bitdepth_luma_qp_scale, 51, mb_qp); + (*currMB)->qp = img->qp = mb_qp; + (*currMB)->delta_qp = (*currMB)->qp - (*currMB)->prev_qp; - update_qp (*currMB); + update_qp (img, *currMB); // deblocking filter parameter if (active_pps->deblocking_filter_control_present_flag) @@ -850,6 +852,7 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co //set transform size int need_8x8_transform = currMB->luma_transform_size_8x8_flag; int uv, nonzerocr[3]={0,0,0}; + short bipred_me = currMB->bipred_me[block8x8]; coeff_cost_cr[1] = coeff_cost_cr[2] = 0; //===== loop over 4x4 blocks ===== @@ -857,10 +860,10 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co { if (((p_dir == 0 || p_dir == 2 )&& l0_mode < 5) || ((p_dir == 1 || p_dir == 2 ) && l1_mode < 5)) { - LumaPrediction (currMB, mb_x, mb_y, 8, 8, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx); + LumaPrediction (currMB, mb_x, mb_y, 8, 8, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx, bipred_me); //===== compute prediction residual ====== - ComputeResidue (pCurImg, img->mpr[0], img->m7[0], mb_y, mb_x, img->opix_y, img->opix_x + mb_x, 8, 8); + ComputeResidue (pCurImg, img->mb_pred[0], img->mb_ores[0], mb_y, mb_x, img->opix_y, img->opix_x + mb_x, 8, 8); } for (byy=0, block_y=mb_y; block_y<mb_y+8; byy+=4, block_y+=4) @@ -873,21 +876,21 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co //===== prediction of 4x4 block ===== if (!(((p_dir == 0 || p_dir == 2 )&& l0_mode < 5) || ((p_dir == 1 || p_dir == 2 ) && l1_mode < 5))) { - LumaPrediction (currMB, block_x, block_y, 4, 4, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx); + LumaPrediction (currMB, block_x, block_y, 4, 4, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx, bipred_me); //===== compute prediction residual ====== - ComputeResidue(pCurImg, img->mpr[0], img->m7[0], block_y, block_x, img->opix_y, pic_pix_x, 4, 4); + ComputeResidue(pCurImg, img->mb_pred[0], img->mb_ores[0], block_y, block_x, img->opix_y, pic_pix_x, 4, 4); } if (img->P444_joined) { - for (uv=0; uv<2; uv++) + for (uv = PLANE_U; uv <= PLANE_V; uv++) { - select_plane((ColorPlane) (uv + 1)); - ChromaPrediction (currMB, uv, block_x, block_y, 4, 4, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx); + select_plane((ColorPlane) (uv)); + ChromaPrediction (currMB, uv - 1, block_x, block_y, 4, 4, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx, bipred_me); //===== compute prediction residual ====== - ComputeResidue(imgUV_org[uv], img->mpr[uv+1], img->m7[uv+1], block_y, block_x, img->opix_y, pic_pix_x, 4, 4); + ComputeResidue(pImgOrg[uv], img->mb_pred[uv], img->mb_ores[uv], block_y, block_x, img->opix_y, pic_pix_x, 4, 4); } select_plane(PLANE_Y); } @@ -897,7 +900,6 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co ((currMB->qp_scaled[0])==0 && img->lossless_qpprime_flag==1) ) { //===== DCT, Quantization, inverse Quantization, IDCT, Reconstruction ===== - //select_dct(currMB); nonzero = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &coeff_cost, 0); if (nonzero) @@ -944,20 +946,20 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co cbp_blk_mask = (block_x>>2) + block_y; //===== prediction of 4x4 block ===== - LumaPrediction (currMB, block_x, block_y, 8, 8, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx); + LumaPrediction (currMB, block_x, block_y, 8, 8, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx, bipred_me); //===== compute prediction residual ====== - ComputeResidue (pCurImg, img->mpr[0], img->m7[0], block_y, block_x, img->opix_y, pic_pix_x, 8, 8); + ComputeResidue (pCurImg, img->mb_pred[0], img->mb_ores[0], block_y, block_x, img->opix_y, pic_pix_x, 8, 8); if (img->P444_joined) { - for (uv=0; uv<2; uv++) + for (uv = PLANE_U; uv <= PLANE_V; uv++) { - select_plane((ColorPlane) (uv + 1)); - ChromaPrediction (currMB, uv, block_x, block_y, 8, 8, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx); + select_plane((ColorPlane) uv); + ChromaPrediction (currMB, uv - 1, block_x, block_y, 8, 8, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx, bipred_me); //===== compute prediction residual ====== - ComputeResidue (imgUV_org[uv], img->mpr[uv + 1], img->m7[uv + 1], block_y, block_x, img->opix_y, pic_pix_x, 8, 8); + ComputeResidue (pImgOrg[uv], img->mb_pred[uv], img->mb_ores[uv], block_y, block_x, img->opix_y, pic_pix_x, 8, 8); } select_plane(PLANE_Y); } @@ -1027,7 +1029,7 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co memset( img->cofAC[block8x8][0][0], 0, 4 * 2 * 65 * sizeof(int)); for (j=mb_y; j<mb_y+8; j++) - memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x + mb_x], &img->mpr[0][j][mb_x], 2 * BLOCK_SIZE * sizeof(imgpel)); + memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x + mb_x], &img->mb_pred[0][j][mb_x], 2 * BLOCK_SIZE * sizeof(imgpel)); if (img->type==SP_SLICE) { @@ -1051,7 +1053,7 @@ int LumaResidualCoding8x8 ( Macroblock* currMB, //!< Current Macroblock to be co memset( img->cofAC[block8x8 + 4 * uv][0][0], 0, 4 * 2 * 65 * sizeof(int)); for (j=mb_y; j<mb_y+8; j++) - memcpy(&enc_picture->imgUV[uv - 1][img->pix_y + j][img->pix_x + mb_x], &img->mpr[uv][j][mb_x], 2 * BLOCK_SIZE * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[uv - 1][img->pix_y + j][img->pix_x + mb_x], &img->mb_pred[uv][j][mb_x], 2 * BLOCK_SIZE * sizeof(imgpel)); } } } @@ -1076,7 +1078,7 @@ void SetModesAndRefframe (Macroblock* currMB, int b8, short* p_dir, int list_mod if (img->type!=B_SLICE) { - list_ref_idx[0] = enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i]; + list_ref_idx[0] = enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x+i]; list_ref_idx[1] = 0; list_mode[0] = currMB->b8mode[b8]; list_mode[1] = 0; @@ -1092,7 +1094,7 @@ void SetModesAndRefframe (Macroblock* currMB, int b8, short* p_dir, int list_mod } else if (currMB->b8pdir[b8]==0) { - list_ref_idx[0] = enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i]; + list_ref_idx[0] = enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x+i]; list_ref_idx[1] = 0; list_mode[0] = currMB->b8mode[b8]; list_mode[1] = 0; @@ -1100,14 +1102,14 @@ void SetModesAndRefframe (Macroblock* currMB, int b8, short* p_dir, int list_mod else if (currMB->b8pdir[b8]==1) { list_ref_idx[0] = 0; - list_ref_idx[1] = enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x+i]; + list_ref_idx[1] = enc_picture->motion.ref_idx[LIST_1][img->block_y+j][img->block_x+i]; list_mode[0] = 0; list_mode[1] = currMB->b8mode[b8]; } else { - list_ref_idx[0] = enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i]; - list_ref_idx[1] = enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x+i]; + list_ref_idx[0] = enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x+i]; + list_ref_idx[1] = enc_picture->motion.ref_idx[LIST_1][img->block_y+j][img->block_x+i]; list_mode[0] = currMB->b8mode[b8]; list_mode[1] = currMB->b8mode[b8]; } @@ -1128,7 +1130,7 @@ void LumaResidualCoding (Macroblock *currMB) short list_ref_idx[2]; short p_dir; int sum_cnt_nonz[3] = {0 ,0, 0}; - //imgpel (*curr_mpr)[16] = img->mpr[0]; + //imgpel (*mb_pred)[16] = img->mb_pred[0]; currMB->cbp = 0; currMB->cbp_blk = 0; @@ -1157,7 +1159,7 @@ void LumaResidualCoding (Macroblock *currMB) currMB->cbp &= 0xfffff0 ; currMB->cbp_blk &= 0xff0000 ; for (j=0; j < MB_BLOCK_SIZE; j++) - memcpy(&enc_picture->imgY[img->pix_y+j][img->pix_x], img->mpr[0][j], MB_BLOCK_SIZE * sizeof (imgpel)); + memcpy(&enc_picture->imgY[img->pix_y+j][img->pix_x], img->mb_pred[0][j], MB_BLOCK_SIZE * sizeof (imgpel)); memset( img->cofAC[0][0][0], 0, 4 * 4 * 2 * 65 * sizeof(int)); @@ -1184,7 +1186,7 @@ void LumaResidualCoding (Macroblock *currMB) cmp_cbp[uv] &= 0xfffff0 ; cur_cbp_blk[uv] &= 0xff0000 ; for (j=0; j < MB_BLOCK_SIZE; j++) - memcpy(&enc_picture->p_img[uv][img->pix_y+j][img->pix_x], img->mpr[uv][j], MB_BLOCK_SIZE * sizeof (imgpel)); + memcpy(&enc_picture->p_img[uv][img->pix_y+j][img->pix_x], img->mb_pred[uv][j], MB_BLOCK_SIZE * sizeof (imgpel)); memset( img->cofAC[4 * uv][0][0], 0, 4 * 4 * 2 * 65 * sizeof(int)); } @@ -1209,7 +1211,8 @@ int TransformDecision (Macroblock *currMB, int block_check, int *cost) int num_blks; int cost8x8=0, cost4x4=0; int *diff_ptr; - imgpel (*curr_mpr)[16] = img->mpr[0]; + short bipred_me; + imgpel (*mb_pred)[16] = img->mb_pred[0]; if(block_check==-1) { @@ -1225,12 +1228,12 @@ int TransformDecision (Macroblock *currMB, int block_check, int *cost) for (; block8x8<num_blks; block8x8++) { SetModesAndRefframe (currMB, block8x8, &p_dir, list_mode, list_ref_idx); - + bipred_me = currMB->bipred_me[block8x8]; mb_y = (block8x8 >> 1) << 3; mb_x = (block8x8 & 0x01) << 3; //===== prediction of 8x8 block ===== - LumaPrediction (currMB, mb_x, mb_y, 8, 8, p_dir, list_mode[0], list_mode[1], list_ref_idx[0], list_ref_idx[1]); + LumaPrediction (currMB, mb_x, mb_y, 8, 8, p_dir, list_mode[0], list_mode[1], list_ref_idx[0], list_ref_idx[1], bipred_me); //===== loop over 4x4 blocks ===== for (k=0, block_y=mb_y; block_y<mb_y+8; block_y+=4) @@ -1242,7 +1245,7 @@ int TransformDecision (Macroblock *currMB, int block_check, int *cost) for (j=block_y; j<block_y + 4; j++) { for (i = block_x; i < block_x + 4; i++, k++) - diff64[k] = pCurImg[img->opix_y+j][img->opix_x + i] - curr_mpr[j][i]; + diff64[k] = pCurImg[img->opix_y+j][img->opix_x + i] - mb_pred[j][i]; } cost4x4 += distortion4x4 (diff_ptr); } @@ -1272,43 +1275,27 @@ int TransformDecision (Macroblock *currMB, int block_check, int *cost) void ChromaResidualCoding (Macroblock *currMB) { int chroma_cbp; - static const int block8x8_idx[3][4][4] = //ADD-VG-15052004 - { - { {0, 1, 0, 0}, - {2, 3, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { {0, 1, 0, 0}, - {0, 1, 0, 0}, - {2, 3, 0, 0}, - {2, 3, 0, 0}, - }, - { {0, 0, 1, 1}, - {0, 0, 1, 1}, - {2, 2, 3, 3}, - {2, 2, 3, 3} - } - }; static int uv, block8, block_y, block_x, j, i; static int list_mode[2]; static short p_dir, list_ref_idx[2]; int skipped = (currMB->mb_type == 0 && (img->type == P_SLICE || img->type == SP_SLICE)); int yuv = img->yuv_format - 1; - imgpel (*curr_mpr)[16] = NULL; + short bipred_me; + imgpel (*mb_pred)[16] = NULL; for (chroma_cbp = 0, uv=0; uv<2; uv++) { - curr_mpr = img->mpr[ uv + 1]; + mb_pred = img->mb_pred[ uv + 1]; //===== prediction of chrominance blocks ===d== block8 = 0; for (block_y=0; block_y < img->mb_cr_size_y; block_y+=4) for (block_x=0; block_x < img->mb_cr_size_x; block_x+=4) { block8 = block8x8_idx[yuv][block_y>>2][block_x>>2]; + bipred_me = currMB->bipred_me[block8]; SetModesAndRefframe (currMB, block8, &p_dir, list_mode, list_ref_idx); - ChromaPrediction4x4 (currMB, uv, block_x, block_y, p_dir, list_mode[0], list_mode[1], list_ref_idx[0], list_ref_idx[1]); + ChromaPrediction4x4 (currMB, uv, block_x, block_y, p_dir, list_mode[0], list_mode[1], list_ref_idx[0], list_ref_idx[1], bipred_me); //ChromaPrediction (currMB, uv, block_x, block_y, 4, 4, p_dir, l0_mode, l1_mode, l0_ref_idx, l1_ref_idx); } @@ -1316,24 +1303,26 @@ void ChromaResidualCoding (Macroblock *currMB) if (img->NoResidueDirect) { for (j=0; j<img->mb_cr_size_y; j++) - memcpy(&enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x], curr_mpr[j], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x], mb_pred[j], img->mb_cr_size_x * sizeof(imgpel)); } else if (skipped && img->type==SP_SLICE) { for (j=0; j<img->mb_cr_size_y; j++) - memset(img->m7[uv + 1][j], 0 , img->mb_cr_size_x * sizeof(int)); + memset(img->mb_ores[uv + 1][j], 0 , img->mb_cr_size_x * sizeof(int)); + for (j=0; j<img->mb_cr_size_y; j++) + memset(img->mb_rres[uv + 1][j], 0 , img->mb_cr_size_x * sizeof(int)); } else if (skipped) { for (j=0; j<img->mb_cr_size_y; j++) - memcpy(&enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x], curr_mpr[j], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[uv][img->pix_c_y+j][img->pix_c_x], mb_pred[j], img->mb_cr_size_x * sizeof(imgpel)); } else { for (j=0; j<img->mb_cr_size_y; j++) for (i=0; i<img->mb_cr_size_x; i++) { - img->m7[uv + 1][j][i] = imgUV_org[uv][img->opix_c_y+j][img->opix_c_x+i] - curr_mpr[j][i]; + img->mb_ores[uv + 1][j][i] = pImgOrg[uv + 1][img->opix_c_y+j][img->opix_c_x+i] - mb_pred[j][i]; } } @@ -1343,9 +1332,9 @@ void ChromaResidualCoding (Macroblock *currMB) if (skipped && img->type==SP_SLICE) { if(si_frame_indicator || sp2_frame_indicator) - chroma_cbp=dct_chroma_sp2(currMB, uv,chroma_cbp); + chroma_cbp = dct_chroma_sp2(currMB, uv,chroma_cbp); else - chroma_cbp=dct_chroma_sp(currMB, uv,chroma_cbp); + chroma_cbp = dct_chroma_sp(currMB, uv,chroma_cbp); } else { @@ -1443,10 +1432,10 @@ void IntraChromaRDDecision (Macroblock *currMB, RD_PARAMS enc_mb) continue; cost = 0; - for (uv=0; uv<2; uv++) + for (uv = 1; uv < 3; uv++) { - image = imgUV_org[uv]; - curr_mpr_16x16 = img->mpr_16x16[uv + 1]; + image = pImgOrg[uv]; + curr_mpr_16x16 = img->mpr_16x16[uv]; for (block_y=0; block_y<cr_MB_y; block_y+=4) { for (block_x=0; block_x<cr_MB_x; block_x+=4) @@ -1493,7 +1482,7 @@ int ZeroRef (Macroblock* currMB) { for (i=img->block_x; i<img->block_x + BLOCK_MULTIPLE; i++) { - if (enc_picture->ref_idx[LIST_0][j][i]!=0) + if (enc_picture->motion.ref_idx[LIST_0][j][i]!=0) return 0; } } @@ -1916,6 +1905,7 @@ int writeMBLayer (Macroblock *currMB, int rdopt, int *coeff_rate) arienco_start_encoding(eep, dataPart->bitstream->streamBuffer, &(dataPart->bitstream->byte_pos)); reset_pic_bin_count(); } + if (dataPart->bitstream->bits_to_go < 8) { // This will only happen in the CAVLC case, CABAC is already padded @@ -1961,7 +1951,7 @@ int writeMBLayer (Macroblock *currMB, int rdopt, int *coeff_rate) no_bits += se.len; se.bitpattern = enc_picture->imgUV[uv][j][i]; se.value1 = se.bitpattern; - bitCount[BITS_COEFF_UV_MB]+=se.len; + bitCount[BITS_COEFF_UV_MB] += se.len; #if TRACE snprintf(se.tracestring, TRACESTRING_SIZE, "pcm_sample_chroma (%s) (%d %d) = %d", uv?"v":"u", j,i,se.bitpattern); #endif @@ -2167,21 +2157,14 @@ void write_one_macroblock (Macroblock* currMB, int eos_bit, Boolean prev_recode_ } //--- set total bit-counter --- - if(img->P444_joined) - bitCount[BITS_TOTAL_MB] = bitCount[BITS_MB_MODE ] - + bitCount[BITS_COEFF_Y_MB ] - + bitCount[BITS_INTER_MB ] - + bitCount[BITS_CBP_MB ] - + bitCount[BITS_DELTA_QUANT_MB] - + bitCount[BITS_COEFF_CB_MB ] - + bitCount[BITS_COEFF_CR_MB ]; - else - bitCount[BITS_TOTAL_MB] = bitCount[BITS_MB_MODE ] - + bitCount[BITS_COEFF_Y_MB ] - + bitCount[BITS_INTER_MB ] - + bitCount[BITS_CBP_MB ] - + bitCount[BITS_DELTA_QUANT_MB] - + bitCount[BITS_COEFF_UV_MB ]; + bitCount[BITS_TOTAL_MB] = bitCount[BITS_MB_MODE ] + + bitCount[BITS_COEFF_Y_MB ] + + bitCount[BITS_INTER_MB ] + + bitCount[BITS_CBP_MB ] + + bitCount[BITS_DELTA_QUANT_MB] + + bitCount[BITS_COEFF_UV_MB ] + + bitCount[BITS_COEFF_CB_MB ] + + bitCount[BITS_COEFF_CR_MB ]; if ( params->RCEnable ) rc_update_mb_stats( currMB, bitCount ); @@ -2247,7 +2230,9 @@ int writeMotionVector8x8 (Macroblock *currMB, int j1, int refframe, int list_idx, - int mv_mode) + int mv_mode, + short bipred_me + ) { int i, j, k, l, m; int curr_mvd; @@ -2265,8 +2250,8 @@ int writeMotionVector8x8 (Macroblock *currMB, short****** all_mv = img->all_mv; short****** pred_mv = img->pred_mv; - if (currMB->bi_pred_me && currMB->b8pdir[0]==2 && mv_mode == 1 && refindex == 0) - all_mv = currMB->bi_pred_me == 1? img->bipred_mv1 : img->bipred_mv2 ; + if (bipred_me && is_bipred_enabled(mv_mode) && refindex == 0) + all_mv = img->bipred_mv[bipred_me - 1]; for (j = j0; j < j1; j += step_v) { @@ -2331,7 +2316,7 @@ int writeMotionInfo2NAL (Macroblock* currMB) { for (j0 = 0; j0 < 4; j0 += step_v0) { - cref_idx = &enc_picture->ref_idx[LIST_0][img->block_y + j0][img->block_x]; + cref_idx = &enc_picture->motion.ref_idx[LIST_0][img->block_y + j0][img->block_x]; for (i0 = 0; i0 < 4; i0 += step_h0) { k = j0 + (i0 >> 1); @@ -2344,7 +2329,7 @@ int writeMotionInfo2NAL (Macroblock* currMB) for (j0 = 0; j0 < 4; j0 += step_v0) { - cref_idx = &enc_picture->ref_idx[LIST_1][img->block_y + j0][img->block_x]; + cref_idx = &enc_picture->motion.ref_idx[LIST_1][img->block_y + j0][img->block_x]; for (i0 = 0; i0 < 4; i0 += step_h0) { k = j0 + (i0 >> 1); @@ -2362,13 +2347,13 @@ int writeMotionInfo2NAL (Macroblock* currMB) { for (j0=0; j0<4; j0+=step_v0) { - cref_idx = &enc_picture->ref_idx[LIST_0][img->block_y + j0][img->block_x]; + cref_idx = &enc_picture->motion.ref_idx[LIST_0][img->block_y + j0][img->block_x]; for (i0=0; i0<4; i0+=step_h0) { k=j0+(i0 >> 1); if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector { - no_bits += writeMotionVector8x8 (currMB, i0, j0, i0 + step_h0, j0 + step_v0, cref_idx[i0], LIST_0, currMB->b8mode[k]); + no_bits += writeMotionVector8x8 (currMB, i0, j0, i0 + step_h0, j0 + step_v0, cref_idx[i0], LIST_0, currMB->b8mode[k], currMB->bipred_me[k]); } } } @@ -2380,13 +2365,13 @@ int writeMotionInfo2NAL (Macroblock* currMB) { for (j0=0; j0<4; j0+=step_v0) { - cref_idx = &enc_picture->ref_idx[LIST_1][img->block_y + j0][img->block_x]; + cref_idx = &enc_picture->motion.ref_idx[LIST_1][img->block_y + j0][img->block_x]; for (i0=0; i0<4; i0+=step_h0) { k=j0+(i0 >> 1); if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has backward vector { - no_bits += writeMotionVector8x8 (currMB, i0, j0, i0+step_h0, j0+step_v0, cref_idx[i0], LIST_1, currMB->b8mode[k]); + no_bits += writeMotionVector8x8 (currMB, i0, j0, i0+step_h0, j0+step_v0, cref_idx[i0], LIST_1, currMB->b8mode[k], currMB->bipred_me[k]); } } } @@ -2578,7 +2563,7 @@ int writeCoeff4x4_CABAC (Macroblock* currMB, ColorPlane plane, int b8, int b4, i int level, run; int k; int pl_off=plane<<2; - int bits_coeff_mb=((plane==0)?(BITS_COEFF_Y_MB):((plane==1)?BITS_COEFF_CB_MB:BITS_COEFF_CR_MB)); + int bits_coeff_mb = ((plane==0) ? (BITS_COEFF_Y_MB) : ((plane==1) ? BITS_COEFF_CB_MB : BITS_COEFF_CR_MB)); int* ACLevel = img->cofAC[b8+pl_off][b4][0]; int* ACRun = img->cofAC[b8+pl_off][b4][1]; @@ -2633,7 +2618,7 @@ int writeCoeff8x8_CABAC (Macroblock* currMB, ColorPlane plane, int b8, int intra int k; int pl_off=plane<<2; - int bits_coeff_mb=((plane==0)?(BITS_COEFF_Y_MB):((plane==1)?BITS_COEFF_CB_MB:BITS_COEFF_CR_MB)); + int bits_coeff_mb = ((plane == 0) ? (BITS_COEFF_Y_MB) : ((plane == 1) ? BITS_COEFF_CB_MB : BITS_COEFF_CR_MB)); int* ACLevel = img->cofAC[b8+pl_off][0][0]; int* ACRun = img->cofAC[b8+pl_off][0][1]; @@ -2810,7 +2795,7 @@ int writeCoeff16x16 (Macroblock* currMB, ColorPlane plane, int cbp) int* ACLevel; int* ACRun; int data_type; - int bits_coeff_mb=((plane==0)?(BITS_COEFF_Y_MB):((plane==1)?(BITS_COEFF_CB_MB):(BITS_COEFF_CR_MB))); + int bits_coeff_mb = ((plane == 0) ? (BITS_COEFF_Y_MB) : ((plane == 1) ? (BITS_COEFF_CB_MB) : (BITS_COEFF_CR_MB))); if (img->P444_joined) { @@ -3750,16 +3735,16 @@ double find_sad_16x16_JM(Macroblock *currMB, int *intra_mode) current_intra_sad_2 = distortion_sad(pCurImg, curr_mpr_16x16[k]); if (img->P444_joined) { - current_intra_sad_2 += distortion_sad(imgUV_org[0], img->mpr_16x16[1][k]); - current_intra_sad_2 += distortion_sad(imgUV_org[1], img->mpr_16x16[2][k]); + current_intra_sad_2 += distortion_sad(pImgOrg[1], img->mpr_16x16[1][k]); + current_intra_sad_2 += distortion_sad(pImgOrg[2], img->mpr_16x16[2][k]); } break; case ERROR_SSE: current_intra_sad_2 = distortion_sse(pCurImg, curr_mpr_16x16[k]); if (img->P444_joined) { - current_intra_sad_2 += distortion_sse(imgUV_org[0], img->mpr_16x16[1][k]); - current_intra_sad_2 += distortion_sse(imgUV_org[1], img->mpr_16x16[2][k]); + current_intra_sad_2 += distortion_sse(pImgOrg[1], img->mpr_16x16[1][k]); + current_intra_sad_2 += distortion_sse(pImgOrg[2], img->mpr_16x16[2][k]); } break; case ERROR_SATD : @@ -3767,8 +3752,8 @@ double find_sad_16x16_JM(Macroblock *currMB, int *intra_mode) current_intra_sad_2 = distortion_hadamard(pCurImg, curr_mpr_16x16[k]); if (img->P444_joined) { - current_intra_sad_2 += distortion_hadamard(imgUV_org[0], img->mpr_16x16[1][k]); - current_intra_sad_2 += distortion_hadamard(imgUV_org[1], img->mpr_16x16[2][k]); + current_intra_sad_2 += distortion_hadamard(pImgOrg[1], img->mpr_16x16[1][k]); + current_intra_sad_2 += distortion_hadamard(pImgOrg[2], img->mpr_16x16[2][k]); } break; } @@ -3797,9 +3782,9 @@ void change_plane_JV( int nplane ) { img->colour_plane_id = nplane; img->mb_data = img->mb_data_JV[nplane]; - enc_picture = enc_frame_picture_JV[nplane]; - pCurImg = imgY_org_frm_JV[nplane]; - Co_located = Co_located_JV[nplane]; + enc_picture = enc_frame_picture_JV[nplane]; + pCurImg = img_org_frm[nplane]; + Co_located = Co_located_JV[nplane]; } /*! @@ -3819,7 +3804,8 @@ void make_frame_picture_JV() copy_storable_param_JV( nplane, enc_frame_picture[0], enc_frame_picture_JV[nplane] ); } - for( uv=0; uv<2; uv++ ){ + for( uv=0; uv<2; uv++ ) + { for( line=0; line<img->height; line++ ) { nsize = sizeof(imgpel) * img->width; diff --git a/lencod/src/mb_access.c b/lencod/src/mb_access.c index d90a43b..c054a5d 100644 --- a/lencod/src/mb_access.c +++ b/lencod/src/mb_access.c @@ -133,8 +133,8 @@ void get_mb_pos (int mb_addr, int mb_size[2], int *x, int*y) * input x position * \param yN * input y position - * \param is_chroma - * 0 if luma coding, 1 for chroma + * \param mb_size + * Macroblock size in pixel (according to luma or chroma MB access) * \param pix * returns position informations ************************************************************************ @@ -194,8 +194,8 @@ void getNonAffNeighbour(Macroblock *currMb, int xN, int yN, int mb_size[2], Pixe * input x position * \param yN * input y position - * \param is_chroma - * 0 if luma coding, 1 for chroma + * \param mb_size + * Macroblock size in pixel (according to luma or chroma MB access) * \param pix * returns position informations ************************************************************************ @@ -540,6 +540,8 @@ void getAffNeighbour(Macroblock *currMb, int xN, int yN, int mb_size[2], PixelPo * input x block position * \param block_y * input y block position + * \param mb_size + * Macroblock size in pixel (according to luma or chroma MB access) * \param pix * returns position informations ************************************************************************ diff --git a/lencod/src/mbuffer.c b/lencod/src/mbuffer.c index 43656a5..ff5b9e3 100644 --- a/lencod/src/mbuffer.c +++ b/lencod/src/mbuffer.c @@ -111,10 +111,10 @@ int getDpbSize(void) size = 152064; break; case 11: - if (!IS_FREXT_PROFILE(active_sps->profile_idc)&&(active_sps->constrained_set3_flag == 0)) - size = 345600; - else + if (!IS_FREXT_PROFILE(active_sps->profile_idc)&&(active_sps->constrained_set3_flag == 1)) size = 152064; + else + size = 345600; break; case 12: size = 912384; @@ -147,10 +147,7 @@ int getDpbSize(void) size = 12582912; break; case 42: - if( IS_FREXT_PROFILE(active_sps->profile_idc) ) - size = 13369344; - else - size = 12582912; + size = 13369344; break; case 50: size = 42393600; @@ -326,6 +323,20 @@ FrameStore* alloc_frame_store(void) return f; } +void alloc_pic_motion(PicMotionParams *motion, int size_y, int size_x) +{ + get_mem3Dint64 (&(motion->ref_pic_id), 6, size_y, size_x); + get_mem3Dint64 (&(motion->ref_id), 6, size_y, size_x); + get_mem4Dshort (&(motion->mv), 2, size_y, size_x, 2); + get_mem3D ((byte****)(&(motion->ref_idx)), 2, size_y , size_x); + + motion->mb_field = calloc (size_y * size_x, sizeof(int)); + if (motion->mb_field == NULL) + no_mem_exit("alloc_storable_picture: motion->mb_field"); + + get_mem2D (&(motion->field_frame), size_y, size_x); +} + /*! ************************************************************************ * \brief @@ -350,6 +361,8 @@ StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, { StorablePicture *s; int nplane; + int dec; + int ndec = params->NoOfDecoders; //printf ("Allocating (%s) picture (x=%d, y=%d, x_cr=%d, y_cr=%d)\n", (type == FRAME)?"FRAME":(type == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", size_x, size_y, size_x_cr, size_y_cr); @@ -365,6 +378,51 @@ StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, s->p_img_sub[1] = NULL; s->p_img_sub[2] = NULL; + s->dec_imgY = NULL; + s->dec_imgUV = NULL; + s->mb_error_map = NULL; + s->p_dec_img[0] = NULL; + s->p_dec_img[1] = NULL; + s->p_dec_img[2] = NULL; + + if ((params->rdopt == 3) && (ndec > 0)) //PPAHA_TODO: Need to verify whether both checks are necessary. + { + get_mem3D(&(s->mb_error_map), ndec, size_y/MB_BLOCK_SIZE, size_x/MB_BLOCK_SIZE); + get_mem3Dpel(&(s->dec_imgY), ndec, size_y, size_x); + + // This seems somewhat inefficient. Why not allocate array as [ndec][x] where x goes from 0 to 2? + if ((s->p_dec_img[0] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL) + { + no_mem_exit("mbuffer.c: p_dec_img[0]"); + } + if (img->yuv_format != YUV400) + { + get_mem4Dpel(&(s->dec_imgUV), ndec, 2, size_y_cr, size_x_cr); + if ((s->p_dec_img[1] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL) + { + no_mem_exit("mbuffer.c: p_dec_img[1]"); + } + if ((s->p_dec_img[2] = (imgpel***)calloc(ndec,sizeof(imgpel**))) == NULL) + { + no_mem_exit("mbuffer.c: p_dec_img[2]"); + } + } + + for (dec = 0; dec < ndec; dec++) + { + s->p_dec_img[0][dec] = s->dec_imgY[dec]; + } + + if (img->yuv_format != YUV400) + { + for (dec = 0; dec < ndec; dec++) + { + s->p_dec_img[1][dec] = s->dec_imgUV[dec][0]; + s->p_dec_img[2][dec] = s->dec_imgUV[dec][1]; + } + } + } + get_mem2Dpel (&(s->imgY), size_y, size_x); s->p_img[0] = s->imgY; s->p_curr_img = s->p_img[0]; @@ -377,29 +435,21 @@ StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, s->p_curr_img_sub = s->p_img_sub[0]; - s->mb_field = calloc (img->PicSizeInMbs, sizeof(int)); - if (NULL==s->mb_field) - no_mem_exit("alloc_storable_picture: s->mb_field"); + if (params->MbInterlace) + get_mem3Dmp (&s->mv_info, size_y, size_x, 6); + else + get_mem3Dmp (&s->mv_info, size_y, size_x, 2); - get_mem3D ((byte****)(&(s->ref_idx)), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_pic_id), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_id), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->mv), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2); + alloc_pic_motion(&s->motion, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); if( IS_INDEPENDENT(params) ) { for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - get_mem3D ((byte****)(&(s->ref_idx_JV[nplane])), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_pic_id_JV[nplane]), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_id_JV[nplane]), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->mv_JV[nplane]), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2); + alloc_pic_motion(&s->JVmotion[nplane], size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); } } - get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem2D (&(s->field_frame), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - s->pic_num=0; s->frame_num=0; s->long_term_frame_idx=0; @@ -465,6 +515,46 @@ void free_frame_store(FrameStore* f) } } +void free_pic_motion(PicMotionParams *motion) +{ + + if (motion->ref_pic_id) + { + free_mem3Dint64 (motion->ref_pic_id); + motion->ref_pic_id = NULL; + } + if (motion->ref_id) + { + free_mem3Dint64 (motion->ref_id); + motion->ref_id = NULL; + } + + if (motion->mv) + { + free_mem4Dshort (motion->mv); + motion->mv = NULL; + } + + if (motion->ref_idx) + { + free_mem3D ((byte***)motion->ref_idx); + motion->ref_idx = NULL; + } + + if (motion->mb_field) + { + free(motion->mb_field); + motion->mb_field=NULL; + } + + if (motion->field_frame) + { + free_mem2D (motion->field_frame); + motion->field_frame=NULL; + } +} + + /*! ************************************************************************ * \brief @@ -480,68 +570,17 @@ void free_storable_picture(StorablePicture* p) int nplane; if (p) { - if (p->ref_idx) - { - free_mem3D ((byte***)p->ref_idx); - p->ref_idx = NULL; - } - - if (p->ref_pic_id) - { - free_mem3Dint64 (p->ref_pic_id); - p->ref_pic_id = NULL; - } - if (p->ref_id) - { - free_mem3Dint64 (p->ref_id); - p->ref_id = NULL; - } - if (p->mv) - { - free_mem4Dshort (p->mv); - p->mv = NULL; - } + free_mem3Dmp (p->mv_info); + free_pic_motion(&p->motion); if( IS_INDEPENDENT(params) ) { for( nplane=0; nplane<MAX_PLANE; nplane++ ) { - if (p->ref_idx_JV[nplane]) - { - free_mem3D ((byte***)p->ref_idx_JV[nplane]); - p->ref_idx_JV[nplane] = NULL; - } - - if (p->ref_pic_id_JV[nplane]) - { - free_mem3Dint64 (p->ref_pic_id_JV[nplane]); - p->ref_pic_id_JV[nplane] = NULL; - } - if (p->ref_id_JV[nplane]) - { - free_mem3Dint64 (p->ref_id_JV[nplane]); - p->ref_id_JV[nplane] = NULL; - } - if (p->mv_JV[nplane]) - { - free_mem4Dshort (p->mv_JV[nplane]); - p->mv_JV[nplane] = NULL; - } + free_pic_motion(&p->JVmotion[nplane]); } } - if (p->moving_block) - { - free_mem2D (p->moving_block); - p->moving_block=NULL; - } - - if (p->field_frame) - { - free_mem2D (p->field_frame); - p->field_frame=NULL; - } - if (p->imgY) { free_mem2Dpel (p->imgY); @@ -560,6 +599,7 @@ void free_storable_picture(StorablePicture* p) free_mem5Dpel (p->imgUV_sub); p->imgUV_sub = NULL; } + p->p_curr_img = NULL; p->p_curr_img_sub = NULL; p->p_img[0] = NULL; @@ -576,23 +616,11 @@ void free_storable_picture(StorablePicture* p) free_mem4Dpel (p->imgY_sub); p->imgY_sub=NULL; } + if ( p->imgUV_sub && img->yuv_format != YUV400 && params->ChromaMCBuffer ) { - if ( img->yuv_format == YUV420 ) - { - free_mem5Dpel (p->imgUV_sub); - p->imgUV_sub = NULL; - } - else if ( img->yuv_format == YUV422 ) - { - free_mem5Dpel (p->imgUV_sub); - p->imgUV_sub = NULL; - } - else - { // YUV444 - free_mem5Dpel (p->imgUV_sub); - p->imgUV_sub = NULL; - } + free_mem5Dpel (p->imgUV_sub); + p->imgUV_sub = NULL; } } @@ -602,11 +630,30 @@ void free_storable_picture(StorablePicture* p) p->imgUV=NULL; } - if (p->mb_field) + if (p->dec_imgY) { - free(p->mb_field); - p->mb_field=NULL; + free_mem3Dpel(p->dec_imgY); } + if (p->dec_imgUV) + { + free_mem4Dpel(p->dec_imgUV); + } + for (nplane = 0; nplane < 3; nplane++) + { + if (p->p_dec_img[nplane]) + { + free(p->p_dec_img[nplane]); + p->p_dec_img[nplane] = NULL; + } + } + if (p->mb_error_map) + { + free_mem3D(p->mb_error_map); + } + + p->mb_error_map = NULL; + p->dec_imgY = NULL; + p->dec_imgUV = NULL; free(p); p = NULL; @@ -657,16 +704,13 @@ static void unmark_for_reference(FrameStore* fs) fs->frame->imgY_sub=NULL; } - if (fs->frame->ref_pic_id) + if (fs->frame->imgUV_sub) { - free_mem3Dint64 (fs->frame->ref_pic_id); - fs->frame->ref_pic_id = NULL; - } - if (fs->frame->ref_id) - { - free_mem3Dint64 (fs->frame->ref_id); - fs->frame->ref_id = NULL; + free_mem5Dpel (fs->frame->imgUV_sub); + fs->frame->imgUV_sub = NULL; } + + free_pic_motion(&fs->frame->motion); } if (fs->top_field) @@ -677,17 +721,13 @@ static void unmark_for_reference(FrameStore* fs) fs->top_field->imgY_sub=NULL; } - if (fs->top_field->ref_pic_id) + if (fs->top_field->imgUV_sub) { - free_mem3Dint64 (fs->top_field->ref_pic_id); - fs->top_field->ref_pic_id = NULL; - } - if (fs->top_field->ref_id) - { - free_mem3Dint64 (fs->top_field->ref_id); - fs->top_field->ref_id = NULL; + free_mem5Dpel (fs->top_field->imgUV_sub); + fs->top_field->imgUV_sub = NULL; } + free_pic_motion(&fs->top_field->motion); } if (fs->bottom_field) { @@ -696,18 +736,14 @@ static void unmark_for_reference(FrameStore* fs) free_mem4Dpel (fs->bottom_field->imgY_sub); fs->bottom_field->imgY_sub=NULL; } - if (fs->bottom_field->ref_pic_id) + if (fs->bottom_field->imgUV_sub) { - free_mem3Dint64 (fs->bottom_field->ref_pic_id); - fs->bottom_field->ref_pic_id = NULL; + free_mem5Dpel (fs->bottom_field->imgUV_sub); + fs->bottom_field->imgUV_sub = NULL; } - if (fs->bottom_field->ref_id) - { - free_mem3Dint64 (fs->bottom_field->ref_id); - fs->bottom_field->ref_id = NULL; - } - } + free_pic_motion(&fs->bottom_field->motion); + } } @@ -2949,12 +2985,12 @@ void gen_field_ref_ids(StorablePicture *p) { for (j=0 ; j<p->size_y/4 ; j++) { - dummylist0= p->ref_idx[LIST_0][j][i]; - dummylist1= p->ref_idx[LIST_1][j][i]; + dummylist0= p->motion.ref_idx[LIST_0][j][i]; + dummylist1= p->motion.ref_idx[LIST_1][j][i]; //! association with id already known for fields. - p->ref_id[LIST_0][j][i] = (dummylist0>=0)? p->ref_pic_num[LIST_0][dummylist0] : 0; - p->ref_id[LIST_1][j][i] = (dummylist1>=0)? p->ref_pic_num[LIST_1][dummylist1] : 0; - p->field_frame[j][i]=1; + p->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? p->ref_pic_num[LIST_0][dummylist0] : 0; + p->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? p->ref_pic_num[LIST_1][dummylist1] : 0; + p->motion.field_frame[j][i]=1; } } } @@ -3071,25 +3107,25 @@ void dpb_split_field(FrameStore *fs) idiv=i/4; currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2); - if (fs->frame->MbaffFrameFlag && fs->frame->mb_field[currentmb]) + if (fs->frame->MbaffFrameFlag && fs->frame->motion.mb_field[currentmb]) { int list_offset = currentmb%2? 4: 2; - dummylist0 = fs->frame->ref_idx[LIST_0][j][i]; - dummylist1 = fs->frame->ref_idx[LIST_1][j][i]; + dummylist0 = fs->frame->motion.ref_idx[LIST_0][j][i]; + dummylist1 = fs->frame->motion.ref_idx[LIST_1][j][i]; //! association with id already known for fields. - fs->frame->ref_id[LIST_0 + list_offset][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[LIST_0 + list_offset][dummylist0] : 0; - fs->frame->ref_id[LIST_1 + list_offset][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[LIST_1 + list_offset][dummylist1] : 0; + fs->frame->motion.ref_id[LIST_0 + list_offset][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[LIST_0 + list_offset][dummylist0] : 0; + fs->frame->motion.ref_id[LIST_1 + list_offset][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[LIST_1 + list_offset][dummylist1] : 0; //! need to make association with frames - fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->frm_ref_pic_num[LIST_0 + list_offset][dummylist0] : 0; - fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->frm_ref_pic_num[LIST_1 + list_offset][dummylist1] : 0; + fs->frame->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->frm_ref_pic_num[LIST_0 + list_offset][dummylist0] : 0; + fs->frame->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->frm_ref_pic_num[LIST_1 + list_offset][dummylist1] : 0; } else { - dummylist0 = fs->frame->ref_idx[LIST_0][j][i]; - dummylist1 = fs->frame->ref_idx[LIST_1][j][i]; - fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[LIST_0][dummylist0] : -1; - fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[LIST_1][dummylist1] : -1; + dummylist0 = fs->frame->motion.ref_idx[LIST_0][j][i]; + dummylist1 = fs->frame->motion.ref_idx[LIST_1][j][i]; + fs->frame->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[LIST_0][dummylist0] : -1; + fs->frame->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[LIST_1][dummylist1] : -1; } } } @@ -3107,29 +3143,29 @@ void dpb_split_field(FrameStore *fs) currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2); // Assign field mvs attached to MB-Frame buffer to the proper buffer - if (fs->frame->mb_field[currentmb]) + if (fs->frame->motion.mb_field[currentmb]) { - fs->bottom_field->field_frame[j][i] = fs->top_field->field_frame[j][i]=1; - fs->frame->field_frame[2*j][i] = fs->frame->field_frame[2*j+1][i]=1; - - fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj4][i][0]; - fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj4][i][1]; - fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj4][i][0]; - fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj4][i][1]; - fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj4][i]; - fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj4][i]; - fs->bottom_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+4][jj4][i]; - fs->bottom_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+4][jj4][i]; - - - fs->top_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][i][0]; - fs->top_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][i][1]; - fs->top_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][i][0]; - fs->top_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][i][1]; - fs->top_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][i]; - fs->top_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][i]; - fs->top_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+2][jj][i]; - fs->top_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+2][jj][i]; + fs->bottom_field->motion.field_frame[j][i] = fs->top_field->motion.field_frame[j][i]=1; + fs->frame->motion.field_frame[2*j][i] = fs->frame->motion.field_frame[2*j+1][i]=1; + + fs->bottom_field->motion.mv[LIST_0][j][i][0] = fs->frame->motion.mv[LIST_0][jj4][i][0]; + fs->bottom_field->motion.mv[LIST_0][j][i][1] = fs->frame->motion.mv[LIST_0][jj4][i][1]; + fs->bottom_field->motion.mv[LIST_1][j][i][0] = fs->frame->motion.mv[LIST_1][jj4][i][0]; + fs->bottom_field->motion.mv[LIST_1][j][i][1] = fs->frame->motion.mv[LIST_1][jj4][i][1]; + fs->bottom_field->motion.ref_idx[LIST_0][j][i] = fs->frame->motion.ref_idx[LIST_0][jj4][i]; + fs->bottom_field->motion.ref_idx[LIST_1][j][i] = fs->frame->motion.ref_idx[LIST_1][jj4][i]; + fs->bottom_field->motion.ref_id[LIST_0][j][i] = fs->frame->motion.ref_id[LIST_0+4][jj4][i]; + fs->bottom_field->motion.ref_id[LIST_1][j][i] = fs->frame->motion.ref_id[LIST_1+4][jj4][i]; + + + fs->top_field->motion.mv[LIST_0][j][i][0] = fs->frame->motion.mv[LIST_0][jj][i][0]; + fs->top_field->motion.mv[LIST_0][j][i][1] = fs->frame->motion.mv[LIST_0][jj][i][1]; + fs->top_field->motion.mv[LIST_1][j][i][0] = fs->frame->motion.mv[LIST_1][jj][i][0]; + fs->top_field->motion.mv[LIST_1][j][i][1] = fs->frame->motion.mv[LIST_1][jj][i][1]; + fs->top_field->motion.ref_idx[LIST_0][j][i] = fs->frame->motion.ref_idx[LIST_0][jj][i]; + fs->top_field->motion.ref_idx[LIST_1][j][i] = fs->frame->motion.ref_idx[LIST_1][jj][i]; + fs->top_field->motion.ref_id[LIST_0][j][i] = fs->frame->motion.ref_id[LIST_0+2][jj][i]; + fs->top_field->motion.ref_id[LIST_1][j][i] = fs->frame->motion.ref_id[LIST_1+2][jj][i]; } } } @@ -3149,47 +3185,47 @@ void dpb_split_field(FrameStore *fs) currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2); - if (!fs->frame->MbaffFrameFlag || !fs->frame->mb_field[currentmb]) + if (!fs->frame->MbaffFrameFlag || !fs->frame->motion.mb_field[currentmb]) { - fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]=0; + fs->frame->motion.field_frame[2*j+1][i] = fs->frame->motion.field_frame[2*j][i]=0; - fs->top_field->field_frame[j][i] = fs->bottom_field->field_frame[j][i] = 0; + fs->top_field->motion.field_frame[j][i] = fs->bottom_field->motion.field_frame[j][i] = 0; - fs->top_field->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][ii][0]; - fs->top_field->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][ii][1]; - fs->top_field->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][ii][0]; - fs->top_field->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][ii][1]; + fs->top_field->motion.mv[LIST_0][j][i][0] = fs->bottom_field->motion.mv[LIST_0][j][i][0] = fs->frame->motion.mv[LIST_0][jj][ii][0]; + fs->top_field->motion.mv[LIST_0][j][i][1] = fs->bottom_field->motion.mv[LIST_0][j][i][1] = fs->frame->motion.mv[LIST_0][jj][ii][1]; + fs->top_field->motion.mv[LIST_1][j][i][0] = fs->bottom_field->motion.mv[LIST_1][j][i][0] = fs->frame->motion.mv[LIST_1][jj][ii][0]; + fs->top_field->motion.mv[LIST_1][j][i][1] = fs->bottom_field->motion.mv[LIST_1][j][i][1] = fs->frame->motion.mv[LIST_1][jj][ii][1]; // Scaling of references is done here since it will not affect spatial direct (2*0 =0) - if (fs->frame->ref_idx[LIST_0][jj][ii] == -1) - fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = - 1; + if (fs->frame->motion.ref_idx[LIST_0][jj][ii] == -1) + fs->top_field->motion.ref_idx[LIST_0][j][i] = fs->bottom_field->motion.ref_idx[LIST_0][j][i] = - 1; else { - dummylist0=fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][ii]; - fs->top_field ->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->top_ref_pic_num[LIST_0][dummylist0] : 0; - fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->bottom_ref_pic_num[LIST_0][dummylist0] : 0; + dummylist0=fs->top_field->motion.ref_idx[LIST_0][j][i] = fs->bottom_field->motion.ref_idx[LIST_0][j][i] = fs->frame->motion.ref_idx[LIST_0][jj][ii]; + fs->top_field ->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->top_ref_pic_num[LIST_0][dummylist0] : 0; + fs->bottom_field->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->bottom_ref_pic_num[LIST_0][dummylist0] : 0; } - if (fs->frame->ref_idx[LIST_1][jj][ii] == -1) - fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = - 1; + if (fs->frame->motion.ref_idx[LIST_1][jj][ii] == -1) + fs->top_field->motion.ref_idx[LIST_1][j][i] = fs->bottom_field->motion.ref_idx[LIST_1][j][i] = - 1; else { - dummylist1=fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][ii]; + dummylist1=fs->top_field->motion.ref_idx[LIST_1][j][i] = fs->bottom_field->motion.ref_idx[LIST_1][j][i] = fs->frame->motion.ref_idx[LIST_1][jj][ii]; - fs->top_field ->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->top_ref_pic_num[LIST_1][dummylist1] : 0; - fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->bottom_ref_pic_num[LIST_1][dummylist1] : 0; + fs->top_field ->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->top_ref_pic_num[LIST_1][dummylist1] : 0; + fs->bottom_field->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->bottom_ref_pic_num[LIST_1][dummylist1] : 0; } } else { - fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]= fs->frame->mb_field[currentmb]; + fs->frame->motion.field_frame[2*j+1][i] = fs->frame->motion.field_frame[2*j][i]= fs->frame->motion.mb_field[currentmb]; } } } } else { - memset( &(fs->frame->field_frame[0][0]), 0, fs->frame->size_y * (fs->frame->size_x >>4) * sizeof(byte)); + memset( &(fs->frame->motion.field_frame[0][0]), 0, fs->frame->size_y * (fs->frame->size_x >>4) * sizeof(byte)); } } @@ -3297,41 +3333,41 @@ void dpb_combine_field(FrameStore *fs) jj4 = jj + 4; for (i=0 ; i<fs->top_field->size_x/4 ; i++) { - fs->frame->field_frame[jj][i]= fs->frame->field_frame[jj4][i]=1; + fs->frame->motion.field_frame[jj][i]= fs->frame->motion.field_frame[jj4][i]=1; - fs->frame->mv[LIST_0][jj][i][0] = fs->top_field->mv[LIST_0][j][i][0]; - fs->frame->mv[LIST_0][jj][i][1] = fs->top_field->mv[LIST_0][j][i][1] ; - fs->frame->mv[LIST_1][jj][i][0] = fs->top_field->mv[LIST_1][j][i][0]; - fs->frame->mv[LIST_1][jj][i][1] = fs->top_field->mv[LIST_1][j][i][1] ; + fs->frame->motion.mv[LIST_0][jj][i][0] = fs->top_field->motion.mv[LIST_0][j][i][0]; + fs->frame->motion.mv[LIST_0][jj][i][1] = fs->top_field->motion.mv[LIST_0][j][i][1] ; + fs->frame->motion.mv[LIST_1][jj][i][0] = fs->top_field->motion.mv[LIST_1][j][i][0]; + fs->frame->motion.mv[LIST_1][jj][i][1] = fs->top_field->motion.mv[LIST_1][j][i][1] ; - dummylist0=fs->frame->ref_idx[LIST_0][jj][i] = fs->top_field->ref_idx[LIST_0][j][i]; - dummylist1=fs->frame->ref_idx[LIST_1][jj][i] = fs->top_field->ref_idx[LIST_1][j][i]; + dummylist0=fs->frame->motion.ref_idx[LIST_0][jj][i] = fs->top_field->motion.ref_idx[LIST_0][j][i]; + dummylist1=fs->frame->motion.ref_idx[LIST_1][jj][i] = fs->top_field->motion.ref_idx[LIST_1][j][i]; //! association with id already known for fields. - fs->top_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->top_field->ref_pic_num[LIST_0][dummylist0] : 0; - fs->top_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->top_field->ref_pic_num[LIST_1][dummylist1] : 0; + fs->top_field->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->top_field->ref_pic_num[LIST_0][dummylist0] : 0; + fs->top_field->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->top_field->ref_pic_num[LIST_1][dummylist1] : 0; //! need to make association with frames - fs->frame->ref_id[LIST_0][jj][i] = (dummylist0>=0)? fs->top_field->frm_ref_pic_num[LIST_0][dummylist0] : 0; - fs->frame->ref_id[LIST_1][jj][i] = (dummylist1>=0)? fs->top_field->frm_ref_pic_num[LIST_1][dummylist1] : 0; + fs->frame->motion.ref_id[LIST_0][jj][i] = (dummylist0>=0)? fs->top_field->frm_ref_pic_num[LIST_0][dummylist0] : 0; + fs->frame->motion.ref_id[LIST_1][jj][i] = (dummylist1>=0)? fs->top_field->frm_ref_pic_num[LIST_1][dummylist1] : 0; - fs->frame->mv[LIST_0][jj4][i][0] = fs->bottom_field->mv[LIST_0][j][i][0]; - fs->frame->mv[LIST_0][jj4][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] ; - fs->frame->mv[LIST_1][jj4][i][0] = fs->bottom_field->mv[LIST_1][j][i][0]; - fs->frame->mv[LIST_1][jj4][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] ; + fs->frame->motion.mv[LIST_0][jj4][i][0] = fs->bottom_field->motion.mv[LIST_0][j][i][0]; + fs->frame->motion.mv[LIST_0][jj4][i][1] = fs->bottom_field->motion.mv[LIST_0][j][i][1] ; + fs->frame->motion.mv[LIST_1][jj4][i][0] = fs->bottom_field->motion.mv[LIST_1][j][i][0]; + fs->frame->motion.mv[LIST_1][jj4][i][1] = fs->bottom_field->motion.mv[LIST_1][j][i][1] ; - dummylist0=fs->frame->ref_idx[LIST_0][jj4][i] = fs->bottom_field->ref_idx[LIST_0][j][i]; - dummylist1=fs->frame->ref_idx[LIST_1][jj4][i] = fs->bottom_field->ref_idx[LIST_1][j][i]; + dummylist0=fs->frame->motion.ref_idx[LIST_0][jj4][i] = fs->bottom_field->motion.ref_idx[LIST_0][j][i]; + dummylist1=fs->frame->motion.ref_idx[LIST_1][jj4][i] = fs->bottom_field->motion.ref_idx[LIST_1][j][i]; - fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->bottom_field->ref_pic_num[LIST_0][dummylist0] : 0; - fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->bottom_field->ref_pic_num[LIST_1][dummylist1] : 0; + fs->bottom_field->motion.ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->bottom_field->ref_pic_num[LIST_0][dummylist0] : 0; + fs->bottom_field->motion.ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->bottom_field->ref_pic_num[LIST_1][dummylist1] : 0; //! need to make association with frames - fs->frame->ref_id[LIST_0][jj4][i] = (dummylist0>=0)? fs->bottom_field->frm_ref_pic_num[LIST_0][dummylist0] : -1; - fs->frame->ref_id[LIST_1][jj4][i] = (dummylist1>=0)? fs->bottom_field->frm_ref_pic_num[LIST_1][dummylist1] : -1; + fs->frame->motion.ref_id[LIST_0][jj4][i] = (dummylist0>=0)? fs->bottom_field->frm_ref_pic_num[LIST_0][dummylist0] : -1; + fs->frame->motion.ref_id[LIST_1][jj4][i] = (dummylist1>=0)? fs->bottom_field->frm_ref_pic_num[LIST_1][dummylist1] : -1; - fs->top_field->field_frame[j][i]=1; - fs->bottom_field->field_frame[j][i]=1; + fs->top_field->motion.field_frame[j][i]=1; + fs->bottom_field->motion.field_frame[j][i]=1; } } } @@ -3454,6 +3490,21 @@ void fill_frame_num_gap(ImageParameters *img) img->nal_reference_idc = nal_ref_idc_bak; } +/*! + ************************************************************************ + * \brief + * Allocate motion parameter memory for colocated structure + * + ************************************************************************ + */ +void alloc_motion_params(MotionParams *ftype, int size_y, int size_x) +{ + get_mem3Dint64 (&(ftype->ref_pic_id), 2, size_y, size_x); + get_mem4Dshort (&(ftype->mv) , 2, size_y, size_x, 2); + get_mem3D ((byte****)(&(ftype->ref_idx)) , 2, size_y, size_x); + get_mem2D (&(ftype->moving_block) , size_y, size_x); +} + /*! ************************************************************************ * \brief @@ -3481,25 +3532,12 @@ ColocatedParams* alloc_colocated(int size_x, int size_y, int mb_adaptive_frame_f s->size_x = size_x; s->size_y = size_y; - - get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->ref_pic_id), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE,2 ); - - get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); - get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); + alloc_motion_params(&s->frame, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); if (mb_adaptive_frame_field_flag) { - get_mem3D ((byte****)(&(s->top_ref_idx)) , 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->top_ref_pic_id), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->top_mv), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2); - get_mem2D (&(s->top_moving_block), size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE); - - get_mem3D ((byte****)(&(s->bottom_ref_idx)), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE); - get_mem3Dint64 (&(s->bottom_ref_pic_id), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE); - get_mem4Dshort (&(s->bottom_mv), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2); - get_mem2D (&(s->bottom_moving_block), size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE); + alloc_motion_params(&s->top , size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); + alloc_motion_params(&s->bottom, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); } s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag; @@ -3507,6 +3545,27 @@ ColocatedParams* alloc_colocated(int size_x, int size_y, int mb_adaptive_frame_f return s; } + +/*! + ************************************************************************ + * \brief + * Free motion parameter memory for colocated structure + * + ************************************************************************ + */ +void free_motion_params(MotionParams *ftype) +{ + free_mem3Dint64 (ftype->ref_pic_id); + free_mem3D ((byte***)ftype->ref_idx); + free_mem4Dshort (ftype->mv); + + if (ftype->moving_block) + { + free_mem2D (ftype->moving_block); + ftype->moving_block=NULL; + } +} + /*! ************************************************************************ * \brief @@ -3521,45 +3580,12 @@ void free_colocated(ColocatedParams* p) { if (p) { - free_mem3D ((byte***)p->ref_idx); - free_mem3Dint64 (p->ref_pic_id); - free_mem4Dshort (p->mv); - - if (p->moving_block) - { - free_mem2D (p->moving_block); - p->moving_block=NULL; - } - if (p->field_frame) - { - free_mem2D (p->field_frame); - p->field_frame=NULL; - } + free_motion_params(&p->frame); if (p->mb_adaptive_frame_field_flag) { - free_mem3D ((byte***)p->top_ref_idx); - free_mem3Dint64 (p->top_ref_pic_id); - free_mem4Dshort (p->top_mv); - - - if (p->top_moving_block) - { - free_mem2D (p->top_moving_block); - p->top_moving_block=NULL; - } - - free_mem3D ((byte***)p->bottom_ref_idx); - free_mem3Dint64 (p->bottom_ref_pic_id); - free_mem4Dshort (p->bottom_mv); - - - if (p->bottom_moving_block) - { - free_mem2D (p->bottom_moving_block); - p->bottom_moving_block=NULL; - } - + free_motion_params(&p->top ); + free_motion_params(&p->bottom); } free(p); @@ -3579,6 +3605,7 @@ void free_colocated(ColocatedParams* p) void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { StorablePicture *fs, *fs_top, *fs_bottom; + MotionParams *ftype = NULL; int i,j, ii, jj, jdiv; fs_top = fs_bottom = fs = listX[LIST_1 ][0]; @@ -3607,7 +3634,8 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) } if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag) - { + { + ftype = &p->frame; for (j=0 ; j<fs->size_y/4 ; j++) { jdiv = j>>1; @@ -3615,7 +3643,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i<fs->size_x/4 ; i++) { - if (img->MbaffFrameFlag && fs->field_frame[j][i]) + if (img->MbaffFrameFlag && fs->motion.field_frame[j][i]) { //! Assign frame buffers for field MBs //! Check whether we should use top or bottom field mvs. @@ -3623,41 +3651,41 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) if (iabs(enc_picture->poc - fs_bottom->poc) > iabs(enc_picture->poc - fs_top->poc) ) { - p->mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i]; + ftype->mv[LIST_0][j][i][0] = fs_top->motion.mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs_top->motion.mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs_top->motion.mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs_top->motion.mv[LIST_1][jdiv][i][1] ; + ftype->ref_idx[LIST_0][j][i] = fs_top->motion.ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs_top->motion.ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj][i]; p->is_long_term = fs_top->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i]; + ftype->mv[LIST_0][j][i][0] = fs_bottom->motion.mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs_bottom->motion.mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs_bottom->motion.mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs_bottom->motion.mv[LIST_1][jdiv][i][1] ; + ftype->ref_idx[LIST_0][j][i] = fs_bottom->motion.ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs_bottom->motion.ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj + 4][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs_bottom->is_long_term; } } else { - p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][j][i][1] ; - p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][j][i][1] ; - p->ref_idx[LIST_0][j][i] = fs->ref_idx[LIST_0][j][i]; - p->ref_idx[LIST_1][j][i] = fs->ref_idx[LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i]; + ftype->mv[LIST_0][j][i][0] = fs->motion.mv[LIST_0][j][i][0]; + ftype->mv[LIST_0][j][i][1] = fs->motion.mv[LIST_0][j][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs->motion.mv[LIST_1][j][i][0]; + ftype->mv[LIST_1][j][i][1] = fs->motion.mv[LIST_1][j][i][1] ; + ftype->ref_idx[LIST_0][j][i] = fs->motion.ref_idx[LIST_0][j][i]; + ftype->ref_idx[LIST_1][j][i] = fs->motion.ref_idx[LIST_1][j][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][j][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][j][i]; p->is_long_term = fs->is_long_term; } @@ -3669,6 +3697,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) //! Generate field MVs from Frame MVs if (img->structure || img->MbaffFrameFlag) { + ftype = &p->frame; for (j=0 ; j<fs->size_y/8 ; j++) { jj = RSD(j); @@ -3678,102 +3707,102 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) //! Do nothing if macroblock as field coded in MB-AFF if (!img->MbaffFrameFlag ) { - p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][jj][ii][1]; + ftype->mv[LIST_0][j][i][0] = fs->motion.mv[LIST_0][jj][ii][0]; + ftype->mv[LIST_0][j][i][1] = fs->motion.mv[LIST_0][jj][ii][1]; + ftype->mv[LIST_1][j][i][0] = fs->motion.mv[LIST_1][jj][ii][0]; + ftype->mv[LIST_1][j][i][1] = fs->motion.mv[LIST_1][jj][ii][1]; // Scaling of references is done here since it will not affect spatial direct (2*0 =0) - if (fs->ref_idx[LIST_0][jj][ii] == -1) + if (fs->motion.ref_idx[LIST_0][jj][ii] == -1) { - p->ref_idx [LIST_0][j][i] = -1; - p->ref_pic_id[LIST_0][j][i] = -1; + ftype->ref_idx [LIST_0][j][i] = -1; + ftype->ref_pic_id[LIST_0][j][i] = -1; } else { - p->ref_idx [LIST_0][j][i] = fs->ref_idx[LIST_0][jj][ii] ; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id [LIST_0][jj][ii]; + ftype->ref_idx [LIST_0][j][i] = fs->motion.ref_idx[LIST_0][jj][ii] ; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id [LIST_0][jj][ii]; } - if (fs->ref_idx[LIST_1][jj][ii] == -1) + if (fs->motion.ref_idx[LIST_1][jj][ii] == -1) { - p->ref_idx [LIST_1][j][i] = -1; - p->ref_pic_id[LIST_1][j][i] = -1; + ftype->ref_idx [LIST_1][j][i] = -1; + ftype->ref_pic_id[LIST_1][j][i] = -1; } else { - p->ref_idx [LIST_1][j][i] = fs->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id [LIST_1][jj][ii]; + ftype->ref_idx [LIST_1][j][i] = fs->motion.ref_idx[LIST_1][jj][ii]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id [LIST_1][jj][ii]; } p->is_long_term = fs->is_long_term; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i] = + ftype->moving_block[j][i] = !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((ftype->ref_idx[LIST_0][j][i] == 0) + && (iabs(ftype->mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_0][j][i][1])>>1 == 0))) + || ((ftype->ref_idx[LIST_0][j][i] == -1) + && (ftype->ref_idx[LIST_1][j][i] == 0) + && (iabs(ftype->mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_1][j][i][1])>>1 == 0))); } } else { - p->bottom_mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jj][ii][0]; - p->bottom_mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jj][ii][1]; - p->bottom_mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jj][ii][0]; - p->bottom_mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jj][ii][1]; - p->bottom_ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jj][ii]; - p->bottom_ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jj][ii]; - p->bottom_ref_pic_id[LIST_0][j][i] = fs_bottom->ref_id[LIST_0][jj][ii]; - p->bottom_ref_pic_id[LIST_1][j][i] = fs_bottom->ref_id[LIST_1][jj][ii]; + p->bottom.mv[LIST_0][j][i][0] = fs_bottom->motion.mv[LIST_0][jj][ii][0]; + p->bottom.mv[LIST_0][j][i][1] = fs_bottom->motion.mv[LIST_0][jj][ii][1]; + p->bottom.mv[LIST_1][j][i][0] = fs_bottom->motion.mv[LIST_1][jj][ii][0]; + p->bottom.mv[LIST_1][j][i][1] = fs_bottom->motion.mv[LIST_1][jj][ii][1]; + p->bottom.ref_idx[LIST_0][j][i] = fs_bottom->motion.ref_idx[LIST_0][jj][ii]; + p->bottom.ref_idx[LIST_1][j][i] = fs_bottom->motion.ref_idx[LIST_1][jj][ii]; + p->bottom.ref_pic_id[LIST_0][j][i] = fs_bottom->motion.ref_id[LIST_0][jj][ii]; + p->bottom.ref_pic_id[LIST_1][j][i] = fs_bottom->motion.ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->bottom_moving_block[j][i] = + p->bottom.moving_block[j][i] = !((!fs_bottom->is_long_term - && ((p->bottom_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->bottom_ref_idx[LIST_0][j][i] == -1) - && (p->bottom_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->bottom.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->bottom.ref_idx[LIST_0][j][i] == -1) + && (p->bottom.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][1])>>1 == 0))); } - p->top_mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jj][ii][0]; - p->top_mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jj][ii][1]; - p->top_mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jj][ii][0]; - p->top_mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jj][ii][1]; - p->top_ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jj][ii]; - p->top_ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jj][ii]; - p->top_ref_pic_id[LIST_0][j][i] = fs_top->ref_id[LIST_0][jj][ii]; - p->top_ref_pic_id[LIST_1][j][i] = fs_top->ref_id[LIST_1][jj][ii]; + p->top.mv[LIST_0][j][i][0] = fs_top->motion.mv[LIST_0][jj][ii][0]; + p->top.mv[LIST_0][j][i][1] = fs_top->motion.mv[LIST_0][jj][ii][1]; + p->top.mv[LIST_1][j][i][0] = fs_top->motion.mv[LIST_1][jj][ii][0]; + p->top.mv[LIST_1][j][i][1] = fs_top->motion.mv[LIST_1][jj][ii][1]; + p->top.ref_idx[LIST_0][j][i] = fs_top->motion.ref_idx[LIST_0][jj][ii]; + p->top.ref_idx[LIST_1][j][i] = fs_top->motion.ref_idx[LIST_1][jj][ii]; + p->top.ref_pic_id[LIST_0][j][i] = fs_top->motion.ref_id[LIST_0][jj][ii]; + p->top.ref_pic_id[LIST_1][j][i] = fs_top->motion.ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->top_moving_block[j][i] = + p->top.moving_block[j][i] = !((!fs_top->is_long_term - && ((p->top_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->top_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->top_ref_idx[LIST_0][j][i] == -1) - && (p->top_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->top_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->top.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->top.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->top.ref_idx[LIST_0][j][i] == -1) + && (p->top.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->top.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_1][j][i][1])>>1 == 0))); } - if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->field_frame[2*j][i]) + if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->motion.field_frame[2*j][i]) { - p->top_mv[LIST_0][j][i][1] /= 2; - p->top_mv[LIST_1][j][i][1] /= 2; - p->bottom_mv[LIST_0][j][i][1] /= 2; - p->bottom_mv[LIST_1][j][i][1] /= 2; + p->top.mv[LIST_0][j][i][1] /= 2; + p->top.mv[LIST_1][j][i][1] /= 2; + p->bottom.mv[LIST_0][j][i][1] /= 2; + p->bottom.mv[LIST_1][j][i][1] /= 2; } } @@ -3789,6 +3818,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) if (!img->structure) { + ftype = &p->frame; for (j=0 ; j < (fs->size_y>>2) ; j++) { jdiv = j>>1; @@ -3796,32 +3826,32 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i < (fs->size_x>>2) ; i++) { - if (fs->field_frame[j][i]) + if (fs->motion.field_frame[j][i]) { if (iabs(enc_picture->poc - fs->bottom_field->poc) > iabs(enc_picture->poc - fs->top_field->poc)) { - p->mv[LIST_0][j][i][0] = fs->top_field->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->top_field->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->top_field->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->top_field->mv[LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->top_field->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->top_field->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i]; + ftype->mv[LIST_0][j][i][0] = fs->top_field->motion.mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs->top_field->motion.mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs->top_field->motion.mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs->top_field->motion.mv[LIST_1][jdiv][i][1] ; + + ftype->ref_idx[LIST_0][j][i] = fs->top_field->motion.ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs->top_field->motion.ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj][i]; p->is_long_term = fs->top_field->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i]; + ftype->mv[LIST_0][j][i][0] = fs->bottom_field->motion.mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs->bottom_field->motion.mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs->bottom_field->motion.mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs->bottom_field->motion.mv[LIST_1][jdiv][i][1] ; + + ftype->ref_idx[LIST_0][j][i] = fs->bottom_field->motion.ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs->bottom_field->motion.ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][jj + 4][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs->bottom_field->is_long_term; } } @@ -3835,6 +3865,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag) { + ftype = &p->frame; for (j=0 ; j < (fs->size_y>>2) ; j++) { jj = RSD(j); @@ -3842,33 +3873,34 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); - p->mv[LIST_0][j][i][0]=p->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1]=p->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0]=p->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1]=p->mv[LIST_1][jj][ii][1]; + ftype->mv[LIST_0][j][i][0]=ftype->mv[LIST_0][jj][ii][0]; + ftype->mv[LIST_0][j][i][1]=ftype->mv[LIST_0][jj][ii][1]; + ftype->mv[LIST_1][j][i][0]=ftype->mv[LIST_1][jj][ii][0]; + ftype->mv[LIST_1][j][i][1]=ftype->mv[LIST_1][jj][ii][1]; - p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii]; - p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii]; + ftype->ref_idx[LIST_0][j][i]=ftype->ref_idx[LIST_0][jj][ii]; + ftype->ref_idx[LIST_1][j][i]=ftype->ref_idx[LIST_1][jj][ii]; + ftype->ref_pic_id[LIST_0][j][i] = ftype->ref_pic_id[LIST_0][jj][ii]; + ftype->ref_pic_id[LIST_1][j][i] = ftype->ref_pic_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i]= + ftype->moving_block[j][i]= !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((ftype->ref_idx[LIST_0][j][i] == 0) + && (iabs(ftype->mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_0][j][i][1])>>1 == 0))) + || ((ftype->ref_idx[LIST_0][j][i] == -1) + && (ftype->ref_idx[LIST_1][j][i] == 0) + && (iabs(ftype->mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_1][j][i][1])>>1 == 0))); } } } } else { + ftype = &p->frame; for (j=0 ; j<fs->size_y/4 ; j++) { jj = RSD(j); @@ -3876,27 +3908,27 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); //! Use inference flag to remap mvs/references - p->mv[LIST_0][j][i][0]=fs->mv[LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1]=fs->mv[LIST_0][j][i][1]; - p->mv[LIST_1][j][i][0]=fs->mv[LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1]=fs->mv[LIST_1][j][i][1]; + ftype->mv[LIST_0][j][i][0]=fs->motion.mv[LIST_0][j][i][0]; + ftype->mv[LIST_0][j][i][1]=fs->motion.mv[LIST_0][j][i][1]; + ftype->mv[LIST_1][j][i][0]=fs->motion.mv[LIST_1][j][i][0]; + ftype->mv[LIST_1][j][i][1]=fs->motion.mv[LIST_1][j][i][1]; - p->ref_idx[LIST_0][j][i]=fs->ref_idx[LIST_0][j][i]; - p->ref_idx[LIST_1][j][i]=fs->ref_idx[LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i]; + ftype->ref_idx[LIST_0][j][i]=fs->motion.ref_idx[LIST_0][j][i]; + ftype->ref_idx[LIST_1][j][i]=fs->motion.ref_idx[LIST_1][j][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->motion.ref_id[LIST_0][j][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->motion.ref_id[LIST_1][j][i]; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i]= + ftype->moving_block[j][i]= !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((ftype->ref_idx[LIST_0][j][i] == 0) + && (iabs(ftype->mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_0][j][i][1])>>1 == 0))) + || ((ftype->ref_idx[LIST_0][j][i] == -1) + && (ftype->ref_idx[LIST_1][j][i] == 0) + && (iabs(ftype->mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_1][j][i][1])>>1 == 0))); } } } @@ -3905,19 +3937,20 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) if (img->direct_spatial_mv_pred_flag ==0) { + ftype = &p->frame; for (j=0 ; j<fs->size_y/4 ; j++) { for (i=0 ; i<fs->size_x/4 ; i++) { - if ((!img->MbaffFrameFlag &&!img->structure && fs->field_frame[j][i]) || (img->MbaffFrameFlag && fs->field_frame[j][i])) + if ((!img->MbaffFrameFlag &&!img->structure && fs->motion.field_frame[j][i]) || (img->MbaffFrameFlag && fs->motion.field_frame[j][i])) { - p->mv[LIST_0][j][i][1] *= 2; - p->mv[LIST_1][j][i][1] *= 2; + ftype->mv[LIST_0][j][i][1] *= 2; + ftype->mv[LIST_1][j][i][1] *= 2; } - else if (img->structure && !fs->field_frame[j][i]) + else if (img->structure && !fs->motion.field_frame[j][i]) { - p->mv[LIST_0][j][i][1] /= 2; - p->mv[LIST_1][j][i][1] /= 2; + ftype->mv[LIST_0][j][i][1] /= 2; + ftype->mv[LIST_1][j][i][1] /= 2; } } @@ -3970,6 +4003,7 @@ void compute_colocated(ColocatedParams* p, StorablePicture **listX[6]) void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) { StorablePicture *fs, *fs_top, *fs_bottom; + MotionParams *ftype; int i,j, ii, jj, jdiv; int np = img->colour_plane_id; @@ -4000,6 +4034,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag) { + ftype = &p->frame; for (j=0 ; j<fs->size_y/4 ; j++) { jdiv = j/2; @@ -4007,7 +4042,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i<fs->size_x/4 ; i++) { - if (img->MbaffFrameFlag && fs->field_frame[j][i]) + if (img->MbaffFrameFlag && fs->motion.field_frame[j][i]) { //! Assign frame buffers for field MBs //! Check whether we should use top or bottom field mvs. @@ -4015,41 +4050,41 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) if (iabs(enc_picture->poc - fs_bottom->poc) > iabs(enc_picture->poc - fs_top->poc) ) { - p->mv[LIST_0][j][i][0] = fs_top->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_top->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_top->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_top->mv_JV[np][LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_top->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_top->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj][i]; + ftype->mv[LIST_0][j][i][0] = fs_top->JVmotion[np].mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs_top->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs_top->JVmotion[np].mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs_top->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + ftype->ref_idx[LIST_0][j][i] = fs_top->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs_top->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj][i]; p->is_long_term = fs_top->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs_bottom->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs_bottom->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs_bottom->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs_bottom->mv_JV[np][LIST_1][jdiv][i][1] ; - p->ref_idx[LIST_0][j][i] = fs_bottom->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs_bottom->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj + 4][i]; + ftype->mv[LIST_0][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + ftype->ref_idx[LIST_0][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj + 4][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs_bottom->is_long_term; } } else { - p->mv[LIST_0][j][i][0] = fs->mv_JV[np][LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1] = fs->mv_JV[np][LIST_0][j][i][1] ; - p->mv[LIST_1][j][i][0] = fs->mv_JV[np][LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1] = fs->mv_JV[np][LIST_1][j][i][1] ; - p->ref_idx[LIST_0][j][i] = fs->ref_idx_JV[np][LIST_0][j][i]; - p->ref_idx[LIST_1][j][i] = fs->ref_idx_JV[np][LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][j][i]; + ftype->mv[LIST_0][j][i][0] = fs->JVmotion[np].mv[LIST_0][j][i][0]; + ftype->mv[LIST_0][j][i][1] = fs->JVmotion[np].mv[LIST_0][j][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs->JVmotion[np].mv[LIST_1][j][i][0]; + ftype->mv[LIST_1][j][i][1] = fs->JVmotion[np].mv[LIST_1][j][i][1] ; + ftype->ref_idx[LIST_0][j][i] = fs->JVmotion[np].ref_idx[LIST_0][j][i]; + ftype->ref_idx[LIST_1][j][i] = fs->JVmotion[np].ref_idx[LIST_1][j][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][j][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][j][i]; p->is_long_term = fs->is_long_term; } @@ -4061,6 +4096,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) //! Generate field MVs from Frame MVs if (img->structure || img->MbaffFrameFlag) { + ftype = &p->frame; for (j=0 ; j<fs->size_y/8 ; j++) { jj = RSD(j); @@ -4070,102 +4106,102 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) //! Do nothing if macroblock as field coded in MB-AFF if (!img->MbaffFrameFlag ) { - p->mv[LIST_0][j][i][0] = fs->mv_JV[np][LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1] = fs->mv_JV[np][LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0] = fs->mv_JV[np][LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1] = fs->mv_JV[np][LIST_1][jj][ii][1]; + ftype->mv[LIST_0][j][i][0] = fs->JVmotion[np].mv[LIST_0][jj][ii][0]; + ftype->mv[LIST_0][j][i][1] = fs->JVmotion[np].mv[LIST_0][jj][ii][1]; + ftype->mv[LIST_1][j][i][0] = fs->JVmotion[np].mv[LIST_1][jj][ii][0]; + ftype->mv[LIST_1][j][i][1] = fs->JVmotion[np].mv[LIST_1][jj][ii][1]; // Scaling of references is done here since it will not affect spatial direct (2*0 =0) - if (fs->ref_idx[LIST_0][jj][ii] == -1) + if (fs->motion.ref_idx[LIST_0][jj][ii] == -1) { - p->ref_idx [LIST_0][j][i] = -1; - p->ref_pic_id[LIST_0][j][i] = -1; + ftype->ref_idx [LIST_0][j][i] = -1; + ftype->ref_pic_id[LIST_0][j][i] = -1; } else { - p->ref_idx [LIST_0][j][i] = fs->ref_idx_JV[np][LIST_0][jj][ii] ; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV [np][LIST_0][jj][ii]; + ftype->ref_idx [LIST_0][j][i] = fs->JVmotion[np].ref_idx[LIST_0][jj][ii] ; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj][ii]; } - if (fs->ref_idx[LIST_1][jj][ii] == -1) + if (fs->motion.ref_idx[LIST_1][jj][ii] == -1) { - p->ref_idx [LIST_1][j][i] = -1; - p->ref_pic_id[LIST_1][j][i] = -1; + ftype->ref_idx [LIST_1][j][i] = -1; + ftype->ref_pic_id[LIST_1][j][i] = -1; } else { - p->ref_idx [LIST_1][j][i] = fs->ref_idx_JV[np][LIST_1][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV [np][LIST_1][jj][ii]; + ftype->ref_idx [LIST_1][j][i] = fs->JVmotion[np].ref_idx[LIST_1][jj][ii]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj][ii]; } p->is_long_term = fs->is_long_term; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i] = + ftype->moving_block[j][i] = !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((ftype->ref_idx[LIST_0][j][i] == 0) + && (iabs(ftype->mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_0][j][i][1])>>1 == 0))) + || ((ftype->ref_idx[LIST_0][j][i] == -1) + && (ftype->ref_idx[LIST_1][j][i] == 0) + && (iabs(ftype->mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_1][j][i][1])>>1 == 0))); } } else { - p->bottom_mv[LIST_0][j][i][0] = fs_bottom->mv_JV[np][LIST_0][jj][ii][0]; - p->bottom_mv[LIST_0][j][i][1] = fs_bottom->mv_JV[np][LIST_0][jj][ii][1]; - p->bottom_mv[LIST_1][j][i][0] = fs_bottom->mv_JV[np][LIST_1][jj][ii][0]; - p->bottom_mv[LIST_1][j][i][1] = fs_bottom->mv_JV[np][LIST_1][jj][ii][1]; - p->bottom_ref_idx[LIST_0][j][i] = fs_bottom->ref_idx_JV[np][LIST_0][jj][ii]; - p->bottom_ref_idx[LIST_1][j][i] = fs_bottom->ref_idx_JV[np][LIST_1][jj][ii]; - p->bottom_ref_pic_id[LIST_0][j][i] = fs_bottom->ref_id_JV[np][LIST_0][jj][ii]; - p->bottom_ref_pic_id[LIST_1][j][i] = fs_bottom->ref_id_JV[np][LIST_1][jj][ii]; + p->bottom.mv[LIST_0][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_0][jj][ii][0]; + p->bottom.mv[LIST_0][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_0][jj][ii][1]; + p->bottom.mv[LIST_1][j][i][0] = fs_bottom->JVmotion[np].mv[LIST_1][jj][ii][0]; + p->bottom.mv[LIST_1][j][i][1] = fs_bottom->JVmotion[np].mv[LIST_1][jj][ii][1]; + p->bottom.ref_idx[LIST_0][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_0][jj][ii]; + p->bottom.ref_idx[LIST_1][j][i] = fs_bottom->JVmotion[np].ref_idx[LIST_1][jj][ii]; + p->bottom.ref_pic_id[LIST_0][j][i] = fs_bottom->JVmotion[np].ref_id[LIST_0][jj][ii]; + p->bottom.ref_pic_id[LIST_1][j][i] = fs_bottom->JVmotion[np].ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->bottom_moving_block[j][i] = + p->bottom.moving_block[j][i] = !((!fs_bottom->is_long_term - && ((p->bottom_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->bottom_ref_idx[LIST_0][j][i] == -1) - && (p->bottom_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->bottom_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->bottom.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->bottom.ref_idx[LIST_0][j][i] == -1) + && (p->bottom.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->bottom.mv[LIST_1][j][i][1])>>1 == 0))); } - p->top_mv[LIST_0][j][i][0] = fs_top->mv_JV[np][LIST_0][jj][ii][0]; - p->top_mv[LIST_0][j][i][1] = fs_top->mv_JV[np][LIST_0][jj][ii][1]; - p->top_mv[LIST_1][j][i][0] = fs_top->mv_JV[np][LIST_1][jj][ii][0]; - p->top_mv[LIST_1][j][i][1] = fs_top->mv_JV[np][LIST_1][jj][ii][1]; - p->top_ref_idx[LIST_0][j][i] = fs_top->ref_idx_JV[np][LIST_0][jj][ii]; - p->top_ref_idx[LIST_1][j][i] = fs_top->ref_idx_JV[np][LIST_1][jj][ii]; - p->top_ref_pic_id[LIST_0][j][i] = fs_top->ref_id_JV[np][LIST_0][jj][ii]; - p->top_ref_pic_id[LIST_1][j][i] = fs_top->ref_id_JV[np][LIST_1][jj][ii]; + p->top.mv[LIST_0][j][i][0] = fs_top->JVmotion[np].mv[LIST_0][jj][ii][0]; + p->top.mv[LIST_0][j][i][1] = fs_top->JVmotion[np].mv[LIST_0][jj][ii][1]; + p->top.mv[LIST_1][j][i][0] = fs_top->JVmotion[np].mv[LIST_1][jj][ii][0]; + p->top.mv[LIST_1][j][i][1] = fs_top->JVmotion[np].mv[LIST_1][jj][ii][1]; + p->top.ref_idx[LIST_0][j][i] = fs_top->JVmotion[np].ref_idx[LIST_0][jj][ii]; + p->top.ref_idx[LIST_1][j][i] = fs_top->JVmotion[np].ref_idx[LIST_1][jj][ii]; + p->top.ref_pic_id[LIST_0][j][i] = fs_top->JVmotion[np].ref_id[LIST_0][jj][ii]; + p->top.ref_pic_id[LIST_1][j][i] = fs_top->JVmotion[np].ref_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->top_moving_block[j][i] = + p->top.moving_block[j][i] = !((!fs_top->is_long_term - && ((p->top_ref_idx[LIST_0][j][i] == 0) - && (iabs(p->top_mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->top_ref_idx[LIST_0][j][i] == -1) - && (p->top_ref_idx[LIST_1][j][i] == 0) - && (iabs(p->top_mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->top_mv[LIST_1][j][i][1])>>1 == 0))); + && ((p->top.ref_idx[LIST_0][j][i] == 0) + && (iabs(p->top.mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_0][j][i][1])>>1 == 0))) + || ((p->top.ref_idx[LIST_0][j][i] == -1) + && (p->top.ref_idx[LIST_1][j][i] == 0) + && (iabs(p->top.mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(p->top.mv[LIST_1][j][i][1])>>1 == 0))); } - if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->field_frame[2*j][i]) + if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->motion.field_frame[2*j][i]) { - p->top_mv[LIST_0][j][i][1] /= 2; - p->top_mv[LIST_1][j][i][1] /= 2; - p->bottom_mv[LIST_0][j][i][1] /= 2; - p->bottom_mv[LIST_1][j][i][1] /= 2; + p->top.mv[LIST_0][j][i][1] /= 2; + p->top.mv[LIST_1][j][i][1] /= 2; + p->bottom.mv[LIST_0][j][i][1] /= 2; + p->bottom.mv[LIST_1][j][i][1] /= 2; } } @@ -4181,6 +4217,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) if (!img->structure) { + ftype = &p->frame; for (j=0 ; j < (fs->size_y>>2) ; j++) { jdiv = j>>1; @@ -4188,32 +4225,32 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) for (i=0 ; i < (fs->size_x>>2) ; i++) { - if (fs->field_frame[j][i]) + if (fs->motion.field_frame[j][i]) { if (iabs(enc_picture->poc - fs->bottom_field->poc) > iabs(enc_picture->poc - fs->top_field->poc)) { - p->mv[LIST_0][j][i][0] = fs->top_field->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->top_field->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->top_field->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->top_field->mv_JV[np][LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->top_field->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->top_field->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj][i]; + ftype->mv[LIST_0][j][i][0] = fs->top_field->JVmotion[np].mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs->top_field->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs->top_field->JVmotion[np].mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs->top_field->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + + ftype->ref_idx[LIST_0][j][i] = fs->top_field->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs->top_field->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj][i]; p->is_long_term = fs->top_field->is_long_term; } else { - p->mv[LIST_0][j][i][0] = fs->bottom_field->mv_JV[np][LIST_0][jdiv][i][0]; - p->mv[LIST_0][j][i][1] = fs->bottom_field->mv_JV[np][LIST_0][jdiv][i][1] ; - p->mv[LIST_1][j][i][0] = fs->bottom_field->mv_JV[np][LIST_1][jdiv][i][0]; - p->mv[LIST_1][j][i][1] = fs->bottom_field->mv_JV[np][LIST_1][jdiv][i][1] ; - - p->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx_JV[np][LIST_0][jdiv][i]; - p->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx_JV[np][LIST_1][jdiv][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][jj + 4][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][jj + 4][i]; + ftype->mv[LIST_0][j][i][0] = fs->bottom_field->JVmotion[np].mv[LIST_0][jdiv][i][0]; + ftype->mv[LIST_0][j][i][1] = fs->bottom_field->JVmotion[np].mv[LIST_0][jdiv][i][1] ; + ftype->mv[LIST_1][j][i][0] = fs->bottom_field->JVmotion[np].mv[LIST_1][jdiv][i][0]; + ftype->mv[LIST_1][j][i][1] = fs->bottom_field->JVmotion[np].mv[LIST_1][jdiv][i][1] ; + + ftype->ref_idx[LIST_0][j][i] = fs->bottom_field->JVmotion[np].ref_idx[LIST_0][jdiv][i]; + ftype->ref_idx[LIST_1][j][i] = fs->bottom_field->JVmotion[np].ref_idx[LIST_1][jdiv][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][jj + 4][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][jj + 4][i]; p->is_long_term = fs->bottom_field->is_long_term; } } @@ -4227,6 +4264,7 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag) { + ftype = &p->frame; for (j=0 ; j < (fs->size_y>>2) ; j++) { jj = RSD(j); @@ -4234,33 +4272,34 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); - p->mv[LIST_0][j][i][0]=p->mv[LIST_0][jj][ii][0]; - p->mv[LIST_0][j][i][1]=p->mv[LIST_0][jj][ii][1]; - p->mv[LIST_1][j][i][0]=p->mv[LIST_1][jj][ii][0]; - p->mv[LIST_1][j][i][1]=p->mv[LIST_1][jj][ii][1]; + ftype->mv[LIST_0][j][i][0]=ftype->mv[LIST_0][jj][ii][0]; + ftype->mv[LIST_0][j][i][1]=ftype->mv[LIST_0][jj][ii][1]; + ftype->mv[LIST_1][j][i][0]=ftype->mv[LIST_1][jj][ii][0]; + ftype->mv[LIST_1][j][i][1]=ftype->mv[LIST_1][jj][ii][1]; - p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii]; - p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii]; - p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii]; - p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii]; + ftype->ref_idx[LIST_0][j][i]=ftype->ref_idx[LIST_0][jj][ii]; + ftype->ref_idx[LIST_1][j][i]=ftype->ref_idx[LIST_1][jj][ii]; + ftype->ref_pic_id[LIST_0][j][i] = ftype->ref_pic_id[LIST_0][jj][ii]; + ftype->ref_pic_id[LIST_1][j][i] = ftype->ref_pic_id[LIST_1][jj][ii]; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i]= + ftype->moving_block[j][i]= !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((ftype->ref_idx[LIST_0][j][i] == 0) + && (iabs(ftype->mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_0][j][i][1])>>1 == 0))) + || ((ftype->ref_idx[LIST_0][j][i] == -1) + && (ftype->ref_idx[LIST_1][j][i] == 0) + && (iabs(ftype->mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_1][j][i][1])>>1 == 0))); } } } } else { + ftype = &p->frame; for (j=0 ; j<fs->size_y/4 ; j++) { jj = RSD(j); @@ -4268,27 +4307,27 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) { ii = RSD(i); //! Use inference flag to remap mvs/references - p->mv[LIST_0][j][i][0]=fs->mv_JV[np][LIST_0][j][i][0]; - p->mv[LIST_0][j][i][1]=fs->mv_JV[np][LIST_0][j][i][1]; - p->mv[LIST_1][j][i][0]=fs->mv_JV[np][LIST_1][j][i][0]; - p->mv[LIST_1][j][i][1]=fs->mv_JV[np][LIST_1][j][i][1]; + ftype->mv[LIST_0][j][i][0]=fs->JVmotion[np].mv[LIST_0][j][i][0]; + ftype->mv[LIST_0][j][i][1]=fs->JVmotion[np].mv[LIST_0][j][i][1]; + ftype->mv[LIST_1][j][i][0]=fs->JVmotion[np].mv[LIST_1][j][i][0]; + ftype->mv[LIST_1][j][i][1]=fs->JVmotion[np].mv[LIST_1][j][i][1]; - p->ref_idx[LIST_0][j][i]=fs->ref_idx_JV[np][LIST_0][j][i]; - p->ref_idx[LIST_1][j][i]=fs->ref_idx_JV[np][LIST_1][j][i]; - p->ref_pic_id[LIST_0][j][i] = fs->ref_id_JV[np][LIST_0][j][i]; - p->ref_pic_id[LIST_1][j][i] = fs->ref_id_JV[np][LIST_1][j][i]; + ftype->ref_idx[LIST_0][j][i]=fs->JVmotion[np].ref_idx[LIST_0][j][i]; + ftype->ref_idx[LIST_1][j][i]=fs->JVmotion[np].ref_idx[LIST_1][j][i]; + ftype->ref_pic_id[LIST_0][j][i] = fs->JVmotion[np].ref_id[LIST_0][j][i]; + ftype->ref_pic_id[LIST_1][j][i] = fs->JVmotion[np].ref_id[LIST_1][j][i]; if (img->direct_spatial_mv_pred_flag == 1) { - p->moving_block[j][i]= + ftype->moving_block[j][i]= !((!p->is_long_term - && ((p->ref_idx[LIST_0][j][i] == 0) - && (iabs(p->mv[LIST_0][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_0][j][i][1])>>1 == 0))) - || ((p->ref_idx[LIST_0][j][i] == -1) - && (p->ref_idx[LIST_1][j][i] == 0) - && (iabs(p->mv[LIST_1][j][i][0])>>1 == 0) - && (iabs(p->mv[LIST_1][j][i][1])>>1 == 0))); + && ((ftype->ref_idx[LIST_0][j][i] == 0) + && (iabs(ftype->mv[LIST_0][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_0][j][i][1])>>1 == 0))) + || ((ftype->ref_idx[LIST_0][j][i] == -1) + && (ftype->ref_idx[LIST_1][j][i] == 0) + && (iabs(ftype->mv[LIST_1][j][i][0])>>1 == 0) + && (iabs(ftype->mv[LIST_1][j][i][1])>>1 == 0))); } } } @@ -4297,19 +4336,20 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) if (img->direct_spatial_mv_pred_flag ==0) { + ftype = &p->frame; for (j=0 ; j<fs->size_y/4 ; j++) { for (i=0 ; i<fs->size_x/4 ; i++) { - if ((!img->MbaffFrameFlag &&!img->structure && fs->field_frame[j][i]) || (img->MbaffFrameFlag && fs->field_frame[j][i])) + if ((!img->MbaffFrameFlag &&!img->structure && fs->motion.field_frame[j][i]) || (img->MbaffFrameFlag && fs->motion.field_frame[j][i])) { - p->mv[LIST_0][j][i][1] *= 2; - p->mv[LIST_1][j][i][1] *= 2; + ftype->mv[LIST_0][j][i][1] *= 2; + ftype->mv[LIST_1][j][i][1] *= 2; } - else if (img->structure && !fs->field_frame[j][i]) + else if (img->structure && !fs->motion.field_frame[j][i]) { - p->mv[LIST_0][j][i][1] /= 2; - p->mv[LIST_1][j][i][1] /= 2; + ftype->mv[LIST_0][j][i][1] /= 2; + ftype->mv[LIST_1][j][i][1] /= 2; } } @@ -4360,44 +4400,15 @@ void compute_colocated_JV(ColocatedParams* p, StorablePicture **listX[6]) */ void copy_storable_param_JV( int nplane, StorablePicture *d, StorablePicture *s ) { - int np, ny, nx; - // copy ref_idx - for( np=0; np<2; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - memcpy( d->ref_idx_JV[nplane][np][ny], s->ref_idx[np][ny], sizeof(byte)*(img->width/BLOCK_SIZE) ); - } - } + memcpy( d->JVmotion[nplane].ref_idx[0][0], s->motion.ref_idx[0][0], 2 * (img->height/BLOCK_SIZE) * (img->width/BLOCK_SIZE) * sizeof(byte) ); // copy ref_pic_id - for( np=0; np<6; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - memcpy( d->ref_pic_id_JV[nplane][np][ny], s->ref_pic_id[np][ny], sizeof(int64)*(img->width/BLOCK_SIZE) ); - } - } + memcpy( d->JVmotion[nplane].ref_pic_id[0][0], s->motion.ref_pic_id[0][0], 6 * (img->height/BLOCK_SIZE) * (img->width/BLOCK_SIZE) * sizeof(int64) ); - // copy ref_id - for( np=0; np<6; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - memcpy( d->ref_id_JV[nplane][np][ny], s->ref_id[np][ny], sizeof(int64)*(img->width/BLOCK_SIZE) ); - } - } + // copy motion.ref_id + memcpy( d->JVmotion[nplane].ref_id[0][0], s->motion.ref_id[0][0], 6 * (img->width/BLOCK_SIZE) * (img->height/BLOCK_SIZE) * sizeof(int64)); // copy mv - for( np=0; np<2; np++ ) - { - for( ny=0; ny<img->height/BLOCK_SIZE; ny++ ) - { - for( nx=0; nx<img->width/BLOCK_SIZE; nx++ ) - { - memcpy( d->mv_JV[nplane][np][ny][nx], s->mv[np][ny][nx], sizeof(short)*2 ); - } - } - } + memcpy( d->JVmotion[nplane].mv[0][0][0], s->motion.mv[0][0][0], 2 * img->height/BLOCK_SIZE * img->width/BLOCK_SIZE * sizeof(short)*2 ); } diff --git a/lencod/src/mc_prediction.c b/lencod/src/mc_prediction.c index 2aa6e42..7fac0c6 100644 --- a/lencod/src/mc_prediction.c +++ b/lencod/src/mc_prediction.c @@ -146,7 +146,8 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock int l0_mode, //!< list0 prediction mode (1-7, 0=DIRECT if l1_mode=0) int l1_mode, //!< list1 prediction mode (1-7, 0=DIRECT if l0_mode=0) short l0_ref_idx, //!< reference frame for list0 prediction (-1: Intra4x4 pred. with l0_mode) - short l1_ref_idx //!< reference frame for list1 prediction + short l1_ref_idx, //!< reference frame for list1 prediction + short bipred_me //!< use bi prediction mv (0=no bipred, 1 = use set 1, 2 = use set 2) ) { int i, j; @@ -160,13 +161,13 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock imgpel* l1pred = l1_pred; short****** mv_array = img->all_mv; short *curr_mv = NULL; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; int apply_weights = ( (active_pps->weighted_pred_flag && (img->type== P_SLICE || img->type == SP_SLICE)) || (active_pps->weighted_bipred_idc && (img->type== B_SLICE))); - if (currMB->bi_pred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && l0_mode==1 && l1_mode==1) - mv_array = currMB->bi_pred_me == 1? img->bipred_mv1 : img->bipred_mv2; + if (bipred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && is_bipred_enabled(l0_mode) && is_bipred_enabled(l1_mode)) + mv_array = img->bipred_mv[bipred_me - 1]; switch (p_dir) { @@ -199,7 +200,7 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock int weight_denom = luma_log_weight_denom + 1; for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( img->max_imgpel_value, + mb_pred[j][i] = iClip1( img->max_imgpel_value, ((wbp0 * *l0pred++ + wbp1 * *l1pred++ + wp_round) >> (weight_denom)) + offset); } else if (p_dir==0) @@ -208,7 +209,7 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock int offset = wp_offset[0][l0_ref_idx][0]; for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( img->max_imgpel_value, + mb_pred[j][i] = iClip1( img->max_imgpel_value, ((wp * *l0pred++ + wp_luma_round) >> luma_log_weight_denom) + offset); } else // (p_dir==1) @@ -217,7 +218,7 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock int offset = wp_offset[1][l1_ref_idx][0]; for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( img->max_imgpel_value, + mb_pred[j][i] = iClip1( img->max_imgpel_value, ((wp * *l1pred++ + wp_luma_round) >> luma_log_weight_denom) + offset ); } } @@ -227,13 +228,13 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock { for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; + mb_pred[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; } else if (p_dir==0) { for (j=block_y; j<block_y4; j++) { - memcpy(&(curr_mpr[j][block_x]), l0pred, block_size_x * sizeof(imgpel)); + memcpy(&(mb_pred[j][block_x]), l0pred, block_size_x * sizeof(imgpel)); l0pred += block_size_x; } } @@ -241,7 +242,7 @@ void LumaPrediction ( Macroblock* currMB,//!< Current Macroblock { for (j=block_y; j<block_y4; j++) { - memcpy(&(curr_mpr[j][block_x]), l1pred, block_size_x * sizeof(imgpel)); + memcpy(&(mb_pred[j][block_x]), l1pred, block_size_x * sizeof(imgpel)); l1pred += block_size_x; } } @@ -278,10 +279,10 @@ void LumaPredictionBi ( Macroblock* currMB, //!< Current Macroblock int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) || (active_pps->weighted_bipred_idc && (img->type == B_SLICE))); - short ******mv_array = list ? img->bipred_mv1 : img->bipred_mv2; + short ******mv_array = img->bipred_mv[list]; short *mv_arrayl0 = mv_array[LIST_0][l0_ref_idx][l0_mode][by][bx]; short *mv_arrayl1 = mv_array[LIST_1][l1_ref_idx][l1_mode][by][bx]; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; OneComponentLumaPrediction (l0_pred, pic_opix_x + mv_arrayl0[0], pic_opix_y + mv_arrayl0[1], block_size_x, block_size_y, listX[0+currMB->list_offset][l0_ref_idx]); OneComponentLumaPrediction (l1_pred, pic_opix_x + mv_arrayl1[0], pic_opix_y + mv_arrayl1[1], block_size_x, block_size_y, listX[1+currMB->list_offset][l1_ref_idx]); @@ -296,14 +297,14 @@ void LumaPredictionBi ( Macroblock* currMB, //!< Current Macroblock for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( img->max_imgpel_value, + mb_pred[j][i] = iClip1( img->max_imgpel_value, ((wbp0 * *l0pred++ + wbp1 * *l1pred++ + wp_round) >> weight_denom) + offset); } else { for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; + mb_pred[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; } } @@ -477,12 +478,12 @@ void IntraChromaPrediction4x4 (Macroblock* currMB, //! <-- Current Macroblock int block_y) //! <-- relative vertical block coordinate of 4x4 block { int j; - imgpel (*curr_mpr)[16] = img->mpr[ uv ]; + imgpel (*mb_pred)[16] = img->mb_pred[ uv ]; imgpel (*curr_mpr_16x16)[16] = img->mpr_16x16[uv][currMB->c_ipred_mode]; //===== prediction ===== for (j=block_y; j<block_y + BLOCK_SIZE; j++) - memcpy(&curr_mpr[j][block_x],&curr_mpr_16x16[j][block_x], BLOCK_SIZE * sizeof(imgpel)); + memcpy(&mb_pred[j][block_x],&curr_mpr_16x16[j][block_x], BLOCK_SIZE * sizeof(imgpel)); } /*! @@ -501,7 +502,9 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock int l0_mode, // <-- list0 prediction mode (1-7, 0=DIRECT if l1_mode=0) int l1_mode, // <-- list1 prediction mode (1-7, 0=DIRECT if l0_mode=0) short l0_ref_idx, // <-- reference frame for list0 prediction (if (<0) -> intra prediction) - short l1_ref_idx) // <-- reference frame for list1 prediction + short l1_ref_idx, // <-- reference frame for list1 prediction + short bipred_me // <-- use bi prediction mv (0=no bipred, 1 = use set 1, 2 = use set 2) + ) { int i, j; int block_x4 = block_x + block_size_x; @@ -515,13 +518,13 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock short****** mv_array = img->all_mv; int max_imgpel_value_uv = img->max_imgpel_value_comp[1]; int uv_comp = uv + 1; - imgpel (*curr_mpr)[16] = img->mpr[ uv_comp]; + imgpel (*mb_pred)[16] = img->mb_pred[ uv_comp]; int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) || (active_pps->weighted_bipred_idc && (img->type == B_SLICE))); - if (currMB->bi_pred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && l0_mode==1 && l1_mode==1) - mv_array = currMB->bi_pred_me == 1? img->bipred_mv1 : img->bipred_mv2; + if (bipred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && is_bipred_enabled(l0_mode) && is_bipred_enabled(l1_mode)) + mv_array = img->bipred_mv[bipred_me - 1]; //===== INTRA PREDICTION ===== if (p_dir==-1) @@ -560,7 +563,7 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( max_imgpel_value_uv, + mb_pred[j][i] = iClip1( max_imgpel_value_uv, ((wbp0 * *l0pred++ + wbp1 * *l1pred++ + wp_round) >> (weight_denom)) + (offset) ); } else if (p_dir==0) @@ -569,7 +572,7 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock int offset = wp_offset[0][l0_ref_idx][uv_comp]; for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( max_imgpel_value_uv, (( wp * *l0pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); + mb_pred[j][i] = iClip1( max_imgpel_value_uv, (( wp * *l0pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); } else // (p_dir==1) { @@ -578,7 +581,7 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( max_imgpel_value_uv, ((wp * *l1pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); + mb_pred[j][i] = iClip1( max_imgpel_value_uv, ((wp * *l1pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); } } else @@ -587,13 +590,13 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock { for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; + mb_pred[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; } else if (p_dir==0) { for (j=block_y; j<block_y4; j++) { - memcpy(&(curr_mpr[j][block_x]), l0pred, block_size_x * sizeof(imgpel)); + memcpy(&(mb_pred[j][block_x]), l0pred, block_size_x * sizeof(imgpel)); l0pred += block_size_x; } } @@ -601,7 +604,7 @@ void ChromaPrediction ( Macroblock* currMB, // <-- Current Macroblock { for (j=block_y; j<block_y4; j++) { - memcpy(&(curr_mpr[j][block_x]), l1pred, block_size_x * sizeof(imgpel)); + memcpy(&(mb_pred[j][block_x]), l1pred, block_size_x * sizeof(imgpel)); l1pred += block_size_x; } } @@ -624,7 +627,9 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock int l0_mode, // <-- list0 prediction mode (1-7, 0=DIRECT if l1_mode=0) int l1_mode, // <-- list1 prediction mode (1-7, 0=DIRECT if l0_mode=0) short l0_ref_idx, // <-- reference frame for list0 prediction (if (<0) -> intra prediction) - short l1_ref_idx) // <-- reference frame for list1 prediction + short l1_ref_idx, // <-- reference frame for list1 prediction + short bipred_me // <-- use bi prediction mv (0=no bipred, 1 = use set 1, 2 = use set 2) + ) { int i, j; int block_x4 = block_x + BLOCK_SIZE; @@ -634,14 +639,14 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock short****** mv_array = img->all_mv; int max_imgpel_value_uv = img->max_imgpel_value_comp[1]; int uv_comp = uv + 1; - imgpel (*curr_mpr)[16] = img->mpr[uv_comp]; + imgpel (*mb_pred)[16] = img->mb_pred[uv_comp]; int list_offset = currMB->list_offset; int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) || (active_pps->weighted_bipred_idc && (img->type == B_SLICE))); - if (currMB->bi_pred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && l0_mode==1 && l1_mode==1) - mv_array = currMB->bi_pred_me == 1? img->bipred_mv1 : img->bipred_mv2 ; + if (bipred_me && l0_ref_idx == 0 && l1_ref_idx == 0 && p_dir == 2 && is_bipred_enabled(l0_mode) && is_bipred_enabled(l1_mode) ) + mv_array = img->bipred_mv[bipred_me - 1]; //===== INTRA PREDICTION ===== if (p_dir==-1) { @@ -678,7 +683,7 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( max_imgpel_value_uv, + mb_pred[j][i] = iClip1( max_imgpel_value_uv, ((wbp0 * *l0pred++ + wbp1 * *l1pred++ + wp_round) >> (weight_denom)) + (offset) ); } else if (p_dir==0) @@ -687,7 +692,7 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock int offset = wp_offset[0][l0_ref_idx][uv_comp]; for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( max_imgpel_value_uv, (( wp * *l0pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); + mb_pred[j][i] = iClip1( max_imgpel_value_uv, (( wp * *l0pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); } else // (p_dir==1) { @@ -696,7 +701,7 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = iClip1( max_imgpel_value_uv, ((wp * *l1pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); + mb_pred[j][i] = iClip1( max_imgpel_value_uv, ((wp * *l1pred++ + wp_chroma_round) >> chroma_log_weight_denom) + offset); } } else @@ -705,13 +710,13 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock { for (j=block_y; j<block_y4; j++) for (i=block_x; i<block_x4; i++) - curr_mpr[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; + mb_pred[j][i] = (*l0pred++ + *l1pred++ + 1) >> 1; } else if (p_dir==0) { for (j=block_y; j<block_y4; j++) { - memcpy(&(curr_mpr[j][block_x]), l0pred, BLOCK_SIZE * sizeof(imgpel)); + memcpy(&(mb_pred[j][block_x]), l0pred, BLOCK_SIZE * sizeof(imgpel)); l0pred += BLOCK_SIZE; } } @@ -719,7 +724,7 @@ void ChromaPrediction4x4 ( Macroblock* currMB, // <-- Current Macroblock { for (j=block_y; j<block_y4; j++) { - memcpy(&(curr_mpr[j][block_x]), l1pred, BLOCK_SIZE * sizeof(imgpel)); + memcpy(&(mb_pred[j][block_x]), l1pred, BLOCK_SIZE * sizeof(imgpel)); l1pred += BLOCK_SIZE; } } @@ -940,6 +945,15 @@ void IntraChromaPrediction (Macroblock *currMB, int *mb_up, int *mb_left, int*mb { getNeighbour(currMB, 0 , i, img->mb_size[IS_CHROMA], &left[i]); } + + if ( img->MbaffFrameFlag && img->field_mode ) + { + for (i=0;i<cr_MB_y;i++) + { + left[i].pos_y = left[i].pos_y >> 1; + } + } + for (mode=DC_PRED_8; mode<=PLANE_8; mode++) { if ((img->type != I_SLICE || !params->IntraDisableInterOnly) && params->ChromaIntraDisable == 1 && mode!=DC_PRED_8) @@ -951,10 +965,10 @@ void IntraChromaPrediction (Macroblock *currMB, int *mb_up, int *mb_left, int*mb continue; cost = 0; - for (uv=0; uv<2; uv++) + for (uv = 1; uv < 3; uv++) { - image = imgUV_org[uv]; - curr_mpr_16x16 = img->mpr_16x16[uv + 1]; + image = pImgOrg[uv]; + curr_mpr_16x16 = img->mpr_16x16[uv]; for (block_y=0; block_y<cr_MB_y; block_y+=4) for (block_x = 0; block_x < cr_MB_x; block_x += 4) { diff --git a/lencod/src/md_high.c b/lencod/src/md_high.c index baea43a..deb8208 100644 --- a/lencod/src/md_high.c +++ b/lencod/src/md_high.c @@ -25,6 +25,7 @@ #include "me_umhexsmp.h" #include "macroblock.h" + /*! ************************************************************************************* * \brief @@ -48,6 +49,7 @@ void encode_one_macroblock_high (Macroblock *currMB) int mb_available_up; int mb_available_left; int mb_available_up_left; + int best8x8l0ref, best8x8l1ref; short islice = (short) (img->type==I_SLICE); short bslice = (short) (img->type==B_SLICE); @@ -57,11 +59,13 @@ void encode_one_macroblock_high (Macroblock *currMB) int prev_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr); Macroblock* prevMB = (prev_mb_nr >= 0) ? &img->mb_data[prev_mb_nr]:NULL ; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; + Block8x8Info *b8x8info = img->b8x8info; short min_chroma_pred_mode, max_chroma_pred_mode; - short inter_skip = 0; + short inter_skip = 0; + short bipred_me = 0; double min_rate = 0; if(params->SearchMode == UM_HEX) @@ -85,7 +89,6 @@ void encode_one_macroblock_high (Macroblock *currMB) //--------------------------------------------------- store_coding_state (currMB, cs_cm); - if (!intra) { //===== set direct motion vectors ===== @@ -103,8 +106,8 @@ void encode_one_macroblock_high (Macroblock *currMB) //===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS ===== for (min_cost=INT_MAX, mode=1; mode<4; mode++) { - bi_pred_me = 0; - img->bi_pred_me[mode]=0; + bipred_me = 0; + b8x8info->bipred8x8me[mode][0] = 0; if (enc_mb.valid[mode]) { for (cost=0, block=0; block<(mode==1?1:2); block++) @@ -118,22 +121,22 @@ void encode_one_macroblock_high (Macroblock *currMB) //--- get cost and reference frame for List 0 prediction --- bmcost[LIST_0] = INT_MAX; - list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best_ref); if (bslice) { //--- get cost and reference frame for List 1 prediction --- bmcost[LIST_1] = INT_MAX; - list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best_ref); // Compute bipredictive cost between best list 0 and best list 1 references - list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best_ref); - // Finally, if mode 16x16, compute cost for bipredictive ME vectore - if (params->BiPredMotionEstimation && mode == 1) + // currently Bi prediction ME is only supported for modes 1, 2, 3 and ref 0 + if (is_bipred_enabled(mode)) { - list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0); - list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L0, block, mode, &enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L1, block, mode, &enc_mb, bmcost, 0); } else { @@ -142,7 +145,7 @@ void encode_one_macroblock_high (Macroblock *currMB) } // Determine prediction list based on mode cost - determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bi_pred_me); + determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bipred_me); } else // if (bslice) { @@ -150,31 +153,14 @@ void encode_one_macroblock_high (Macroblock *currMB) cost += bmcost[LIST_0]; } - assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice); + assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice, bipred_me); //----- set reference frame and direction parameters ----- - if (mode==3) - { - best8x8l0ref [3][block ] = best8x8l0ref [3][ block+2] = best_ref[LIST_0]; - best8x8pdir [3][block ] = best8x8pdir [3][ block+2] = best_pdir; - best8x8l1ref [3][block ] = best8x8l1ref [3][ block+2] = best_ref[LIST_1]; - } - else if (mode==2) - { - best8x8l0ref [2][2*block] = best8x8l0ref [2][2*block+1] = best_ref[LIST_0]; - best8x8pdir [2][2*block] = best8x8pdir [2][2*block+1] = best_pdir; - best8x8l1ref [2][2*block] = best8x8l1ref [2][2*block+1] = best_ref[LIST_1]; - } - else - { - memset(&best8x8l0ref [1][0], best_ref[LIST_0], 4 * sizeof(char)); - memset(&best8x8l1ref [1][0], best_ref[LIST_1], 4 * sizeof(char)); - best8x8pdir [1][0] = best8x8pdir [1][1] = best8x8pdir [1][2] = best8x8pdir [1][3] = best_pdir; - } + set_block8x8_info(b8x8info, mode, block, best_ref, best_pdir, bipred_me); //--- set reference frames and motion vectors --- - if (mode>1 && block==0) - SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]); + if (mode>1 && block == 0) + SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1], bipred_me); } // for (block=0; block<(mode==1?1:2); block++) if (cost < min_cost) @@ -193,8 +179,8 @@ void encode_one_macroblock_high (Macroblock *currMB) { giRDOpt_B8OnlyFlag = 1; - tr8x8.cost8x8 = INT_MAX; - tr4x4.cost8x8 = INT_MAX; + tr8x8.mb_p8x8_cost = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; //===== store coding state of macroblock ===== store_coding_state (currMB, cs_mb); @@ -202,19 +188,16 @@ void encode_one_macroblock_high (Macroblock *currMB) if (params->Transform8x8Mode) { - tr8x8.cost8x8 = 0; + tr8x8.mb_p8x8_cost = 0; //=========================================================== // Check 8x8 partition with transform size 8x8 //=========================================================== //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block = 0; block < 4; block++) { - submacroblock_mode_decision(enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], + submacroblock_mode_decision(&enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 1); - best8x8mode [block] = tr8x8.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr8x8.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr8x8.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr8x8.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr8x8); } // following params could be added in RD_8x8DATA structure @@ -230,20 +213,16 @@ void encode_one_macroblock_high (Macroblock *currMB) if (params->Transform8x8Mode != 2) { - tr4x4.cost8x8 = 0; + tr4x4.mb_p8x8_cost = 0; //================================================================= // Check 8x8, 8x4, 4x8 and 4x4 partitions with transform size 4x4 //================================================================= //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++) { - submacroblock_mode_decision(enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], + submacroblock_mode_decision(&enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 0); - - best8x8mode [block] = tr4x4.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr4x4.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr4x4.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr4x4.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr4x4); } //--- re-set coding state (as it was before 8x8 block coding) --- // reset_coding_state (currMB, cs_mb); @@ -254,14 +233,14 @@ void encode_one_macroblock_high (Macroblock *currMB) // This is not enabled yet since mpr has reverse order. if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); //check cost for P8x8 for non-rdopt mode giRDOpt_B8OnlyFlag = 0; } else // if (enc_mb.valid[P8x8]) { - tr4x4.cost8x8 = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; } // Find a motion vector for the Skip mode @@ -275,9 +254,6 @@ void encode_one_macroblock_high (Macroblock *currMB) //========= C H O O S E B E S T M A C R O B L O C K M O D E ========= //------------------------------------------------------------------------- - if (params->BiPredMotionEstimation) - img->bi_pred_me[1] =0; - if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params)) { // precompute all new chroma intra prediction modes @@ -323,15 +299,9 @@ void encode_one_macroblock_high (Macroblock *currMB) i16mode = 0; } //--- for INTER16x16 check all prediction directions --- - if (mode==1 && bslice) + if (mode == 1 && bslice) { - best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = (char) ctr16x16; - - if ( (bslice) && (params->BiPredMotionEstimation) - && (ctr16x16 == 2 && img->bi_pred_me[mode] < 2 && mode == 1)) - ctr16x16--; - if (ctr16x16 < 2) - index--; + update_prediction_for_mode16x16(b8x8info, ctr16x16, &index); ctr16x16++; } @@ -344,10 +314,10 @@ void encode_one_macroblock_high (Macroblock *currMB) } else { - - if (params->SkipIntraInInterSlices && !intra && mode >= I4MB && best_mode <=3 && currMB->cbp == 0) - continue; - } + + if (params->SkipIntraInInterSlices && !intra && mode >= I4MB && best_mode <=3 && currMB->cbp == 0) + continue; + } // check if weights are in valid range for biprediction. if (bslice && active_pps->weighted_bipred_idc == 1 && mode < P8x8) @@ -357,13 +327,13 @@ void encode_one_macroblock_high (Macroblock *currMB) Boolean invalid_mode = FALSE; for (cur_blk = 0; cur_blk < 4; cur_blk ++) { - if (best8x8pdir[mode][cur_blk] == 2) + if (b8x8info->best8x8pdir[mode][cur_blk] == 2) { for (cur_comp = 0; cur_comp < (active_sps->chroma_format_idc == YUV400 ? 1 : 3) ; cur_comp ++) { - weight_sum = - wbp_weight[0][(int) best8x8l0ref[mode][cur_blk]][(int) best8x8l1ref[mode][cur_blk]][cur_comp] + - wbp_weight[1][(int) best8x8l0ref[mode][cur_blk]][(int) best8x8l1ref[mode][cur_blk]][cur_comp]; + best8x8l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk]; + best8x8l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk]; + weight_sum = wbp_weight[0][best8x8l0ref][best8x8l1ref][cur_comp] + wbp_weight[1][best8x8l0ref][best8x8l1ref][cur_comp]; if (weight_sum < -128 || weight_sum > 127) { @@ -376,19 +346,11 @@ void encode_one_macroblock_high (Macroblock *currMB) } } if (invalid_mode == TRUE) - { - if ((params->BiPredMotionEstimation) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1) - img->bi_pred_me[mode] = (short) (img->bi_pred_me[mode] + 1); continue; - } } if (enc_mb.valid[mode]) - compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); + compute_mode_RD_cost(mode, currMB, &enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); - if ((params->BiPredMotionEstimation) && (bslice) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1 && best8x8pdir[1][0] == 2) - img->bi_pred_me[mode] = (short) (img->bi_pred_me[mode] + 1); }// for (ctr16x16=0, index=0; index<max_index; index++) }// for (currMB->c_ipred_mode=DC_PRED_8; currMB->c_ipred_mode<=max_chroma_pred_mode; currMB->c_ipred_mode++) diff --git a/lencod/src/md_highfast.c b/lencod/src/md_highfast.c index c02f314..7bcfe72 100644 --- a/lencod/src/md_highfast.c +++ b/lencod/src/md_highfast.c @@ -54,17 +54,19 @@ void encode_one_macroblock_highfast (Macroblock *currMB) short bslice = (img->type==B_SLICE); short pslice = (img->type==P_SLICE) || (img->type==SP_SLICE); short intra = (islice || (pslice && img->mb_y==img->mb_y_upd && img->mb_y_upd!=img->mb_y_intra)); - + int best8x8l0ref, best8x8l1ref; int prev_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr); Macroblock* prevMB = (prev_mb_nr >= 0) ? &img->mb_data[prev_mb_nr]:NULL ; + Block8x8Info *b8x8info = img->b8x8info; short *allmvs = img->all_mv[0][0][0][0][0]; short min_chroma_pred_mode, max_chroma_pred_mode; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; // Fast Mode Decision short inter_skip = 0, intra_skip = 0; + short bipred_me; int cost16 = 0, mode16 = 0; double min_rate = 0, RDCost16 = DBL_MAX; @@ -102,7 +104,7 @@ void encode_one_macroblock_highfast (Macroblock *currMB) best_mode = 0; currMB->c_ipred_mode=DC_PRED_8; min_rdcost = max_rdcost; - compute_mode_RD_cost(0, currMB, enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); + compute_mode_RD_cost(0, currMB, &enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); } } @@ -114,8 +116,8 @@ void encode_one_macroblock_highfast (Macroblock *currMB) //===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS ===== for (min_cost=INT_MAX, mode=1; mode<4; mode++) { - bi_pred_me = 0; - img->bi_pred_me[mode]=0; + bipred_me = 0; + b8x8info->bipred8x8me[mode][0] = 0; if (enc_mb.valid[mode] && !inter_skip) { for (cost=0, block=0; block<(mode==1?1:2); block++) @@ -129,22 +131,22 @@ void encode_one_macroblock_highfast (Macroblock *currMB) //--- get cost and reference frame for List 0 prediction --- bmcost[LIST_0] = INT_MAX; - list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best_ref); if (bslice) { //--- get cost and reference frame for List 1 prediction --- bmcost[LIST_1] = INT_MAX; - list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best_ref); // Compute bipredictive cost between best list 0 and best list 1 references - list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best_ref); - // Finally, if mode 16x16, compute cost for bipredictive ME vectore - if (params->BiPredMotionEstimation && mode == 1) + // currently Bi prediction ME is only supported for modes 1, 2, 3 and ref 0 + if (is_bipred_enabled(mode)) { - list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0); - list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L0, block, mode, &enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L1, block, mode, &enc_mb, bmcost, 0); } else { @@ -153,7 +155,7 @@ void encode_one_macroblock_highfast (Macroblock *currMB) } // Determine prediction list based on mode cost - determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bi_pred_me); + determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bipred_me); } else // if (bslice) { @@ -161,31 +163,13 @@ void encode_one_macroblock_highfast (Macroblock *currMB) cost += bmcost[LIST_0]; } - assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice); - + assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice, bipred_me); //----- set reference frame and direction parameters ----- - if (mode==3) - { - best8x8l0ref [3][block ] = best8x8l0ref [3][ block+2] = best_ref[LIST_0]; - best8x8pdir [3][block ] = best8x8pdir [3][ block+2] = best_pdir; - best8x8l1ref [3][block ] = best8x8l1ref [3][ block+2] = best_ref[LIST_1]; - } - else if (mode==2) - { - best8x8l0ref [2][2*block] = best8x8l0ref [2][2*block+1] = best_ref[LIST_0]; - best8x8pdir [2][2*block] = best8x8pdir [2][2*block+1] = best_pdir; - best8x8l1ref [2][2*block] = best8x8l1ref [2][2*block+1] = best_ref[LIST_1]; - } - else - { - memset(&best8x8l0ref [1][0], best_ref[LIST_0], 4 * sizeof(char)); - memset(&best8x8l1ref [1][0], best_ref[LIST_1], 4 * sizeof(char)); - best8x8pdir [1][0] = best8x8pdir [1][1] = best8x8pdir [1][2] = best8x8pdir [1][3] = best_pdir; - } - + set_block8x8_info(b8x8info, mode, block, best_ref, best_pdir, bipred_me); + //--- set reference frames and motion vectors --- if (mode>1 && block==0) - SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]); + SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1], bipred_me); } // for (block=0; block<(mode==1?1:2); block++) @@ -205,20 +189,12 @@ void encode_one_macroblock_highfast (Macroblock *currMB) //--- for INTER16x16 check all prediction directions --- if (bslice) { - best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = ctr16x16; - - if ( (bslice) && (params->BiPredMotionEstimation) - && (ctr16x16 == 2 && img->bi_pred_me[mode] < 2 && mode == 1)) - ctr16x16--; + update_prediction_for_mode16x16(b8x8info, ctr16x16, &index); ctr16x16++; } - + currMB->c_ipred_mode=DC_PRED_8; - compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); - - if ((params->BiPredMotionEstimation) && (bslice) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1 && best8x8pdir[1][0] == 2) - img->bi_pred_me[mode] = img->bi_pred_me[mode] + 1; + compute_mode_RD_cost(mode, currMB, &enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); } // for (ctr16x16=0, k=0; k<1; k++) if(pslice) @@ -228,9 +204,9 @@ void encode_one_macroblock_highfast (Macroblock *currMB) if(params->EarlySkipEnable) { //===== check for SKIP mode ===== - if ( currMB->cbp==0 && enc_picture->ref_idx[LIST_0][img->block_y][img->block_x]==0 && - enc_picture->mv[LIST_0][img->block_y][img->block_x][0]==allmvs[0] && - enc_picture->mv[LIST_0][img->block_y][img->block_x][1]==allmvs[1] ) + if ( currMB->cbp==0 && enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x]==0 && + enc_picture->motion.mv[LIST_0][img->block_y][img->block_x][0]==allmvs[0] && + enc_picture->motion.mv[LIST_0][img->block_y][img->block_x][1]==allmvs[1] ) { inter_skip = 1; best_mode = 0; @@ -261,8 +237,8 @@ void encode_one_macroblock_highfast (Macroblock *currMB) { giRDOpt_B8OnlyFlag = 1; - tr8x8.cost8x8 = INT_MAX; - tr4x4.cost8x8 = INT_MAX; + tr8x8.mb_p8x8_cost = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; //===== store coding state of macroblock ===== store_coding_state (currMB, cs_mb); @@ -270,19 +246,16 @@ void encode_one_macroblock_highfast (Macroblock *currMB) if (params->Transform8x8Mode) { - tr8x8.cost8x8 = 0; + tr8x8.mb_p8x8_cost = 0; //=========================================================== // Check 8x8 partition with transform size 8x8 //=========================================================== //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++) { - submacroblock_mode_decision(enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], + submacroblock_mode_decision(&enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 1); - best8x8mode [block] = tr8x8.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr8x8.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr8x8.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr8x8.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr8x8); } // following params could be added in RD_8x8DATA structure @@ -298,20 +271,16 @@ void encode_one_macroblock_highfast (Macroblock *currMB) if (params->Transform8x8Mode != 2) { - tr4x4.cost8x8 = 0; + tr4x4.mb_p8x8_cost = 0; //================================================================= // Check 8x8, 8x4, 4x8 and 4x4 partitions with transform size 4x4 //================================================================= //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++) { - submacroblock_mode_decision(enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], + submacroblock_mode_decision(&enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 0); - - best8x8mode [block] = tr4x4.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr4x4.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr4x4.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr4x4.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr4x4); } //--- re-set coding state (as it was before 8x8 block coding) --- // reset_coding_state (currMB, cs_mb); @@ -322,14 +291,14 @@ void encode_one_macroblock_highfast (Macroblock *currMB) // This is not enabled yet since mpr has reverse order. if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); //check cost for P8x8 for non-rdopt mode giRDOpt_B8OnlyFlag = 0; } else // if (enc_mb.valid[P8x8]) { - tr4x4.cost8x8 = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; } } @@ -359,9 +328,6 @@ void encode_one_macroblock_highfast (Macroblock *currMB) // if Fast High mode, compute inter modes separate process for inter/intra max_index = ((!intra && params->SelectiveIntraEnable ) ? 5 : 9); - if (params->BiPredMotionEstimation) - img->bi_pred_me[1] =0; - if (((img->yuv_format != YUV400) && !IS_INDEPENDENT(params)) && max_index != 5) { // precompute all new chroma intra prediction modes @@ -410,13 +376,7 @@ void encode_one_macroblock_highfast (Macroblock *currMB) //--- for INTER16x16 check all prediction directions --- if (mode==1 && bslice) { - best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = (char) ctr16x16; - - if ( (bslice) && (params->BiPredMotionEstimation) - && (ctr16x16 == 2 && img->bi_pred_me[mode] < 2 && mode == 1)) - ctr16x16--; - if (ctr16x16 < 2) - index--; + update_prediction_for_mode16x16(b8x8info, ctr16x16, &index); ctr16x16++; } @@ -432,14 +392,13 @@ void encode_one_macroblock_highfast (Macroblock *currMB) Boolean invalid_mode = FALSE; for (cur_blk = 0; cur_blk < 4; cur_blk ++) { - if (best8x8pdir[mode][cur_blk] == 2) + if (b8x8info->best8x8pdir[mode][cur_blk] == 2) { for (cur_comp = 0; cur_comp < (active_sps->chroma_format_idc == YUV400 ? 1 : 3) ; cur_comp ++) { - weight_sum = - wbp_weight[0][(int) best8x8l0ref[mode][cur_blk]][(int) best8x8l1ref[mode][cur_blk]][cur_comp] + - wbp_weight[1][(int) best8x8l0ref[mode][cur_blk]][(int) best8x8l1ref[mode][cur_blk]][cur_comp]; - + best8x8l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk]; + best8x8l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk]; + weight_sum = wbp_weight[0][best8x8l0ref][best8x8l1ref][cur_comp] + wbp_weight[1][best8x8l0ref][best8x8l1ref][cur_comp]; if (weight_sum < -128 || weight_sum > 127) { invalid_mode = TRUE; @@ -451,20 +410,11 @@ void encode_one_macroblock_highfast (Macroblock *currMB) } } if (invalid_mode == TRUE) - { - if ((params->BiPredMotionEstimation) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1) - img->bi_pred_me[mode] = (short) (img->bi_pred_me[mode] + 1); - continue; - } + continue; } if (enc_mb.valid[mode]) - compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); - - if ((params->BiPredMotionEstimation) && (bslice) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1 && best8x8pdir[1][0] == 2) - img->bi_pred_me[mode] = (short) (img->bi_pred_me[mode] + 1); + compute_mode_RD_cost(mode, currMB, &enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); }// for (ctr16x16=0, index=0; index<max_index; index++) }// for (currMB->c_ipred_mode=DC_PRED_8; currMB->c_ipred_mode<=max_chroma_pred_mode; currMB->c_ipred_mode++) @@ -531,7 +481,7 @@ void encode_one_macroblock_highfast (Macroblock *currMB) } if (enc_mb.valid[mode]) - compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); + compute_mode_RD_cost(mode, currMB, &enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); } // for (index = 5; index < max_index; index++) } } @@ -626,10 +576,10 @@ static void fast_mode_intra_decision(Macroblock *currMB, short *intra_skip, doub for(i = 0; i < 8; i++) { - SBE += iabs(imgUV_org[0][img->opix_c_y][img->opix_c_x+i] - enc_picture->imgUV[0][img->pix_c_y-1][img->pix_c_x+i]); - SBE += iabs(imgUV_org[0][img->opix_c_y+i][img->opix_c_x] - enc_picture->imgUV[0][img->pix_c_y+i][img->pix_c_x-1]); - SBE += iabs(imgUV_org[1][img->opix_c_y][img->opix_c_x+i] - enc_picture->imgUV[1][img->pix_c_y-1][img->pix_c_x+i]); - SBE += iabs(imgUV_org[1][img->opix_c_y+i][img->opix_c_x] - enc_picture->imgUV[1][img->pix_c_y+i][img->pix_c_x-1]); + SBE += iabs(pImgOrg[1][img->opix_c_y][img->opix_c_x+i] - enc_picture->imgUV[0][img->pix_c_y-1][img->pix_c_x+i]); + SBE += iabs(pImgOrg[1][img->opix_c_y+i][img->opix_c_x] - enc_picture->imgUV[0][img->pix_c_y+i][img->pix_c_x-1]); + SBE += iabs(pImgOrg[2][img->opix_c_y][img->opix_c_x+i] - enc_picture->imgUV[1][img->pix_c_y-1][img->pix_c_x+i]); + SBE += iabs(pImgOrg[2][img->opix_c_y+i][img->opix_c_x] - enc_picture->imgUV[1][img->pix_c_y+i][img->pix_c_x-1]); } ABE = 1.0/64 * SBE; } diff --git a/lencod/src/md_highloss.c b/lencod/src/md_highloss.c index 2eb09c7..9c00bf8 100644 --- a/lencod/src/md_highloss.c +++ b/lencod/src/md_highloss.c @@ -49,6 +49,7 @@ void encode_one_macroblock_highloss (Macroblock *currMB) int mb_available_up; int mb_available_left; int mb_available_up_left; + int best8x8l0ref, best8x8l1ref; short islice = (short) (img->type==I_SLICE); short bslice = (short) (img->type==B_SLICE); @@ -59,12 +60,14 @@ void encode_one_macroblock_highloss (Macroblock *currMB) int prev_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr); Macroblock* prevMB = (prev_mb_nr >= 0) ? &img->mb_data[prev_mb_nr]:NULL ; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; + Block8x8Info *b8x8info = img->b8x8info; short min_chroma_pred_mode, max_chroma_pred_mode; - short inter_skip = 0; - double min_rate = 0; + short inter_skip = 0; + short bipred_me = 0; + double min_rate = 0; if(params->SearchMode == UM_HEX) { @@ -110,8 +113,8 @@ void encode_one_macroblock_highloss (Macroblock *currMB) //===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS ===== for (min_cost=INT_MAX, mode=1; mode<4; mode++) { - bi_pred_me = 0; - img->bi_pred_me[mode]=0; + bipred_me = 0; + b8x8info->bipred8x8me[mode][0] = 0; if (enc_mb.valid[mode]) { for (cost=0, block=0; block<(mode==1?1:2); block++) @@ -125,22 +128,22 @@ void encode_one_macroblock_highloss (Macroblock *currMB) //--- get cost and reference frame for List 0 prediction --- bmcost[LIST_0] = INT_MAX; - list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best_ref); if (bslice) { //--- get cost and reference frame for List 1 prediction --- bmcost[LIST_1] = INT_MAX; - list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best_ref); // Compute bipredictive cost between best list 0 and best list 1 references - list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best_ref); - // Finally, if mode 16x16, compute cost for bipredictive ME vectore - if (params->BiPredMotionEstimation && mode == 1) + // currently Bi prediction ME is only supported for modes 1, 2, 3 + if (is_bipred_enabled(mode)) { - list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0); - list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L0, block, mode, &enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L1, block, mode, &enc_mb, bmcost, 0); } else { @@ -149,7 +152,7 @@ void encode_one_macroblock_highloss (Macroblock *currMB) } // Determine prediction list based on mode cost - determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bi_pred_me); + determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bipred_me); } else // if (bslice) { @@ -157,31 +160,14 @@ void encode_one_macroblock_highloss (Macroblock *currMB) cost += bmcost[LIST_0]; } - assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice); - + assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice, bipred_me); //----- set reference frame and direction parameters ----- - if (mode==3) - { - best8x8l0ref [3][block ] = best8x8l0ref [3][ block+2] = best_ref[LIST_0]; - best8x8pdir [3][block ] = best8x8pdir [3][ block+2] = best_pdir; - best8x8l1ref [3][block ] = best8x8l1ref [3][ block+2] = best_ref[LIST_1]; - } - else if (mode==2) - { - best8x8l0ref [2][2*block] = best8x8l0ref [2][2*block+1] = best_ref[LIST_0]; - best8x8pdir [2][2*block] = best8x8pdir [2][2*block+1] = best_pdir; - best8x8l1ref [2][2*block] = best8x8l1ref [2][2*block+1] = best_ref[LIST_1]; - } - else - { - memset(&best8x8l0ref [1][0], best_ref[LIST_0], 4 * sizeof(char)); - memset(&best8x8l1ref [1][0], best_ref[LIST_1], 4 * sizeof(char)); - best8x8pdir [1][0] = best8x8pdir [1][1] = best8x8pdir [1][2] = best8x8pdir [1][3] = best_pdir; - } - + set_block8x8_info(b8x8info, mode, block, best_ref, best_pdir, bipred_me); + + //--- set reference frames and motion vectors --- if (mode>1 && block==0) - SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]); + SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1], bipred_me); } // for (block=0; block<(mode==1?1:2); block++) if (cost < min_cost) @@ -200,8 +186,8 @@ void encode_one_macroblock_highloss (Macroblock *currMB) { giRDOpt_B8OnlyFlag = 1; - tr8x8.cost8x8 = INT_MAX; - tr4x4.cost8x8 = INT_MAX; + tr8x8.mb_p8x8_cost = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; //===== store coding state of macroblock ===== store_coding_state (currMB, cs_mb); @@ -209,19 +195,16 @@ void encode_one_macroblock_highloss (Macroblock *currMB) if (params->Transform8x8Mode) { - tr8x8.cost8x8 = 0; + tr8x8.mb_p8x8_cost = 0; //=========================================================== // Check 8x8 partition with transform size 8x8 //=========================================================== //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++) { - submacroblock_mode_decision(enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], + submacroblock_mode_decision(&enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 1); - best8x8mode [block] = tr8x8.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr8x8.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr8x8.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr8x8.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr8x8); } // following params could be added in RD_8x8DATA structure @@ -237,20 +220,16 @@ void encode_one_macroblock_highloss (Macroblock *currMB) if (params->Transform8x8Mode != 2) { - tr4x4.cost8x8 = 0; + tr4x4.mb_p8x8_cost = 0; //================================================================= // Check 8x8, 8x4, 4x8 and 4x4 partitions with transform size 4x4 //================================================================= //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++) { - submacroblock_mode_decision(enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], + submacroblock_mode_decision(&enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 0); - - best8x8mode [block] = tr4x4.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr4x4.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr4x4.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr4x4.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr4x4); } //--- re-set coding state (as it was before 8x8 block coding) --- // reset_coding_state (currMB, cs_mb); @@ -261,14 +240,14 @@ void encode_one_macroblock_highloss (Macroblock *currMB) // This is not enabled yet since mpr has reverse order. if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); //check cost for P8x8 for non-rdopt mode giRDOpt_B8OnlyFlag = 0; } else // if (enc_mb.valid[P8x8]) { - tr4x4.cost8x8 = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; } // Find a motion vector for the Skip mode @@ -284,9 +263,6 @@ void encode_one_macroblock_highloss (Macroblock *currMB) //------------------------------------------------------------------------- { - if (params->BiPredMotionEstimation) - img->bi_pred_me[1] =0; - if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params)) { // precompute all new chroma intra prediction modes @@ -295,8 +271,8 @@ void encode_one_macroblock_highloss (Macroblock *currMB) if (params->FastCrIntraDecision ) { IntraChromaRDDecision(currMB, enc_mb); - min_chroma_pred_mode = (short) currMB->c_ipred_mode; - max_chroma_pred_mode = (short) currMB->c_ipred_mode; + min_chroma_pred_mode = (short) currMB->c_ipred_mode; + max_chroma_pred_mode = (short) currMB->c_ipred_mode; } else { @@ -332,13 +308,7 @@ void encode_one_macroblock_highloss (Macroblock *currMB) //--- for INTER16x16 check all prediction directions --- if (mode==1 && bslice) { - best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = (char) ctr16x16; - - if ( (bslice) && (params->BiPredMotionEstimation) - && (ctr16x16 == 2 && img->bi_pred_me[mode] < 2 && mode == 1)) - ctr16x16--; - if (ctr16x16 < 2) - index--; + update_prediction_for_mode16x16(b8x8info, ctr16x16, &index); ctr16x16++; } @@ -354,13 +324,13 @@ void encode_one_macroblock_highloss (Macroblock *currMB) Boolean invalid_mode = FALSE; for (cur_blk = 0; cur_blk < 4; cur_blk ++) { - if (best8x8pdir[mode][cur_blk] == 2) + if (b8x8info->best8x8pdir[mode][cur_blk] == 2) { for (cur_comp = 0; cur_comp < (active_sps->chroma_format_idc == YUV400 ? 1 : 3) ; cur_comp ++) { - weight_sum = - wbp_weight[0][(int) best8x8l0ref[mode][cur_blk]][(int) best8x8l1ref[mode][cur_blk]][cur_comp] + - wbp_weight[1][(int) best8x8l0ref[mode][cur_blk]][(int) best8x8l1ref[mode][cur_blk]][cur_comp]; + best8x8l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk]; + best8x8l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk]; + weight_sum = wbp_weight[0][best8x8l0ref][best8x8l1ref][cur_comp] + wbp_weight[1][best8x8l0ref][best8x8l1ref][cur_comp]; if (weight_sum < -128 || weight_sum > 127) { @@ -373,20 +343,12 @@ void encode_one_macroblock_highloss (Macroblock *currMB) } } if (invalid_mode == TRUE) - { - if ((params->BiPredMotionEstimation) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1) - img->bi_pred_me[mode] = (short) (img->bi_pred_me[mode] + 1); continue; - } } if (enc_mb.valid[mode]) - compute_mode_RD_cost(mode, currMB, enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); + compute_mode_RD_cost(mode, currMB, &enc_mb, &min_rdcost, &min_dcost, &min_rate, i16mode, bslice, &inter_skip); - if ((params->BiPredMotionEstimation) && (bslice) && ctr16x16 == 2 - && img->bi_pred_me[mode] < 2 && mode == 1 && best8x8pdir[1][0] == 2) - img->bi_pred_me[mode] = (short) (img->bi_pred_me[mode] + 1); }// for (ctr16x16=0, index=0; index<max_index; index++) }// for (currMB->c_ipred_mode=DC_PRED_8; currMB->c_ipred_mode<=max_chroma_pred_mode; currMB->c_ipred_mode++) diff --git a/lencod/src/md_low.c b/lencod/src/md_low.c index 60944d9..63fda5c 100644 --- a/lencod/src/md_low.c +++ b/lencod/src/md_low.c @@ -25,6 +25,7 @@ #include "me_umhex.h" #include "me_umhexsmp.h" #include "macroblock.h" +#include "q_around.h" //==== MODULE PARAMETERS ==== @@ -33,7 +34,6 @@ static imgpel temp_imgU[16][16]; static imgpel temp_imgV[16][16]; - /*! ************************************************************************************* * \brief @@ -43,7 +43,7 @@ static imgpel temp_imgV[16][16]; void encode_one_macroblock_low (Macroblock *currMB) { - int block, mode, i, j, k, dummy; + int block, mode, i=0, j, k, dummy; char best_pdir; RD_PARAMS enc_mb; char best_ref[2] = {0, -1}; @@ -60,18 +60,18 @@ void encode_one_macroblock_low (Macroblock *currMB) short pslice = (short) ((img->type==P_SLICE) || (img->type==SP_SLICE)); short intra = (short) (islice || (pslice && img->mb_y==img->mb_y_upd && img->mb_y_upd!=img->mb_y_intra)); int lambda_mf[3]; - int pix_x, pix_y; int prev_mb_nr = FmoGetPreviousMBNr(img->current_mb_nr); Macroblock* prevMB = (prev_mb_nr >= 0) ? &img->mb_data[prev_mb_nr]:NULL ; + Block8x8Info *b8x8info = img->b8x8info; char **ipredmodes = img->ipredmode; short *allmvs = params->IntraProfile ? NULL: img->all_mv[0][0][0][0][0]; int ****i4p; //for non-RD-opt. mode - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; int tmp_8x8_flag, tmp_no_mbpart; // Fast Mode Decision - short inter_skip = 0; + short bipred_me, inter_skip = 0; if(params->SearchMode == UM_HEX) @@ -88,7 +88,6 @@ void encode_one_macroblock_low (Macroblock *currMB) //===== Setup Macroblock encoding parameters ===== init_enc_mb_params(currMB, &enc_mb, intra, bslice); - // reset chroma intra predictor to default currMB->c_ipred_mode = DC_PRED_8; @@ -113,8 +112,8 @@ void encode_one_macroblock_low (Macroblock *currMB) //===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS ===== for (min_cost=INT_MAX, mode=1; mode<4; mode++) { - bi_pred_me = 0; - img->bi_pred_me[mode]=0; + bipred_me = 0; + b8x8info->bipred8x8me[mode][0] = 0; if (enc_mb.valid[mode] && !inter_skip) { for (cost=0, block=0; block<(mode==1?1:2); block++) @@ -128,22 +127,22 @@ void encode_one_macroblock_low (Macroblock *currMB) //--- get cost and reference frame for List 0 prediction --- bmcost[LIST_0] = INT_MAX; - list_prediction_cost(currMB, LIST_0, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_0, block, mode, &enc_mb, bmcost, best_ref); if (bslice) { //--- get cost and reference frame for List 1 prediction --- bmcost[LIST_1] = INT_MAX; - list_prediction_cost(currMB, LIST_1, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, LIST_1, block, mode, &enc_mb, bmcost, best_ref); // Compute bipredictive cost between best list 0 and best list 1 references - list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref); + list_prediction_cost(currMB, BI_PRED, block, mode, &enc_mb, bmcost, best_ref); - // Finally, if mode 16x16, compute cost for bipredictive ME vectore - if (params->BiPredMotionEstimation && mode == 1) + // currently Bi prediction ME is only supported for modes 1, 2, 3 + if (is_bipred_enabled(mode)) { - list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0); - list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L0, block, mode, &enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L1, block, mode, &enc_mb, bmcost, 0); } else { @@ -152,7 +151,7 @@ void encode_one_macroblock_low (Macroblock *currMB) } // Determine prediction list based on mode cost - determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bi_pred_me); + determine_prediction_list(mode, bmcost, best_ref, &best_pdir, &cost, &bipred_me); } else // if (bslice) { @@ -160,31 +159,13 @@ void encode_one_macroblock_low (Macroblock *currMB) cost += bmcost[LIST_0]; } - assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice); - + assign_enc_picture_params(mode, best_pdir, block, enc_mb.list_offset[LIST_0], best_ref[LIST_0], best_ref[LIST_1], bslice, bipred_me); //----- set reference frame and direction parameters ----- - if (mode==3) - { - best8x8l0ref [3][block ] = best8x8l0ref [3][ block+2] = best_ref[LIST_0]; - best8x8pdir [3][block ] = best8x8pdir [3][ block+2] = best_pdir; - best8x8l1ref [3][block ] = best8x8l1ref [3][ block+2] = best_ref[LIST_1]; - } - else if (mode==2) - { - best8x8l0ref [2][2*block] = best8x8l0ref [2][2*block+1] = best_ref[LIST_0]; - best8x8pdir [2][2*block] = best8x8pdir [2][2*block+1] = best_pdir; - best8x8l1ref [2][2*block] = best8x8l1ref [2][2*block+1] = best_ref[LIST_1]; - } - else - { - memset(&best8x8l0ref [1][0], best_ref[LIST_0], 4 * sizeof(char)); - memset(&best8x8l1ref [1][0], best_ref[LIST_1], 4 * sizeof(char)); - best8x8pdir [1][0] = best8x8pdir [1][1] = best8x8pdir [1][2] = best8x8pdir [1][3] = best_pdir; - } + set_block8x8_info(b8x8info, mode, block, best_ref, best_pdir, bipred_me); //--- set reference frames and motion vectors --- if (mode>1 && block==0) - SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]); + SetRefAndMotionVectors (currMB, block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1], bipred_me); } // for (block=0; block<(mode==1?1:2); block++) currMB->luma_transform_size_8x8_flag = 0; @@ -212,8 +193,8 @@ void encode_one_macroblock_low (Macroblock *currMB) { giRDOpt_B8OnlyFlag = 1; - tr8x8.cost8x8 = INT_MAX; - tr4x4.cost8x8 = INT_MAX; + tr8x8.mb_p8x8_cost = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; //===== store coding state of macroblock ===== store_coding_state (currMB, cs_mb); @@ -221,19 +202,16 @@ void encode_one_macroblock_low (Macroblock *currMB) if (params->Transform8x8Mode) { - tr8x8.cost8x8 = 0; + tr8x8.mb_p8x8_cost = 0; //=========================================================== // Check 8x8 partition with transform size 8x8 //=========================================================== //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block = 0; block < 4; block++) { - submacroblock_mode_decision(enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], + submacroblock_mode_decision(&enc_mb, &tr8x8, currMB, cofAC8x8ts[0][block], cofAC8x8ts[1][block], cofAC8x8ts[2][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 1); - best8x8mode [block] = tr8x8.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr8x8.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr8x8.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr8x8.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr8x8); } // following params could be added in RD_8x8DATA structure @@ -249,20 +227,16 @@ void encode_one_macroblock_low (Macroblock *currMB) if (params->Transform8x8Mode != 2) { - tr4x4.cost8x8 = 0; + tr4x4.mb_p8x8_cost = 0; //================================================================= // Check 8x8, 8x4, 4x8 and 4x4 partitions with transform size 4x4 //================================================================= //===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) ===== for (cost_direct=cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++) { - submacroblock_mode_decision(enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], + submacroblock_mode_decision(&enc_mb, &tr4x4, currMB, cofAC8x8[block], cofAC8x8CbCr[0][block], cofAC8x8CbCr[1][block], &have_direct, bslice, block, &cost_direct, &cost, &cost8x8_direct, 0); - - best8x8mode [block] = tr4x4.part8x8mode [block]; - best8x8pdir [P8x8][block] = tr4x4.part8x8pdir [block]; - best8x8l0ref[P8x8][block] = tr4x4.part8x8l0ref[block]; - best8x8l1ref[P8x8][block] = tr4x4.part8x8l1ref[block]; + set_subblock8x8_info(b8x8info, P8x8, block, &tr4x4); } //--- re-set coding state (as it was before 8x8 block coding) --- // reset_coding_state (currMB, cs_mb); @@ -274,54 +248,58 @@ void encode_one_macroblock_low (Macroblock *currMB) // This is not enabled yet since mpr has reverse order. if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); //check cost for P8x8 for non-rdopt mode - if (tr4x4.cost8x8 < min_cost || tr8x8.cost8x8 < min_cost) + if (tr4x4.mb_p8x8_cost < min_cost || tr8x8.mb_p8x8_cost < min_cost) { best_mode = P8x8; + + if (img->AdaptiveRounding) + store_adaptive_rounding_parameters_luma (currMB, best_mode); + if (params->Transform8x8Mode == 2) { - min_cost = tr8x8.cost8x8; + min_cost = tr8x8.mb_p8x8_cost; currMB->luma_transform_size_8x8_flag=1; } else if (params->Transform8x8Mode) { - if (tr8x8.cost8x8 < tr4x4.cost8x8) + if (tr8x8.mb_p8x8_cost < tr4x4.mb_p8x8_cost) { - min_cost = tr8x8.cost8x8; + min_cost = tr8x8.mb_p8x8_cost; currMB->luma_transform_size_8x8_flag=1; } - else if(tr4x4.cost8x8 < tr8x8.cost8x8) + else if(tr4x4.mb_p8x8_cost < tr8x8.mb_p8x8_cost) { - min_cost = tr4x4.cost8x8; + min_cost = tr4x4.mb_p8x8_cost; currMB->luma_transform_size_8x8_flag=0; } else { if (GetBestTransformP8x8() == 0) { - min_cost = tr4x4.cost8x8; + min_cost = tr4x4.mb_p8x8_cost; currMB->luma_transform_size_8x8_flag=0; } else { - min_cost = tr8x8.cost8x8; + min_cost = tr8x8.mb_p8x8_cost; currMB->luma_transform_size_8x8_flag=1; } } } else { - min_cost = tr4x4.cost8x8; + min_cost = tr4x4.mb_p8x8_cost; currMB->luma_transform_size_8x8_flag=0; } - }// if ((tr4x4.cost8x8 < min_cost || tr8x8.cost8x8 < min_cost)) + }// if ((tr4x4.mb_p8x8_cost < min_cost || tr8x8.mb_p8x8_cost < min_cost)) giRDOpt_B8OnlyFlag = 0; } else // if (enc_mb.valid[P8x8]) { - tr4x4.cost8x8 = INT_MAX; + tr4x4.mb_p8x8_cost = INT_MAX; } // Find a motion vector for the Skip mode @@ -387,7 +365,7 @@ void encode_one_macroblock_low (Macroblock *currMB) //Rate control if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); min_cost = cost; best_mode = 0; @@ -409,6 +387,7 @@ void encode_one_macroblock_low (Macroblock *currMB) currMB->mb_type = I8MB; temp_cpb = Mode_Decision_for_new_Intra8x8Macroblock (currMB, enc_mb.lambda_md, &rd_cost); + if (rd_cost <= min_rd_cost) //HYU_NOTE. bug fix. 08/15/07 { currMB->cbp = temp_cpb; @@ -429,31 +408,21 @@ void encode_one_macroblock_low (Macroblock *currMB) for(j=0; j<MB_BLOCK_SIZE; j++) { - pix_y = img->pix_y + j; - for(i=0; i<MB_BLOCK_SIZE; i++) - { - pix_x = img->pix_x + i; - temp_imgY[j][i] = enc_picture->imgY[pix_y][pix_x]; - } + memcpy(temp_imgY[j], &enc_picture->imgY[img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof (imgpel)); } if (img->P444_joined) { for(j=0; j<MB_BLOCK_SIZE; j++) { - pix_y = img->pix_y + j; - for(i=0; i<MB_BLOCK_SIZE; i++) - { - pix_x = img->pix_x + i; - temp_imgU[j][i] = enc_picture->imgUV[0][pix_y][pix_x]; - temp_imgV[j][i] = enc_picture->imgUV[1][pix_y][pix_x]; - } + memcpy(temp_imgU[j], &enc_picture->imgUV[0][img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof (imgpel)); + memcpy(temp_imgV[j], &enc_picture->imgUV[1][img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof (imgpel)); } } - + //Rate control if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); min_rd_cost = rd_cost; best_mode = I8MB; @@ -486,11 +455,14 @@ void encode_one_macroblock_low (Macroblock *currMB) //Rate control if (params->RCEnable) - rc_store_diff(img->opix_x, img->opix_y, curr_mpr); + rc_store_diff(img->opix_x, img->opix_y, mb_pred); min_rd_cost = rd_cost; best_mode = I4MB; tmp_8x8_flag = currMB->luma_transform_size_8x8_flag; + + if (img->AdaptiveRounding) + store_adaptive_rounding_parameters_luma (currMB, best_mode); } else { @@ -539,6 +511,10 @@ void encode_one_macroblock_low (Macroblock *currMB) best_mode = I16MB; min_rd_cost = rd_cost; currMB->cbp = pDCT_16x16 (currMB, PLANE_Y, i16mode); + + if (img->AdaptiveRounding) + store_adaptive_rounding_parameters_luma (currMB, best_mode); + if (img->P444_joined) { select_plane(PLANE_U); @@ -616,6 +592,9 @@ void encode_one_macroblock_low (Macroblock *currMB) currMB->luma_transform_size_8x8_flag = best_transform_flag; LumaResidualCoding (currMB); + if (img->AdaptiveRounding) + store_adaptive_rounding_parameters_luma (currMB, best_mode); + if (img->P444_joined) { if((currMB->cbp==0 && cmp_cbp[1] == 0 && cmp_cbp[2] == 0) &&(best_mode==0)) @@ -626,7 +605,7 @@ void encode_one_macroblock_low (Macroblock *currMB) //Rate control if (params->RCEnable) - rc_store_diff(img->opix_x,img->opix_y,curr_mpr); + rc_store_diff(img->opix_x,img->opix_y,mb_pred); } } } @@ -644,6 +623,9 @@ void encode_one_macroblock_low (Macroblock *currMB) if ((img->yuv_format != YUV400) && (img->yuv_format != YUV444)) ChromaResidualCoding (currMB); + if (img->AdaptiveRounding) + store_adaptive_rounding_parameters_chroma (currMB, best_mode); + if (best_mode==I16MB) { img->i16offset = I16Offset (currMB->cbp, i16mode); @@ -655,18 +637,18 @@ void encode_one_macroblock_low (Macroblock *currMB) if(img->P444_joined) { if ((pslice) && best_mode==1 && currMB->cbp==0 && cmp_cbp[1] == 0 && cmp_cbp[2] == 0 && - enc_picture->ref_idx[LIST_0][img->block_y][img->block_x] == 0 && - enc_picture->mv [LIST_0][img->block_y][img->block_x][0] == allmvs[0] && - enc_picture->mv [LIST_0][img->block_y][img->block_x][1] == allmvs[1]) + enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x] == 0 && + enc_picture->motion.mv [LIST_0][img->block_y][img->block_x][0] == allmvs[0] && + enc_picture->motion.mv [LIST_0][img->block_y][img->block_x][1] == allmvs[1]) { currMB->mb_type = currMB->b8mode[0] = currMB->b8mode[1] = currMB->b8mode[2] = currMB->b8mode[3] = 0; currMB->luma_transform_size_8x8_flag = 0; } } else if ((pslice) && best_mode==1 && currMB->cbp==0 && - enc_picture->ref_idx[LIST_0][img->block_y][img->block_x] == 0 && - enc_picture->mv [LIST_0][img->block_y][img->block_x][0] == allmvs[0] && - enc_picture->mv [LIST_0][img->block_y][img->block_x][1] == allmvs[1]) + enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x] == 0 && + enc_picture->motion.mv [LIST_0][img->block_y][img->block_x][0] == allmvs[0] && + enc_picture->motion.mv [LIST_0][img->block_y][img->block_x][1] == allmvs[1]) { currMB->mb_type = currMB->b8mode[0] = currMB->b8mode[1] = currMB->b8mode[2] = currMB->b8mode[3] = 0; currMB->luma_transform_size_8x8_flag = 0; @@ -711,5 +693,11 @@ void encode_one_macroblock_low (Macroblock *currMB) { img->intra_block[img->current_mb_nr] = IS_INTRA(currMB); } + + /*update adaptive rounding offset params*/ + if (img->AdaptiveRounding) + { + update_offset_params(currMB, best_mode, currMB->luma_transform_size_8x8_flag); + } } diff --git a/lencod/src/me_epzs.c b/lencod/src/me_epzs.c index 541a0f3..87dd65b 100644 --- a/lencod/src/me_epzs.c +++ b/lencod/src/me_epzs.c @@ -76,10 +76,10 @@ static int pattern_data[5][12][4] = }; // Other definitions -static const char c_EPZSPattern[6][20] = { "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"}; -static const char c_EPZSDualPattern[7][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"}; -static const char c_EPZSFixed[3][20] = { "Disabled","All P", "All P + B"}; -static const char c_EPZSOther[2][20] = { "Disabled","Enabled"}; +static const char c_EPZSPattern[6][20] = { "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"}; +static const char c_EPZSDualPattern[7][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"}; +static const char c_EPZSFixed[3][20] = { "Disabled","All P", "All P + B"}; +static const char c_EPZSOther[2][20] = { "Disabled","Enabled"}; static int medthres[8]; static int maxthres[8]; @@ -89,9 +89,12 @@ static int mv_scale[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES]; static short **EPZSMap; //!< Memory Map definition int ***EPZSDistortion; //!< Array for storing SAD Values +int ***EPZSBiDistortion; //!< Array for storing SAD Values #if EPZSREF +MotionVector *****EPZS_Motion; //!< Array for storing Motion Vectors short ******EPZSMotion; //!< Array for storing Motion Vectors #else +MotionVector ****EPZS_Motion; //!< Array for storing Motion Vectors short *****EPZSMotion; //!< Array for storing Motion Vectors #endif @@ -101,6 +104,28 @@ EPZSStructure *window_predictor, *window_predictor_extended; EPZSStructure *sdiamond,*square,*ediamond,*ldiamond, *sbdiamond, *pmvfast; EPZSColocParams *EPZSCo_located; +/*! +************************************************************************************* +* \brief +* Determine stop criterion for EPZS +************************************************************************************* +*/ +static int EPZSDetermineStopCriterion(int* prevSad, PixelPos *block_a, PixelPos *block_b, PixelPos *block_c, int pic_pix_x2, int blocktype, int blocksize_x) +{ + int sadA, sadB, sadC, stopCriterion; + + sadA = block_a->available ? prevSad[pic_pix_x2 - blocksize_x] : INT_MAX; + sadB = block_b->available ? prevSad[pic_pix_x2] : INT_MAX; + sadC = block_c->available ? prevSad[pic_pix_x2 + blocksize_x] : INT_MAX; + + stopCriterion = imin(sadA,imin(sadB,sadC)); + stopCriterion = imax(stopCriterion,minthres[blocktype]); + stopCriterion = imin(stopCriterion,maxthres[blocktype]); + + stopCriterion = (9 * imax (medthres[blocktype], stopCriterion) + 2 * medthres[blocktype]) >> 3; + return stopCriterion; +} + // Functions /*! ************************************************************************ @@ -128,12 +153,12 @@ static EPZSColocParams* allocEPZScolocated(int size_x, int size_y, int mb_adapti s->size_x = size_x; s->size_y = size_y; - get_mem4Dshort (&(s->mv), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2); + get_mem3Dmv(&(s->frame), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE); if (mb_adaptive_frame_field_flag) { - get_mem4Dshort (&(s->top_mv), 2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2); - get_mem4Dshort (&(s->bottom_mv),2, size_y / BLOCK_SIZE/2, size_x / BLOCK_SIZE, 2); + get_mem3Dmv(&(s->top), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); + get_mem3Dmv(&(s->bot), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE); } s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag; @@ -155,12 +180,12 @@ static void freeEPZScolocated(EPZSColocParams* p) { if (p) { - free_mem4Dshort (p->mv); + free_mem3Dmv (p->frame); if (p->mb_adaptive_frame_field_flag) { - free_mem4Dshort (p->top_mv); - free_mem4Dshort (p->bottom_mv); + free_mem3Dmv (p->top); + free_mem3Dmv (p->bot); } free(p); @@ -250,6 +275,20 @@ static int RoundLog2 (int iValue) return iRet; } +/*! +*********************************************************************** +* \brief +* Add Predictor function +* +*********************************************************************** +*/ +static inline int add_predictor(MotionVector *cur_mv, MotionVector prd_mv, int mvScale, int shift_mv) +{ + *cur_mv = prd_mv; + cur_mv->mv_x = rshift_rnd_sf((mvScale * cur_mv->mv_x), shift_mv); + cur_mv->mv_y = rshift_rnd_sf((mvScale * cur_mv->mv_y), shift_mv); + return (*((int*) cur_mv) != 0); +} /*! ************************************************************************ @@ -328,7 +367,7 @@ static void EPZSWindowPredictorInit (short search_range, EPZSStructure * predict * EPZS Global Initialization ************************************************************************ */ -int EPZSInit (void) +int EPZSInit (InputParameters *params, ImageParameters *img) { int pel_error_me = 1 << (img->bitdepth_luma - 8); int pel_error_me_cr = 1 << (img->bitdepth_chroma - 8); @@ -392,13 +431,16 @@ int EPZSInit (void) //memory_size += get_offset_mem2Dshort(&EPZSMap, searcharray, searcharray, (searcharray>>1), (searcharray>>1)); memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE); + memory_size += get_mem3Dint (&EPZSBiDistortion, 6, 7, img->width/BLOCK_SIZE); memory_size += get_mem2Dshort (&EPZSMap, searcharray, searcharray ); if (params->EPZSSpatialMem) { #if EPZSREF + memory_size += get_mem5Dmv (&EPZS_Motion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE); memory_size += get_mem6Dshort (&EPZSMotion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE, 2); #else + memory_size += get_mem4Dmv (&EPZS_Motion, 6, 7, 4, img->width/BLOCK_SIZE); memory_size += get_mem5Dshort (&EPZSMotion, 6, 7, 4, img->width/BLOCK_SIZE, 2); #endif } @@ -461,7 +503,7 @@ int EPZSInit (void) * Delete EPZS Alocated memory ************************************************************************ */ -void EPZSDelete (void) +void EPZSDelete (InputParameters *params) { if (params->EPZSTemporal) freeEPZScolocated (EPZSCo_located); @@ -469,6 +511,7 @@ void EPZSDelete (void) //free_offset_mem2Dshort(EPZSMap, searcharray, (searcharray>>1), (searcharray>>1)); free_mem2Dshort(EPZSMap); free_mem3Dint (EPZSDistortion); + free_mem3Dint (EPZSBiDistortion); freeEPZSpattern(window_predictor_extended); freeEPZSpattern(window_predictor); freeEPZSpattern(predictor); @@ -482,8 +525,10 @@ void EPZSDelete (void) if (params->EPZSSpatialMem) { #if EPZSREF + free_mem5Dmv (EPZS_Motion); free_mem6Dshort (EPZSMotion); #else + free_mem4Dmv (EPZS_Motion); free_mem5Dshort (EPZSMotion); #endif } @@ -497,9 +542,7 @@ void EPZSDelete (void) * EPZS Slice Level Initialization ************************************************************************ */ -void -EPZSSliceInit (EPZSColocParams * p, - StorablePicture ** listX[6]) +void EPZSSliceInit (InputParameters *params, ImageParameters *img, EPZSColocParams * p, StorablePicture ** listX[6]) { StorablePicture *fs, *fs_top, *fs_bottom; StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx; @@ -519,12 +562,12 @@ EPZSSliceInit (EPZSColocParams * p, { for (i = 0; i < listXsize[j]; i++) { - if (j/2 == 0) + if ((j >> 1) == 0) { iTRb = iClip3 (-128, 127, enc_picture->poc - listX[j][i]->poc); iTRp = iClip3 (-128, 127, enc_picture->poc - listX[j][k]->poc); } - else if (j/2 == 1) + else if ((j >> 1) == 1) { iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc); iTRp = iClip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc); @@ -584,6 +627,7 @@ EPZSSliceInit (EPZSColocParams * p, prescale = 256; epzs_scale[0][j][i] = rshift_rnd_sf((mv_scale[j][0][i] * prescale), 8); epzs_scale[0][j + 1][i] = prescale - 256; + if (listXsize[list + j]>1) { iTRp = iClip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc); @@ -635,107 +679,157 @@ EPZSSliceInit (EPZSColocParams * p, } } - //if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag) if (!active_sps->frame_mbs_only_flag) { - for (j = 0; j < fs->size_y >> 2; j++) + if (img->MbaffFrameFlag) { - jj = j / 2; - jdiv = j / 2 + 4 * (j / 8); - for (i = 0; i < fs->size_x >> 2; i++) + for (j = 0; j < fs->size_y >> 2; j++) { - if (img->MbaffFrameFlag && fs->field_frame[j][i]) + jj = j >> 1; + jdiv = jj + 4 * (j >> 3); + + for (i = 0; i < fs->size_x >> 2; i++) { - //! Assign frame buffers for field MBs - //! Check whether we should use top or bottom field mvs. - //! Depending on the assigned poc values. - if (iabs (enc_picture->poc - fs_bottom->poc) > iabs (enc_picture->poc - fs_top->poc)) + if (fs->motion.field_frame[j][i]) { - tempmv_scale[LIST_0] = 256; - tempmv_scale[LIST_1] = 0; - - if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1) + //! Assign frame buffers for field MBs + //! Check whether we should use top or bottom field mvs. + //! Depending on the assigned poc values. + if (iabs (enc_picture->poc - fs_bottom->poc) > iabs (enc_picture->poc - fs_top->poc)) { - fsx = fs_top1; - loffset = 1; - } - else - { - fsx = fs_top; - loffset = 0; - } + tempmv_scale[LIST_0] = 256; + tempmv_scale[LIST_1] = 0; - if (fs->ref_id [LIST_0][jdiv][i] != -1) - { - for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) + if (fs->motion.ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1) + { + fsx = fs_top1; + loffset = 1; + } + else { - if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv][i]) + fsx = fs_top; + loffset = 0; + } + + if (fs->motion.ref_id [LIST_0][jdiv][i] != -1) + { + for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) { - tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; - tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; - break; + if (enc_picture->ref_pic_num[LIST_0][iref]==fs->motion.ref_id [LIST_0][jdiv][i]) + { + tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; + tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; + break; + } } + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision)); + } + else + { + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; } - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][1]), invmv_precision)); } else { - p->mv[LIST_0][j][i][0] = 0; - p->mv[LIST_0][j][i][1] = 0; - p->mv[LIST_1][j][i][0] = 0; - p->mv[LIST_1][j][i][1] = 0; - } + tempmv_scale[LIST_0] = 256; + tempmv_scale[LIST_1] = 0; + + if (fs->motion.ref_id [LIST_0][jdiv + 4][i] < 0 && listXsize[LIST_0] > 1) + { + fsx = fs_bottom1; + loffset = 1; + } + else + { + fsx = fs_bottom; + loffset = 0; + } + if (fs->motion.ref_id [LIST_0][jdiv + 4][i] != -1) + { + for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) + { + if (enc_picture->ref_pic_num[LIST_0][iref]==fs->motion.ref_id [LIST_0][jdiv + 4][i]) + { + tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; + tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; + break; + } + } + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision)); + } + else + { + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; + } + } } else { tempmv_scale[LIST_0] = 256; tempmv_scale[LIST_1] = 0; - - if (fs->ref_id [LIST_0][jdiv + 4][i] < 0 && listXsize[LIST_0] > 1) + if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) { - fsx = fs_bottom1; + fsx = fs1; loffset = 1; } else { - fsx = fs_bottom; + fsx = fs; loffset = 0; } - if (fs->ref_id [LIST_0][jdiv + 4][i] != -1) + if (fsx->motion.ref_id [LIST_0][j][i] != -1) { for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) { - if (enc_picture->ref_pic_num[LIST_0][iref]==fs->ref_id [LIST_0][jdiv + 4][i]) + if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i]) { tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; break; } } - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][jj][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); } else { - p->mv[LIST_0][j][i][0] = 0; - p->mv[LIST_0][j][i][1] = 0; - p->mv[LIST_1][j][i][0] = 0; - p->mv[LIST_1][j][i][1] = 0; + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; } } } - else + } + } + else + { + for (j = 0; j < fs->size_y >> 2; j++) + { + jj = j >> 1; + jdiv = jj + 4 * (j >> 3); + + for (i = 0; i < fs->size_x >> 2; i++) { tempmv_scale[LIST_0] = 256; tempmv_scale[LIST_1] = 0; - if (fs->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) + if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) { fsx = fs1; loffset = 1; @@ -746,169 +840,169 @@ EPZSSliceInit (EPZSColocParams * p, loffset = 0; } - if (fsx->ref_id [LIST_0][j][i] != -1) + if (fsx->motion.ref_id [LIST_0][j][i] != -1) { for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) { - if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][j][i]) + if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i]) { tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; break; } } - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); } else { - p->mv[LIST_0][j][i][0] = 0; - p->mv[LIST_0][j][i][1] = 0; - p->mv[LIST_1][j][i][0] = 0; - p->mv[LIST_1][j][i][1] = 0; + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; } } } } - } - - //! Generate field MVs from Frame MVs - if (img->structure || img->MbaffFrameFlag) - { - for (j = 0; j < fs->size_y / 8; j++) + + //! Generate field MVs from Frame MVs + if (img->structure || img->MbaffFrameFlag) { - for (i = 0; i < fs->size_x / 4; i++) + for (j = 0; j < fs->size_y / 8; j++) { - if (!img->MbaffFrameFlag) + for (i = 0; i < fs->size_x / 4; i++) { - tempmv_scale[LIST_0] = 256; - tempmv_scale[LIST_1] = 0; - - if (fs->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) + if (!img->MbaffFrameFlag) { - fsx = fs1; - loffset = 1; - } - else - { - fsx = fs; - loffset = 0; - } + tempmv_scale[LIST_0] = 256; + tempmv_scale[LIST_1] = 0; - if (fsx->ref_id [LIST_0][j][i] != -1) - { - for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) + if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) + { + fsx = fs1; + loffset = 1; + } + else + { + fsx = fs; + loffset = 0; + } + + if (fsx->motion.ref_id [LIST_0][j][i] != -1) { - if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][j][i]) + for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) { - tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; - tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; - break; + if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i]) + { + tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; + tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; + break; + } } + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + } + else + { + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; } - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); } else { - p->mv[LIST_0][j][i][0] = 0; - p->mv[LIST_0][j][i][1] = 0; - p->mv[LIST_1][j][i][0] = 0; - p->mv[LIST_1][j][i][1] = 0; - } - } - else - { - tempmv_scale[LIST_0] = 256; - tempmv_scale[LIST_1] = 0; + tempmv_scale[LIST_0] = 256; + tempmv_scale[LIST_1] = 0; - if (fs_bottom->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) - { - fsx = fs_bottom1; - loffset = 1; - } - else - { - fsx = fs_bottom; - loffset = 0; - } + if (fs_bottom->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) + { + fsx = fs_bottom1; + loffset = 1; + } + else + { + fsx = fs_bottom; + loffset = 0; + } - if (fsx->ref_id [LIST_0][j][i] != -1) - { - for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 4]); iref++) + if (fsx->motion.ref_id [LIST_0][j][i] != -1) { - if (enc_picture->ref_pic_num[LIST_0 + 4][iref]==fsx->ref_id [LIST_0][j][i]) + for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 4]); iref++) { - tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 4][iref]; - tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 4][iref]; - break; + if (enc_picture->ref_pic_num[LIST_0 + 4][iref]==fsx->motion.ref_id [LIST_0][j][i]) + { + tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 4][iref]; + tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 4][iref]; + break; + } } + p->bot[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->bot[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + p->bot[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->bot[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + } + else + { + p->bot[LIST_0][j][i].mv_x = 0; + p->bot[LIST_0][j][i].mv_y = 0; + p->bot[LIST_1][j][i].mv_x = 0; + p->bot[LIST_1][j][i].mv_y = 0; } - p->bottom_mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->bottom_mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - p->bottom_mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->bottom_mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - } - else - { - p->bottom_mv[LIST_0][j][i][0] = 0; - p->bottom_mv[LIST_0][j][i][1] = 0; - p->bottom_mv[LIST_1][j][i][0] = 0; - p->bottom_mv[LIST_1][j][i][1] = 0; - } - if (!fs->field_frame[2 * j][i]) - { - p->bottom_mv[LIST_0][j][i][1] = (p->bottom_mv[LIST_0][j][i][1] + 1) >> 1; - p->bottom_mv[LIST_1][j][i][1] = (p->bottom_mv[LIST_1][j][i][1] + 1) >> 1; - } + if (!fs->motion.field_frame[2 * j][i]) + { + p->bot[LIST_0][j][i].mv_y = (p->bot[LIST_0][j][i].mv_y + 1) >> 1; + p->bot[LIST_1][j][i].mv_y = (p->bot[LIST_1][j][i].mv_y + 1) >> 1; + } - tempmv_scale[LIST_0] = 256; - tempmv_scale[LIST_1] = 0; + tempmv_scale[LIST_0] = 256; + tempmv_scale[LIST_1] = 0; - if (fs_top->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) - { - fsx = fs_top1; - loffset = 1; - } - else - { - fsx = fs_top; - loffset = 0; - } + if (fs_top->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) + { + fsx = fs_top1; + loffset = 1; + } + else + { + fsx = fs_top; + loffset = 0; + } - if (fsx->ref_id [LIST_0][j][i] != -1) - { - for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 2]); iref++) + if (fsx->motion.ref_id [LIST_0][j][i] != -1) { - if (enc_picture->ref_pic_num[LIST_0 + 2][iref]==fsx->ref_id [LIST_0][j][i]) + for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 2]); iref++) { - tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 2][iref]; - tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 2][iref]; - break; + if (enc_picture->ref_pic_num[LIST_0 + 2][iref]==fsx->motion.ref_id [LIST_0][j][i]) + { + tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 2][iref]; + tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 2][iref]; + break; + } } + p->top[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->top[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + p->top[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->top[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + } + else + { + p->top[LIST_0][j][i].mv_x = 0; + p->top[LIST_0][j][i].mv_y = 0; + p->top[LIST_1][j][i].mv_x = 0; + p->top[LIST_1][j][i].mv_y = 0; } - p->top_mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->top_mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - p->top_mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->top_mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - } - else - { - p->top_mv[LIST_0][j][i][0] = 0; - p->top_mv[LIST_0][j][i][1] = 0; - p->top_mv[LIST_1][j][i][0] = 0; - p->top_mv[LIST_1][j][i][1] = 0; - } - if (!fs->field_frame[2 * j][i]) - { - p->top_mv[LIST_0][j][i][1] = rshift_rnd_sf((p->top_mv[LIST_0][j][i][1]), 1); - p->top_mv[LIST_1][j][i][1] = rshift_rnd_sf((p->top_mv[LIST_1][j][i][1]), 1); + if (!fs->motion.field_frame[2 * j][i]) + { + p->top[LIST_0][j][i].mv_y = (p->top[LIST_0][j][i].mv_y + 1) >> 1; + p->top[LIST_1][j][i].mv_y = (p->top[LIST_1][j][i].mv_y + 1) >> 1; + } } } } @@ -928,12 +1022,12 @@ EPZSSliceInit (EPZSColocParams * p, jdiv = (j>>1) + ((j>>3) << 2); for (i = 0; i < fs->size_x >> 2; i++) { - if (fs->field_frame[j][i]) + if (fs->motion.field_frame[j][i]) { tempmv_scale[LIST_0] = 256; tempmv_scale[LIST_1] = 0; - if (fs->ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1) + if (fs->motion.ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1) { fsx = fs1; loffset = 1; @@ -943,11 +1037,11 @@ EPZSSliceInit (EPZSColocParams * p, fsx = fs; loffset = 0; } - if (fsx->ref_id [LIST_0][jdiv][i] != -1) + if (fsx->motion.ref_id [LIST_0][jdiv][i] != -1) { for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) { - if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][jdiv][i]) + if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][jdiv][i]) { tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; @@ -957,25 +1051,25 @@ EPZSSliceInit (EPZSColocParams * p, if (iabs (enc_picture->poc - fsx->bottom_field->poc) > iabs (enc_picture->poc - fsx->top_field->poc)) { - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->mv[LIST_0][jj][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->motion.mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->motion.mv[LIST_0][jj][i][1]), invmv_precision)); } else { - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->mv[LIST_0][jj][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->mv[LIST_0][jj][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->motion.mv[LIST_0][jj][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->motion.mv[LIST_0][jj][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->motion.mv[LIST_0][jj][i][1]), invmv_precision)); } } else { - p->mv[LIST_0][j][i][0] = 0; - p->mv[LIST_0][j][i][1] = 0; - p->mv[LIST_1][j][i][0] = 0; - p->mv[LIST_1][j][i][1] = 0; + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; } } } @@ -991,7 +1085,7 @@ EPZSSliceInit (EPZSColocParams * p, { tempmv_scale[LIST_0] = 256; tempmv_scale[LIST_1] = 0; - if (fs->ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) + if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1) { fsx = fs1; loffset = 1; @@ -1001,11 +1095,12 @@ EPZSSliceInit (EPZSColocParams * p, fsx = fs; loffset = 0; } - if (fsx->ref_id [LIST_0][j][i] != -1) + + if (fsx->motion.ref_id [LIST_0][j][i] != -1) { for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++) { - if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->ref_id [LIST_0][j][i]) + if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i]) { tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref]; tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref]; @@ -1013,17 +1108,17 @@ EPZSSliceInit (EPZSColocParams * p, } } - p->mv[LIST_0][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->mv[LIST_0][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); - p->mv[LIST_1][j][i][0] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][0]), invmv_precision)); - p->mv[LIST_1][j][i][1] = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->mv[LIST_0][j][i][1]), invmv_precision)); + p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); + p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision)); + p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision)); } else { - p->mv[LIST_0][j][i][0] = 0; - p->mv[LIST_0][j][i][1] = 0; - p->mv[LIST_1][j][i][0] = 0; - p->mv[LIST_1][j][i][1] = 0; + p->frame[LIST_0][j][i].mv_x = 0; + p->frame[LIST_0][j][i].mv_y = 0; + p->frame[LIST_1][j][i].mv_x = 0; + p->frame[LIST_1][j][i].mv_y = 0; } } } @@ -1035,15 +1130,15 @@ EPZSSliceInit (EPZSColocParams * p, { for (i = 0; i < fs->size_x >> 2; i++) { - if ((!img->MbaffFrameFlag && !img->structure && fs->field_frame[j][i]) || (img->MbaffFrameFlag && fs->field_frame[j][i])) + if ((!img->MbaffFrameFlag && !img->structure && fs->motion.field_frame[j][i]) || (img->MbaffFrameFlag && fs->motion.field_frame[j][i])) { - p->mv[LIST_0][j][i][1] *= 2; - p->mv[LIST_1][j][i][1] *= 2; + p->frame[LIST_0][j][i].mv_y *= 2; + p->frame[LIST_1][j][i].mv_y *= 2; } - else if (img->structure && !fs->field_frame[j][i]) + else if (img->structure && !fs->motion.field_frame[j][i]) { - p->mv[LIST_0][j][i][1] = rshift_rnd_sf((p->mv[LIST_0][j][i][1]), 1); - p->mv[LIST_1][j][i][1] = rshift_rnd_sf((p->mv[LIST_1][j][i][1]), 1); + p->frame[LIST_0][j][i].mv_y = rshift_rnd_sf(p->frame[LIST_0][j][i].mv_y, 1); + p->frame[LIST_1][j][i].mv_y = rshift_rnd_sf(p->frame[LIST_1][j][i].mv_y, 1); } } } @@ -1264,6 +1359,7 @@ static void EPZSSpatialMemPredictors (int list, { #if EPZSREF short ***mv = EPZSMotion[list][ref][blocktype]; + //MotionVector ***prd_mv = &EPZS_Motion[list][ref][blocktype]; MotionVector *cur_mv = &predictor->point[*prednum].motion; // Left Predictor @@ -1271,7 +1367,6 @@ static void EPZSSpatialMemPredictors (int list, { cur_mv->mv_x = mv[by][pic_x - bs_x][0]; cur_mv->mv_y = mv[by][pic_x - bs_x][1]; - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); *prednum += (*((int*) cur_mv) != 0); cur_mv = &predictor->point[*prednum].motion; } @@ -1280,7 +1375,6 @@ static void EPZSSpatialMemPredictors (int list, // Up predictor cur_mv->mv_x = mv[by][pic_x][0]; cur_mv->mv_y = mv[by][pic_x][1]; - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); *prednum += (*((int*) cur_mv) != 0); // Up-Right predictor @@ -1289,13 +1383,13 @@ static void EPZSSpatialMemPredictors (int list, cur_mv = &predictor->point[*prednum].motion; cur_mv->mv_x = mv[by][pic_x + bs_x][0]; cur_mv->mv_y = mv[by][pic_x + bs_x][1]; - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); *prednum += (*((int*) cur_mv) != 0); } #else int mot_scale = mv_scale[list][ref][0]; short **mv = EPZSMotion[list][blocktype]; + MotionVector **predictor = &EPZS_Motion[list][blocktype]; // Left Predictor predictor->point[*prednum].motion.mv_x = (pic_x > 0) @@ -1330,6 +1424,7 @@ static void EPZSSpatialMemPredictors (int list, #endif } + /*! *********************************************************************** * \brief @@ -1355,90 +1450,54 @@ EPZSTemporalPredictors (int list, // <-- current list int min_mcost) { int mvScale = mv_scale[list + list_offset][ref][0]; - short ***col_mv = (list_offset == 0) ? EPZSCo_located->mv[list] - : (list_offset == 2) ? EPZSCo_located->top_mv[list] : EPZSCo_located->bottom_mv[list]; + MotionVector **col_mv = (list_offset == 0) ? EPZSCo_located->frame[list] + : (list_offset == 2) ? EPZSCo_located->top[list] : EPZSCo_located->bot[list]; short temp_shift_mv = 8 + mv_rescale; // 16 - invmv_precision + mv_rescale MotionVector *cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); - + *prednum += add_predictor(cur_mv, col_mv[o_block_y][o_block_x], mvScale, temp_shift_mv); if (min_mcost > stopCriterion && ref < 2) { if (block_available_left) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x - 1][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x - 1][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x - 1], mvScale, temp_shift_mv); //Up_Left if (block_available_up) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x - 1][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x - 1][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x - 1], mvScale, temp_shift_mv); } //Down_Left if (block_available_below) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x - 1][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x - 1][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x - 1], mvScale, temp_shift_mv); } } // Up if (block_available_up) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x], mvScale, temp_shift_mv); } // Up - Right if (block_available_right) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x + blockshape_x][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y][o_block_x + blockshape_x][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y][o_block_x + blockshape_x], mvScale, temp_shift_mv); if (block_available_up) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y - 1][o_block_x + blockshape_x][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y - 1][o_block_x + blockshape_x], mvScale, temp_shift_mv); } if (block_available_below) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x], mvScale, temp_shift_mv); } } if (block_available_below) { - cur_mv = &predictor->point[*prednum].motion; - cur_mv->mv_x = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x][0]), temp_shift_mv); - cur_mv->mv_y = rshift_rnd_sf((mvScale * col_mv[o_block_y + blockshape_y][o_block_x][1]), temp_shift_mv); - //*prednum += ((cur_mv->mv_x | cur_mv->mv_y) != 0); - *prednum += (*((int*) cur_mv) != 0); + *prednum += add_predictor( &predictor->point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x], mvScale, temp_shift_mv); } } } @@ -1561,6 +1620,7 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock int second_mcost = INT_MAX; int *prevSad = EPZSDistortion[list + list_offset][blocktype - 1]; short *motion=NULL; + MotionVector *p_motion = NULL; short invalid_refs = 0; byte checkMedian = FALSE; @@ -1604,9 +1664,11 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock if (params->EPZSSpatialMem) { #if EPZSREF - motion = EPZSMotion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2]; + motion = EPZSMotion [list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2]; + p_motion = &EPZS_Motion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2]; #else - motion = EPZSMotion[list + list_offset][blocktype - 1][block_y][pic_pix_x2]; + motion = EPZSMotion [list + list_offset][blocktype - 1][block_y][pic_pix_x2]; + p_motion = &EPZS_Motion[list + list_offset][blocktype - 1][block_y][pic_pix_x2]; #endif } @@ -1638,8 +1700,8 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock { motion[0] = tmp.mv_x; motion[1] = tmp.mv_y; + *p_motion = tmp; } - return min_mcost; } @@ -1662,7 +1724,6 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock int mb_available_right = (img->mb_x < (img_width >> 4) - 1); int mb_available_below = (img->mb_y < (img_height >> 4) - 1); - int sadA, sadB, sadC; int block_available_right; int block_available_below; int prednum = 5; @@ -1709,15 +1770,7 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock } block_available_below = (mb_y + blocksize_y != MB_BLOCK_SIZE) || (mb_available_below); - sadA = block_a.available ? prevSad[pic_pix_x2 - blockshape_x] : INT_MAX; - sadB = block_b.available ? prevSad[pic_pix_x2] : INT_MAX; - sadC = block_c.available ? prevSad[pic_pix_x2 + blockshape_x] : INT_MAX; - - stopCriterion = imin(sadA,imin(sadB,sadC)); - stopCriterion = imax(stopCriterion,minthres[blocktype]); - stopCriterion = imin(stopCriterion,maxthres[blocktype]); - - stopCriterion = (9 * imax (medthres[blocktype], stopCriterion) + 2 * medthres[blocktype]) >> 3; + stopCriterion = EPZSDetermineStopCriterion(prevSad, &block_a, &block_b, &block_c, pic_pix_x2, blocktype, blockshape_x); //! Add Spatial Predictors in predictor list. //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little @@ -1762,7 +1815,7 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion)); // above seems to result in memory leak issues which need to be resolved - if (conditionEPZS && img->current_mb_nr != 0) + if (conditionEPZS && img->current_mb_nr != 0 && params->EPZSBlockType) EPZSBlockTypePredictors (block_x, block_y, blocktype, ref, list, predictor, &prednum); //! Check all predictors @@ -1916,8 +1969,9 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock if (params->EPZSSpatialMem && ref == 0) #endif { - motion[0] = tmp.mv_x; - motion[1] = tmp.mv_y; + motion[0] = tmp.mv_x; + motion[1] = tmp.mv_y; + *p_motion = tmp; } return min_mcost; @@ -1961,8 +2015,11 @@ EPZSPelBlockMotionSearch (Macroblock *currMB, // <-- current Macroblock if (params->EPZSSpatialMem && ref == 0) #endif { - motion[0] = tmp.mv_x; - motion[1] = tmp.mv_y; + motion[0] = tmp.mv_x; + motion[1] = tmp.mv_y; + *p_motion = tmp; + //printf("value %d %d %d %d\n", p_motion->mv_x, p_motion->mv_y, EPZS_Motion[list + list_offset][ref][0][0][0].mv_x, EPZS_Motion[list + list_offset][ref][0][0][0].mv_y); + //printf("xxxxx %d %d %d %d\n", p_motion->mv_x, p_motion->mv_y, EPZS_Motion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2].mv_x, EPZS_Motion[list + list_offset][ref][blocktype - 1][block_y][pic_pix_x2].mv_y); } mv[0] = tmp.mv_x; @@ -1995,8 +2052,10 @@ EPZSBiPredBlockMotionSearch (Macroblock *currMB, // <-- Current Macroblock short static_mv[2], // <--> in: search center (x|y) int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) + int iteration_no, // <-- bi pred iteration number int lambda_factor, // <-- lagrangian parameter for determining motion cost - int apply_weights) // <-- perform weight based ME + int apply_weights // <-- perform weight based ME + ) { StorablePicture *ref_picture1 = listX[list + list_offset][ref]; StorablePicture *ref_picture2 = listX[(list ^ 1) + list_offset][0]; @@ -2004,12 +2063,14 @@ EPZSBiPredBlockMotionSearch (Macroblock *currMB, // <-- Current Macroblock short blocksize_x = params->blc_size[blocktype][0]; // horizontal block size short mb_x = pic_pix_x - img->opix_x; short mb_y = pic_pix_y - img->opix_y; - + short pic_pix_x2 = pic_pix_x >> 2; + //short pic_pix_y2 = pic_pix_y >> 2; + int stopCriterion = medthres[blocktype]; int mapCenter_x = search_range - mv[0]; int mapCenter_y = search_range - mv[1]; int second_mcost = INT_MAX; - + int *prevSad = EPZSBiDistortion[list + list_offset][blocktype - 1]; short invalid_refs = 0; byte checkMedian = FALSE; EPZSStructure *searchPatternF = searchPattern; @@ -2130,8 +2191,10 @@ EPZSBiPredBlockMotionSearch (Macroblock *currMB, // <-- Current Macroblock else if (mb_x+blocksize_x == MB_BLOCK_SIZE) block_c.available = 0; } + + stopCriterion = EPZSDetermineStopCriterion(prevSad, &block_a, &block_b, &block_c, pic_pix_x2, blocktype, blocksize_x); + // stopCriterion = (11 * medthres[blocktype]) >> 3; - stopCriterion = (11 * medthres[blocktype]) >> 3; //! Add Spatial Predictors in predictor list. //! Scheme adds zero, left, top-left, top, top-right. Note that top-left adds very little @@ -2310,6 +2373,11 @@ EPZSBiPredBlockMotionSearch (Macroblock *currMB, // <-- Current Macroblock } } } + if (iteration_no == 0) + { + prevSad[pic_pix_x2] = min_mcost; + } + mv[0] = tmp.mv_x; mv[1] = tmp.mv_y; @@ -2323,8 +2391,7 @@ return min_mcost; * AMT/HYC *********************************************************************** */ -void -EPZSOutputStats (FILE * stat, short stats_file) +void EPZSOutputStats (InputParameters *params, FILE * stat, short stats_file) { if (stats_file == 1) { diff --git a/lencod/src/me_fullfast.c b/lencod/src/me_fullfast.c index 737119b..b10b925 100644 --- a/lencod/src/me_fullfast.c +++ b/lencod/src/me_fullfast.c @@ -189,8 +189,7 @@ ClearFastFullIntegerSearch () * (have to be called in start_macroblock()) *********************************************************************** */ -void -ResetFastFullIntegerSearch () +void ResetFastFullIntegerSearch () { int list; for (list=0; list<2; list++) @@ -326,6 +325,7 @@ void SetupFastFullPelSearch (Macroblock *currMb, short ref, int list) // <-- r if (ChromaMEEnable) { imgpel *auxptr; + int uv; int bsx_c = BLOCK_SIZE >> (chroma_shift_x - 2); int bsy_c = BLOCK_SIZE >> (chroma_shift_y - 2); int pic_pix_x_c = img->opix_x >> (chroma_shift_x - 2); @@ -333,9 +333,9 @@ void SetupFastFullPelSearch (Macroblock *currMb, short ref, int list) // <-- r // copy the original cmp1 and cmp2 data to the orig_pic matrix // This seems to be wrong. - for (k=0; k<2; k++) + for (uv = 1; uv < 3; uv++) { - srcptr = auxptr = orig_pels + (256 << k); + srcptr = auxptr = orig_pels + (256 << (uv - 1)); for ( pixel_y = 0, i = 0; i < (BLOCK_SIZE >> (chroma_shift_y - 2)); i++, pixel_y += bsy_c ) { for ( pixel_x = 0, k = 0; k < (BLOCK_SIZE >> (chroma_shift_x - 2)); k++, pixel_x += bsx_c ) @@ -343,7 +343,7 @@ void SetupFastFullPelSearch (Macroblock *currMb, short ref, int list) // <-- r srcptr = auxptr; for (j = 0; j < bsy_c; j++) { - memcpy( srcptr, &imgUV_org[k][pic_pix_y_c + pixel_y + j][pic_pix_x_c + pixel_x], bsx_c * sizeof(imgpel)); + memcpy( srcptr, &pImgOrg[uv][pic_pix_y_c + pixel_y + j][pic_pix_x_c + pixel_x], bsx_c * sizeof(imgpel)); srcptr += bsx_c; } auxptr += MB_BLOCK_SIZE; @@ -389,7 +389,7 @@ void SetupFastFullPelSearch (Macroblock *currMb, short ref, int list) // <-- r height_pad = ref_picture->size_y_pad; //===== get search center: predictor of 16x16 block ===== - SetMotionVectorPredictor (currMB, pmv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, 0, 0, 16, 16); + SetMotionVectorPredictor (currMB, pmv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, 0, 0, 16, 16); mv[0] = pmv[0] / 4; mv[1] = pmv[1] / 4; @@ -543,7 +543,7 @@ void SetupFastFullPelSearch (Macroblock *currMB, short ref, int list) // <-- r } //===== get search center: predictor of 16x16 block ===== - SetMotionVectorPredictor (currMB, pmv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, 0, 0, 16, 16); + SetMotionVectorPredictor (currMB, pmv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, 0, 0, 16, 16); search_center_x[list][ref] = pmv[0] / 4; search_center_y[list][ref] = pmv[1] / 4; @@ -573,11 +573,11 @@ void SetupFastFullPelSearch (Macroblock *currMB, short ref, int list) // <-- r } if ( ChromaMEEnable) { - for (k = 0; k < 2; k++) + for (k = 1; k < 3; k++) { for (y = img->opix_c_y; y < img->opix_c_y + img->mb_cr_size_y; y++) { - memcpy(srcptr, &imgUV_org[k][y][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(srcptr, &pImgOrg[k][y][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel)); srcptr += img->mb_cr_size_x; } } diff --git a/lencod/src/me_fullsearch.c b/lencod/src/me_fullsearch.c index d260199..ce03a9b 100644 --- a/lencod/src/me_fullsearch.c +++ b/lencod/src/me_fullsearch.c @@ -161,6 +161,7 @@ FullPelBlockMotionBiPred (Macroblock *currMB, // <-- current Macroblock short static_mv[2], // <--> in: search center (x|y) int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) + int iteration_no, // <-- bi pred iteration number int lambda_factor, // <-- lagrangian parameter for determining motion cost int apply_weights // <-- perform weight based ME ) diff --git a/lencod/src/me_umhex.c b/lencod/src/me_umhex.c index 2c72b6a..78a497a 100644 --- a/lencod/src/me_umhex.c +++ b/lencod/src/me_umhex.c @@ -31,6 +31,7 @@ #include "refbuf.h" #include "mb_access.h" #include "image.h" +#include "enc_statistics.h" #include "me_distortion.h" #define Q_BITS 15 @@ -63,15 +64,7 @@ static int Median_Pred_Thd_MB[8]; static int Big_Hexagon_Thd_MB[8]; static int Multi_Ref_Thd_MB[8]; - -static const int quant_coef[6][4][4] = { - {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}}, - {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}}, - {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}}, - {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}}, - {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}}, - {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}} -}; +extern const int quant_coef[6][4][4]; void UMHEX_DefineThreshold() @@ -115,8 +108,8 @@ void UMHEX_DefineThreshold() void UMHEX_DefineThresholdMB() { - int gb_qp_per = (params->qpN-MIN_QP)/6; - int gb_qp_rem = (params->qpN-MIN_QP)%6; + int gb_qp_per = (params->qpN)/6; + int gb_qp_rem = (params->qpN)%6; int gb_q_bits = Q_BITS+gb_qp_per; int gb_qp_const,Thresh4x4; @@ -833,7 +826,7 @@ void UMHEX_setup(short ref, int list, int block_y, int block_x, int blocktype, s int temp_blocktype = 0; int indication_blocktype[8]={0,0,1,1,2,4,4,5}; N_Bframe = params->successive_Bframe; - n_Bframe =(N_Bframe) ? (frame_ctr[B_SLICE]%(N_Bframe+1)): 0; + n_Bframe =(N_Bframe) ? (stats->frame_ctr[B_SLICE]%(N_Bframe+1)): 0; /**************************** MV prediction **********************/ @@ -961,6 +954,7 @@ UMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB, // <-- current short s_mv[2], // <--> in: search center (x|y) / out: motion vector (x|y) - in pel units int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) + int iteration_no, // <-- bi pred iteration number int lambda_factor, // <-- lagrangian parameter for determining motion cost int apply_weights ) @@ -1132,9 +1126,9 @@ UMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB, // <-- current { int N_Bframe=0; int n_Bframe=0; - short****** bipred_mv = list ? img->bipred_mv1 : img->bipred_mv2; + short****** bipred_mv = img->bipred_mv[list]; N_Bframe = params->successive_Bframe; - n_Bframe = frame_ctr[B_SLICE]%(N_Bframe+1); + n_Bframe = stats->frame_ctr[B_SLICE]%(N_Bframe+1); /**************************** MV prediction **********************/ diff --git a/lencod/src/me_umhexsmp.c b/lencod/src/me_umhexsmp.c index f11a9bb..2fec1ad 100644 --- a/lencod/src/me_umhexsmp.c +++ b/lencod/src/me_umhexsmp.c @@ -865,6 +865,7 @@ smpUMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB, // <-- current M short s_mv[2], // <--> in: search center (x|y) int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) + int iteration_no, // <-- bi pred iteration number int lambda_factor, // <-- lagrangian parameter for determining motion cost int apply_weights ) diff --git a/lencod/src/memalloc.c b/lencod/src/memalloc.c index 2507225..3ddd21b 100644 --- a/lencod/src/memalloc.c +++ b/lencod/src/memalloc.c @@ -55,6 +55,326 @@ void free_top_bot_planes(imgpel **imgTopField, imgpel **imgBotField) free (imgBotField); } +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> LambdaParams array2D[rows][columns] + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int get_mem2Dlm(LambdaParams ***array2D, int dim0, int dim1) +{ + int i; + + if((*array2D = (LambdaParams**)calloc(dim0, sizeof(LambdaParams*))) == NULL) + no_mem_exit("get_mem2Dlm: array2D"); + if((*(*array2D) = (LambdaParams* )calloc(dim0 * dim1,sizeof(LambdaParams ))) == NULL) + no_mem_exit("get_mem2Dlm: array2D"); + + for(i = 1 ; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * dim1 * sizeof(LambdaParams); +} + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2Dlm() + ************************************************************************ + */ +void free_mem2Dlm(LambdaParams **array2D) +{ + if (array2D) + { + if (*array2D) + free (*array2D); + else + error ("free_mem2Dlm: trying to free unused memory",100); + + free (array2D); + } + else + { + error ("free_mem2Dlm: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> PicMotionParams2 array2D[rows][columns] + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int get_mem2Dmp(PicMotionParams2 ***array2D, int dim0, int dim1) +{ + int i; + + if((*array2D = (PicMotionParams2**)calloc(dim0, sizeof(PicMotionParams2*))) == NULL) + no_mem_exit("get_mem2Dmv: array2D"); + if((*(*array2D) = (PicMotionParams2* )calloc(dim0 * dim1,sizeof(PicMotionParams2 ))) == NULL) + no_mem_exit("get_mem2Dmp: array2D"); + + for(i = 1 ; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * dim1 * sizeof(PicMotionParams2); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> PicMotionParams2 array3D[frames][rows][columns] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dmp(PicMotionParams2 ****array3D, int dim0, int dim1, int dim2) +{ + int i; + + if(((*array3D) = (PicMotionParams2***)calloc(dim0,sizeof(PicMotionParams2**))) == NULL) + no_mem_exit("get_mem3Dmp: array3D"); + + get_mem2Dmp(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i - 1] + dim1; + + return dim0 * dim1 * dim2 * sizeof(PicMotionParams2); +} + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2Dmp() + ************************************************************************ + */ +void free_mem2Dmp(PicMotionParams2 **array2D) +{ + if (array2D) + { + if (*array2D) + free (*array2D); + else + error ("free_mem2Dmp: trying to free unused memory",100); + + free (array2D); + } + else + { + error ("free_mem2Dmp: trying to free unused memory",100); + } +} + + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was allocated with get_mem3Dmp() + ************************************************************************ + */ +void free_mem3Dmp(PicMotionParams2 ***array3D) +{ + if (array3D) + { + free_mem2Dmp(*array3D); + free (array3D); + } + else + { + error ("free_mem3Dmp: trying to free unused memory",100); + } +} + + + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> MotionVector array2D[rows][columns] + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int get_mem2Dmv(MotionVector ***array2D, int dim0, int dim1) +{ + int i; + + if((*array2D = (MotionVector**)calloc(dim0, sizeof(MotionVector*))) == NULL) + no_mem_exit("get_mem2Dmv: array2D"); + if((*(*array2D) = (MotionVector* )calloc(dim0 * dim1,sizeof(MotionVector ))) == NULL) + no_mem_exit("get_mem2Dmv: array2D"); + + for(i = 1 ; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * dim1 * sizeof(MotionVector); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> MotionVector array3D[frames][rows][columns] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dmv(MotionVector ****array3D, int dim0, int dim1, int dim2) +{ + int i; + + if(((*array3D) = (MotionVector***)calloc(dim0,sizeof(MotionVector**))) == NULL) + no_mem_exit("get_mem3Dmv: array3D"); + + get_mem2Dmv(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i - 1] + dim1; + + return dim0 * dim1 * dim2 * sizeof(MotionVector); +} + +/*! + ************************************************************************ + * \brief + * Allocate 4D memory array -> MotionVector array3D[dim0][dim1][dim2][dim3] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem4Dmv(MotionVector *****array4D, int dim0, int dim1, int dim2, int dim3) +{ + int i; + + if(((*array4D) = (MotionVector****)calloc(dim0,sizeof(MotionVector***))) == NULL) + no_mem_exit("get_mem4Dpel: array4D"); + + get_mem3Dmv(*array4D, dim0 * dim1, dim2, dim3); + + for(i = 1; i < dim0; i++) + (*array4D)[i] = (*array4D)[i - 1] + dim1; + + return dim0 * dim1 * dim2 * dim3 * sizeof(MotionVector); +} + +/*! + ************************************************************************ + * \brief + * Allocate 5D memory array -> MotionVector array3D[dim0][dim1][dim2][dim3][dim4] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem5Dmv(MotionVector ******array5D, int dim0, int dim1, int dim2, int dim3, int dim4) +{ + int i; + + if(((*array5D) = (MotionVector*****)calloc(dim0,sizeof(MotionVector****))) == NULL) + no_mem_exit("get_mem5Dpel: array5D"); + + get_mem4Dmv(*array5D, dim0 * dim1, dim2, dim3, dim4); + + for(i = 1; i < dim0; i++) + (*array5D)[i] = (*array5D)[i - 1] + dim1; + + return dim0 * dim1 * dim2 * dim3 * dim4 * sizeof(MotionVector); +} + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2Dmv() + ************************************************************************ + */ +void free_mem2Dmv(MotionVector **array2D) +{ + if (array2D) + { + if (*array2D) + free (*array2D); + else + error ("free_mem2Dmv: trying to free unused memory",100); + + free (array2D); + } + else + { + error ("free_mem2Dmv: trying to free unused memory",100); + } +} + + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was allocated with get_mem3Dmv() + ************************************************************************ + */ +void free_mem3Dmv(MotionVector ***array3D) +{ + if (array3D) + { + free_mem2Dmv(*array3D); + free (array3D); + } + else + { + error ("free_mem3Dmv: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * free 4D memory array + * which was allocated with get_mem4Dmv() + ************************************************************************ + */ +void free_mem4Dmv(MotionVector ****array4D) +{ + if (array4D) + { + free_mem3Dmv(*array4D); + free (array4D); + } + else + { + error ("free_mem4Dmv: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * free 5D memory array + * which was allocated with get_mem5Dmv() + ************************************************************************ + */ +void free_mem5Dmv(MotionVector *****array5D) +{ + if (array5D) + { + free_mem4Dmv(*array5D); + free (array5D); + } + else + { + error ("free_mem5Dmv: trying to free unused memory",100); + } +} /*! ************************************************************************ @@ -164,7 +484,8 @@ void free_mem2Dpel(imgpel **array2D) { if (*array2D) free (*array2D); - else error ("free_mem2Dpel: trying to free unused memory",100); + else + error ("free_mem2Dpel: trying to free unused memory",100); free (array2D); } @@ -914,14 +1235,14 @@ int get_mem2Ddouble(double ***array2D, int rows, int columns) * memory size in bytes ************************************************************************ */ -int get_mem2Ddb_offset(double ***array2D, int rows, int columns, int offset) +int get_mem2Dodouble(double ***array2D, int rows, int columns, int offset) { int i; if((*array2D = (double**)calloc(rows, sizeof(double*))) == NULL) - no_mem_exit("get_mem2Ddb_offset: array2D"); + no_mem_exit("get_mem2Dodouble: array2D"); if(((*array2D)[0] = (double* )calloc(rows*columns,sizeof(double ))) == NULL) - no_mem_exit("get_mem2Ddb_offset: array2D"); + no_mem_exit("get_mem2Dodouble: array2D"); (*array2D)[0] += offset; @@ -940,15 +1261,15 @@ int get_mem2Ddb_offset(double ***array2D, int rows, int columns, int offset) * memory size in bytes ************************************************************************ */ -int get_mem3Ddb_offset(double ****array3D, int rows, int columns, int pels, int offset) +int get_mem3Dodouble(double ****array3D, int rows, int columns, int pels, int offset) { int i,j; if(((*array3D) = (double***)calloc(rows,sizeof(double**))) == NULL) - no_mem_exit("get_mem3Ddb_offset: array3D"); + no_mem_exit("get_mem3Dodouble: array3D"); if(((*array3D)[0] = (double** )calloc(rows*columns,sizeof(double*))) == NULL) - no_mem_exit("get_mem3Ddb_offset: array3D"); + no_mem_exit("get_mem3Dodouble: array3D"); (*array3D) [0] += offset; @@ -958,7 +1279,7 @@ int get_mem3Ddb_offset(double ****array3D, int rows, int columns, int pels, int for (i = 0; i < rows; i++) for (j = -offset; j < columns - offset; j++) if(((*array3D)[i][j] = (double* )calloc(pels,sizeof(double))) == NULL) - no_mem_exit("get_mem3Ddb_offset: array3D"); + no_mem_exit("get_mem3Dodouble: array3D"); return rows*columns*pels*sizeof(double); } @@ -1005,15 +1326,15 @@ int get_offset_mem2Dshort(short ***array2D, int rows, int columns, int offset_y, * memory size in bytes ************************************************************************ */ -int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int offset) +int get_mem3Doint(int ****array3D, int rows, int columns, int pels, int offset) { int i,j; if(((*array3D) = (int***)calloc(rows,sizeof(int**))) == NULL) - no_mem_exit("get_mem3Dint_offset: array3D"); + no_mem_exit("get_mem3Doint: array3D"); if(((*array3D)[0] = (int** )calloc(rows*columns,sizeof(int*))) == NULL) - no_mem_exit("get_mem3Dint_offset: array3D"); + no_mem_exit("get_mem3Doint: array3D"); (*array3D) [0] += offset; @@ -1023,7 +1344,7 @@ int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int of for (i = 0; i < rows; i++) for (j = -offset; j < columns - offset; j++) if(((*array3D)[i][j] = (int* )calloc(pels,sizeof(int))) == NULL) - no_mem_exit("get_mem3Dint_offset: array3D"); + no_mem_exit("get_mem3Doint: array3D"); return rows*columns*pels*sizeof(int); } @@ -1038,7 +1359,7 @@ int get_mem3Dint_offset(int ****array3D, int rows, int columns, int pels, int of * memory size in bytes ************************************************************************ */ -int get_mem2Dint_offset(int ***array2D, int rows, int columns, int offset) +int get_mem2Doint(int ***array2D, int rows, int columns, int offset) { int i; @@ -1118,20 +1439,20 @@ void free_mem2Ddouble(double **array2D) * which was allocated with get_mem2Ddouble() ************************************************************************ */ -void free_mem2Ddb_offset(double **array2D, int offset) +void free_mem2Dodouble(double **array2D, int offset) { if (array2D) { array2D[0] -= offset; if (array2D[0]) free (array2D[0]); - else error ("free_mem2Ddb_offset: trying to free unused memory",100); + else error ("free_mem2Dodouble: trying to free unused memory",100); free (array2D); } else { - error ("free_mem2Ddb_offset: trying to free unused memory",100); + error ("free_mem2Dodouble: trying to free unused memory",100); } } @@ -1141,7 +1462,7 @@ void free_mem2Ddb_offset(double **array2D, int offset) * free 3D memory array with offset ************************************************************************ */ -void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset) +void free_mem3Dodouble(double ***array3D, int rows, int columns, int offset) { int i, j; @@ -1154,19 +1475,19 @@ void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset) if (array3D[i][j]) free(array3D[i][j]); else - error ("free_mem3Ddb_offset: trying to free unused memory",100); + error ("free_mem3Dodouble: trying to free unused memory",100); } } array3D[0] -= offset; if (array3D[0]) free(array3D[0]); else - error ("free_mem3Ddb_offset: trying to free unused memory",100); + error ("free_mem3Dodouble: trying to free unused memory",100); free (array3D); } else { - error ("free_mem3Ddb_offset: trying to free unused memory",100); + error ("free_mem3Dodouble: trying to free unused memory",100); } } @@ -1176,7 +1497,7 @@ void free_mem3Ddb_offset(double ***array3D, int rows, int columns, int offset) * free 3D memory array with offset ************************************************************************ */ -void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset) +void free_mem3Doint(int ***array3D, int rows, int columns, int offset) { int i, j; @@ -1189,19 +1510,19 @@ void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset) if (array3D[i][j]) free(array3D[i][j]); else - error ("free_mem3Dint_offset: trying to free unused memory",100); + error ("free_mem3Doint: trying to free unused memory",100); } } array3D[0] -= offset; if (array3D[0]) free(array3D[0]); else - error ("free_mem3Dint_offset: trying to free unused memory",100); + error ("free_mem3Doint: trying to free unused memory",100); free (array3D); } else { - error ("free_mem3Dint_offset: trying to free unused memory",100); + error ("free_mem3Doint: trying to free unused memory",100); } } @@ -1213,7 +1534,7 @@ void free_mem3Dint_offset(int ***array3D, int rows, int columns, int offset) * which was allocated with get_mem2Ddouble() ************************************************************************ */ -void free_mem2Dint_offset(int **array2D, int offset) +void free_mem2Doint(int **array2D, int offset) { if (array2D) { @@ -1221,14 +1542,14 @@ void free_mem2Dint_offset(int **array2D, int offset) if (array2D[0]) free (array2D[0]); else - error ("free_mem2Dint_offset: trying to free unused memory",100); + error ("free_mem2Doint: trying to free unused memory",100); free (array2D); } else { - error ("free_mem2Dint_offset: trying to free unused memory",100); + error ("free_mem2Doint: trying to free unused memory",100); } } @@ -1278,3 +1599,58 @@ void free_mem3Ddouble(double ***array3D) } } + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> LambdaParams array2D[rows][columns] + * Note that array is shifted towards offset allowing negative values + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Dolm(LambdaParams ***array2D, int rows, int columns, int offset) +{ + int i; + + if((*array2D = (LambdaParams**) calloc(rows, sizeof(LambdaParams*))) == NULL) + no_mem_exit("get_mem2Dolm: array2D"); + if(((*array2D)[0] = (LambdaParams* ) calloc(rows*columns,sizeof(LambdaParams))) == NULL) + no_mem_exit("get_mem2Dolm: array2D"); + + (*array2D)[0] += offset; + + for(i=1 ; i<rows ; i++) + (*array2D)[i] = (*array2D)[i-1] + columns ; + + return rows*columns*sizeof(LambdaParams); +} + + +/*! +************************************************************************ +* \brief +* free 2D LambdaParams memory array (with offset) +* which was allocated with get_mem2Dlm() +************************************************************************ +*/ +void free_mem2Dolm(LambdaParams **array2D, int offset) +{ + if (array2D) + { + array2D[0] -= offset; + if (array2D[0]) + free (array2D[0]); + else + error ("free_mem2Dolm: trying to free unused memory",100); + + free (array2D); + + } + else + { + error ("free_mem2Dolm: trying to free unused memory",100); + } +} + diff --git a/lencod/src/mode_decision.c b/lencod/src/mode_decision.c index 62f46b7..6321f2c 100644 --- a/lencod/src/mode_decision.c +++ b/lencod/src/mode_decision.c @@ -26,6 +26,7 @@ #include "me_umhexsmp.h" #include "macroblock.h" #include "rdo_quant.h" +#include "errdo.h" //==== MODULE PARAMETERS ==== @@ -54,7 +55,6 @@ void reset_valid_modes(RD_PARAMS *enc_mb) */ void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bslice) { - int mode; int l,k; //Setup list offset @@ -62,9 +62,9 @@ void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bs enc_mb->list_offset[LIST_1] = LIST_1 + currMB->list_offset; enc_mb->curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field)); - + // Set valid modes - enc_mb->valid[I8MB] = (!params->DisableIntraInInter || intra )? params->Transform8x8Mode : 0; + enc_mb->valid[I8MB] = (!params->DisableIntraInInter || intra )? params->Transform8x8Mode : 0; enc_mb->valid[I4MB] = (!params->DisableIntraInInter || intra )? ((params->Transform8x8Mode == 2) ? 0 : 1) : 0; enc_mb->valid[I4MB] = (!params->DisableIntra4x4 ) ? enc_mb->valid[I4MB] : 0; enc_mb->valid[I16MB] = (!params->DisableIntraInInter || intra )? 1 : 0; @@ -81,7 +81,7 @@ void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bs enc_mb->valid[7] = (!intra && params->InterSearch[bslice][7] && !(params->Transform8x8Mode==2)); enc_mb->valid[P8x8] = (enc_mb->valid[4] || enc_mb->valid[5] || enc_mb->valid[6] || enc_mb->valid[7]); enc_mb->valid[12] = (img->type == SI_SLICE); - + if (params->UseRDOQuant && params->RDOQ_CP_Mode && (img->qp != img->masterQP) ) RDOQ_update_mode(enc_mb, bslice); @@ -122,63 +122,28 @@ void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bs // computations and cleanup code. if (bslice && img->nal_reference_idc) { - enc_mb->lambda_md = img->lambda_md[5][img->qp]; + enc_mb->lambda_md = img->lambda_md[5][img->masterQP]; - enc_mb->lambda_me[F_PEL] = img->lambda_me[5][img->qp][F_PEL]; - enc_mb->lambda_me[H_PEL] = img->lambda_me[5][img->qp][H_PEL]; - enc_mb->lambda_me[Q_PEL] = img->lambda_me[5][img->qp][Q_PEL]; - - enc_mb->lambda_mf[F_PEL] = img->lambda_mf[5][img->qp][F_PEL]; - enc_mb->lambda_mf[H_PEL] = img->lambda_mf[5][img->qp][H_PEL]; - enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[5][img->qp][Q_PEL]; + enc_mb->lambda_me[F_PEL] = img->lambda_me[5][img->masterQP][F_PEL]; + enc_mb->lambda_me[H_PEL] = img->lambda_me[5][img->masterQP][H_PEL]; + enc_mb->lambda_me[Q_PEL] = img->lambda_me[5][img->masterQP][Q_PEL]; + enc_mb->lambda_mf[F_PEL] = img->lambda_mf[5][img->masterQP][F_PEL]; + enc_mb->lambda_mf[H_PEL] = img->lambda_mf[5][img->masterQP][H_PEL]; + enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[5][img->masterQP][Q_PEL]; } else { - enc_mb->lambda_md = img->lambda_md[img->type][img->qp]; - - enc_mb->lambda_me[F_PEL] = img->lambda_me[img->type][img->qp][F_PEL]; - enc_mb->lambda_me[H_PEL] = img->lambda_me[img->type][img->qp][H_PEL]; - enc_mb->lambda_me[Q_PEL] = img->lambda_me[img->type][img->qp][Q_PEL]; - - enc_mb->lambda_mf[F_PEL] = img->lambda_mf[img->type][img->qp][F_PEL]; - enc_mb->lambda_mf[H_PEL] = img->lambda_mf[img->type][img->qp][H_PEL]; - enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[img->type][img->qp][Q_PEL]; + enc_mb->lambda_md = img->lambda_md[img->type][img->masterQP]; + enc_mb->lambda_me[F_PEL] = img->lambda_me[img->type][img->masterQP][F_PEL]; + enc_mb->lambda_me[H_PEL] = img->lambda_me[img->type][img->masterQP][H_PEL]; + enc_mb->lambda_me[Q_PEL] = img->lambda_me[img->type][img->masterQP][Q_PEL]; + + enc_mb->lambda_mf[F_PEL] = img->lambda_mf[img->type][img->masterQP][F_PEL]; + enc_mb->lambda_mf[H_PEL] = img->lambda_mf[img->type][img->masterQP][H_PEL]; + enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[img->type][img->masterQP][Q_PEL]; } - - if (params->UseRDOQuant) - { - if (bslice && img->nal_reference_idc) - { - enc_mb->lambda_md = img->lambda_md[5][img->masterQP]; - - enc_mb->lambda_me[F_PEL] = img->lambda_me[5][img->masterQP][F_PEL]; - enc_mb->lambda_me[H_PEL] = img->lambda_me[5][img->masterQP][H_PEL]; - enc_mb->lambda_me[Q_PEL] = img->lambda_me[5][img->masterQP][Q_PEL]; - - enc_mb->lambda_mf[F_PEL] = img->lambda_mf[5][img->masterQP][F_PEL]; - enc_mb->lambda_mf[H_PEL] = img->lambda_mf[5][img->masterQP][H_PEL]; - enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[5][img->masterQP][Q_PEL]; - } - else - { - enc_mb->lambda_md = img->lambda_md[img->type][img->masterQP]; - enc_mb->lambda_me[F_PEL] = img->lambda_me[img->type][img->masterQP][F_PEL]; - enc_mb->lambda_me[H_PEL] = img->lambda_me[img->type][img->masterQP][H_PEL]; - enc_mb->lambda_me[Q_PEL] = img->lambda_me[img->type][img->masterQP][Q_PEL]; - - enc_mb->lambda_mf[F_PEL] = img->lambda_mf[img->type][img->masterQP][F_PEL]; - enc_mb->lambda_mf[H_PEL] = img->lambda_mf[img->type][img->masterQP][H_PEL]; - enc_mb->lambda_mf[Q_PEL] = img->lambda_mf[img->type][img->masterQP][Q_PEL]; - } - } - - // Initialize bipredME decisions - for (mode=0; mode<MAXMODE; mode++) - { - img->bi_pred_me[mode]=0; - } - + if (!img->MbaffFrameFlag) { for (l = LIST_0; l < BI_PRED; l++) @@ -232,11 +197,11 @@ void init_enc_mb_params(Macroblock* currMB, RD_PARAMS *enc_mb, int intra, int bs * computation of prediction list (including biprediction) cost ************************************************************************************* */ -void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_PARAMS enc_mb, int bmcost[5], char best_ref[2]) +void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_PARAMS *enc_mb, int bmcost[5], char best_ref[2]) { short ref; int mcost; - int cur_list = list < BI_PRED ? enc_mb.list_offset[list] : enc_mb.list_offset[LIST_0]; + int cur_list = list < BI_PRED ? enc_mb->list_offset[list] : enc_mb->list_offset[LIST_0]; //--- get cost and reference frame for forward prediction --- @@ -252,8 +217,8 @@ void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_ ((params->sp2_frame_indicator || params->sp_output_indicator) && ((img->type == P_SLICE || img->type == SP_SLICE) &&(ref==0)))) { mcost = (params->rdopt - ? REF_COST (enc_mb.lambda_mf[Q_PEL], ref, cur_list) - : (int) (2 * enc_mb.lambda_me[Q_PEL] * imin(ref, 1))); + ? REF_COST (enc_mb->lambda_mf[Q_PEL], ref, cur_list) + : (int) (2 * enc_mb->lambda_me[Q_PEL] * imin(ref, 1))); mcost += motion_cost[mode][list][ref][block]; if (mcost < bmcost[list]) @@ -278,34 +243,34 @@ void list_prediction_cost(Macroblock *currMB, int list, int block, int mode, RD_ else { bmcost[list] = (params->rdopt - ? (REF_COST (enc_mb.lambda_mf[Q_PEL], (short)best_ref[LIST_0], cur_list) - + REF_COST (enc_mb.lambda_mf[Q_PEL], (short)best_ref[LIST_1], cur_list + LIST_1)) - : (int) (2 * (enc_mb.lambda_me[Q_PEL] * (imin((short)best_ref[LIST_0], 1) + imin((short)best_ref[LIST_1], 1))))); - bmcost[list] += BIDPartitionCost (currMB, mode, block, best_ref, enc_mb.lambda_mf[Q_PEL]); + ? (REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_0], cur_list) + + REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_1], cur_list + LIST_1)) + : (int) (2 * (enc_mb->lambda_me[Q_PEL] * (imin((short)best_ref[LIST_0], 1) + imin((short)best_ref[LIST_1], 1))))); + bmcost[list] += BIDPartitionCost (currMB, mode, block, best_ref, enc_mb->lambda_mf[Q_PEL]); } } else { bmcost[list] = (params->rdopt - ? (REF_COST (enc_mb.lambda_mf[Q_PEL], (short)best_ref[LIST_0], cur_list) - + REF_COST (enc_mb.lambda_mf[Q_PEL], (short)best_ref[LIST_1], cur_list + LIST_1)) - : (int) (2 * (enc_mb.lambda_me[Q_PEL] * (imin((short)best_ref[LIST_0], 1) + imin((short)best_ref[LIST_1], 1))))); - bmcost[list] += BIDPartitionCost (currMB, mode, block, best_ref, enc_mb.lambda_mf[Q_PEL]); + ? (REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_0], cur_list) + + REF_COST (enc_mb->lambda_mf[Q_PEL], (short)best_ref[LIST_1], cur_list + LIST_1)) + : (int) (2 * (enc_mb->lambda_me[Q_PEL] * (imin((short)best_ref[LIST_0], 1) + imin((short)best_ref[LIST_1], 1))))); + bmcost[list] += BIDPartitionCost (currMB, mode, block, best_ref, enc_mb->lambda_mf[Q_PEL]); } } else { bmcost[list] = (params->rdopt - ? (REF_COST (enc_mb.lambda_mf[Q_PEL], 0, cur_list) - + REF_COST (enc_mb.lambda_mf[Q_PEL], 0, cur_list + LIST_1)) - : (int) (4 * enc_mb.lambda_me[Q_PEL])); - bmcost[list] += BPredPartitionCost(currMB, mode, block, 0, 0, enc_mb.lambda_mf[Q_PEL], !(list&1)); + ? (REF_COST (enc_mb->lambda_mf[Q_PEL], 0, cur_list) + + REF_COST (enc_mb->lambda_mf[Q_PEL], 0, cur_list + LIST_1)) + : (int) (4 * enc_mb->lambda_me[Q_PEL])); + bmcost[list] += BPredPartitionCost(currMB, mode, block, 0, 0, enc_mb->lambda_mf[Q_PEL], !(list&1)); } } -int compute_ref_cost(RD_PARAMS enc_mb, int ref, int list) +int compute_ref_cost(RD_PARAMS *enc_mb, int ref, int list) { - return WEIGHTED_COST(enc_mb.lambda_mf[Q_PEL],((listXsize[enc_mb.list_offset[list]] <= 1)? 0:refbits[ref])); + return WEIGHTED_COST(enc_mb->lambda_mf[Q_PEL],((listXsize[enc_mb->list_offset[list]] <= 1)? 0:refbits[ref])); } /*! @@ -314,82 +279,23 @@ int compute_ref_cost(RD_PARAMS enc_mb, int ref, int list) * Determination of prediction list based on simple distortion computation ************************************************************************************* */ -void determine_prediction_list(int mode, int bmcost[5], char best_ref[2], char *best_pdir, int *cost, short *bi_pred_me) +void determine_prediction_list(int mode, int bmcost[5], char best_ref[2], char *best_pdir, int *cost, short *bipred_me) { - if ((!params->BiPredMotionEstimation) || (mode != 1)) + int bestlist; + + *cost += iminarray ( bmcost, 5, &bestlist); + + if (bestlist <= BI_PRED) //LIST_0, LIST_1 & BI_DIR { - //--- get prediction direction ---- - if (bmcost[LIST_0] <= bmcost[LIST_1] - && bmcost[LIST_0] <= bmcost[BI_PRED]) - { - *best_pdir = 0; - *cost += bmcost[LIST_0]; - } - else if (bmcost[LIST_1] <= bmcost[LIST_0] - && bmcost[LIST_1] <= bmcost[BI_PRED]) - { - *best_pdir = 1; - *cost += bmcost[LIST_1]; - } - else - { - *best_pdir = 2; - *cost += bmcost[BI_PRED]; - } + *best_pdir = bestlist; + *bipred_me = 0; } - else + else //BI_PRED_L0 & BI_PRED_L1 { - img->bi_pred_me[mode]=0; - *bi_pred_me = 0; - //--- get prediction direction ---- - if (bmcost[LIST_0] <= bmcost[LIST_1] - && bmcost[LIST_0] <= bmcost[BI_PRED] - && bmcost[LIST_0] <= bmcost[BI_PRED_L0] - && bmcost[LIST_0] <= bmcost[BI_PRED_L1]) - { - *best_pdir = 0; - *cost += bmcost[LIST_0]; - //best_ref[LIST_1] = 0; - } - else if (bmcost[LIST_1] <= bmcost[LIST_0] - && bmcost[LIST_1] <= bmcost[BI_PRED] - && bmcost[LIST_1] <= bmcost[BI_PRED_L0] - && bmcost[LIST_1] <= bmcost[BI_PRED_L1]) - { - *best_pdir = 1; - *cost += bmcost[LIST_1]; - //best_ref[LIST_0] = 0; - } - else if (bmcost[BI_PRED] <= bmcost[LIST_0] - && bmcost[BI_PRED] <= bmcost[LIST_1] - && bmcost[BI_PRED] <= bmcost[BI_PRED_L0] - && bmcost[BI_PRED] <= bmcost[BI_PRED_L1]) - { - *best_pdir = 2; - *cost += bmcost[BI_PRED]; - //best_ref[LIST_1] = 0; - } - else if (bmcost[BI_PRED_L0] <= bmcost[LIST_0] - && bmcost[BI_PRED_L0] <= bmcost[LIST_1] - && bmcost[BI_PRED_L0] <= bmcost[BI_PRED] - && bmcost[BI_PRED_L0] <= bmcost[BI_PRED_L1]) - { - *best_pdir = 2; - *cost += bmcost[BI_PRED_L0]; - *bi_pred_me = 1; - img->bi_pred_me[mode]=1; - best_ref[LIST_1] = 0; - best_ref[LIST_0] = 0; - } - else - { - *best_pdir = 2; - *cost += bmcost[BI_PRED_L1]; - *bi_pred_me = 2; - best_ref[LIST_1] = 0; - best_ref[LIST_0] = 0; - img->bi_pred_me[mode]=2; - } + *best_pdir = 2; + *bipred_me = bestlist - 2; + best_ref[LIST_1] = 0; + best_ref[LIST_0] = 0; } } @@ -401,7 +307,7 @@ void determine_prediction_list(int mode, int bmcost[5], char best_ref[2], char * */ void compute_mode_RD_cost(int mode, Macroblock *currMB, - RD_PARAMS enc_mb, + RD_PARAMS *enc_mb, double *min_rdcost, double *min_dcost, double *min_rate, @@ -413,7 +319,7 @@ void compute_mode_RD_cost(int mode, currMB->luma_transform_size_8x8_flag = params->Transform8x8Mode==2 ? (mode >= 1 && mode <= 3) || (mode == 0 && bslice && active_sps->direct_8x8_inference_flag) - || ((mode == P8x8) && (enc_mb.valid[4])) + || ((mode == P8x8) && (enc_mb->valid[4])) : 0; //store_coding_state (currMB, cs_cm); // RD SetModesAndRefframeForBlocks (currMB, mode); @@ -426,13 +332,13 @@ void compute_mode_RD_cost(int mode, { while(1) { - if (RDCost_for_macroblocks (currMB, enc_mb.lambda_md, mode, min_rdcost, min_dcost, min_rate, i16mode)) + if (RDCost_for_macroblocks (currMB, enc_mb->lambda_md, mode, min_rdcost, min_dcost, min_rate, i16mode)) { //Rate control if (params->RCEnable) { if(mode == P8x8) - rc_store_diff(img->opix_x,img->opix_y, currMB->luma_transform_size_8x8_flag == 1 ? tr8x8.mpr8x8 : tr4x4.mpr8x8); + rc_store_diff(img->opix_x, img->opix_y, currMB->luma_transform_size_8x8_flag == 1 ? tr8x8.mpr8x8 : tr4x4.mpr8x8); else rc_store_diff(img->opix_x, img->opix_y, pred); } @@ -468,7 +374,7 @@ void compute_mode_RD_cost(int mode, continue; } //=========== try mb_type P8x8 for mode 4 with 4x4/8x8 transform =========== - else if ((mode == P8x8) && (enc_mb.valid[4]) && (currMB->luma_transform_size_8x8_flag == 0)) + else if ((mode == P8x8) && (enc_mb->valid[4]) && (currMB->luma_transform_size_8x8_flag == 0)) { currMB->luma_transform_size_8x8_flag = 1; //check 8x8 partition for transform size 8x8 continue; @@ -484,14 +390,14 @@ void compute_mode_RD_cost(int mode, } // Encode with no coefficients. Currently only for direct. This could be extended to all other modes as in example. - //if (mode < P8x8 && (*inter_skip == 0) && enc_mb.valid[mode] && currMB->cbp && (currMB->cbp&15) != 15 && !params->nobskip) - if ( bslice && mode == 0 && (*inter_skip == 0) && enc_mb.valid[mode] + //if (mode < P8x8 && (*inter_skip == 0) && enc_mb->valid[mode] && currMB->cbp && (currMB->cbp&15) != 15 && !params->nobskip) + if ( bslice && mode == 0 && (*inter_skip == 0) && enc_mb->valid[mode] && currMB->cbp && (currMB->cbp&15) != 15 && !params->nobskip && !(currMB->qp_scaled[0] == 0 && img->lossless_qpprime_flag==1) ) { img->NoResidueDirect = 1; - if (RDCost_for_macroblocks (currMB, enc_mb.lambda_md, mode, min_rdcost, min_dcost, min_rate, i16mode)) + if (RDCost_for_macroblocks (currMB, enc_mb->lambda_md, mode, min_rdcost, min_dcost, min_rate, i16mode)) { //Rate control if (params->RCEnable) @@ -510,7 +416,7 @@ void compute_mode_RD_cost(int mode, * Mode Decision for an 8x8 sub-macroblock ************************************************************************************* */ -void submacroblock_mode_decision(RD_PARAMS enc_mb, +void submacroblock_mode_decision(RD_PARAMS *enc_mb, RD_8x8DATA *dataTr, Macroblock *currMB, int ***cofACtr, @@ -544,12 +450,13 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, ? (transform8x8 ? img->fadjust8x8Cr : img->fadjust4x4Cr): NULL; int lumaAdjustIndex = transform8x8 ? 2 : 3; int chromaAdjustIndex = transform8x8 ? 0 : 2; - short pdir; - short bi_pred_me; + short pdir, bipred_me = 0; + char best_pdir = 0; char best_ref[2] = {0, -1}; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; + #ifdef BEST_NZ_COEFF int best_nz_coeff[2][2]; #endif @@ -575,11 +482,11 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, store_coding_state (currMB, cs_cm); //===== LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION ===== - for (min_cost8x8 = INT_MAX, min_rdcost = 1e30, index = (bslice?0:1); index < maxindex; index++) + for (min_cost8x8 = INT_MAX, min_rdcost = 1e20, index = (bslice?0:1); index < maxindex; index++) { mode = b8_mode_table[index]; *cost = 0; - if (enc_mb.valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag))) + if (enc_mb->valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag))) { curr_cbp_blk = 0; @@ -611,7 +518,7 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, switch(params->Transform8x8Mode) { case 1: // Mixture of 8x8 & 4x4 transform - if((direct8x8_tmp < direct4x4_tmp) || !(enc_mb.valid[5] && enc_mb.valid[6] && enc_mb.valid[7])) + if((direct8x8_tmp < direct4x4_tmp) || !(enc_mb->valid[5] && enc_mb->valid[6] && enc_mb->valid[7])) *cost = direct8x8_tmp; else *cost = direct4x4_tmp; @@ -644,7 +551,7 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, char b_ref; //======= motion estimation for all reference frames ======== //----------------------------------------------------------- - memcpy(lambda_mf, enc_mb.lambda_mf, 3 * sizeof(int)); + memcpy(lambda_mf, enc_mb->lambda_mf, 3 * sizeof(int)); if (params->CtxAdptLagrangeMult == 1) { lambda_mf[F_PEL] = (int)(lambda_mf[F_PEL] * lambda_mf_factor); @@ -662,22 +569,21 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, block_x = img->block_x + (block & 0x01)*2; block_y = img->block_y + (block & 0x02); b_ref = best_ref[LIST_0]; - ref_pic_num = enc_picture->ref_pic_num[enc_mb.list_offset[LIST_0]][(short) b_ref]; + ref_pic_num = enc_picture->ref_pic_num[enc_mb->list_offset[LIST_0]][(short) b_ref]; for (j = block_y; j< block_y + 2; j++) { - memset(&enc_picture->ref_idx [LIST_0][j][block_x], b_ref, 2 * sizeof(char)); + memset(&enc_picture->motion.ref_idx [LIST_0][j][block_x], b_ref, 2 * sizeof(char)); } for (j = block_y; j< block_y + 2; j++) { for (i = block_x; i < block_x + 2; i++) { - enc_picture->ref_pic_id[LIST_0][j][i] = ref_pic_num; + enc_picture->motion.ref_pic_id[LIST_0][j][i] = ref_pic_num; } } - if (bslice) { //--- get cost and reference frame for LIST 1 prediction --- @@ -687,16 +593,28 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, // Compute bipredictive cost between best list 0 and best list 1 references list_prediction_cost(currMB, BI_PRED, block, mode, enc_mb, bmcost, best_ref); + + // currently Bi prediction ME is only supported for modes 1, 2, 3 and only for ref 0 and only for ref 0 + if (is_bipred_enabled(mode)) + { + list_prediction_cost(currMB, BI_PRED_L0, block, mode, enc_mb, bmcost, 0); + list_prediction_cost(currMB, BI_PRED_L1, block, mode, enc_mb, bmcost, 0); + } + else + { + bmcost[BI_PRED_L0] = INT_MAX; + bmcost[BI_PRED_L1] = INT_MAX; + } //--- get prediction direction ---- - determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bi_pred_me); - + determine_prediction_list(mode, bmcost, best_ref, &best_pdir, cost, &bipred_me); + //store backward reference index for every block for (k = LIST_0; k <= LIST_1; k++) { for (j = block_y; j< block_y + 2; j++) { - memset(&enc_picture->ref_idx[k][j][block_x], best_ref[k], 2 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[k][j][block_x], best_ref[k], 2 * sizeof(char)); } } } // if (bslice) @@ -710,25 +628,26 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, if (params->rdopt) { //--- get and check rate-distortion cost --- - rdcost = RDCost_for_8x8blocks (currMB, &cnt_nonz, &curr_cbp_blk, enc_mb.lambda_md, - block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1]); + rdcost = RDCost_for_8x8blocks (currMB, &cnt_nonz, &curr_cbp_blk, enc_mb->lambda_md, + block, mode, best_pdir, best_ref[LIST_0], best_ref[LIST_1], bipred_me); } else { if (*cost!=INT_MAX) - *cost += (REF_COST (enc_mb.lambda_mf[Q_PEL], B8Mode2Value (mode, best_pdir), - enc_mb.list_offset[(best_pdir < 1 ? LIST_0 : LIST_1)]) - 1); + *cost += (REF_COST (enc_mb->lambda_mf[Q_PEL], B8Mode2Value (mode, best_pdir), + enc_mb->list_offset[(best_pdir < 1 ? LIST_0 : LIST_1)]) - 1); } //--- set variables if best mode has changed --- if ( ( params->rdopt && rdcost < min_rdcost) || (!params->rdopt && *cost < min_cost8x8)) { - min_cost8x8 = *cost; - min_rdcost = rdcost; - dataTr->part8x8mode [block] = mode; - dataTr->part8x8pdir [block] = best_pdir; - dataTr->part8x8l0ref[block] = best_ref[LIST_0]; - dataTr->part8x8l1ref[block] = best_ref[LIST_1]; + min_cost8x8 = *cost; + min_rdcost = rdcost; + dataTr->part8x8mode [block] = mode; + dataTr->part8x8pdir [block] = best_pdir; + dataTr->part8x8l0ref [block] = best_ref[LIST_0]; + dataTr->part8x8l1ref [block] = best_ref[LIST_1]; + dataTr->part8x8bipred[block] = bipred_me; currMB->b8mode[block] = mode; @@ -774,7 +693,12 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, for (j=j0; j<j0 + BLOCK_SIZE_8x8; j++) { memcpy(&dataTr->rec_mbY8x8[j][i0],&enc_picture->imgY[img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); - memcpy(&dataTr->mpr8x8[j][i0],&curr_mpr[j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); + memcpy(&dataTr->mpr8x8[j][i0],&mb_pred[j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); + } + + if (params->rdopt == 3) + { + errdo_store_best_block(img, decs->dec_mbY8x8, enc_picture->p_dec_img[0], i0, j0, BLOCK_SIZE_8x8); //Store best 8x8 block for each hypothetical decoder } if(img->type==SP_SLICE && (!si_frame_indicator)) @@ -784,14 +708,15 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, memcpy(&dataTr->lrec[j][i0],&lrec[img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(int)); } } + if(img->P444_joined) { for (j=j0; j<j0+8; j++) { memcpy(&dataTr->rec_mb8x8_cr[0][j][i0],&enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); memcpy(&dataTr->rec_mb8x8_cr[1][j][i0],&enc_picture->imgUV[1][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); - memcpy(&dataTr->mpr8x8CbCr[0][j][i0],&img->mpr[1][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); - memcpy(&dataTr->mpr8x8CbCr[1][j][i0],&img->mpr[2][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); + memcpy(&dataTr->mpr8x8CbCr[0][j][i0],&img->mb_pred[1][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); + memcpy(&dataTr->mpr8x8CbCr[1][j][i0],&img->mb_pred[2][j][i0], BLOCK_SIZE_8x8 * sizeof(imgpel)); } } @@ -823,7 +748,7 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, //--- re-set coding state as it was before coding with current mode was performed --- reset_coding_state (currMB, cs_cm); - } // if ((enc_mb.valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag))) + } // if ((enc_mb->valid[mode] && (transform8x8 == 0 || mode != 0 || (mode == 0 && active_sps->direct_8x8_inference_flag))) } // for (min_rdcost=1e30, index=(bslice?0:1); index<6; index++) #ifdef BEST_NZ_COEFF @@ -835,13 +760,13 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, #endif if (!transform8x8) - dataTr->cost8x8 += min_cost8x8; + dataTr->mb_p8x8_cost += min_cost8x8; if (!params->rdopt) { if (transform8x8) { - dataTr->cost8x8 += min_cost8x8; + dataTr->mb_p8x8_cost += min_cost8x8; mode = dataTr->part8x8mode[block]; pdir = dataTr->part8x8pdir[block]; } @@ -852,8 +777,10 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, } curr_cbp_blk = 0; + currMB->bipred_me[block] = dataTr->part8x8bipred[block]; best_cnt_nonz = LumaResidualCoding8x8 (currMB, &dummy, &curr_cbp_blk, block, pdir, - (pdir==0||pdir==2?mode:0), (pdir==1||pdir==2?mode:0), dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block]); + (pdir == 0 || pdir == 2 ? mode : 0), (pdir == 1 || pdir == 2 ? mode : 0), + dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block]); if (img->P444_joined) best_cnt_nonz += coeff_cost_cr[1] + coeff_cost_cr[2]; @@ -879,7 +806,7 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, } for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++) { - memcpy(&dataTr->mpr8x8[j][i0], &curr_mpr[j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); + memcpy(&dataTr->mpr8x8[j][i0], &mb_pred[j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); } @@ -897,8 +824,8 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, { memcpy(&dataTr->rec_mb8x8_cr[0][j][i0], &enc_picture->imgUV[0][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); memcpy(&dataTr->rec_mb8x8_cr[1][j][i0], &enc_picture->imgUV[1][img->pix_y + j][img->pix_x + i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); - memcpy(&dataTr->mpr8x8CbCr[0][j][i0], &img->mpr[1][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); - memcpy(&dataTr->mpr8x8CbCr[1][j][i0], &img->mpr[2][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); + memcpy(&dataTr->mpr8x8CbCr[0][j][i0], &img->mb_pred[1][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); + memcpy(&dataTr->mpr8x8CbCr[1][j][i0], &img->mb_pred[2][j][i0], BLOCK_SIZE_8x8 * sizeof (imgpel)); } } } @@ -921,6 +848,12 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, { memcpy(&enc_picture->imgY[img->pix_y + j][img->pix_x], dataTr->rec_mbY8x8[j], BLOCK_SIZE_8x8 * sizeof(imgpel)); } + + if (params->rdopt == 3) + { + errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY8x8, j0, BLOCK_SIZE_8x8); + } + if(img->type==SP_SLICE &&(!si_frame_indicator)) { for (j = j0; j < j0 + BLOCK_SIZE_8x8; j++) @@ -947,7 +880,7 @@ void submacroblock_mode_decision(RD_PARAMS enc_mb, StoreNewMotionVectorsBlock8x8(0, block, dataTr->part8x8mode[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8pdir[block], bslice); } //===== set motion vectors and reference frames (prediction) ===== - SetRefAndMotionVectors (currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block]); + SetRefAndMotionVectors (currMB, block, dataTr->part8x8mode[block], dataTr->part8x8pdir[block], dataTr->part8x8l0ref[block], dataTr->part8x8l1ref[block], dataTr->part8x8bipred[block]); //===== set the coding state after current block ===== //if (transform8x8 == 0 || block < 3) @@ -1037,4 +970,99 @@ void update_lambda_costs(RD_PARAMS *enc_mb, int lambda_mf[3]) } } +/*! + ************************************************************************************* + * \brief + * Return array's minimum and its index + ************************************************************************************* + */ +int iminarray ( int arr[], int size, int *minind ) +{ + int i; + int mincand = arr[0]; + *minind = 0; + for ( i = 1; i < size; i++ ) + { + if (arr[i] < mincand) + { + mincand = arr[i]; + *minind = i; + } + } + return mincand; +} +/*! + ************************************************************************************* + * \brief + * Determines whether bi prediction is enabaled for current mode + ************************************************************************************* + */ +int is_bipred_enabled(int mode) +{ + int enabled = 0; + mode = mode == P8x8 ? 4: mode; + if (params->BiPredMotionEstimation) + { + if (mode > 0 && mode < 5) + { + enabled = (params->BiPredSearch[mode - 1]) ? 1: 0; + } + else + { + enabled = 0; + } + } + else + { + enabled = 0; + } + return enabled; +} + + +/*! + ************************************************************************************* + * \brief + * Update prediction direction for mode P16x16 to check all prediction directions + ************************************************************************************* + */ +void update_prediction_for_mode16x16(Block8x8Info *b8x8info, int ctr16x16, int *index) +{ + char pdir = 0; + short i, bipred_me = 0; + switch (ctr16x16) + { + case 0: + *index = *index - 1; + break; + case 1: + pdir = 1; + *index = *index - 1; + break; + case 2: + pdir = 2; + if (params->BiPredMotionEstimation) + { + *index = *index - 1; + } + break; + case 3: + pdir = 2; + bipred_me = 1; + *index = *index - 1; + break; + case 4: + pdir = 2; + bipred_me = 2; + break; + default: + error("invalid 'ctr16x16' value", -1); + break; + } + for (i = 0; i< 4; i++) + { + b8x8info->bipred8x8me[1][i] = bipred_me; + b8x8info->best8x8pdir[1][i] = pdir; + } +} diff --git a/lencod/src/mv-search.c b/lencod/src/mv-search.c index 4e6eade..d723ea6 100644 --- a/lencod/src/mv-search.c +++ b/lencod/src/mv-search.c @@ -70,7 +70,7 @@ int (*IntPelME) (Macroblock *, imgpel *, short, int, int, char ***, short int, int, int, short[2], short[2], int, int, int, int); int (*BiPredME) (Macroblock *, imgpel *, short, int, int, char ***, short ****, - int, int, int, short[2], short[2], short[2], short[2], int, int, int, int); + int, int, int, short[2], short[2], short[2], short[2], int, int, int, int, int); int (*SubPelBiPredME) (imgpel* orig_pic, short ref, int list, int pic_pix_x, int pic_pix_y, int blocktype, short pred_mv1[2], short pred_mv2[2], short mv1[2], short mv2[2], @@ -80,6 +80,10 @@ int (*SubPelME) (imgpel* orig_pic, short ref, int list, int list_offset, i int search_pos2, int search_pos4, int min_mcost, int* lambda_factor, int apply_weights); +int BlockMotionSearch (Macroblock *currMB, short,int,int,int,int,int, int*); +int BiPredBlockMotionSearch(Macroblock *currMB, short[2], short*, short, int, int, int, int , int, int, int*); + +int GetSkipCostMB (Macroblock *currMB); extern ColocatedParams *Co_located; extern const short block_type_shift_factor[8]; @@ -246,18 +250,18 @@ void SetMotionVectorPredictor (Macroblock *currMB, { if (mb_x < 8) // first column of 8x8 blocks { - if (mb_y==8) + if (mb_y == 8 ) { if (blockshape_x == 16) block_c.available = 0; } - else + else if (mb_x+blockshape_x == 8) { - if (mb_x+blockshape_x == 8) block_c.available = 0; + block_c.available = 0; } } - else + else if (mb_x+blockshape_x == 16) { - if (mb_x+blockshape_x == 16) block_c.available = 0; + block_c.available = 0; } } @@ -311,9 +315,12 @@ void SetMotionVectorPredictor (Macroblock *currMB, /* Prediction if only one of the neighbors uses the reference frame * we are checking */ - if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L; - else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U; - else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR; + if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) + mvPredType = MVPRED_L; + else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) + mvPredType = MVPRED_U; + else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) + mvPredType = MVPRED_UR; // Directional predictions if(blockshape_x == 8 && blockshape_y == 16) { @@ -419,8 +426,7 @@ void SetMotionVectorPredictor (Macroblock *currMB, * Initialize the motion search ************************************************************************ */ -void -Init_Motion_Search_Module () +void Init_Motion_Search_Module (void) { int bits, i_min, i_max, k; int i, l; @@ -567,10 +573,12 @@ Init_Motion_Search_Module () InitializeFastFullIntegerSearch (); init_ME_engine(params->SearchMode); + + if (params->SearchMode == UM_HEX) + UMHEX_DefineThreshold(); } } - /*! ************************************************************************ * \brief @@ -600,6 +608,20 @@ Clear_Motion_Search_Module () ClearFastFullIntegerSearch (); } +static inline int mv_bits_cost(short ***all_mv, short ***p_mv, int by, int bx, int step_v0, int step_v, int step_h0, int step_h, int mvd_bits) +{ + int v, h; + for (v=by; v<by + step_v0; v+=step_v) + { + for (h=bx; h<bx + step_h0; h+=step_h) + { + mvd_bits += mvbits[ all_mv[v][h][0] - p_mv[v][h][0] ]; + mvd_bits += mvbits[ all_mv[v][h][1] - p_mv[v][h][1] ]; + } + } + return mvd_bits; +} + /*! *********************************************************************** * \brief @@ -633,29 +655,16 @@ int BPredPartitionCost (Macroblock *currMB, int by0_part = by0[parttype][block8x8]; int bx0_part = bx0[parttype][block8x8]; - short ***all_mv_l0 = list ? img->bipred_mv1[LIST_0][ref_l0][blocktype] : img->bipred_mv2[LIST_0][ref_l0][blocktype]; - short ***all_mv_l1 = list ? img->bipred_mv1[LIST_1][ref_l1][blocktype] : img->bipred_mv2[LIST_1][ref_l1][blocktype]; + short ***all_mv_l0 = img->bipred_mv[list][LIST_0][ref_l0][blocktype]; + short ***all_mv_l1 = img->bipred_mv[list][LIST_1][ref_l1][blocktype]; short ***p_mv_l0 = img->pred_mv[LIST_0][ref_l0][blocktype]; short ***p_mv_l1 = img->pred_mv[LIST_1][ref_l1][blocktype]; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; - for (v = by0_part; v < by0_part + step_v0; v += step_v) - { - for (h = bx0_part; h < bx0_part + step_h0; h += step_h) - { - mvd_bits += mvbits[ all_mv_l0[v][h][0] - p_mv_l0[v][h][0] ]; - mvd_bits += mvbits[ all_mv_l0[v][h][1] - p_mv_l0[v][h][1] ]; - } - } - - for (v = by0_part; v < by0_part + step_v0; v += step_v) - { - for (h = bx0_part; h < bx0_part + step_h0; h += step_h) - { - mvd_bits += mvbits[ all_mv_l1[v][h][0] - p_mv_l1[v][h][0] ]; - mvd_bits += mvbits[ all_mv_l1[v][h][1] - p_mv_l1[v][h][1] ]; - } - } + // List0 + mvd_bits = mv_bits_cost(all_mv_l0, p_mv_l0, by0_part, bx0_part, step_v0, step_v, step_h0, step_h, mvd_bits); + // List1 + mvd_bits = mv_bits_cost(all_mv_l1, p_mv_l1, by0_part, bx0_part, step_v0, step_v, step_h0, step_h, mvd_bits); mcost = WEIGHTED_COST (lambda_factor, mvd_bits); @@ -673,7 +682,7 @@ int BPredPartitionCost (Macroblock *currMB, { for (i = 0; i < 4; i++) diff64[k++] = curr_blk[byy+j][bxx+i] = - pCurImg[pic_pix_y+j][pic_pix_x+i] - curr_mpr[j+block_y][i+block_x]; + pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x]; } if ((!params->Transform8x8Mode) || (blocktype>4)) @@ -767,12 +776,12 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock if ( ChromaMEEnable ) { // copy the original cmp1 and cmp2 data to the orig_pic matrix - for ( i = 0; i<=1; i++) + for ( i = 1; i<=2; i++) { - orig_pic_tmp = orig_pic + (256 << i); + orig_pic_tmp = orig_pic + (256 << (i - 1)); for (j = pic_pix_y_c; j < pic_pix_y_c + bsy_c; j++) { - memcpy(orig_pic_tmp, &(imgUV_org[i][j][pic_pix_x_c]), bsx_c * sizeof(imgpel)); + memcpy(orig_pic_tmp, &(pImgOrg[i][j][pic_pix_x_c]), bsx_c * sizeof(imgpel)); orig_pic_tmp += bsx_c; } } @@ -796,9 +805,10 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock //=========================================== if (params->SearchMode == UM_HEX) - UMHEXSetMotionVectorPredictor(currMB, pred_mv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, mb_x, mb_y, bsx, bsy, &search_range); + UMHEXSetMotionVectorPredictor(currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, mb_x, mb_y, bsx, bsy, &search_range); else - SetMotionVectorPredictor (currMB, pred_mv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, mb_x, mb_y, bsx, bsy); + SetMotionVectorPredictor (currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, mb_x, mb_y, bsx, bsy); + //================================== //===== INTEGER-PEL SEARCH ===== @@ -825,8 +835,8 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock clip_mv_range(img, search_range, mv, params->EPZSGrid); //--- perform motion search --- - min_mcost = IntPelME (currMB, orig_pic, ref, list, list_offset, - enc_picture->ref_idx, enc_picture->mv, pic_pix_x, pic_pix_y, blocktype, + min_mcost = IntPelME (currMB, orig_pic, ref, list, list_offset, + enc_picture->motion.ref_idx, enc_picture->motion.mv, pic_pix_x, pic_pix_y, blocktype, pred_mv, mv, search_range<<(params->EPZSGrid), min_mcost, lambda_factor[F_PEL], apply_weights); //===== convert search center to quarter-pel units ===== @@ -892,25 +902,65 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock } - // Bipred ME consideration. This needs to go in a separate function, and at some point support smaller partitions - if (img->type==B_SLICE && params->BiPredMotionEstimation != 0 && (blocktype == 1) && (ref==0)) + // Bipred ME consideration: returns minimum bipred cost + if (img->type == B_SLICE && is_bipred_enabled(blocktype) && (ref == 0)) { - short ******bipred_mv = list ? img->bipred_mv1 : img->bipred_mv2; - int min_mcostbi = max_value; - short bimv[2] = {0, 0}, tempmv[2] = {0, 0}; - short *pred_mv1 = NULL; - short *pred_mv2 = NULL; - short *bi_mv1 = NULL, *bi_mv2 = NULL; - short iterlist=list; - short pred_mv_bi[2]; + BiPredBlockMotionSearch(currMB, mv, pred_mv, ref, list, mb_x, mb_y, blocktype, search_range, apply_bi_weights, lambda_factor); + } + +#if GET_METIME + ftime(&tstruct2); // end time ms + me_tmp_time=(tstruct2.time - tstruct1.time) * 1000 + (tstruct2.millitm - tstruct1.millitm); + me_tot_time += me_tmp_time; + me_time += me_tmp_time; +#endif + return min_mcost; +} + + +/*! + *********************************************************************** + * \brief + * Block bi-prediction motion search + *********************************************************************** + */ +int BiPredBlockMotionSearch(Macroblock *currMB, //!< Current Macroblock + short mv[2], //!< current list motion vector + short* pred_mv, //!< current list motion vector predictor + short ref, //!< reference idx + int list, //!< reference picture list + int mb_x, //!< x-coordinate inside macroblock + int mb_y, //!< y-coordinate inside macroblock + int blocktype, //!< block type (1-16x16 ... 7-4x4) + int search_range, //!< 1-d search range for integer-position search + int apply_bi_weights, //!< apply bipred weights + int* lambda_factor) //!< lagrangian parameter for determining motion cost +{ + int iteration_no, i, j; + short bipred_type = list ? 0 : 1; + short****** bipred_mv = img->bipred_mv[bipred_type]; + int min_mcostbi = INT_MAX; + short bimv[2] = {0, 0}, tempmv[2] = {0, 0}; + short* pred_mv1 = NULL; + short* pred_mv2 = NULL; + short* bi_mv1 = NULL, *bi_mv2 = NULL; + short iterlist=list; + short pred_mv_bi[2]; + int block_x = (mb_x>>2); + int block_y = (mb_y>>2); + int bsx = params->blc_size[blocktype][0]; + int bsy = params->blc_size[blocktype][1]; + int pic_pix_x = img->opix_x + mb_x; + int pic_pix_y = img->opix_y + mb_y; + int list_offset = ((img->MbaffFrameFlag) && (currMB->mb_field)) ? img->current_mb_nr % 2 ? 4 : 2 : 0; if (params->SearchMode == UM_HEX) { bipred_flag = 1; - UMHEXSetMotionVectorPredictor(currMB, pred_mv_bi, enc_picture->ref_idx[list ^ 1], enc_picture->mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), mb_x, mb_y, bsx, bsy, &search_range); + UMHEXSetMotionVectorPredictor(currMB, pred_mv_bi, enc_picture->motion.ref_idx[list ^ 1], enc_picture->motion.mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), mb_x, mb_y, bsx, bsy, &search_range); } else - SetMotionVectorPredictor (currMB, pred_mv_bi, enc_picture->ref_idx[list ^ 1], enc_picture->mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), mb_x, mb_y, bsx, bsy); + SetMotionVectorPredictor (currMB, pred_mv_bi, enc_picture->motion.ref_idx[list ^ 1], enc_picture->motion.mv[(list == LIST_0? LIST_1: LIST_0)], 0, (list == LIST_0? LIST_1: LIST_0), mb_x, mb_y, bsx, bsy); if ((params->SearchMode != EPZS) || (params->EPZSSubPelGrid == 0)) { @@ -926,9 +976,9 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock } //Bi-predictive motion Refinements - for (i=0; i <= params->BiPredMERefinements; i++) + for (iteration_no = 0; iteration_no <= params->BiPredMERefinements; iteration_no++) { - if (i & 0x01) + if (iteration_no & 0x01) { pred_mv1 = pred_mv; pred_mv2 = pred_mv_bi; @@ -950,11 +1000,11 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist, list_offset, ref); // Get bipred mvs for list iterlist given previously computed mvs from other list - min_mcostbi = BiPredME (currMB, orig_pic, ref, iterlist, list_offset, enc_picture->ref_idx, enc_picture->mv, + min_mcostbi = BiPredME (currMB, orig_pic, ref, iterlist, list_offset, enc_picture->motion.ref_idx, enc_picture->motion.mv, pic_pix_x, pic_pix_y, blocktype, pred_mv1, pred_mv2, bi_mv1, bi_mv2, - (params->BiPredMESearchRange <<(params->EPZSGrid))>>i, min_mcostbi, lambda_factor[F_PEL], apply_bi_weights); + (params->BiPredMESearchRange <<(params->EPZSGrid))>>iteration_no, min_mcostbi, iteration_no, lambda_factor[F_PEL], apply_bi_weights); - if (i > 0 && (tempmv[0] == bi_mv1[0]) && (tempmv[1] == bi_mv1[1])) + if (iteration_no > 0 && (tempmv[0] == bi_mv1[0]) && (tempmv[1] == bi_mv1[1])) { break; } @@ -972,7 +1022,7 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock { if (params->BiPredMESubPel) { - min_mcostbi = max_value; + min_mcostbi = INT_MAX; PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist, list_offset, ref); min_mcostbi = SubPelBiPredME (orig_pic, ref, iterlist, pic_pix_x, pic_pix_y, blocktype, @@ -981,7 +1031,7 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock if (params->BiPredMESubPel==2) { - min_mcostbi = max_value; + min_mcostbi = INT_MAX; PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist ^ 1, list_offset, ref); min_mcostbi = SubPelBiPredME (orig_pic, ref, iterlist ^ 1, pic_pix_x, pic_pix_y, blocktype, @@ -999,29 +1049,7 @@ BlockMotionSearch (Macroblock *currMB, //!< Current Macroblock bipred_mv[iterlist ^ 1][0][blocktype][j][i][1] = bi_mv2[1]; } } - } - -#if GET_METIME - ftime(&tstruct2); // end time ms - me_tmp_time=(tstruct2.time - tstruct1.time) * 1000 + (tstruct2.millitm - tstruct1.millitm); - me_tot_time += me_tmp_time; - me_time += me_tmp_time; -#endif - return min_mcost; -} - -int mv_bits_cost(short ***all_mv, short ***p_mv, int by, int bx, int step_v0, int step_v, int step_h0, int step_h, int mvd_bits) -{ - int v, h; - for (v=by; v<by + step_v0; v+=step_v) - { - for (h=bx; h<bx + step_h0; h+=step_h) - { - mvd_bits += mvbits[ all_mv[v][h][0] - p_mv[v][h][0] ]; - mvd_bits += mvbits[ all_mv[v][h][1] - p_mv[v][h][1] ]; - } - } - return mvd_bits; + return min_mcostbi; } /*! @@ -1058,29 +1086,15 @@ int BIDPartitionCost (Macroblock *currMB, short *** p_mv_l1 = img->pred_mv[LIST_1][(int) cur_ref[LIST_1]][blocktype]; short *** all_mv_l0 = img->all_mv [LIST_0][(int) cur_ref[LIST_0]][blocktype]; short *** all_mv_l1 = img->all_mv [LIST_1][(int) cur_ref[LIST_1]][blocktype]; - - imgpel (*curr_mpr)[16] = img->mpr[0]; + short bipred_me = 0; //no bipred for this case + imgpel (*mb_pred)[16] = img->mb_pred[0]; //----- cost for motion vector bits ----- // Should write a separate, small function to do this processing // List0 - for (v=by; v<by + step_v0; v+=step_v) - { - for (h=bx; h<bx + step_h0; h+=step_h) - { - mvd_bits += mvbits[ all_mv_l0[v][h][0] - p_mv_l0[v][h][0] ]; - mvd_bits += mvbits[ all_mv_l0[v][h][1] - p_mv_l0[v][h][1] ]; - } - } + mvd_bits = mv_bits_cost(all_mv_l0, p_mv_l0, by, bx, step_v0, step_v, step_h0, step_h, mvd_bits); // List1 - for (v=by; v<by + step_v0; v+=step_v) - { - for (h=bx; h<bx + step_h0; h+=step_h) - { - mvd_bits += mvbits[ all_mv_l1[v][h][0] - p_mv_l1[v][h][0] ]; - mvd_bits += mvbits[ all_mv_l1[v][h][1] - p_mv_l1[v][h][1] ]; - } - } + mvd_bits = mv_bits_cost(all_mv_l1, p_mv_l1, by, bx, step_v0, step_v, step_h0, step_h, mvd_bits); mcost = WEIGHTED_COST (lambda_factor, mvd_bits); @@ -1091,13 +1105,13 @@ int BIDPartitionCost (Macroblock *currMB, for (bxx=0, h=bx; h<bx + step_h0; bxx+=4, h++) { pic_pix_x = img->opix_x + (block_x = (h<<2)); - LumaPrediction (currMB, block_x, block_y, 4, 4, 2, blocktype, blocktype, (short) cur_ref[0], (short) cur_ref[1]); + LumaPrediction (currMB, block_x, block_y, 4, 4, 2, blocktype, blocktype, (short) cur_ref[0], (short) cur_ref[1], bipred_me); for (k=j=0; j<4; j++) { for ( i=0; i<4; i++) diff64[k++] = curr_blk[byy+j][bxx+i] = - pCurImg[pic_pix_y+j][pic_pix_x+i] - curr_mpr[j+block_y][i+block_x]; + pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x]; } if ((!params->Transform8x8Mode) || (blocktype>4)) mcost += distortion4x4 (diff64); @@ -1107,6 +1121,7 @@ int BIDPartitionCost (Macroblock *currMB, if (params->Transform8x8Mode && (blocktype<=4)) // tchen 4-29-04 { for (byy=0; byy < params->blc_size[parttype][1]; byy+=bsy) + { for (bxx=0; bxx<params->blc_size[parttype][0]; bxx+=bsx) { for (k=0, j=byy;j<byy + 8;j++, k += 8) @@ -1114,6 +1129,7 @@ int BIDPartitionCost (Macroblock *currMB, mcost += distortion8x8(diff64); } + } } return mcost; } @@ -1132,35 +1148,37 @@ int GetSkipCostMB (Macroblock *currMB) int curr_diff[8][8]; int mb_x, mb_y; int block; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; for(block = 0;block < 4;block++) { mb_y = (block >> 1)<<3; mb_x = (block & 0x01)<<3; - for (block_y=mb_y; block_y<mb_y+8; block_y+=4) + for (block_y = mb_y; block_y < mb_y+8; block_y += 4) { pic_pix_y = img->opix_y + block_y; - for (block_x=mb_x; block_x<mb_x+8; block_x+=4) + for (block_x = mb_x; block_x < mb_x + 8; block_x += 4) { pic_pix_x = img->opix_x + block_x; //===== prediction of 4x4 block ===== - LumaPrediction (currMB, block_x, block_y, 4, 4, 0, 0, 0, 0, 0); + LumaPrediction (currMB, block_x, block_y, 4, 4, 0, 0, 0, 0, 0, 0); //===== get displaced frame difference ====== - for (k=j=0; j<4; j++) - for (i=0; i<4; i++, k++) + for (k = j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++, k++) { - diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] = pCurImg[pic_pix_y+j][pic_pix_x+i] - curr_mpr[j+block_y][i+block_x]; + diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] = pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x]; } + } - if(!((params->rdopt==0) && (params->Transform8x8Mode))) - cost += distortion4x4 (diff); + if(!((params->rdopt==0) && (params->Transform8x8Mode))) + cost += distortion4x4 (diff); } } - if((params->rdopt==0)&&(params->Transform8x8Mode)) + if((params->rdopt == 0) && (params->Transform8x8Mode)) { for(k=j=0; j<8; j++, k+=8) memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int)); @@ -1191,7 +1209,7 @@ void FindSkipModeMotionVector (Macroblock *currMB) int a_ref_idx = 0; int b_mv_y = 0; int b_ref_idx = 0; - short ***mv = enc_picture->mv[LIST_0]; + short ***mv = enc_picture->motion.mv[LIST_0]; int *mb_size = img->mb_size[IS_LUMA]; @@ -1201,7 +1219,7 @@ void FindSkipModeMotionVector (Macroblock *currMB) if (mb_a.available) { a_mv_y = mv[mb_a.pos_y][mb_a.pos_x][1]; - a_ref_idx = enc_picture->ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x]; + a_ref_idx = enc_picture->motion.ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x]; if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field) { @@ -1218,7 +1236,7 @@ void FindSkipModeMotionVector (Macroblock *currMB) if (mb_b.available) { b_mv_y = mv[mb_b.pos_y][mb_b.pos_x][1]; - b_ref_idx = enc_picture->ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x]; + b_ref_idx = enc_picture->motion.ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x]; if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field) { @@ -1241,7 +1259,7 @@ void FindSkipModeMotionVector (Macroblock *currMB) } else { - SetMotionVectorPredictor (currMB, pmv, enc_picture->ref_idx[LIST_0], mv, 0, LIST_0, 0, 0, 16, 16); + SetMotionVectorPredictor (currMB, pmv, enc_picture->motion.ref_idx[LIST_0], mv, 0, LIST_0, 0, 0, 16, 16); for (bx = 0;bx < 4;bx++) { memcpy(all_mv [0][bx], pmv, 2* sizeof(short)); @@ -1265,7 +1283,8 @@ int GetDirectCost8x8 (Macroblock *currMB, int block, int *cost8x8) int cost = 0; int mb_y = (block/2)<<3; int mb_x = (block%2)<<3; - imgpel (*curr_mpr)[16] = img->mpr[0]; + short bipred_me = 0; + imgpel (*mb_pred)[16] = img->mb_pred[0]; for (block_y=mb_y; block_y<mb_y+8; block_y+=4) { @@ -1286,21 +1305,21 @@ int GetDirectCost8x8 (Macroblock *currMB, int block, int *cost8x8) LumaPrediction (currMB, block_x, block_y, 4, 4, direct_pdir[pic_pix_y>>2][pic_pix_x>>2], 0, 0, direct_ref_idx[LIST_0][pic_pix_y>>2][pic_pix_x>>2], - direct_ref_idx[LIST_1][pic_pix_y>>2][pic_pix_x>>2]); + direct_ref_idx[LIST_1][pic_pix_y>>2][pic_pix_x>>2], bipred_me); //===== get displaced frame difference ====== for (k=j=0; j<4; j++) for (i=0; i<4; i++, k++) { diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] = - pCurImg[pic_pix_y+j][pic_pix_x+i] - curr_mpr[j+block_y][i+block_x]; + pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x]; } cost += distortion4x4 (diff); } } - if((params->rdopt==0)&&(params->Transform8x8Mode)) + if((params->rdopt == 0) && (params->Transform8x8Mode)) { k=0; for(j=0; j<8; j++, k+=8) @@ -1405,8 +1424,8 @@ PartitionMotionSearch (Macroblock *currMB, search_range = params->search_range / ((imin(ref,1)+1) * imin(2,blocktype)); //----- set arrays ----- - ref_array = enc_picture->ref_idx[list]; - mv_array = enc_picture->mv[list]; + ref_array = enc_picture->motion.ref_idx[list]; + mv_array = enc_picture->motion.mv[list]; //----- init motion cost ----- //motion_cost[blocktype][list][ref][block8x8] = 0; @@ -1421,7 +1440,7 @@ PartitionMotionSearch (Macroblock *currMB, for (h=bx; h<bx+step_h0; h+=step_h) { all_mv = img->all_mv[list][ref][blocktype][v][h]; - pic_block_x = img->block_x + h; + pic_block_x = img->block_x + h; //--- motion search for block --- if (Motion_Selected != 1) @@ -1471,36 +1490,24 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) int refList; int ref_idx; - byte ** moving_block; - short **** co_located_mv; - char *** co_located_ref_idx; - int64 *** co_located_ref_id; - char ** ref_pic_l0 = enc_picture->ref_idx[LIST_0]; - char ** ref_pic_l1 = enc_picture->ref_idx[LIST_1]; + MotionParams *colocated; + char ** ref_pic_l0 = enc_picture->motion.ref_idx[LIST_0]; + char ** ref_pic_l1 = enc_picture->motion.ref_idx[LIST_1]; if (currMB->list_offset) { if(img->current_mb_nr%2) { - moving_block = Co_located->bottom_moving_block; - co_located_mv = Co_located->bottom_mv; - co_located_ref_idx = Co_located->bottom_ref_idx; - co_located_ref_id = Co_located->bottom_ref_pic_id; + colocated = &Co_located->bottom; } else { - moving_block = Co_located->top_moving_block; - co_located_mv = Co_located->top_mv; - co_located_ref_idx = Co_located->top_ref_idx; - co_located_ref_id = Co_located->top_ref_pic_id; + colocated = &Co_located->top; } } else { - moving_block = Co_located->moving_block; - co_located_mv = Co_located->mv; - co_located_ref_idx = Co_located->ref_idx; - co_located_ref_id = Co_located->ref_pic_id; + colocated = &Co_located->frame; } if (img->direct_spatial_mv_pred_flag) //spatial direct mode copy from decoder @@ -1626,10 +1633,10 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) l1_refX = (l1_refX >= 0 && l1_refC >= 0) ? imin(l1_refX,l1_refC): imax(l1_refX,l1_refC); if (l0_refX >=0) - SetMotionVectorPredictor (currMB, pmvfw, enc_picture->ref_idx[LIST_0], enc_picture->mv[LIST_0], l0_refX, LIST_0, 0, 0, 16, 16); + SetMotionVectorPredictor (currMB, pmvfw, enc_picture->motion.ref_idx[LIST_0], enc_picture->motion.mv[LIST_0], l0_refX, LIST_0, 0, 0, 16, 16); if (l1_refX >=0) - SetMotionVectorPredictor (currMB, pmvbw, enc_picture->ref_idx[LIST_1], enc_picture->mv[LIST_1], l1_refX, LIST_1, 0, 0, 16, 16); + SetMotionVectorPredictor (currMB, pmvbw, enc_picture->motion.ref_idx[LIST_1], enc_picture->motion.mv[LIST_1], l1_refX, LIST_1, 0, 0, 16, 16); for (block_y=0; block_y<4; block_y++) { @@ -1645,7 +1652,7 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) if (l0_refX >=0) { - if (!l0_refX && !moving_block[opic_block_y][opic_block_x]) + if (!l0_refX && !colocated->moving_block[opic_block_y][opic_block_x]) { memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2 * sizeof(short)); direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=0; @@ -1664,7 +1671,7 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) if (l1_refX >=0) { - if(l1_refX==0 && !moving_block[opic_block_y][opic_block_x]) + if(l1_refX==0 && !colocated->moving_block[opic_block_y][opic_block_x]) { memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2 * sizeof(short)); direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX; @@ -1748,8 +1755,8 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) opic_block_x = (img->opix_x>>2) + block_x; all_mvs = img->all_mv; - refList = (co_located_ref_idx[LIST_0][opic_block_y][opic_block_x]== -1 ? LIST_1 : LIST_0); - ref_idx = co_located_ref_idx[refList][opic_block_y][opic_block_x]; + refList = (colocated->ref_idx[LIST_0][opic_block_y][opic_block_x]== -1 ? LIST_1 : LIST_0); + ref_idx = colocated->ref_idx[refList][opic_block_y][opic_block_x]; // next P is intra mode if (ref_idx==-1) @@ -1768,7 +1775,7 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0+currMB->list_offset]);iref++) { - if (refpic[iref]==co_located_ref_id[refList ][opic_block_y][opic_block_x]) + if (refpic[iref]==colocated->ref_pic_id[refList ][opic_block_y][opic_block_x]) { mapped_idx=iref; break; @@ -1786,18 +1793,18 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) if (mv_scale==9999) { // forward - memcpy(all_mvs[LIST_0][0][0][block_y][block_x], co_located_mv[refList][opic_block_y][opic_block_x], 2* sizeof(short)); + memcpy(all_mvs[LIST_0][0][0][block_y][block_x], colocated->mv[refList][opic_block_y][opic_block_x], 2* sizeof(short)); // backward memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2* sizeof(short)); } else { // forward - all_mvs[LIST_0][mapped_idx][0][block_y][block_x][0] = (mv_scale * co_located_mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8; - all_mvs[LIST_0][mapped_idx][0][block_y][block_x][1] = (mv_scale * co_located_mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8; + all_mvs[LIST_0][mapped_idx][0][block_y][block_x][0] = (mv_scale * colocated->mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8; + all_mvs[LIST_0][mapped_idx][0][block_y][block_x][1] = (mv_scale * colocated->mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8; // backward - all_mvs[LIST_1][ 0][0][block_y][block_x][0] = ((mv_scale - 256)* co_located_mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8; - all_mvs[LIST_1][ 0][0][block_y][block_x][1] = ((mv_scale - 256)* co_located_mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8; + all_mvs[LIST_1][ 0][0][block_y][block_x][0] = ((mv_scale - 256)* colocated->mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8; + all_mvs[LIST_1][ 0][0][block_y][block_x][1] = ((mv_scale - 256)* colocated->mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8; } // Test Level Limits if satisfied. @@ -1842,4 +1849,3 @@ void Get_Direct_Motion_Vectors (Macroblock *currMB) } } } - diff --git a/lencod/src/nal.c b/lencod/src/nal.c index 15794ad..b4b58b9 100644 --- a/lencod/src/nal.c +++ b/lencod/src/nal.c @@ -17,6 +17,7 @@ #include "contributors.h" #include "global.h" +#include "enc_statistics.h" /*! ************************************************************************ diff --git a/lencod/src/parset.c b/lencod/src/parset.c index b25a12e..5f84804 100644 --- a/lencod/src/parset.c +++ b/lencod/src/parset.c @@ -101,7 +101,6 @@ void GenerateParameterSets (void) else GeneratePictureParameterSet( PicParSet[0], sps, 0, params->WeightedPrediction, params->WeightedBiprediction, params->chroma_qp_index_offset, 0); - } active_sps = sps; @@ -250,7 +249,7 @@ void GenerateSequenceParameterSet( seq_parameter_set_rbsp_t *sps, //!< Sequence } // Parameter Set ID hard coded to zero - sps->seq_parameter_set_id = 0; + sps->seq_parameter_set_id = SPS_id; // Fidelity Range Extensions stuff sps->bit_depth_luma_minus8 = params->output.bit_depth[0] - 8; diff --git a/lencod/src/q_around.c b/lencod/src/q_around.c new file mode 100644 index 0000000..e5271d9 --- /dev/null +++ b/lencod/src/q_around.c @@ -0,0 +1,369 @@ + +/*! + ************************************************************************************* + * \file q_around.c + * + * \brief + * Quantization Adaptive Rounding (JVT-N011) + * \author + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Ehsan Maani <emaan@dolby.com> + * + ************************************************************************************* + */ + +#include "global.h" +#include "memalloc.h" +#include "q_offsets.h" +#include "q_around.h" + +static const int AdaptRndCrPos[2][5] = +{ + // P, B, I, SP, SI + { 4, 7, 1, 4, 1}, // Intra MB + { 10, 13, 10, 10, 10} // Inter MB +}; + +static const int AdaptRndPos[4][5] = +{ + // P, B, I, SP, SI + { 3, 6, 0, 3, 0}, // 4x4 Intra MB + { 1, 2, 0, 1, 2}, // 8x8 Intra MB + { 9, 12, 9, 9, 9}, // 4x4 Inter MB + { 3, 4, 3, 3, 3}, // 8x8 Inter MB +}; + +ARoundOffset bestOffset; + +int **fadjust8x8 = NULL, **fadjust4x4 = NULL, ***fadjust4x4Cr = NULL, ***fadjust8x8Cr = NULL; + +static void allocate_offset_memory(InputParameters *params, ARoundOffset *offset) +{ + get_mem2Dint(&offset->InterFAdjust4x4, 16, 16); + get_mem2Dint(&offset->IntraFAdjust4x4, 16, 16); + get_mem2Dint(&offset->InterFAdjust8x8, 16, 16); + get_mem2Dint(&offset->IntraFAdjust8x8, 16, 16); + + if (params->yuv_format != 0 ) + { + if (params->yuv_format == YUV444) + { + get_mem3Dint(&offset->InterFAdjust8x8Cr, 2, 16, 16); + get_mem3Dint(&offset->IntraFAdjust8x8Cr, 2, 16, 16); + } + get_mem3Dint(&offset->InterFAdjust4x4Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); + get_mem3Dint(&offset->IntraFAdjust4x4Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); + } +} + +static void free_offset_memory(InputParameters *params, ARoundOffset *offset) +{ + free_mem2Dint(offset->InterFAdjust4x4); + free_mem2Dint(offset->IntraFAdjust4x4); + free_mem2Dint(offset->InterFAdjust8x8); + free_mem2Dint(offset->IntraFAdjust8x8); + + if (params->yuv_format != 0 ) + { + if (params->yuv_format == YUV444) + { + free_mem3Dint(offset->InterFAdjust8x8Cr); + free_mem3Dint(offset->IntraFAdjust8x8Cr); + } + free_mem3Dint(offset->InterFAdjust4x4Cr); + free_mem3Dint(offset->IntraFAdjust4x4Cr); + } +} + + +void setup_adaptive_rounding (InputParameters *params) +{ + allocate_offset_memory(params, &bestOffset); + + get_mem2Dint(&fadjust8x8, 16, 16); + get_mem2Dint(&fadjust4x4, 16, 16); + if (params->yuv_format != 0 ) + { + get_mem3Dint(&fadjust4x4Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); + get_mem3Dint(&fadjust8x8Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); + } +} + +void clear_adaptive_rounding (InputParameters *params) +{ + free_offset_memory(params, &bestOffset); + + free_mem2Dint(fadjust8x8); + free_mem2Dint(fadjust4x4); + if (params->yuv_format != 0) + { + free_mem3Dint(fadjust4x4Cr); + free_mem3Dint(fadjust8x8Cr); + } +} + +void store_adaptive_rounding (ImageParameters *img, int block_y, int block_x) +{ + int j; + + for (j = block_y; j < block_y + 4; j++) + memcpy(&fadjust4x4[j][block_x],&img->fadjust4x4[1][j][block_x], BLOCK_SIZE * sizeof(int)); + + if (img->P444_joined) + { + for (j = block_y; j < block_y + 4; j++) + { + memcpy(&fadjust4x4Cr[0][j][block_x],&img->fadjust4x4Cr[0][1][j][block_x], BLOCK_SIZE * sizeof(int)); + } + for (j = block_y; j < block_y + 4; j++) + { + memcpy(&fadjust4x4Cr[1][j][block_x],&img->fadjust4x4Cr[1][1][j][block_x], BLOCK_SIZE * sizeof(int)); + } + } +} + +void update_adaptive_rounding(ImageParameters *img, int block_y, int block_x) +{ + int j; + + for (j = block_y; j < block_y + BLOCK_SIZE; j++) + memcpy (&img->fadjust4x4[1][j][block_x],&fadjust4x4[j][block_x], BLOCK_SIZE * sizeof(int)); + + if (img->P444_joined) + { + for (j = 0; j < block_y + BLOCK_SIZE; j++) + { + memcpy (&img->fadjust4x4Cr[0][1][j][block_x],&fadjust4x4Cr[0][j][block_x], BLOCK_SIZE * sizeof(int)); + } + for (j = 0; j < block_y + BLOCK_SIZE; j++) + { + memcpy (&img->fadjust4x4Cr[1][1][j][block_x],&fadjust4x4Cr[1][j][block_x], BLOCK_SIZE * sizeof(int)); + } + } +} + +/*! + ************************************************************************************* + * \brief + * Store adaptive rounding luma parameters + ************************************************************************************* + */ + +void store_adaptive_rounding_parameters_luma (Macroblock *currMB, int mode) +{ + int is_inter = (mode != I4MB) && (mode != I16MB) && (mode != I8MB); + + if (currMB->luma_transform_size_8x8_flag) + { + if ((mode == P8x8)) + memcpy(&(bestOffset.InterFAdjust8x8[0][0]),&(img->fadjust8x8[2][0][0]), MB_PIXELS * sizeof(int)); + else if (is_inter) + memcpy(&(bestOffset.InterFAdjust8x8[0][0]),&(img->fadjust8x8[0][0][0]), MB_PIXELS * sizeof(int)); + else + memcpy(&(bestOffset.IntraFAdjust8x8[0][0]),&(img->fadjust8x8[1][0][0]), MB_PIXELS * sizeof(int)); + } + else + { + if ((mode == P8x8)) + memcpy(&(bestOffset.InterFAdjust4x4[0][0]),&(img->fadjust4x4[3][0][0]),MB_PIXELS * sizeof(int)); + else if (is_inter) + memcpy(&(bestOffset.InterFAdjust4x4[0][0]),&(img->fadjust4x4[0][0][0]),MB_PIXELS * sizeof(int)); + else + memcpy(&(bestOffset.IntraFAdjust4x4[0][0]),&(img->fadjust4x4[1 + mode == I16MB][0][0]),MB_PIXELS * sizeof(int)); + } +} + + +/*! + ************************************************************************************* + * \brief + * Store adaptive rounding chroma parameters + ************************************************************************************* + */ +void store_adaptive_rounding_parameters_chroma (Macroblock *currMB, int mode) +{ + int j; + int is_inter = (mode != I4MB)&&(mode != I16MB)&&(mode != I8MB); + + if (img->P444_joined) + { + if (currMB->luma_transform_size_8x8_flag) + { + if ((mode == P8x8)) + { + memcpy(&(bestOffset.InterFAdjust8x8Cr[0][0][0]),&(img->fadjust8x8Cr[0][2][0][0]), MB_PIXELS * sizeof(int)); + memcpy(&(bestOffset.InterFAdjust8x8Cr[1][0][0]),&(img->fadjust8x8Cr[1][2][0][0]), MB_PIXELS * sizeof(int)); + } + else if (is_inter) + { + memcpy(&(bestOffset.InterFAdjust8x8Cr[0][0][0]),&(img->fadjust8x8Cr[0][0][0][0]), MB_PIXELS * sizeof(int)); + memcpy(&(bestOffset.InterFAdjust8x8Cr[1][0][0]),&(img->fadjust8x8Cr[1][0][0][0]), MB_PIXELS * sizeof(int)); + } + else + { + memcpy(&(bestOffset.IntraFAdjust8x8Cr[0][0][0]),&(img->fadjust8x8Cr[0][1][0][0]), MB_PIXELS * sizeof(int)); + memcpy(&(bestOffset.IntraFAdjust8x8Cr[1][0][0]),&(img->fadjust8x8Cr[1][1][0][0]), MB_PIXELS * sizeof(int)); + } + } + else + { + if ((mode == P8x8)) + { + memcpy(&(bestOffset.InterFAdjust4x4Cr[0][0][0]),&(img->fadjust4x4Cr[0][3][0][0]), MB_PIXELS * sizeof(int)); + memcpy(&(bestOffset.InterFAdjust4x4Cr[1][0][0]),&(img->fadjust4x4Cr[1][3][0][0]), MB_PIXELS * sizeof(int)); + } + else if (is_inter) + { + memcpy(&(bestOffset.InterFAdjust4x4Cr[0][0][0]),&(img->fadjust4x4Cr[0][0][0][0]), MB_PIXELS * sizeof(int)); + memcpy(&(bestOffset.InterFAdjust4x4Cr[1][0][0]),&(img->fadjust4x4Cr[1][0][0][0]), MB_PIXELS * sizeof(int)); + } + else + { + memcpy(&(bestOffset.IntraFAdjust4x4Cr[0][0][0]),&(img->fadjust4x4Cr[0][1 + mode == I16MB][0][0]), MB_PIXELS * sizeof(int)); + memcpy(&(bestOffset.IntraFAdjust4x4Cr[1][0][0]),&(img->fadjust4x4Cr[1][1 + mode == I16MB][0][0]), MB_PIXELS * sizeof(int)); + } + } + } + + if ( (params->yuv_format == YUV420 || params->yuv_format == YUV422) && (params->AdaptRndChroma)) + { + if (currMB->luma_transform_size_8x8_flag && mode == P8x8) + { + for (j = 0; j < img->mb_cr_size_y; j++) + { + memcpy(bestOffset.InterFAdjust4x4Cr[0][j],img->fadjust8x8Cr[0][0][j],img->mb_cr_size_x * sizeof(int)); + memcpy(bestOffset.InterFAdjust4x4Cr[1][j],img->fadjust8x8Cr[1][0][j],img->mb_cr_size_x * sizeof(int)); + } + } + else if (mode == P8x8) + { + for (j = 0; j < img->mb_cr_size_y; j++) + { + memcpy(bestOffset.InterFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][2][j],img->mb_cr_size_x * sizeof(int)); + memcpy(bestOffset.InterFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][2][j],img->mb_cr_size_x * sizeof(int)); + } + } + else if (is_inter) + { + for (j = 0; j < img->mb_cr_size_y; j++) + { + memcpy(bestOffset.InterFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][0][j],img->mb_cr_size_x * sizeof(int)); + memcpy(bestOffset.InterFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][0][j],img->mb_cr_size_x * sizeof(int)); + } + } + else + { + for (j = 0; j < img->mb_cr_size_y; j++) + { + memcpy(bestOffset.IntraFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][1][j],img->mb_cr_size_x * sizeof(int)); + memcpy(bestOffset.IntraFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][1][j],img->mb_cr_size_x * sizeof(int)); + } + } + } +} + +/*! + ************************************************************************************* + * \brief + * Store all adaptive rounding parameters + ************************************************************************************* + */ +void store_adaptive_rounding_parameters (Macroblock *currMB, int mode) +{ + store_adaptive_rounding_parameters_luma (currMB, mode); + store_adaptive_rounding_parameters_chroma (currMB, mode); +} + +/*! +************************************************************************ +* \brief +* update rounding offsets based on JVT-N011 +************************************************************************ +*/ +void update_offset_params(Macroblock *currMB, int mode, int luma_transform_size_8x8_flag) +{ + int is_inter = (mode != I4MB)&&(mode != I16MB) && (mode != I8MB); + int luma_pos = AdaptRndPos[(is_inter<<1) + luma_transform_size_8x8_flag][img->type]; + int i,j; + int qp = currMB->qp + img->bitdepth_luma_qp_scale; + int cur_qp = params->AdaptRoundingFixed ? 0 : qp; + int temp = 0; + int offsetRange = 1 << (OffsetBits - 1); + int blk_mask = 0x03 + (luma_transform_size_8x8_flag<<2); + int blk_shift = 2 + luma_transform_size_8x8_flag; + short **offsetList = luma_transform_size_8x8_flag ? OffsetList8x8[cur_qp] : OffsetList4x4[cur_qp]; + + int **fAdjust = is_inter + ? (luma_transform_size_8x8_flag ? bestOffset.InterFAdjust8x8 : bestOffset.InterFAdjust4x4) + : (luma_transform_size_8x8_flag ? bestOffset.IntraFAdjust8x8 : bestOffset.IntraFAdjust4x4); + + if( (active_sps->chroma_format_idc == YUV444) && IS_INDEPENDENT(params) ) + { + if( luma_transform_size_8x8_flag ) // 8x8 + luma_pos += 5 * img->colour_plane_id; + else // 4x4 + luma_pos += img->colour_plane_id; + } + + for (j=0; j < MB_BLOCK_SIZE; j++) + { + int j_pos = ((j & blk_mask)<<blk_shift); + for (i=0; i < MB_BLOCK_SIZE; i++) + { + temp = j_pos + (i & blk_mask); + offsetList[luma_pos][temp] += fAdjust[j][i]; + offsetList[luma_pos][temp] = iClip3(0, offsetRange, offsetList[luma_pos][temp]); + } + } + + if(img->P444_joined) + { + int ***fAdjustCbCr = (int ***) (is_inter + ? (luma_transform_size_8x8_flag ? bestOffset.InterFAdjust8x8Cr : bestOffset.InterFAdjust4x4Cr) + : (luma_transform_size_8x8_flag ? bestOffset.IntraFAdjust8x8Cr : bestOffset.IntraFAdjust4x4Cr)); + int uv; + + for(uv = 0; uv < 2; uv++) + { + luma_pos = AdaptRndPos[(is_inter<<1) + luma_transform_size_8x8_flag][img->type]; + if(luma_transform_size_8x8_flag ) // 8x8 + luma_pos += 5 * (uv+1); + else // 4x4 + luma_pos += (uv+1); + for (j=0; j < MB_BLOCK_SIZE; j++) + { + int j_pos = ((j & blk_mask)<<blk_shift); + for (i=0; i < MB_BLOCK_SIZE; i++) + { + temp = j_pos + (i & blk_mask); + offsetList[luma_pos][temp] += fAdjustCbCr[uv][j][i]; + offsetList[luma_pos][temp] = iClip3(0,offsetRange,offsetList[luma_pos][temp]); + } + } + } + } + + if ((params->AdaptRndChroma) && (params->yuv_format == YUV420 || params->yuv_format == YUV422 )) + { + int u_pos = AdaptRndCrPos[is_inter][img->type]; + int v_pos = u_pos + 1; + int jpos; + + int ***fAdjustCr = is_inter ? bestOffset.InterFAdjust4x4Cr : bestOffset.IntraFAdjust4x4Cr; + + for (j = 0; j < img->mb_cr_size_y; j++) + { + jpos = ((j & 0x03)<<2); + for (i = 0; i < img->mb_cr_size_x; i++) + { + temp = jpos + (i & 0x03); + OffsetList4x4[cur_qp][u_pos][temp] += fAdjustCr[0][j][i]; + OffsetList4x4[cur_qp][u_pos][temp] = iClip3(0,offsetRange,OffsetList4x4[cur_qp][u_pos][temp]); + OffsetList4x4[cur_qp][v_pos][temp] += fAdjustCr[1][j][i]; + OffsetList4x4[cur_qp][v_pos][temp] = iClip3(0,offsetRange,OffsetList4x4[cur_qp][v_pos][temp]); + } + } + } +} + + diff --git a/lencod/src/q_matrix.c b/lencod/src/q_matrix.c index 568cd1d..a0c7177 100644 --- a/lencod/src/q_matrix.c +++ b/lencod/src/q_matrix.c @@ -16,11 +16,153 @@ extern char *GetConfigFileContent (char *Filename, int error_type); #define MAX_ITEMS_TO_PARSE 1000 -extern const int quant_coef[6][4][4]; -extern const int dequant_coef[6][4][4]; +const int quant_coef[6][4][4] = { + {{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243},{13107, 8066,13107, 8066},{ 8066, 5243, 8066, 5243}}, + {{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660},{11916, 7490,11916, 7490},{ 7490, 4660, 7490, 4660}}, + {{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194},{10082, 6554,10082, 6554},{ 6554, 4194, 6554, 4194}}, + {{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647},{ 9362, 5825, 9362, 5825},{ 5825, 3647, 5825, 3647}}, + {{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355},{ 8192, 5243, 8192, 5243},{ 5243, 3355, 5243, 3355}}, + {{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893},{ 7282, 4559, 7282, 4559},{ 4559, 2893, 4559, 2893}} +}; + +const int dequant_coef[6][4][4] = { + {{10, 13, 10, 13},{ 13, 16, 13, 16},{10, 13, 10, 13},{ 13, 16, 13, 16}}, + {{11, 14, 11, 14},{ 14, 18, 14, 18},{11, 14, 11, 14},{ 14, 18, 14, 18}}, + {{13, 16, 13, 16},{ 16, 20, 16, 20},{13, 16, 13, 16},{ 16, 20, 16, 20}}, + {{14, 18, 14, 18},{ 18, 23, 18, 23},{14, 18, 14, 18},{ 18, 23, 18, 23}}, + {{16, 20, 16, 20},{ 20, 25, 20, 25},{16, 20, 16, 20},{ 20, 25, 20, 25}}, + {{18, 23, 18, 23},{ 23, 29, 23, 29},{18, 23, 18, 23},{ 23, 29, 23, 29}} +}; + +const int quant_coef8[6][8][8] = +{ + { + {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222}, + {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, + {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481}, + {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, + {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222}, + {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, + {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481}, + {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428} + }, + { + {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058}, + {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, + {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290}, + {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, + {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058}, + {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, + {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290}, + {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826} + }, + { + {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675}, + {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, + {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985}, + {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, + {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675}, + {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, + {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985}, + {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943} + }, + { + {9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931}, + {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, + {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259}, + {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, + {9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931}, + {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, + {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259}, + {8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228} + }, + { + {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740}, + {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, + {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777}, + {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, + {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740}, + {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, + {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777}, + {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346} + }, + { + {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830}, + {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, + {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640}, + {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, + {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830}, + {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, + {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640}, + {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428} + } +}; + + -extern const int quant_coef8[6][8][8]; -extern const int dequant_coef8[6][8][8]; +const int dequant_coef8[6][8][8] = +{ + { + {20, 19, 25, 19, 20, 19, 25, 19}, + {19, 18, 24, 18, 19, 18, 24, 18}, + {25, 24, 32, 24, 25, 24, 32, 24}, + {19, 18, 24, 18, 19, 18, 24, 18}, + {20, 19, 25, 19, 20, 19, 25, 19}, + {19, 18, 24, 18, 19, 18, 24, 18}, + {25, 24, 32, 24, 25, 24, 32, 24}, + {19, 18, 24, 18, 19, 18, 24, 18} + }, + { + {22, 21, 28, 21, 22, 21, 28, 21}, + {21, 19, 26, 19, 21, 19, 26, 19}, + {28, 26, 35, 26, 28, 26, 35, 26}, + {21, 19, 26, 19, 21, 19, 26, 19}, + {22, 21, 28, 21, 22, 21, 28, 21}, + {21, 19, 26, 19, 21, 19, 26, 19}, + {28, 26, 35, 26, 28, 26, 35, 26}, + {21, 19, 26, 19, 21, 19, 26, 19} + }, + { + {26, 24, 33, 24, 26, 24, 33, 24}, + {24, 23, 31, 23, 24, 23, 31, 23}, + {33, 31, 42, 31, 33, 31, 42, 31}, + {24, 23, 31, 23, 24, 23, 31, 23}, + {26, 24, 33, 24, 26, 24, 33, 24}, + {24, 23, 31, 23, 24, 23, 31, 23}, + {33, 31, 42, 31, 33, 31, 42, 31}, + {24, 23, 31, 23, 24, 23, 31, 23} + }, + { + {28, 26, 35, 26, 28, 26, 35, 26}, + {26, 25, 33, 25, 26, 25, 33, 25}, + {35, 33, 45, 33, 35, 33, 45, 33}, + {26, 25, 33, 25, 26, 25, 33, 25}, + {28, 26, 35, 26, 28, 26, 35, 26}, + {26, 25, 33, 25, 26, 25, 33, 25}, + {35, 33, 45, 33, 35, 33, 45, 33}, + {26, 25, 33, 25, 26, 25, 33, 25} + }, + { + {32, 30, 40, 30, 32, 30, 40, 30}, + {30, 28, 38, 28, 30, 28, 38, 28}, + {40, 38, 51, 38, 40, 38, 51, 38}, + {30, 28, 38, 28, 30, 28, 38, 28}, + {32, 30, 40, 30, 32, 30, 40, 30}, + {30, 28, 38, 28, 30, 28, 38, 28}, + {40, 38, 51, 38, 40, 38, 51, 38}, + {30, 28, 38, 28, 30, 28, 38, 28} + }, + { + {36, 34, 46, 34, 36, 34, 46, 34}, + {34, 32, 43, 32, 34, 32, 43, 32}, + {46, 43, 58, 43, 46, 43, 58, 43}, + {34, 32, 43, 32, 34, 32, 43, 32}, + {36, 34, 46, 34, 36, 34, 46, 34}, + {34, 32, 43, 32, 34, 32, 43, 32}, + {46, 43, 58, 43, 46, 43, 58, 43}, + {34, 32, 43, 32, 34, 32, 43, 32} + } +}; int matrix4x4_check[6] = {0, 0, 0, 0, 0, 0}; diff --git a/lencod/src/q_offsets.c b/lencod/src/q_offsets.c index 5d100c0..9f1989a 100644 --- a/lencod/src/q_offsets.c +++ b/lencod/src/q_offsets.c @@ -159,7 +159,7 @@ static const short Offset8_inter_default[64] = { void allocate_QOffsets () { int max_bitdepth = imax(params->output.bit_depth[0], params->output.bit_depth[1]); - int max_qp = (3 + 6*(max_bitdepth) - MIN_QP); + int max_qp = (3 + 6*(max_bitdepth)); get_mem5Dint(&LevelOffset4x4Comp, 3, 2, max_qp + 1, 4, 4); get_mem5Dint(&LevelOffset8x8Comp, 3, 2, max_qp + 1, 8, 8); @@ -428,8 +428,8 @@ void Init_QOffsetMatrix () void InitOffsetParam () { int i, k; - int max_qp_luma = (4 + 6*(params->output.bit_depth[0]) - MIN_QP); - int max_qp_cr = (4 + 6*(params->output.bit_depth[1]) - MIN_QP); + int max_qp_luma = (4 + 6*(params->output.bit_depth[0])); + int max_qp_cr = (4 + 6*(params->output.bit_depth[1])); for (i = 0; i < (params->AdaptRoundingFixed ? 1 : imax(max_qp_luma, max_qp_cr)); i++) { @@ -496,7 +496,7 @@ void CalculateOffsetParam () int img_type = (img->type == SI_SLICE ? I_SLICE : (img->type == SP_SLICE ? P_SLICE : img->type)); int max_qp_scale = imax(img->bitdepth_luma_qp_scale, img->bitdepth_chroma_qp_scale); - int max_qp = 51 + max_qp_scale - MIN_QP; + int max_qp = 51 + max_qp_scale; AdaptRndWeight = params->AdaptRndWFactor[img->nal_reference_idc != 0][img_type]; AdaptRndCrWeight = params->AdaptRndCrWFactor[img->nal_reference_idc != 0][img_type]; @@ -630,7 +630,7 @@ void CalculateOffset8Param () int q_bits, qp; int max_qp_scale = imax(img->bitdepth_luma_qp_scale, img->bitdepth_chroma_qp_scale); - int max_qp = 51 + max_qp_scale - MIN_QP; + int max_qp = 51 + max_qp_scale; if (img->type == I_SLICE || img->type == SI_SLICE ) { diff --git a/lencod/src/quant4x4.c b/lencod/src/quant4x4.c index a3a6dac..25e2828 100644 --- a/lencod/src/quant4x4.c +++ b/lencod/src/quant4x4.c @@ -24,28 +24,25 @@ * ************************************************************************ */ -void init_quant_4x4(ImageParameters *img) +void init_quant_4x4(InputParameters *params, ImageParameters *img) { if (params->UseRDOQuant == 1) { quant_4x4 = quant_4x4_trellis; + quant_dc4x4 = quant_dc4x4_trellis; quant_ac4x4 = quant_ac4x4_trellis; - if (params->RDOQ_CR == 1) - quant_ac4x4cr = quant_ac4x4_trellis; - else - quant_ac4x4cr = quant_ac4x4_normal; } else if (img->AdaptiveRounding) { - quant_4x4 = quant_4x4_around; - quant_ac4x4 = quant_ac4x4_around; - quant_ac4x4cr = quant_ac4x4_around; + quant_4x4 = quant_4x4_around; + quant_dc4x4 = quant_dc4x4_normal; + quant_ac4x4 = quant_ac4x4_around; } else { quant_4x4 = quant_4x4_normal; + quant_dc4x4 = quant_dc4x4_normal; quant_ac4x4 = quant_ac4x4_normal; - quant_ac4x4cr = quant_ac4x4_normal; } } diff --git a/lencod/src/quant4x4_around.c b/lencod/src/quant4x4_around.c index 6a105ba..a108075 100644 --- a/lencod/src/quant4x4_around.c +++ b/lencod/src/quant4x4_around.c @@ -9,6 +9,7 @@ * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Limin Liu <limin.liu@dolby.com> * ************************************************************************************* */ @@ -65,36 +66,44 @@ int quant_4x4_around(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - if (level != 0) + if (*m7 != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); - - fadjust4x4[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), q_bits + 1); - - nonzero = TRUE; - - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; - - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); - // inverse scale can be alternative performed as follows to ensure 16bit - // arithmetic is satisfied. - // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); - *ACL++ = level; - *ACR++ = run; - // reset zero level counter - run = 0; + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + fadjust4x4[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), q_bits + 1); + + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); + // inverse scale can be alternative performed as follows to ensure 16bit + // arithmetic is satisfied. + // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + fadjust4x4[j][block_x + i] = 0; + run++; + *m7 = 0; + } } else { fadjust4x4[j][block_x + i] = 0; run++; - *m7 = 0; - } + } } *ACL = 0; @@ -105,7 +114,7 @@ int quant_4x4_around(int (*tblock)[16], int block_y, int block_x, int qp, int quant_ac4x4_around(int (*tblock)[16], int block_y, int block_x, int qp, int* ACLevel, int* ACRun, int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost) + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type) { static int i,j, coeff_ctr; @@ -127,39 +136,116 @@ int quant_ac4x4_around(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - - if (level != 0) + if (*m7 != 0) + { + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + fadjust4x4[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1)); + + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); + // inverse scale can be alternative performed as follows to ensure 16bit + // arithmetic is satisfied. + // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + fadjust4x4[j][block_x + i] = 0; + run++; + *m7 = 0; + } + } + else { - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); + fadjust4x4[j][block_x + i] = 0; + run++; + } + } - fadjust4x4[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1)); - nonzero = TRUE; + *ACL = 0; + + return nonzero; +} + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 4x4 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc4x4_around(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + static int *m7; + static int scaled_coeff; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int q_bits = Q_BITS + qp_per + 1; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); - // inverse scale can be alternative performed as follows to ensure 16bit - // arithmetic is satisfied. - // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); - *ACL++ = level; - *ACR++ = run; + // Quantization + for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++) + { + i = *p_scan++; // horizontal position + j = *p_scan++; // vertical position + + m7 = &tblock[j][i]; + + if (*m7 != 0) + { + scaled_coeff = iabs (*m7) * levelscale; + level = (scaled_coeff + (leveloffset[0][0] << 1) ) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + level = isignab(level, *m7); + + *m7 = level; + *DCL++ = level; + *DCR++ = run; // reset zero level counter - run = 0; + run = 0; + nonzero = TRUE; } else { - fadjust4x4[j][block_x + i] = 0; run++; *m7 = 0; - } + } + } + else + { + run++; + } } - *ACL = 0; + *DCL = 0; return nonzero; } - diff --git a/lencod/src/quant4x4_normal.c b/lencod/src/quant4x4_normal.c index 378b190..e510073 100644 --- a/lencod/src/quant4x4_normal.c +++ b/lencod/src/quant4x4_normal.c @@ -9,6 +9,7 @@ * \author * Main contributors (see contributors.h for copyright, address and affiliation details) * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Limin Liu <limin.liu@dolby.com> * ************************************************************************************* */ @@ -64,33 +65,40 @@ int quant_4x4_normal(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - if (level != 0) + if (*m7 != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); - - nonzero = TRUE; - - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; - - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); - // inverse scale can be alternative performed as follows to ensure 16bit - // arithmetic is satisfied. - // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); - *ACL++ = level; - *ACR++ = run; - // reset zero level counter - run = 0; + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); + // inverse scale can be alternative performed as follows to ensure 16bit + // arithmetic is satisfied. + // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } } else { run++; - *m7 = 0; - } + } } *ACL = 0; @@ -101,7 +109,7 @@ int quant_4x4_normal(int (*tblock)[16], int block_y, int block_x, int qp, int quant_ac4x4_normal(int (*tblock)[16], int block_y, int block_x, int qp, int* ACLevel, int* ACRun, int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost) + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type) { static int i,j, coeff_ctr; @@ -123,37 +131,115 @@ int quant_ac4x4_normal(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - - if (level != 0) + if (*m7 != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); - - nonzero = TRUE; - - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; - - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); - // inverse scale can be alternative performed as follows to ensure 16bit - // arithmetic is satisfied. - // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); - *ACL++ = level; - *ACR++ = run; - // reset zero level counter - run = 0; + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 4); + // inverse scale can be alternative performed as follows to ensure 16bit + // arithmetic is satisfied. + // *m7 = (qp_per<4) ? rshift_rnd_sf((level*invlevelscale[j][i]),4-qp_per) : (level*invlevelscale[j][i])<<(qp_per-4); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } } else { run++; - *m7 = 0; - } + } } *ACL = 0; return nonzero; } + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 4x4 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc4x4_normal(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; + + static int *m7; + static int scaled_coeff; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int q_bits = Q_BITS + qp_per + 1; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + // Quantization + for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++) + { + i = *p_scan++; // horizontal position + j = *p_scan++; // vertical position + + m7 = &tblock[j][i]; + + if (*m7 != 0) + { + scaled_coeff = iabs (*m7) * levelscale; + level = (scaled_coeff + (leveloffset[0][0] << 1) ) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + level = isignab(level, *m7); + + *m7 = level; + *DCL++ = level; + *DCR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } + } + else + { + run++; + } + } + + *DCL = 0; + + return nonzero; +} + diff --git a/lencod/src/quant4x4_trellis.c b/lencod/src/quant4x4_trellis.c index e4ccc8b..93cc524 100644 --- a/lencod/src/quant4x4_trellis.c +++ b/lencod/src/quant4x4_trellis.c @@ -8,6 +8,8 @@ * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Qualcomm + * - Limin Liu <limin.liu@dolby.com> * ************************************************************************************* */ @@ -28,7 +30,7 @@ #include "quant4x4.h" #include "rdo_quant.h" -const int estErr4x4[6][4][4]= +const int estErr4x4[6][4][4] = { { {25600, 27040, 25600, 27040}, @@ -69,10 +71,11 @@ const int estErr4x4[6][4][4]= }; -void rdoq_4x4(int (*tblock)[16], int block_y, int block_x,int qp_per, int qp_rem, +void rdoq_4x4(int (*tblock)[16], int block_y, int block_x, int qp_per, int qp_rem, int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[16]); -void rdoq_ac4x4(int (*tblock)[16] , int block_x, int qp_per, int qp_rem, - int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[16]); + +void rdoq_ac4x4(int (*tblock)[16] , int block_y, int block_x, int qp_per, int qp_rem, + int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[16], int type); /*! ************************************************************************ @@ -102,9 +105,9 @@ int quant_4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, int* ACL = &ACLevel[0]; int* ACR = &ACRun[0]; - int levelTrellis[16]; + static int levelTrellis[16]; - rdoq_4x4(tblock,block_y,block_x,qp_per,qp_rem,levelscale,leveloffset,pos_scan, levelTrellis); + rdoq_4x4(tblock, block_y, block_x, qp_per, qp_rem, levelscale, leveloffset, pos_scan, levelTrellis); // Quantization for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++) @@ -113,6 +116,8 @@ int quant_4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; + if (*m7 != 0) + { /* scaled_coeff = iabs (*m7) * levelscale[j][i]; level = (scaled_coeff + leveloffset[j][i]) >> q_bits; @@ -121,7 +126,7 @@ int quant_4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, if (level != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) + if (params->symbol_mode == CAVLC) level = imin(level, CAVLC_LEVEL_LIMIT); nonzero = TRUE; @@ -139,7 +144,12 @@ int quant_4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, { run++; *m7 = 0; - } + } + } + else + { + run++; + } } *ACL = 0; @@ -155,23 +165,15 @@ int quant_4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, * ************************************************************************ */ -void rdoq_4x4(int (*tblock)[16], int block_y, int block_x,int qp_per, int qp_rem, - int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[16]) +void rdoq_4x4(int (*tblock)[16], int block_y, int block_x, int qp_per, int qp_rem, + int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[]) { - static int i,j, coeff_ctr; - - static int *m7; - - int level; - - int q_bits = Q_BITS + qp_per; - - int m4[4][4], ii; + const byte *p_scan = &pos_scan[0][0]; levelDataStruct levelData[16]; - double lambda_md=0, normFact=pow(2,(2*DQ_BITS+19)); - double err; - int lowerInt, kStart=0, kStop=0, noCoeff = 0, estBits; + double lambda_md = 0; + int kStart=0, kStop=0, noCoeff = 0, estBits; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + int type = LUMA_4x4; if ((img->type==B_SLICE) && img->nal_reference_idc) { @@ -182,69 +184,26 @@ void rdoq_4x4(int (*tblock)[16], int block_y, int block_x,int qp_per, int qp_rem lambda_md = img->lambda_md[img->type][img->masterQP]; } - for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++) - { - i = pos_scan[coeff_ctr][0]; - j = pos_scan[coeff_ctr][1]; - - m7 = &tblock[j][block_x]; - m4[j][i] = m7[i]; - } - - for (coeff_ctr=0;coeff_ctr < 16; coeff_ctr++) - { - i=pos_scan[coeff_ctr][0]; - j=pos_scan[coeff_ctr][1]; - - levelData[coeff_ctr].levelDouble = iabs(m4[j][i] * levelscale[i][j]); - level=(levelData[coeff_ctr].levelDouble>>q_bits); - - lowerInt=(((int)levelData[coeff_ctr].levelDouble - (level<<q_bits))<(1<<(q_bits-1)))? 1 : 0; - - levelData[coeff_ctr].level[0]=0; - if (level==0 && lowerInt==1) - { - levelData[coeff_ctr].noLevels=1; - } - else if (level==0 && lowerInt==0) - { - levelData[coeff_ctr].level[1] = level+1; - levelData[coeff_ctr].noLevels=2; - kStop=coeff_ctr; - noCoeff++; - } - else if (level>0 && lowerInt==1) - { - levelData[coeff_ctr].level[1] = level; - levelData[coeff_ctr].noLevels=2; - kStop=coeff_ctr; - noCoeff++; - } - else - { - levelData[coeff_ctr].level[1] = level; - levelData[coeff_ctr].level[2] = level+1; - levelData[coeff_ctr].noLevels=3; - kStop=coeff_ctr; - kStart=coeff_ctr; - noCoeff++; - } - - for (ii=0; ii<levelData[coeff_ctr].noLevels; ii++) - { - err=(double)(levelData[coeff_ctr].level[ii]<<q_bits)-(double)levelData[coeff_ctr].levelDouble; - levelData[coeff_ctr].errLevel[ii] = (err * err * (double) estErr4x4[qp_rem][i][j]) / normFact; - } - } - - estBits=est_write_and_store_CBP_block_bit(currMB, LUMA_4x4, block_y, block_x); + noCoeff = init_trellis_data(tblock, block_x, qp_per, qp_rem, levelscale, leveloffset, p_scan, currMB, levelData, &kStart, &kStop, type); + estBits = est_write_and_store_CBP_block_bit(currMB, LUMA_4x4); est_writeRunLevel_CABAC(levelData, levelTrellis, LUMA_4x4, lambda_md, kStart, kStop, noCoeff, estBits); } +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 4x4 block (LUMA_16AC or CHROMA_AC) + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, int* ACLevel, int* ACRun, int **fadjust4x4, int **levelscale, int **invlevelscale, int **leveloffset, - int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost) + int *coeff_cost, const byte (*pos_scan)[2], const byte *c_cost, int type) { static int i,j, coeff_ctr; @@ -257,9 +216,9 @@ int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, int* ACL = &ACLevel[0]; int* ACR = &ACRun[0]; - int levelTrellis[16]; + static int levelTrellis[16]; - rdoq_ac4x4(tblock, block_x, qp_per, qp_rem, levelscale, leveloffset, pos_scan, levelTrellis); + rdoq_ac4x4(tblock, block_y, block_x, qp_per, qp_rem, levelscale, leveloffset, pos_scan, levelTrellis, type); // Quantization for (coeff_ctr = 1; coeff_ctr < 16; coeff_ctr++) @@ -268,19 +227,19 @@ int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; + if (*m7 != 0) + { /* scaled_coeff = iabs (*m7) * levelscale[j][i]; level = (scaled_coeff + leveloffset[j][i]) >> q_bits; */ - level=levelTrellis[coeff_ctr-1]; + level=levelTrellis[coeff_ctr - 1]; if (level != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) + if (params->symbol_mode == CAVLC) level = imin(level, CAVLC_LEVEL_LIMIT); - nonzero = TRUE; - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; level = isignab(level, *m7); @@ -292,12 +251,18 @@ int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, *ACR++ = run; // reset zero level counter run = 0; + nonzero = TRUE; } else { run++; *m7 = 0; - } + } + } + else + { + run++; + } } *ACL = 0; @@ -305,23 +270,21 @@ int quant_ac4x4_trellis(int (*tblock)[16], int block_y, int block_x, int qp, return nonzero; } -void rdoq_ac4x4(int (*tblock)[16] , int block_x, int qp_per, int qp_rem, - int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[16]) +/*! +************************************************************************ +* \brief +* Rate distortion optimized Quantization process for +* all coefficients in a 4x4 block (LUMA_16AC or CHROMA_AC) +* +************************************************************************ +*/ +void rdoq_ac4x4(int (*tblock)[16] , int block_y, int block_x, int qp_per, int qp_rem, + int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[], int type) { - static int i,j, coeff_ctr; - - static int *m7; - - int level; - - int q_bits = Q_BITS + qp_per; const byte *p_scan = &pos_scan[1][0]; - - int k; levelDataStruct levelData[16]; - double lambda_md=0, normFact=pow(2,(2*DQ_BITS+19)); - double err; - int lowerInt, kStart=0, kStop=0, noCoeff=0, estBits; + double lambda_md=0; + int kStart = 0, kStop = 0, noCoeff = 0, estBits; Macroblock *currMB = &img->mb_data[img->current_mb_nr]; if ((img->type==B_SLICE) && img->nal_reference_idc) @@ -333,59 +296,82 @@ void rdoq_ac4x4(int (*tblock)[16] , int block_x, int qp_per, int qp_rem, lambda_md = img->lambda_md[img->type][img->masterQP]; } - for (coeff_ctr=0;coeff_ctr < 15;coeff_ctr++) + noCoeff = init_trellis_data(tblock, block_x, qp_per, qp_rem, levelscale, leveloffset, p_scan, currMB, levelData, &kStart, &kStop, type); + estBits = est_write_and_store_CBP_block_bit(currMB, type); + est_writeRunLevel_CABAC(levelData, levelTrellis, type, lambda_md, kStart, kStop, noCoeff, estBits); +} + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 4x4 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc4x4_trellis(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int levelscale, int invlevelscale, int **leveloffset, const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; + + static int *m7; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int qp_rem = qp_rem_matrix[qp]; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + static int levelTrellis[16]; + + rdoq_dc(tblock,qp_per,qp_rem, levelscale, leveloffset,pos_scan, levelTrellis, LUMA_16DC); + + // Quantization + for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++) { - // i=pos_scan[coeff_ctr+1][0]; // scan is shifted due to DC - //j=pos_scan[coeff_ctr+1][1]; // scan is shifted due to DC i = *p_scan++; // horizontal position j = *p_scan++; // vertical position - m7 = &tblock[j][block_x + i]; + m7 = &tblock[j][i]; - levelData[coeff_ctr].levelDouble=iabs(*m7 * levelscale[i][j]); - level=(levelData[coeff_ctr].levelDouble>>q_bits); + if (*m7 != 0) + { + level = levelTrellis[coeff_ctr]; - lowerInt=(((int)levelData[coeff_ctr].levelDouble - (level<<q_bits))<(1<<(q_bits-1)))? 1 : 0; + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); - levelData[coeff_ctr].level[0]=0; - if (level==0 && lowerInt==1) - { - levelData[coeff_ctr].noLevels=1; - } - else if (level==0 && lowerInt==0) - { - levelData[coeff_ctr].level[1] = level+1; - levelData[coeff_ctr].noLevels=2; - kStop=coeff_ctr; - noCoeff++; - } - else if (level>0 && lowerInt==1) - { - levelData[coeff_ctr].level[1] = level; - levelData[coeff_ctr].noLevels=2; - kStop=coeff_ctr; - noCoeff++; + level = isignab(level, *m7); + + *m7 = level; + *DCL++ = level; + *DCR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } } else { - levelData[coeff_ctr].level[1] = level; - levelData[coeff_ctr].level[2] = level+1; - levelData[coeff_ctr].noLevels=3; - kStop=coeff_ctr; - kStart=coeff_ctr; - noCoeff++; - } - - for (k=0; k<levelData[coeff_ctr].noLevels; k++) - { - err=(double)(levelData[coeff_ctr].level[k]<<q_bits)-(double)levelData[coeff_ctr].levelDouble; - levelData[coeff_ctr].errLevel[k]=(err*err*(double)estErr4x4[qp_rem][i][j])/normFact; - } + run++; + } } - estBits=est_write_and_store_CBP_block_bit(currMB, LUMA_16AC, 0, 0); - - est_writeRunLevel_CABAC(levelData, levelTrellis, LUMA_16AC, lambda_md, kStart, kStop, noCoeff, estBits); -} + *DCL = 0; + return nonzero; +} + diff --git a/lencod/src/quant8x8.c b/lencod/src/quant8x8.c index d2cd78d..ee42805 100644 --- a/lencod/src/quant8x8.c +++ b/lencod/src/quant8x8.c @@ -28,7 +28,7 @@ * ************************************************************************ */ -void init_quant_8x8(ImageParameters *img) +void init_quant_8x8(InputParameters *params, ImageParameters *img) { if (params->UseRDOQuant == 1) { diff --git a/lencod/src/quant8x8_around.c b/lencod/src/quant8x8_around.c index 7e7ff83..d913719 100644 --- a/lencod/src/quant8x8_around.c +++ b/lencod/src/quant8x8_around.c @@ -58,40 +58,45 @@ int quant_8x8_around(int (*tblock)[16], int block_y, int block_x, int qp, int* ACL = &ACLevel[0]; int* ACR = &ACRun[0]; -// Quantization + // Quantization for (coeff_ctr = 0; coeff_ctr < 64; coeff_ctr++) { i = *p_scan++; // horizontal position j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - - if (level != 0) + if (*m7 != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - fadjust8x8[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1)); + if (level != 0) + { + fadjust8x8[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1)); - nonzero = TRUE; + nonzero = TRUE; - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); - *ACL++ = level; - *ACR++ = run; - // reset zero level counter - run = 0; + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + } + else + { + fadjust8x8[j][block_x + i] = 0; + run++; + *m7 = 0; + } } else { fadjust8x8[j][block_x + i] = 0; run++; - *m7 = 0; - } + } } *ACL = 0; @@ -144,33 +149,41 @@ int quant_8x8cavlc_around(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - - if (level != 0) + if (*m7 != 0) { - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); - - fadjust8x8[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1)); - - nonzero=TRUE; - - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[k]]; - - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); - - *(ACL[k])++ = level; - *(ACR[k])++ = runs[k]; - // reset zero level counter - runs[k] = 0; + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + fadjust8x8[j][block_x + i] = rshift_rnd_sf((AdaptRndWeight * (scaled_coeff - (level << q_bits))), (q_bits + 1)); + + nonzero=TRUE; + + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[k]]; + + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); + + *(ACL[k])++ = level; + *(ACR[k])++ = runs[k]; + // reset zero level counter + runs[k] = 0; + } + else + { + fadjust8x8[j][block_x + i] = 0; + runs[k]++; + *m7 = 0; + } } else { fadjust8x8[j][block_x + i] = 0; runs[k]++; - *m7 = 0; } } } diff --git a/lencod/src/quant8x8_normal.c b/lencod/src/quant8x8_normal.c index e06f193..8167eed 100644 --- a/lencod/src/quant8x8_normal.c +++ b/lencod/src/quant8x8_normal.c @@ -51,7 +51,7 @@ int quant_8x8_normal(int (*tblock)[16], int block_y, int block_x, int qp, static int scaled_coeff; int level, run = 0; - int nonzero = FALSE; + int nonzero = FALSE; int qp_per = qp_per_matrix[qp]; int q_bits = Q_BITS_8 + qp_per; const byte *p_scan = &pos_scan[0][0]; @@ -65,27 +65,34 @@ int quant_8x8_normal(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - - if (level != 0) + if (*m7 != 0) { - nonzero = TRUE; + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + nonzero = TRUE; - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); - *ACL++ = level; - *ACR++ = run; - // reset zero level counter - run = 0; + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + } + else + { + run++; + *m7 = 0; + } } else { run++; - *m7 = 0; - } + } } *ACL = 0; @@ -93,7 +100,6 @@ int quant_8x8_normal(int (*tblock)[16], int block_y, int block_x, int qp, return nonzero; } - /*! ************************************************************************ * \brief @@ -139,6 +145,8 @@ int quant_8x8cavlc_normal(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; + if (*m7 != 0) + { scaled_coeff = iabs (*m7) * levelscale[j][i]; level = (scaled_coeff + leveloffset[j][i]) >> q_bits; @@ -160,8 +168,13 @@ int quant_8x8cavlc_normal(int (*tblock)[16], int block_y, int block_x, int qp, } else { + runs[k]++; + *m7 = 0; + } + } + else + { runs[k]++; - *m7 = 0; } } } @@ -171,3 +184,4 @@ int quant_8x8cavlc_normal(int (*tblock)[16], int block_y, int block_x, int qp, return nonzero; } + diff --git a/lencod/src/quant8x8_trellis.c b/lencod/src/quant8x8_trellis.c index a2c3e95..9a154a7 100644 --- a/lencod/src/quant8x8_trellis.c +++ b/lencod/src/quant8x8_trellis.c @@ -92,7 +92,7 @@ const int estErr8x8[6][8][8]={ }; void rdoq_8x8(int (*tblock)[16], int block_y, int block_x,int qp_per, int qp_rem, - int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[64]); + int **levelscale, int **leveloffset, const byte *p_scan, int levelTrellis[64]); /*! ************************************************************************ * \brief @@ -123,7 +123,7 @@ int quant_8x8_trellis(int (*tblock)[16], int block_y, int block_x, int qp, int levelTrellis[64]; - rdoq_8x8(tblock,block_y,block_x,qp_per,qp_rem,levelscale,leveloffset,pos_scan, levelTrellis); + rdoq_8x8(tblock,block_y,block_x,qp_per,qp_rem,levelscale,leveloffset,p_scan,levelTrellis); // Quantization for (coeff_ctr = 0; coeff_ctr < 64; coeff_ctr++) @@ -132,34 +132,37 @@ int quant_8x8_trellis(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - /* - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - */ - level = levelTrellis[coeff_ctr]; - - if (level != 0) - { - - if (params->symbol_mode == CAVLC && img->qp < 10) - level = imin(level, CAVLC_LEVEL_LIMIT); + if (*m7 != 0) + { + /* + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + */ + level = levelTrellis[coeff_ctr]; - nonzero = TRUE; + if (level != 0) + { + nonzero = TRUE; - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run]; - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); - *ACL++ = level; - *ACR++ = run; - // reset zero level counter - run = 0; + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); + *ACL++ = level; + *ACR++ = run; + // reset zero level counter + run = 0; + } + else + { + run++; + *m7 = 0; + } } else { run++; - *m7 = 0; - } + } } *ACL = 0; @@ -212,27 +215,36 @@ int quant_8x8cavlc_trellis(int (*tblock)[16], int block_y, int block_x, int qp, j = *p_scan++; // vertical position m7 = &tblock[j][block_x + i]; - scaled_coeff = iabs (*m7) * levelscale[j][i]; - level = (scaled_coeff + leveloffset[j][i]) >> q_bits; - - if (level != 0) + if (*m7 != 0) { - nonzero=TRUE; - - *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[k]]; - - level = isignab(level, *m7); - *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); - - *(ACL[k])++ = level; - *(ACR[k])++ = runs[k]; - // reset zero level counter - runs[k] = 0; + scaled_coeff = iabs (*m7) * levelscale[j][i]; + level = (scaled_coeff + leveloffset[j][i]) >> q_bits; + + if (level != 0) + { + level = imin(level, CAVLC_LEVEL_LIMIT); + + nonzero=TRUE; + + *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[k]]; + + level = isignab(level, *m7); + *m7 = rshift_rnd_sf(((level * invlevelscale[j][i]) << qp_per), 6); + + *(ACL[k])++ = level; + *(ACR[k])++ = runs[k]; + // reset zero level counter + runs[k] = 0; + } + else + { + runs[k]++; + *m7 = 0; + } } else - { + { runs[k]++; - *m7 = 0; } } } @@ -252,21 +264,13 @@ int quant_8x8cavlc_trellis(int (*tblock)[16], int block_y, int block_x, int qp, ************************************************************************ */ void rdoq_8x8(int (*tblock)[16], int block_y, int block_x,int qp_per, int qp_rem, - int **levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[64]) + int **levelscale, int **leveloffset, const byte *p_scan, int levelTrellis[64]) { - static int i,j, coeff_ctr; - - static int *m7; - - int level; - - int q_bits = Q_BITS_8 + qp_per; - - int m4[8][8], ii; levelDataStruct levelData[64]; - double lambda_md=0, normFact=pow(2,(2 * Q_BITS_8 + 9)); - double err; - int lowerInt, kStart=0, kStop=0, noCoeff = 0; + double lambda_md=0; + int kStart=0, kStop=0, noCoeff = 0; + Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + int type = LUMA_8x8; if ((img->type==B_SLICE) && img->nal_reference_idc) { @@ -277,61 +281,7 @@ void rdoq_8x8(int (*tblock)[16], int block_y, int block_x,int qp_per, int qp_rem lambda_md = img->lambda_md[img->type][img->masterQP]; } - for (coeff_ctr = 0; coeff_ctr < 64; coeff_ctr++) - { - i = pos_scan[coeff_ctr][0]; - j = pos_scan[coeff_ctr][1]; - - m7 = &tblock[j][block_x]; - m4[j][i] = m7[i]; - } - - for (coeff_ctr=0; coeff_ctr < 64; coeff_ctr++) - { - i=pos_scan[coeff_ctr][0]; - j=pos_scan[coeff_ctr][1]; - - levelData[coeff_ctr].levelDouble = iabs(m4[j][i] * levelscale[i][j]); - level=(levelData[coeff_ctr].levelDouble>>q_bits); - - lowerInt=(((int)levelData[coeff_ctr].levelDouble-(level<<q_bits))<(1<<(q_bits-1)))? 1 : 0; - - levelData[coeff_ctr].level[0]=0; - if (level==0 && lowerInt==1) - { - levelData[coeff_ctr].noLevels=1; - } - else if (level==0 && lowerInt==0) - { - levelData[coeff_ctr].level[1] = level+1; - levelData[coeff_ctr].noLevels=2; - kStop=coeff_ctr; - noCoeff++; - } - else if (level>0 && lowerInt==1) - { - levelData[coeff_ctr].level[1] = level; - levelData[coeff_ctr].noLevels=2; - kStop=coeff_ctr; - noCoeff++; - } - else - { - levelData[coeff_ctr].level[1] = level; - levelData[coeff_ctr].level[2] = level+1; - levelData[coeff_ctr].noLevels=3; - kStop=coeff_ctr; - kStart=coeff_ctr; - noCoeff++; - } - - for (ii=0; ii<levelData[coeff_ctr].noLevels; ii++) - { - err=(double)(levelData[coeff_ctr].level[ii]<<q_bits)-(double)levelData[coeff_ctr].levelDouble; - levelData[coeff_ctr].errLevel[ii] = (err * err * (double) estErr8x8[qp_rem][i][j]) / normFact; - } - } - + noCoeff = init_trellis_data(tblock, block_x, qp_per, qp_rem, levelscale, leveloffset, p_scan, currMB, levelData, &kStart, &kStop, type); est_writeRunLevel_CABAC(levelData, levelTrellis, LUMA_8x8, lambda_md, kStart, kStop, noCoeff, 0); } diff --git a/lencod/src/quantChroma.c b/lencod/src/quantChroma.c new file mode 100644 index 0000000..eeb4db7 --- /dev/null +++ b/lencod/src/quantChroma.c @@ -0,0 +1,57 @@ + +/*! + ************************************************************************************* + * \file quantChroma.c + * + * \brief + * Quantization initialization function for Chroma blocks + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + ************************************************************************************* + */ + +#include "contributors.h" + +#include "global.h" +#include "quant4x4.h" +#include "quantChroma.h" + +/*! +************************************************************************ +* \brief +* Quantization initialization function +* +************************************************************************ +*/ +void init_quant_Chroma(InputParameters *params, ImageParameters *img) +{ + if (params->UseRDOQuant == 1 && params->RDOQ_CR == 1) + { + quant_ac4x4cr = quant_ac4x4_trellis; + if (params->yuv_format == YUV422) + quant_dc_cr = quant_dc4x2_trellis; + else + quant_dc_cr = quant_dc2x2_trellis; + } + else if (params->UseRDOQuant == 1 || (!img->AdaptiveRounding)) + { + quant_ac4x4cr = quant_ac4x4_normal; + if (params->yuv_format == YUV422) + quant_dc_cr = quant_dc4x2_normal; + else + quant_dc_cr = quant_dc2x2_normal; + } + else + { + quant_ac4x4cr = quant_ac4x4_around; + if (params->yuv_format == YUV422) + quant_dc_cr = quant_dc4x2_around; + else + quant_dc_cr = quant_dc2x2_around; + } +} + + diff --git a/lencod/src/quantChroma_around.c b/lencod/src/quantChroma_around.c new file mode 100644 index 0000000..8541156 --- /dev/null +++ b/lencod/src/quantChroma_around.c @@ -0,0 +1,171 @@ + +/*! + ************************************************************************************* + * \file quantChroma_around.c + * + * \brief + * Quantization process for a Chroma block + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + ************************************************************************************* + */ + +#include "contributors.h" + +#include <math.h> + +#include "global.h" +#include "q_matrix.h" +#include "quant4x4.h" +#include "quantChroma.h" + + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 2x2 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc2x2_around(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]) +{ + static int coeff_ctr; + + static int *m7; + static int scaled_coeff; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int q_bits = Q_BITS + qp_per + 1; + //const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + m7 = *tblock; + + // Quantization + for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) + { + // we need to update leveloffset to a 4x1 array that would contain offset info for + // every 2x2 DC position + if (*m7) + { + scaled_coeff = iabs (*m7) * levelscale; + level = (scaled_coeff + (leveloffset[0][0] << 1) ) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + level = isignab(level, *m7); + + *m7++ = ((level * invlevelscale) << qp_per) >> 5; + + *DCL++ = level; + *DCR++ = run; + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7++ = 0; + } + } + else + { + run++; + m7++; + } + } + + *DCL = 0; + + return nonzero; +} + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 2x2 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc4x2_around(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; + + static int *m7; + static int scaled_coeff; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int q_bits = Q_BITS + qp_per + 1; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + // Quantization + for (coeff_ctr = 0; coeff_ctr < 8; coeff_ctr++) + { + j = *p_scan++; // note that in this part, somehow coefficients were transposed from 2x4 to 4x2. + i = *p_scan++; + + m7 = &tblock[j][i]; + + if (*m7 != 0) + { + scaled_coeff = iabs (*m7) * levelscale; + level = (scaled_coeff + (leveloffset[0][0] << 1) ) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + level = isignab(level, *m7); + + *m7 = rshift_rnd_sf(((level * invlevelscale) << qp_per), 6); + + *DCL++ = level; + *DCR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } + } + else + { + run++; + } + } + + *DCL = 0; + + return nonzero; +} + + + diff --git a/lencod/src/quantChroma_normal.c b/lencod/src/quantChroma_normal.c new file mode 100644 index 0000000..b5e8a3d --- /dev/null +++ b/lencod/src/quantChroma_normal.c @@ -0,0 +1,171 @@ + +/*! + ************************************************************************************* + * \file quantChroma_normal.c + * + * \brief + * Quantization process for a Chroma block + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + ************************************************************************************* + */ + +#include "contributors.h" + +#include <math.h> + +#include "global.h" +#include "q_matrix.h" +#include "quant4x4.h" +#include "quantChroma.h" + + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 2x2 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc2x2_normal(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]) +{ + static int coeff_ctr; + + static int *m7; + static int scaled_coeff; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int q_bits = Q_BITS + qp_per + 1; + //const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + m7 = *tblock; + + // Quantization + for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) + { + // we need to update leveloffset to a 4x1 array that would contain offset info for + // every 2x2 DC position + if (*m7) + { + scaled_coeff = iabs (*m7) * levelscale; + level = (scaled_coeff + (leveloffset[0][0] << 1) ) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + level = isignab(level, *m7); + + *m7++ = ((level * invlevelscale) << qp_per) >> 5; + + *DCL++ = level; + *DCR++ = run; + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7++ = 0; + } + } + else + { + run++; + m7++; + } + } + + *DCL = 0; + + return nonzero; +} + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 2x2 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc4x2_normal(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; + + static int *m7; + static int scaled_coeff; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int q_bits = Q_BITS + qp_per + 1; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + // Quantization + for (coeff_ctr = 0; coeff_ctr < 8; coeff_ctr++) + { + j = *p_scan++; // note that in this part, somehow coefficients were transposed from 2x4 to 4x2. + i = *p_scan++; + + m7 = &tblock[j][i]; + + if (*m7 != 0) + { + scaled_coeff = iabs (*m7) * levelscale; + level = (scaled_coeff + (leveloffset[0][0] << 1) ) >> q_bits; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + level = isignab(level, *m7); + + *m7 = rshift_rnd_sf(((level * invlevelscale) << qp_per), 6); + + *DCL++ = level; + *DCR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } + } + else + { + run++; + } + } + + *DCL = 0; + + return nonzero; +} + + + diff --git a/lencod/src/quantChroma_trellis.c b/lencod/src/quantChroma_trellis.c new file mode 100644 index 0000000..e2c388a --- /dev/null +++ b/lencod/src/quantChroma_trellis.c @@ -0,0 +1,173 @@ + +/*! + ************************************************************************************* + * \file quantChroma_trellis.c + * + * \brief + * Quantization process for a Chroma block (trellis based) + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + ************************************************************************************* + */ + +#include "contributors.h" + +#include <math.h> + +#include "global.h" +#include "q_matrix.h" +#include "quant4x4.h" +#include "quantChroma.h" +#include "rdo_quant.h" + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 2x2 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc2x2_trellis(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; + + static int *m7; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int qp_rem = qp_rem_matrix[qp]; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + static int levelTrellis[16]; + + rdoq_dc(tblock,qp_per,qp_rem, levelscale, leveloffset,pos_scan, levelTrellis, CHROMA_DC); + + for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) + { + j = *p_scan++; // note that in this part, coefficients were previously transposed from 2x4 to 4x2. + i = *p_scan++; + + m7 = &tblock[j][i]; + + if (*m7 != 0) + { + level = levelTrellis[coeff_ctr]; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + + level = isignab(level, *m7); + + *m7 = ((level * invlevelscale) << qp_per) >> 5; + + *DCL++ = level; + *DCR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } + } + else + { + run++; + } + } + + *DCL = 0; + + return nonzero; +} + +/*! + ************************************************************************ + * \brief + * Quantization process for All coefficients for a 2x2 DC block + * + * \par Input: + * + * \par Output: + * + ************************************************************************ + */ +int quant_dc4x2_trellis(int (*tblock)[4], int qp, int* DCLevel, int* DCRun, + int **fadjust, int levelscale, int invlevelscale, int **leveloffset, + const byte (*pos_scan)[2]) +{ + static int i,j, coeff_ctr; + + static int *m7; + + int level, run = 0; + int nonzero = FALSE; + int qp_per = qp_per_matrix[qp]; + int qp_rem = qp_rem_matrix[qp]; + const byte *p_scan = &pos_scan[0][0]; + int* DCL = &DCLevel[0]; + int* DCR = &DCRun[0]; + + static int levelTrellis[16]; + + rdoq_dc(tblock,qp_per,qp_rem, levelscale, leveloffset,pos_scan, levelTrellis, CHROMA_DC_2x4); + + for (coeff_ctr=0; coeff_ctr < 4; coeff_ctr++) + { + j = *p_scan++; // note that in this part, somehow coefficients were transposed from 2x4 to 4x2. + i = *p_scan++; + + m7 = &tblock[j][i]; + + if (*m7 != 0) + { + level = levelTrellis[coeff_ctr]; + + if (level != 0) + { + if (params->symbol_mode == CAVLC) + level = imin(level, CAVLC_LEVEL_LIMIT); + level = isignab(level, *m7); + + *m7 = rshift_rnd_sf(((level * invlevelscale) << qp_per), 6); + + *DCL++ = level; + *DCR++ = run; + // reset zero level counter + run = 0; + nonzero = TRUE; + } + else + { + run++; + *m7 = 0; + } + } + else + { + run++; + } + } + + *DCL = 0; + + return nonzero; +} + + diff --git a/lencod/src/ratectl.c b/lencod/src/ratectl.c index 6134a26..a06d534 100644 --- a/lencod/src/ratectl.c +++ b/lencod/src/ratectl.c @@ -57,7 +57,7 @@ void update_qp_cbp(Macroblock *currMB, short best_mode) currMB->delta_qp = 0; currMB->qp = currMB->prev_qp; img->qp = currMB->qp; - update_qp(currMB); + update_qp(img, currMB); } @@ -67,9 +67,6 @@ void update_qp_cbp(Macroblock *currMB, short best_mode) rdopt->qp = currMB->qp; rdopt->delta_qp = currMB->delta_qp; rdopt->prev_cbp = currMB->prev_cbp; - - delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp; - qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp; } } @@ -404,7 +401,7 @@ void update_qp_cbp_tmp(Macroblock *currMB, int cbp, int best_mode) currMB->delta_qp = 0; currMB->qp = currMB->prev_qp; img->qp = currMB->qp; - update_qp(currMB); + update_qp(img, currMB); } } diff --git a/lencod/src/rc_quadratic.c b/lencod/src/rc_quadratic.c index 7ccb9fe..2109d29 100644 --- a/lencod/src/rc_quadratic.c +++ b/lencod/src/rc_quadratic.c @@ -604,9 +604,12 @@ void rc_init_pict(rc_quadratic *prc, int fieldpic,int topfield,int targetcomputa /* update the total number of bits if the bandwidth is changed*/ if(prc->PrevBitRate != prc->bit_rate) generic_RC->RemainingBits +=(int) floor((prc->bit_rate-prc->PrevBitRate) * (prc->Np + prc->Nb) / prc->frame_rate+0.5); - if((prc->NumberofCodedPFrame==1)&&(generic_RC->NumberofCodedBFrame==1)) + if(generic_RC->NumberofCodedBFrame == 1) { - prc->AveWp = prc->Wp; + if(prc->NumberofCodedPFrame == 1) + { + prc->AveWp = prc->Wp; + } prc->AveWb = prc->Wb; } else if(generic_RC->NumberofCodedBFrame > 1) @@ -681,9 +684,6 @@ void rc_init_pict(rc_quadratic *prc, int fieldpic,int topfield,int targetcomputa } prc->Target = (int)(mult * prc->Target); - /* reserve some bits for smoothing */ - prc->Target = (int)((1.0 - 0.0 * params->successive_Bframe) * prc->Target); - /* HRD consideration */ if ( params->RCUpdateMode != RC_MODE_3 || img->type == P_SLICE ) prc->Target = iClip3(prc->LowerBound, prc->UpperBound2, prc->Target); @@ -2458,9 +2458,9 @@ void updateModelQPFrame( rc_quadratic *prc, int m_Bits ) * rate control at the MB level ************************************************************************************* */ -void rc_handle_mb( int prev_mb, Macroblock *currMB, Slice *curr_slice ) +int rc_handle_mb( int prev_mb, Macroblock *currMB, Slice *curr_slice ) { - int dq; + int mb_qp = img->qp; Macroblock *prevMB = NULL; if (prev_mb > -1) @@ -2468,154 +2468,66 @@ void rc_handle_mb( int prev_mb, Macroblock *currMB, Slice *curr_slice ) prevMB = &img->mb_data[prev_mb]; if ( params->MbInterlace == ADAPTIVE_CODING && !img->bot_MB && currMB->mb_field ) - currMB->qp = img->qp = prevMB->qp; - currMB->prev_qp = prevMB->qp; - - currMB->prev_dqp = (prevMB->slice_nr == img->current_slice_nr) ? prevMB->delta_qp : 0; - } - else - { - currMB->prev_qp = curr_slice->qp; - currMB->prev_dqp = 0; + mb_qp = prevMB->qp; } + // frame layer rate control - if (params->basicunit == img->FrameSizeInMbs) - { - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - currMB->prev_qp; - } - else // basic unit layer rate control + if (params->basicunit != img->FrameSizeInMbs) { // each I or B frame has only one QP if ( ((img->type == I_SLICE || img->type == B_SLICE) && params->RCUpdateMode != RC_MODE_1 ) || !(img->number) ) { - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - currMB->prev_qp; + return mb_qp; } else if ( img->type == P_SLICE || params->RCUpdateMode == RC_MODE_1 ) { if (!img->write_macroblock) //write macroblock { - if (prev_mb < 0) //first macroblock (of slice) - { - // Initialize delta qp change from last macroblock. Feature may be used for future rate control - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - currMB->prev_qp; - delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp; - qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp; - } - else + if (prev_mb > -1) { if (!((params->MbInterlace) && img->bot_MB)) //top macroblock { - prevMB = &img->mb_data[prev_mb]; - if (prevMB->prev_cbp == 1) - { - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - prevMB->qp; - } - else + if (prevMB->prev_cbp != 1) { - currMB->qp = img->qp = prevMB->prev_qp; - currMB->delta_qp = currMB->qp - prevMB->qp; + mb_qp = prevMB->prev_qp; } - delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp; - qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp; - } - else //bottom macroblock - { - // Initialize delta qp change from last macroblock. Feature may be used for future rate control - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - currMB->prev_qp; } } } - else - { - if (!img->bot_MB) //write top macroblock - { - if (img->write_mbaff_frame) - { - currMB->delta_qp = delta_qp_mbaff[0][img->bot_MB]; - currMB->qp = img->qp = qp_mbaff[0][img->bot_MB]; - } - else - { - if (prev_mb < 0) //first macroblock (of slice) - { - // Initialize delta qp change from last macroblock. Feature may be used for future rate control - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - currMB->prev_qp; - delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp; - qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp; - } - else - { - currMB->delta_qp = delta_qp_mbaff[1][img->bot_MB]; - currMB->qp = img->qp = qp_mbaff[1][img->bot_MB]; - } - } - } - else //write bottom macroblock - { - currMB->qp = img->qp; - currMB->delta_qp = currMB->qp - currMB->prev_qp; - } - } // compute the quantization parameter for each basic unit of P frame - + if (!img->write_macroblock) { - if(!((params->MbInterlace) && img->bot_MB)) { if(params->RCUpdateMode <= MAX_RC_MODE && (img->NumberofCodedMacroBlocks > 0) && (img->NumberofCodedMacroBlocks % img->BasicUnit == 0)) { + updateRCModel(quadratic_RC); // frame coding if(active_sps->frame_mbs_only_flag) { - updateRCModel(quadratic_RC); - img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag); - } - // picture adaptive field/frame coding - else if((params->PicInterlace!=FRAME_CODING)&&(!params->MbInterlace)&&(generic_RC->NoGranularFieldRC==0)) - { - updateRCModel(quadratic_RC); img->BasicUnitQP = updateQP(quadratic_RC, generic_RC->TopFieldFlag); + } - // mb adaptive f/f coding, field coding - else if((params->MbInterlace)) + // picture adaptive field/frame coding + else if(params->MbInterlace || ((params->PicInterlace!=FRAME_CODING) && (generic_RC->NoGranularFieldRC==0))) { - updateRCModel(quadratic_RC); img->BasicUnitQP = updateQP(quadratic_RC, generic_RC->TopFieldFlag); } } if(img->current_mb_nr==0) - img->BasicUnitQP=img->qp; - currMB->predict_qp = iClip3(currMB->qp - img->min_qp_delta, currMB->qp + img->max_qp_delta, img->BasicUnitQP); + img->BasicUnitQP = mb_qp; - dq = currMB->delta_qp + currMB->predict_qp - currMB->qp; - dq = iClip3(-img->min_qp_delta, img->max_qp_delta, dq); - currMB->predict_error = dq - currMB->delta_qp; - img->qp += currMB->predict_error; - currMB->qp = img->qp; - currMB->delta_qp = dq; - if (params->MbInterlace) - { - delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp; - qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp; - } + mb_qp = img->BasicUnitQP; + mb_qp = iClip3(-img->bitdepth_luma_qp_scale, 51, mb_qp); } - else - currMB->prev_qp = img->qp; } } } - - update_qp(currMB); + return mb_qp; } /*! @@ -2730,15 +2642,15 @@ void rc_free_memory( void ) void rc_update_mb_stats( Macroblock *currMB, int *bitCount ) { // Rate control - img->NumberofMBHeaderBits= bitCount[BITS_MB_MODE] + bitCount[BITS_INTER_MB] - + bitCount[BITS_CBP_MB ] + bitCount[BITS_DELTA_QUANT_MB]; - img->NumberofMBTextureBits= bitCount[BITS_COEFF_Y_MB]+ bitCount[BITS_COEFF_UV_MB]; + img->NumberofMBHeaderBits = bitCount[BITS_MB_MODE] + bitCount[BITS_INTER_MB] + + bitCount[BITS_CBP_MB ] + bitCount[BITS_DELTA_QUANT_MB]; + img->NumberofMBTextureBits = bitCount[BITS_COEFF_Y_MB]+ bitCount[BITS_COEFF_UV_MB]; switch (params->RCUpdateMode) { case RC_MODE_0: case RC_MODE_1: case RC_MODE_2: case RC_MODE_3: - generic_RC->NumberofTextureBits +=img->NumberofMBTextureBits; - generic_RC->NumberofHeaderBits +=img->NumberofMBHeaderBits; + generic_RC->NumberofTextureBits += img->NumberofMBTextureBits; + generic_RC->NumberofHeaderBits += img->NumberofMBHeaderBits; // basic unit layer rate control if(img->BasicUnit < img->FrameSizeInMbs) { diff --git a/lencod/src/rd_intra_jm.c b/lencod/src/rd_intra_jm.c index 3c215b0..ce114a1 100644 --- a/lencod/src/rd_intra_jm.c +++ b/lencod/src/rd_intra_jm.c @@ -15,28 +15,18 @@ ************************************************************************** */ -#include <math.h> #include <limits.h> #include "global.h" -#include "rdopt_coding_state.h" -#include "memalloc.h" -#include "mb_access.h" -#include "elements.h" -#include "intrarefresh.h" #include "image.h" -#include "transform8x8.h" -#include "cabac.h" -#include "vlc.h" -#include "ratectl.h" // head file for rate control -#include "mode_decision.h" #include "macroblock.h" -#include "symbol.h" -#include "q_offsets.h" +#include "mb_access.h" +#include "rdopt_coding_state.h" +#include "mode_decision.h" #include "rdopt.h" #include "rd_intra_jm.h" - +#include "q_around.h" /*! ************************************************************************************* @@ -46,10 +36,10 @@ */ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int b4, double lambda, double* min_cost, int cr_cbp[3]) { - int ipmode, best_ipmode = 0, i, j, y, dummy; - int c_nz, nonzero = 0; - int* ACLevel = img->cofAC[b8][b4][0]; - int* ACRun = img->cofAC[b8][b4][1]; + int ipmode, best_ipmode = 0, i, j, y, dummy; + int c_nz, nonzero = 0; + int* ACLevel = img->cofAC[b8][b4][0]; + int* ACRun = img->cofAC[b8][b4][1]; int c_nzCbCr[3]= {999,999, 999}; static imgpel rec4x4[4][4]; static imgpel rec4x4CbCr[2][4][4]; @@ -66,7 +56,7 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int int pic_block_y = pic_pix_y >> 2; double min_rdcost = 1e30; - int left_available, up_available, all_available; + int left_available, up_available, all_available; char upMode; char leftMode; @@ -131,15 +121,15 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int if( available_mode) { // get prediction and prediction error - generate_pred_error(&pCurImg[pic_opix_y], img->mpr_4x4[0][ipmode], &img->mpr[0][block_y], &img->m7[0][block_y], pic_opix_x, block_x); + generate_pred_error(&pCurImg[pic_opix_y], img->mpr_4x4[0][ipmode], &img->mb_pred[0][block_y], &img->mb_ores[0][block_y], pic_opix_x, block_x); if (img->yuv_format == YUV444) { - ipmode_DPCM=ipmode; + ipmode_DPCM = ipmode; if (!IS_INDEPENDENT(params)) { - generate_pred_error(&imgUV_org[0][pic_opix_y], img->mpr_4x4[1][ipmode], &img->mpr[1][block_y], &img->m7[1][block_y], pic_opix_x, block_x); - generate_pred_error(&imgUV_org[1][pic_opix_y], img->mpr_4x4[2][ipmode], &img->mpr[2][block_y], &img->m7[2][block_y], pic_opix_x, block_x); + generate_pred_error(&pImgOrg[1][pic_opix_y], img->mpr_4x4[1][ipmode], &img->mb_pred[1][block_y], &img->mb_ores[1][block_y], pic_opix_x, block_x); + generate_pred_error(&pImgOrg[2][pic_opix_y], img->mpr_4x4[2][ipmode], &img->mb_pred[2][block_y], &img->mb_ores[2][block_y], pic_opix_x, block_x); } } @@ -153,7 +143,7 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int { //--- set coefficients --- memcpy(cofAC4x4[0],ACLevel, 18 * sizeof(int)); - memcpy(cofAC4x4[1],ACRun, 18 * sizeof(int)); + memcpy(cofAC4x4[1],ACRun, 18 * sizeof(int)); //--- set reconstruction --- for (y=0; y<4; y++) @@ -200,7 +190,7 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int //store_coding_state (currMB, cs_ib4); if (img->AdaptiveRounding) { - store_adaptive_rounding (block_y, block_x); + store_adaptive_rounding (img, block_y, block_x); } } @@ -229,8 +219,8 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int { for (i=0; i<4; i++) { - img->mpr[k][block_y+j][block_x+i] = img->mpr_4x4[k][best_ipmode][j][i]; - img->m7[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[k][best_ipmode][j][i]; + img->mb_pred[k][block_y+j][block_x+i] = img->mpr_4x4[k][best_ipmode][j][i]; + img->mb_ores[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_4x4[k][best_ipmode][j][i]; } } cr_cbp[k] = pDCT_4x4(currMB, k, block_x,block_y,&dummy,1); @@ -245,7 +235,7 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int for (y=0; y<BLOCK_SIZE; y++) { memcpy (&enc_picture->imgY[pic_pix_y + y][pic_pix_x],rec4x4[y], BLOCK_SIZE * sizeof(imgpel)); - memcpy (&img->mpr[0][block_y + y][block_x],img->mpr_4x4[0][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel)); + memcpy (&img->mb_pred[0][block_y + y][block_x],img->mpr_4x4[0][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel)); } // SP/SI reconstuction @@ -253,7 +243,7 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int { for (y=0; y<BLOCK_SIZE; y++) { - memcpy (&lrec[pic_pix_y+y][pic_pix_x],lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame + memcpy (&lrec[pic_pix_y+y][pic_pix_x], lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame } } if (img->P444_joined) @@ -267,14 +257,14 @@ int Mode_Decision_for_4x4IntraBlocks_JM_High (Macroblock *currMB, int b8, int for (y=0; y<BLOCK_SIZE; y++) { memcpy(&enc_picture->imgUV[uv][pic_pix_y+y][pic_pix_x],rec4x4CbCr[uv][y], BLOCK_SIZE * sizeof(imgpel)); - memcpy(&img->mpr[uv + 1][block_y+y][block_x], img->mpr_4x4[uv + 1][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel)); + memcpy(&img->mb_pred[uv + 1][block_y+y][block_x], img->mpr_4x4[uv + 1][best_ipmode][y], BLOCK_SIZE * sizeof(imgpel)); } } } if (img->AdaptiveRounding) { - update_adaptive_rounding(block_y, block_x); + update_adaptive_rounding(img, block_y, block_x); } @@ -371,8 +361,8 @@ int Mode_Decision_for_4x4IntraBlocks_JM_Low (Macroblock *currMB, int b8, int if (img->P444_joined) { - compute_comp_cost(&imgUV_org[0][pic_opix_y], img->mpr_4x4[1][ipmode], pic_opix_x, &cost); - compute_comp_cost(&imgUV_org[1][pic_opix_y], img->mpr_4x4[2][ipmode], pic_opix_x, &cost); + compute_comp_cost(&pImgOrg[1][pic_opix_y], img->mpr_4x4[1][ipmode], pic_opix_x, &cost); + compute_comp_cost(&pImgOrg[2][pic_opix_y], img->mpr_4x4[2][ipmode], pic_opix_x, &cost); } if (cost < *min_cost) @@ -394,11 +384,11 @@ int Mode_Decision_for_4x4IntraBlocks_JM_Low (Macroblock *currMB, int b8, int (char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1)); // get prediction and prediction error - generate_pred_error(&pCurImg[pic_opix_y], img->mpr_4x4[0][best_ipmode], &img->mpr[0][block_y], &img->m7[0][block_y], pic_opix_x, block_x); + generate_pred_error(&pCurImg[pic_opix_y], img->mpr_4x4[0][best_ipmode], &img->mb_pred[0][block_y], &img->mb_ores[0][block_y], pic_opix_x, block_x); ipmode_DPCM=best_ipmode; - select_dct(currMB); + select_dct(img, currMB); nonzero = cr_cbp[0] = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1); if (img->P444_joined) @@ -411,8 +401,8 @@ int Mode_Decision_for_4x4IntraBlocks_JM_Low (Macroblock *currMB, int b8, int { for (i=0; i<4; i++) { - img->mpr[k][block_y+j][block_x+i] = img->mpr_4x4[k][best_ipmode][j][i]; - img->m7[k][block_y+j][block_x+i] = pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - img->mpr_4x4[k][best_ipmode][j][i]; + img->mb_pred[k][block_y+j][block_x+i] = img->mpr_4x4[k][best_ipmode][j][i]; + img->mb_ores[k][block_y+j][block_x+i] = pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - img->mpr_4x4[k][best_ipmode][j][i]; } } @@ -509,6 +499,7 @@ void Intra16x16_Mode_Decision (Macroblock* currMB, int* i16mode) { /* generate intra prediction samples for all 4 16x16 modes */ intrapred_16x16 (currMB, PLANE_Y); + if (img->P444_joined) { select_plane(PLANE_U); diff --git a/lencod/src/rdo_quant.c b/lencod/src/rdo_quant.c index 014a9ce..162da7a 100644 --- a/lencod/src/rdo_quant.c +++ b/lencod/src/rdo_quant.c @@ -39,7 +39,8 @@ const int entropyBits[128]= 151031, 153495, 155959, 158423, 160887, 163351, 165814, 168278, 170742, 173207, 175669, 178134, 180598, 183061, 185525, 187989 }; - +extern const int estErr4x4[6][4][4]; +extern const int estErr8x8[6][8][8]; extern const int maxpos []; extern const int type2ctx_bcbp[]; extern const int type2ctx_map []; @@ -289,6 +290,195 @@ int biari_state(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePt return(ctx_state); } +/*! +************************************************************************ +* \brief +* Rate distortion optimized Quantization process for +* all coefficients in a DC block (luma, chroma) +* +************************************************************************ +*/ +void rdoq_dc(int (*tblock)[4], int qp_per, int qp_rem, int levelscale, int **leveloffset, const byte (*pos_scan)[2], int levelTrellis[], int type) +{ + const byte *p_scan = &pos_scan[0][0]; + levelDataStruct levelData[16]; + double lambda_md = 0; + int kStart=0, kStop=0, noCoeff = 0, estBits; + Macroblock *currMB = &img->mb_data[img->current_mb_nr]; + + if ((img->type==B_SLICE) && img->nal_reference_idc) + { + lambda_md = img->lambda_md[5][img->masterQP]; + } + else + { + lambda_md = img->lambda_md[img->type][img->masterQP]; + } + + noCoeff = init_trellis_data_DC(tblock, qp_per, qp_rem, levelscale, leveloffset, p_scan, currMB, levelData, &kStart, &kStop, type); + estBits = est_write_and_store_CBP_block_bit(currMB, type); + est_writeRunLevel_CABAC(levelData, levelTrellis, type, lambda_md, kStart, kStop, noCoeff, estBits); +} + + + +/*! +**************************************************************************** +* \brief +* estimate CABAC CBP bits +**************************************************************************** +*/ +int init_trellis_data(int (*tblock)[16], int block_x, int qp_per, int qp_rem, int **levelscale, int **leveloffset, const byte *p_scan, Macroblock *currMB, + levelDataStruct levelData[], int* kStart, int* kStop, int type) +{ + int noCoeff = 0; + int i, j, coeff_ctr, end_coeff_ctr = ( (type == LUMA_8x8) ? 64 : ( (type == LUMA_4x4 || type == CHROMA_AC) ? 16 : 15 ) ); + static int *m7; + int q_bits; + double err, normFact; + int level, lowerInt, k; + + if (type == LUMA_8x8) + { + q_bits = Q_BITS_8 + qp_per; + normFact = pow(2,(2 * Q_BITS_8 + 9)); + } + else + { + q_bits = Q_BITS + qp_per; + normFact = pow(2,(2 * DQ_BITS + 19)); + } + + for (coeff_ctr = 0; coeff_ctr < end_coeff_ctr; coeff_ctr++) + { + i = *p_scan++; // horizontal position + j = *p_scan++; // vertical position + m7 = &tblock[j][block_x + i]; + + levelData[coeff_ctr].levelDouble = iabs(*m7 * levelscale[i][j]); + level = (levelData[coeff_ctr].levelDouble >> q_bits); + + lowerInt=( ((int)levelData[coeff_ctr].levelDouble - (level<<q_bits)) < ( 1 << (q_bits - 1) ) )? 1 : 0; + levelData[coeff_ctr].level[0] = 0; + + if (level == 0 && lowerInt == 1) + { + levelData[coeff_ctr].noLevels = 1; + } + else if (level == 0 && lowerInt == 0) + { + levelData[coeff_ctr].level[1] = level + 1; + levelData[coeff_ctr].noLevels = 2; + *kStop = coeff_ctr; + noCoeff++; + } + else if (level > 0 && lowerInt == 1) + { + levelData[coeff_ctr].level[1] = level; + levelData[coeff_ctr].noLevels = 2; + *kStop = coeff_ctr; + noCoeff++; + } + else + { + levelData[coeff_ctr].level[1] = level; + levelData[coeff_ctr].level[2] = level + 1; + levelData[coeff_ctr].noLevels = 3; + *kStop = coeff_ctr; + *kStart = coeff_ctr; + noCoeff++; + } + + for (k = 0; k < levelData[coeff_ctr].noLevels; k++) + { + err = (double)(levelData[coeff_ctr].level[k]<<q_bits)-(double)levelData[coeff_ctr].levelDouble; + if (type == LUMA_8x8) + levelData[coeff_ctr].errLevel[k] = (err*err*(double)estErr8x8[qp_rem][i][j])/normFact; + else + levelData[coeff_ctr].errLevel[k] = (err*err*(double)estErr4x4[qp_rem][i][j])/normFact; + } + } + return (noCoeff); +} + + +/*! +**************************************************************************** +* \brief +* estimate CABAC CBP bits for Luma DC +**************************************************************************** +*/ +int init_trellis_data_DC(int (*tblock)[4], int qp_per, int qp_rem, + int levelscale, int **leveloffset, const byte *p_scan, Macroblock *currMB, + levelDataStruct levelData[], int* kStart, int* kStop, int type) +{ + int noCoeff = 0; + int i, j, coeff_ctr, end_coeff_ctr; + static int *m7; + int q_bits; + double err, normFact; + int level, lowerInt, k; + + end_coeff_ctr = ( (type == LUMA_16DC || type == CB_16DC || type == CB_16DC || type == CHROMA_DC_4x4) ? 16 : ( (type == CHROMA_DC) ? 4 : 8 ) ); + q_bits = Q_BITS + qp_per + 1; + normFact = pow(2,(2 * DQ_BITS + 19)); + + for (coeff_ctr = 0; coeff_ctr < end_coeff_ctr; coeff_ctr++) + { + if (type == LUMA_16DC) + { + i = *p_scan++; // horizontal position + j = *p_scan++; // vertical position + } + else + { + j = *p_scan++; // horizontal position + i = *p_scan++; // vertical position + } + m7 = &tblock[j][i]; + + levelData[coeff_ctr].levelDouble = iabs(*m7 * levelscale); + level = (levelData[coeff_ctr].levelDouble >> q_bits); + + lowerInt=( ((int)levelData[coeff_ctr].levelDouble - (level<<q_bits)) < ( 1 << (q_bits - 1) ) )? 1 : 0; + levelData[coeff_ctr].level[0] = 0; + if (level == 0 && lowerInt == 1) + { + levelData[coeff_ctr].noLevels = 1; + } + else if (level == 0 && lowerInt == 0) + { + levelData[coeff_ctr].level[1] = level + 1; + levelData[coeff_ctr].noLevels = 2; + *kStop = coeff_ctr; + noCoeff++; + } + else if (level > 0 && lowerInt == 1) + { + levelData[coeff_ctr].level[1] = level; + levelData[coeff_ctr].noLevels = 2; + *kStop = coeff_ctr; + noCoeff++; + } + else + { + levelData[coeff_ctr].level[1] = level; + levelData[coeff_ctr].level[2] = level + 1; + levelData[coeff_ctr].noLevels = 3; + *kStop = coeff_ctr; + *kStart = coeff_ctr; + noCoeff++; + } + + for (k = 0; k < levelData[coeff_ctr].noLevels; k++) + { + err = (double)(levelData[coeff_ctr].level[k]<<q_bits)-(double)levelData[coeff_ctr].levelDouble; + levelData[coeff_ctr].errLevel[k] = (err*err*(double)estErr4x4[qp_rem][0][0])/normFact; + } + } + return (noCoeff); +} + /*! **************************************************************************** @@ -296,61 +486,142 @@ int biari_state(EncodingEnvironmentPtr eep, signed short symbol, BiContextTypePt * estimate CABAC CBP bits **************************************************************************** */ -int est_write_and_store_CBP_block_bit(Macroblock* currMB, int type, int block_y, int block_x) // marta - CBP +/*! +**************************************************************************** +* \brief +* estimate CABAC CBP bits +**************************************************************************** +*/ +int est_write_and_store_CBP_block_bit(Macroblock* currMB, int type) { #define BIT_SET(x,n) ((int)(((x)&((int64)1<<(n)))>>(n))) - int bit, default_bit = (IS_INTRA(currMB) ? 1 : 0); + int y_ac = (type==LUMA_16AC || type==LUMA_8x8 || type==LUMA_8x4 || type==LUMA_4x8 || type==LUMA_4x4 + || type==CB_16AC || type==CB_8x8 || type==CB_8x4 || type==CB_4x8 || type==CB_4x4 + || type==CR_16AC || type==CR_8x8 || type==CR_8x4 || type==CR_4x8 || type==CR_4x4); + int y_dc = (type==LUMA_16DC || type==CB_16DC || type==CR_16DC); + int u_ac = (type==CHROMA_AC && !img->is_v_block); + int v_ac = (type==CHROMA_AC && img->is_v_block); + int chroma_dc = (type==CHROMA_DC || type==CHROMA_DC_2x4 || type==CHROMA_DC_4x4); + int u_dc = (chroma_dc && !img->is_v_block); + int v_dc = (chroma_dc && img->is_v_block); + int j = ((y_ac || u_ac || v_ac ? img->subblock_y : 0) << 2); + int i = (y_ac || u_ac || v_ac ? img->subblock_x : 0); + int bit; + int default_bit = (IS_INTRA(currMB) ? 1 : 0); int upper_bit = default_bit; int left_bit = default_bit; - int ctx, estBits; + int ctx, estBits = 0; int bit_pos_a = 0; int bit_pos_b = 0; - int *mb_size = img->mb_size[IS_LUMA]; - if (type!=LUMA_8x8) + PixelPos block_a, block_b; + + if (y_ac || y_dc) { - PixelPos block_a, block_b; + get4x4Neighbour(currMB, (i << 2) - 1, j , img->mb_size[IS_LUMA], &block_a); + get4x4Neighbour(currMB, (i << 2), j -1, img->mb_size[IS_LUMA], &block_b); + if (y_ac) + { + if (block_a.available) + bit_pos_a = 4*block_a.y + block_a.x; + if (block_b.available) + bit_pos_b = 4*block_b.y + block_b.x; + } + } + else + { + get4x4Neighbour(currMB, (i << 2) - 1, j , img->mb_size[IS_CHROMA], &block_a); + get4x4Neighbour(currMB, (i << 2), j - 1, img->mb_size[IS_CHROMA], &block_b); + if (u_ac||v_ac) + { + if (block_a.available) + bit_pos_a = (block_a.y << 2) + block_a.x; + if (block_b.available) + bit_pos_b = (block_b.y << 2) + block_b.x; + } + } - get4x4Neighbour (currMB, block_x - 1 , block_y , mb_size, &block_a); - get4x4Neighbour (currMB, block_x , block_y - 1, mb_size, &block_b); + bit = (y_dc ? 0 : y_ac ? 1 : u_dc ? 17 : v_dc ? 18 : u_ac ? 19 : 35); - if (block_a.available) - bit_pos_a = 4*block_a.y + block_a.x; - if (block_b.available) - bit_pos_b = 4*block_b.y + block_b.x; + if (enc_picture->chroma_format_idc!=YUV444 || IS_INDEPENDENT(params)) + { + if (type!=LUMA_8x8) + { + if (block_b.available) + { + if(img->mb_data[block_b.mb_addr].mb_type==IPCM) + upper_bit=1; + else + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits[0],bit+bit_pos_b); + } - bit = 1; // 4x4: bit=1 + if (block_a.available) + { + if(img->mb_data[block_a.mb_addr].mb_type==IPCM) + left_bit=1; + else + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[0],bit+bit_pos_a); + } + ctx = 2*upper_bit+left_bit; + //===== encode symbol ===== + estBits=estBitsCabac[type].blockCbpBits[ctx][0]-estBitsCabac[type].blockCbpBits[ctx][1]; + } + } + else + { if (block_b.available) { - if(img->mb_data[block_b.mb_addr].mb_type==IPCM) + if(img->mb_data[block_b.mb_addr].mb_type == IPCM) upper_bit=1; else - upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits[0],bit+bit_pos_b); + { + if(type==LUMA_8x8) + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits_8x8[0], bit + bit_pos_b); + else if (type==CB_8x8) + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits_8x8[1], bit + bit_pos_b); + else if (type==CR_8x8) + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits_8x8[2], bit + bit_pos_b); + else if ((type==CB_4x4)||(type==CB_4x8)||(type==CB_8x4)||(type==CB_16AC)||(type==CB_16DC)) + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits[1], bit + bit_pos_b); + else if ((type==CR_4x4)||(type==CR_4x8)||(type==CR_8x4)||(type==CR_16AC)||(type==CR_16DC)) + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits[2], bit + bit_pos_b); + else + upper_bit = BIT_SET(img->mb_data[block_b.mb_addr].cbp_bits[0], bit + bit_pos_b); + } } - if (block_a.available) { if(img->mb_data[block_a.mb_addr].mb_type==IPCM) - left_bit=1; + left_bit = 1; else - left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[0],bit+bit_pos_a); + { + if(type==LUMA_8x8) + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[0],bit + bit_pos_a); + else if (type==CB_8x8) + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[1],bit + bit_pos_a); + else if (type==CR_8x8) + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits_8x8[2],bit + bit_pos_a); + else if ((type==CB_4x4)||(type==CB_4x8)||(type==CB_8x4)||(type==CB_16AC)||(type==CB_16DC)) + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[1],bit + bit_pos_a); + else if ((type==CR_4x4)||(type==CR_4x8)||(type==CR_8x4)||(type==CR_16AC)||(type==CR_16DC)) + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[2],bit + bit_pos_a); + else + left_bit = BIT_SET(img->mb_data[block_a.mb_addr].cbp_bits[0],bit + bit_pos_a); + } } ctx = 2*upper_bit+left_bit; + //===== encode symbol ===== estBits=estBitsCabac[type].blockCbpBits[ctx][0]-estBitsCabac[type].blockCbpBits[ctx][1]; } - else - { - estBits=0; - } + return(estBits); } - /*! **************************************************************************** * \brief @@ -361,7 +632,7 @@ void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int int noCoeff, int estCBP) { int k, i; - int estBits; + int estBits; double lagr, lagrMin=0, lagrTabMin, lagrTab; int c1 = 1, c2 = 0, c1Tab[3], c2Tab[3]; int iBest, levelTab[64]; @@ -369,25 +640,24 @@ void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int double lagrAcc, lagrLastMin=0, lagrLast; int kBest=0, kStart, first; - maxK=maxpos[type]; - for (k=0; k<=maxK; k++) + maxK = maxpos[type]; + for (k = 0; k <= maxK; k++) { - levelTabMin[k]=0; + levelTabMin[k] = 0; } - if (noCoeff>0) + if (noCoeff > 0) { - if (noCoeff>1) + if (noCoeff > 1) { - kStart=kInit; kBest=0; first=1; - - lagrAcc=0; - for (k=kStart; k<=kStop; k++) + kStart = kInit; kBest = 0; first = 1; + lagrAcc = 0; + for (k = kStart; k <= kStop; k++) { - lagrAcc+=levelData[k].errLevel[0]; + lagrAcc += levelData[k].errLevel[0]; } - if (levelData[kStart].noLevels>2) + if (levelData[kStart].noLevels > 2) { lagrAcc-=levelData[kStart].errLevel[0]; lagrLastMin=lambda*(estBitsCabac[type].lastBits[pos2ctx_last[type][kStart]][1]-estBitsCabac[type].lastBits[pos2ctx_last[type][kStart]][0])+lagrAcc; @@ -397,32 +667,30 @@ void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int first=0; } - for (k=kStart; k<=kStop; k++) + for (k = kStart; k <= kStop; k++) { lagrMin=levelData[k].errLevel[0]+lambda*estBitsCabac[type].significantBits[pos2ctx_map[type][k]][0]; - lagrAcc-=levelData[k].errLevel[0]; + lagrAcc -= levelData[k].errLevel[0]; if (levelData[k].noLevels>1) { - estBits=SIGN_BITS+estBitsCabac[type].significantBits[pos2ctx_map[type][k]][1]+ + estBits = SIGN_BITS+estBitsCabac[type].significantBits[pos2ctx_map[type][k]][1]+ estBitsCabac[type].greaterOneBits[0][4][0]; - lagrLast=levelData[k].errLevel[1]+lambda*(estBits+estBitsCabac[type].lastBits[pos2ctx_last[type][k]][1])+lagrAcc; - lagr=levelData[k].errLevel[1]+lambda*(estBits+estBitsCabac[type].lastBits[pos2ctx_last[type][k]][0]); + lagrLast = levelData[k].errLevel[1]+lambda*(estBits+estBitsCabac[type].lastBits[pos2ctx_last[type][k]][1])+lagrAcc; + lagr = levelData[k].errLevel[1]+lambda*(estBits+estBitsCabac[type].lastBits[pos2ctx_last[type][k]][0]); lagrMin=(lagr<lagrMin)?lagr:lagrMin; - if (lagrLast<lagrLastMin || first==1) + if (lagrLast < lagrLastMin || first==1) { - kBest=k; - first=0; - lagrLastMin=lagrLast; + kBest = k; + first = 0; + lagrLastMin = lagrLast; } - } lagrAcc+=lagrMin; } - kStart=kBest; } else @@ -430,52 +698,52 @@ void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int kStart=kStop; } - lagrTabMin=0; - for (k=0; k<=kStart; k++) + lagrTabMin = 0; + for (k = 0; k <= kStart; k++) { - lagrTabMin+=levelData[k].errLevel[0]; + lagrTabMin += levelData[k].errLevel[0]; } // Initial Lagrangian calculation lagrTab=0; ////////////////////////// - lagrTabMin+=(lambda*estCBP); - iBest=0; first=1; - for (k=kStart; k>=0; k--) + lagrTabMin += (lambda*estCBP); + iBest = 0; first = 1; + for (k = kStart; k >= 0; k--) { - last=(k==kStart); + last = (k == kStart); if (!last) { lagrMin=levelData[k].errLevel[0]+lambda*estBitsCabac[type].significantBits[pos2ctx_map[type][k]][0]; - iBest=0; - first=0; + iBest = 0; + first = 0; } - for (i=1; i < levelData[k].noLevels; i++) + for (i = 1; i < levelData[k].noLevels; i++) { - estBits=SIGN_BITS+estBitsCabac[type].significantBits[pos2ctx_map[type][k]][1]; - estBits+=estBitsCabac[type].lastBits[pos2ctx_last[type][k]][last]; + estBits = SIGN_BITS + estBitsCabac[type].significantBits[pos2ctx_map[type][k]][1]; + estBits += estBitsCabac[type].lastBits[pos2ctx_last[type][k]][last]; // greater than 1 - greater_one = (levelData[k].level[i]>1); + greater_one = (levelData[k].level[i] > 1); c1Tab[i]=c1; c2Tab[i]=c2; - ctx = imin(c1Tab[i],4); - estBits+=estBitsCabac[type].greaterOneBits[0][ctx][greater_one]; + ctx = imin(c1Tab[i], 4); + estBits += estBitsCabac[type].greaterOneBits[0][ctx][greater_one]; // magnitude if greater than 1 if (greater_one) { ctx = imin(c2Tab[i], max_c2[type]); - if ((levelData[k].level[i]-2)<MAX_PREC_COEFF) + if ( (levelData[k].level[i] - 2) < MAX_PREC_COEFF) { - estBits+=precalcUnaryLevelTab[estBitsCabac[type].greaterOneState[ctx]][levelData[k].level[i]-2]; + estBits += precalcUnaryLevelTab[estBitsCabac[type].greaterOneState[ctx]][levelData[k].level[i] - 2]; } else { - estBits+=est_unary_exp_golomb_level_encode(levelData[k].level[i]-2, ctx, type); + estBits += est_unary_exp_golomb_level_encode(levelData[k].level[i] - 2, ctx, type); } c1Tab[i] = 0; @@ -486,12 +754,12 @@ void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int c1Tab[i]++; } - lagr=levelData[k].errLevel[i]+lambda*estBits; + lagr = levelData[k].errLevel[i] + lambda*estBits; if (lagr<lagrMin || first==1) { - iBest=i; + iBest = i; lagrMin=lagr; - first=0; + first = 0; } } @@ -500,16 +768,16 @@ void est_writeRunLevel_CABAC(levelDataStruct levelData[], int levelTabMin[], int c1=c1Tab[iBest]; c2=c2Tab[iBest]; } - levelTab[k]=levelData[k].level[iBest]; + levelTab[k] = levelData[k].level[iBest]; lagrTab+=lagrMin; } /////////////////////////////////// - if (lagrTab<lagrTabMin) + if (lagrTab < lagrTabMin) { - for (k=0; k<=kStart; k++) + for (k = 0; k <= kStart; k++) { - levelTabMin[k]=levelTab[k]; + levelTabMin[k] = levelTab[k]; } } } @@ -575,6 +843,8 @@ void trellis_mp(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb) estRunLevel_CABAC(currMB, LUMA_16AC); if (params->Transform8x8Mode) estRunLevel_CABAC(currMB, LUMA_8x8); + if (params->yuv_format != YUV400) + estRunLevel_CABAC(currMB, CHROMA_AC); qp_left = (currMB->mb_available_left) ? currMB->mb_available_left->qp : img->masterQP; qp_up = (currMB->mb_available_up) ? currMB->mb_available_up->qp : img->masterQP; @@ -611,20 +881,17 @@ void trellis_mp(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb) #endif if (img->current_mb_nr ==0 && deltaQP != 0) continue; - + reset_macroblock(currMB, prev_mb); currMB->qp = img->qp; currMB->delta_qp = currMB->qp - currMB->prev_qp; - update_qp (currMB); - - delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp; - qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp; + update_qp (img, currMB); encode_one_macroblock (currMB); if ( rddata_trellis_curr.min_rdcost < rddata_trellis_best.min_rdcost) copy_rddata_trellis(&rddata_trellis_best,rdopt); - + if (params->RDOQ_CP_MV) Motion_Selected = 1; @@ -633,6 +900,8 @@ void trellis_mp(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb) break; if ((params->RDOQ_Fast) && (rddata_trellis_curr.cbp == 0) && (rddata_trellis_curr.mb_type != 0)) break; + if ((params->RDOQ_Fast) && (rddata_trellis_best.mb_type == 0) && (rddata_trellis_best.cbp == 0)) + break; #endif } @@ -652,6 +921,8 @@ void trellis_sp(Macroblock *currMB, int CurrentMbAddr, Boolean prev_recode_mb) estRunLevel_CABAC(currMB, LUMA_16AC); if (params->Transform8x8Mode) estRunLevel_CABAC(currMB, LUMA_8x8); + if (params->yuv_format != YUV400) + estRunLevel_CABAC(currMB, CHROMA_AC); encode_one_macroblock (currMB); write_one_macroblock (currMB, 1, prev_recode_mb); @@ -721,7 +992,7 @@ void copy_rddata_trellis (RD_DATA *dest, RD_DATA *src) dest->delta_qp = src->delta_qp; dest->prev_cbp = src->prev_cbp; dest->cbp_blk = src->cbp_blk; - dest->bi_pred_me = src->bi_pred_me; + if (img->type != I_SLICE) { @@ -768,8 +1039,8 @@ void updateMV_mp(int *m_cost, short ref, int list, int h, int v, int blocktype, memcpy(img->all_mv[list][ref][blocktype][v+j][h+i], all_mv, 2 * sizeof(short)); } - SetMotionVectorPredictor (currMB, pred_mv, enc_picture->ref_idx[list], enc_picture->mv[list], ref, list, h<<2, v<<2, bsx, bsy); - + SetMotionVectorPredictor (currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, h<<2, v<<2, bsx, bsy); + if ( (tmp_pred_mv[0] != pred_mv[0]) || (tmp_pred_mv[1] != pred_mv[1]) ) { *m_cost -= MV_COST_SMP (lambda_factor[H_PEL], all_mv[0], all_mv[1], tmp_pred_mv[0], tmp_pred_mv[1]); diff --git a/lencod/src/rdopt.c b/lencod/src/rdopt.c index 3f61ca0..8ab8c05 100644 --- a/lencod/src/rdopt.c +++ b/lencod/src/rdopt.c @@ -22,6 +22,7 @@ #include "global.h" #include "rdopt.h" +#include "q_around.h" #include "rdopt_coding_state.h" #include "memalloc.h" #include "mb_access.h" @@ -40,29 +41,13 @@ #include "symbol.h" #include "q_offsets.h" #include "conformance.h" +#include "errdo.h" imgpel pred[16][16]; #define FASTMODE 1 //#define RESET_STATE -extern int QP2QUANT[40]; - -const int AdaptRndCrPos[2][5] = -{ - // P, B, I, SP, SI - { 4, 7, 1, 4, 1}, // Intra MB - { 10, 13, 10, 10, 10} // Inter MB -}; - -const int AdaptRndPos[4][5] = -{ - // P, B, I, SP, SI - { 3, 6, 0, 3, 0}, // 4x4 Intra MB - { 1, 2, 0, 1, 2}, // 8x8 Intra MB - { 9, 12, 9, 9, 9}, // 4x4 Inter MB - { 3, 4, 3, 3, 3}, // 8x8 Inter MB -}; imgpel rec_mbY[16][16], rec_mb_cr[2][16][16]; // reconstruction values @@ -73,12 +58,6 @@ static int diff4x4[64]; static int diff8x8[64]; RD_8x8DATA tr4x4, tr8x8; -int **bestInterFAdjust4x4=NULL, **bestIntraFAdjust4x4=NULL; -int **bestInterFAdjust8x8=NULL, **bestIntraFAdjust8x8=NULL; -int ***bestInterFAdjust4x4Cr=NULL, ***bestIntraFAdjust4x4Cr=NULL; -int ***bestInterFAdjust8x8Cr=NULL, ***bestIntraFAdjust8x8Cr=NULL; -int **fadjust8x8=NULL, **fadjust4x4=NULL, ***fadjust4x4Cr=NULL, ***fadjust8x8Cr=NULL; - int ****cofAC=NULL, ****cofAC8x8=NULL; // [8x8block][4x4block][level/run][scan_pos] int ***cofDC=NULL; // [yuv][level/run][scan_pos] @@ -86,18 +65,13 @@ int **cofAC4x4=NULL, ****cofAC4x4intern=NULL; // [level/run][scan_pos] int cbp, cbp8x8, cnt_nonz_8x8; int cbp_blk8x8; char l0_refframe[4][4], l1_refframe[4][4]; -short b8mode[4], b8pdir[4]; -short best8x8mode [4]; // [block] -char best8x8pdir [MAXMODE][4]; // [mode][block] -char best8x8l0ref [MAXMODE][4]; // [mode][block] -char best8x8l1ref [MAXMODE][4]; // [mode][block] -char best8x8ref[2][MAXMODE][4]; // [mode][block] +short b8mode[4], b8pdir[4], b8bipred_me[4]; CSptr cs_mb=NULL, cs_b8=NULL, cs_cm=NULL, cs_ib8=NULL, cs_ib4=NULL; int best_c_imode; int best_i16offset; short best_mode; -short bi_pred_me; + //mixed transform sizes definitions int luma_transform_size_8x8_flag; @@ -123,9 +97,6 @@ void StoreMV8x8(int dir); void RestoreMV8x8(int dir); // end of mixed transform sizes definitions -//Adaptive Rounding update function -void update_offset_params(Macroblock *currMB, int mode, int luma_transform_size_8x8_flag); - char b4_ipredmode[16], b4_intra_pred_modes[16]; /*! @@ -134,7 +105,7 @@ char b4_ipredmode[16], b4_intra_pred_modes[16]; * delete structure for RD-optimized mode decision ************************************************************************ */ -void clear_rdopt () +void clear_rdopt (InputParameters *params) { free_mem_DCcoeff (cofDC); free_mem_ACcoeff (cofAC); @@ -160,24 +131,7 @@ void clear_rdopt () if (params->AdaptiveRounding) { - free_mem2Dint(bestInterFAdjust4x4); - free_mem2Dint(bestIntraFAdjust4x4); - free_mem2Dint(bestInterFAdjust8x8); - free_mem2Dint(bestIntraFAdjust8x8); - free_mem2Dint(fadjust8x8); - free_mem2Dint(fadjust4x4); - if (params->yuv_format != 0) - { - if (params->yuv_format == YUV444) - { - free_mem3Dint(bestInterFAdjust8x8Cr); - free_mem3Dint(bestIntraFAdjust8x8Cr); - } - free_mem3Dint(bestInterFAdjust4x4Cr); - free_mem3Dint(bestIntraFAdjust4x4Cr); - free_mem3Dint(fadjust4x4Cr); - free_mem3Dint(fadjust8x8Cr); - } + clear_adaptive_rounding (params); } // structure for saving the coding state @@ -195,7 +149,7 @@ void clear_rdopt () * create structure for RD-optimized mode decision ************************************************************************ */ -void init_rdopt () +void init_rdopt (InputParameters *params) { rdopt = NULL; @@ -226,6 +180,8 @@ void init_rdopt () cofAC4x4CbCr[1] = cofAC4x4CbCrintern[1][0][0]; } + SetLagrangianMultipliers = params->rdopt == 0 ? SetLagrangianMultipliersOff : SetLagrangianMultipliersOn; + switch (params->rdopt) { case 0: @@ -244,24 +200,7 @@ void init_rdopt () } if (params->AdaptiveRounding) { - get_mem2Dint(&bestInterFAdjust4x4, 16, 16); - get_mem2Dint(&bestIntraFAdjust4x4, 16, 16); - get_mem2Dint(&bestInterFAdjust8x8, 16, 16); - get_mem2Dint(&bestIntraFAdjust8x8, 16, 16); - get_mem2Dint(&fadjust8x8, 16, 16); - get_mem2Dint(&fadjust4x4, 16, 16); - if (params->yuv_format != 0 ) - { - if (params->yuv_format == YUV444) - { - get_mem3Dint(&bestInterFAdjust8x8Cr, 2, 16, 16); - get_mem3Dint(&bestIntraFAdjust8x8Cr, 2, 16, 16); - } - get_mem3Dint(&bestInterFAdjust4x4Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); - get_mem3Dint(&bestIntraFAdjust4x4Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); - get_mem3Dint(&fadjust4x4Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); - get_mem3Dint(&fadjust8x8Cr, 2, img->mb_cr_size_y, img->mb_cr_size_x); - } + setup_adaptive_rounding (params); } // structure for saving the coding state @@ -512,13 +451,12 @@ double RDCost_for_4x4IntraBlocks (Macroblock *currMB, DataPartition *dataPart; //===== perform DCT, Q, IQ, IDCT, Reconstruction ===== - select_dct(currMB); + //select_dct(img, currMB); *nonzero = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1); //===== get distortion (SSD) of 4x4 block ===== distortion += compute_SSE(&pCurImg[pic_opix_y], &enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x, 4, 4); - ipmode_DPCM=NO_INTRA_PMODE; //For residual DPCM if(img->P444_joined) { ColorPlane k; @@ -530,6 +468,7 @@ double RDCost_for_4x4IntraBlocks (Macroblock *currMB, } select_plane(PLANE_Y); } + ipmode_DPCM=NO_INTRA_PMODE; //===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) ===== se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1; @@ -583,7 +522,9 @@ double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to co int mode, // <-- partitioning mode short pdir, // <-- prediction direction short l0_ref, // <-- L0 reference picture - short l1_ref) // <-- L1 reference picture + short l1_ref, // <-- L1 reference picture + short bipred_me // <-- bi prediction mode + ) { int k; int rate=0; @@ -609,8 +550,8 @@ double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to co //===== //===== GET COEFFICIENTS, RECONSTRUCTIONS, CBP //===== - currMB->bi_pred_me=0; - + currMB->bipred_me[block] = bipred_me; + if (direct) { if (direct_pdir[img->block_y+j0][img->block_x+i0]<0) // mode not allowed @@ -646,15 +587,16 @@ double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to co { //===== get residue ===== // We need the reconstructed prediction residue for the simulated decoders. - compute_residue_b8block (block, -1); + //compute_residue_b8block (img, &enc_picture->p_img[0][img->pix_y], decs->res_img[0], block, -1); + compute_residue_block (img, &enc_picture->p_img[0][img->pix_y], decs->res_img[0], img->mb_pred[0], block, 8); //===== //===== GET DISTORTION //===== for (k=0; k<params->NoOfDecoders ;k++) { - decode_one_b8block (k, P8x8, block, mode, l0_ref); - distortion += compute_SSE(&pCurImg[img->opix_y+pay], &decs->decY[k][img->opix_y+pay], img->opix_x+pax, img->opix_x+pax, 8, 8); + decode_one_b8block (img, enc_picture, k, P8x8, block, mode, l0_ref); + distortion += compute_SSE(&pCurImg[img->opix_y+pay], &enc_picture->p_dec_img[0][k][img->opix_y+pay], img->opix_x+pax, img->opix_x+pax, 8, 8); } distortion /= params->NoOfDecoders; } @@ -664,8 +606,8 @@ double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to co if (img->P444_joined) { - distortion += compute_SSE(&imgUV_org[0][img->opix_y + pay], &enc_picture->imgUV[0][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8); - distortion += compute_SSE(&imgUV_org[1][img->opix_y + pay], &enc_picture->imgUV[1][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8); + distortion += compute_SSE(&pImgOrg[1][img->opix_y + pay], &enc_picture->imgUV[0][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8); + distortion += compute_SSE(&pImgOrg[2][img->opix_y + pay], &enc_picture->imgUV[1][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8); } } @@ -709,11 +651,11 @@ double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to co if (pdir==0 || pdir==2) { - rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l0_ref, LIST_0, mode); + rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l0_ref, LIST_0, mode, currMB->bipred_me[block]); } if (pdir==1 || pdir==2) { - rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l1_ref, LIST_1, mode); + rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l1_ref, LIST_1, mode, currMB->bipred_me[block]); } } @@ -764,16 +706,21 @@ int I16Offset (int cbp, int i16mode) */ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) { - int i,j,k,l; + int i,j,k,l; int bframe = (img->type==B_SLICE); - int block_x, block_y; + int block_x, block_y, block8x8, block4x4; int cur_ref; int clist; - char cref[2]; + char cref[2], curref, bestref; + Block8x8Info *b8x8info = img->b8x8info; //--- macroblock type --- currMB->mb_type = mode; - currMB->bi_pred_me= (mode == 1 ? img->bi_pred_me[mode] : 0); + + for( i = 0; i < 4; i++) + { + currMB->bipred_me[i] = b8x8info->bipred8x8me[mode][i]; + } //--- block 8x8 mode and prediction direction --- switch (mode) @@ -798,14 +745,14 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) for(i=0;i<4;i++) { currMB->b8mode[i] = mode; - currMB->b8pdir[i] = best8x8pdir[mode][i]; + currMB->b8pdir[i] = b8x8info->best8x8pdir[mode][i]; } break; case P8x8: - memcpy(currMB->b8mode, best8x8mode, 4 * sizeof(short)); + memcpy(currMB->b8mode, b8x8info->best8x8mode, 4 * sizeof(short)); for(i=0;i<4;i++) { - currMB->b8pdir[i] = best8x8pdir[mode][i]; + currMB->b8pdir[i] = b8x8info->best8x8pdir[mode][i]; } break; case I4MB: @@ -844,8 +791,9 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) exit (1); } -#define IS_FW ((best8x8pdir[mode][k]==0 || best8x8pdir[mode][k]==2) && (mode!=P8x8 || best8x8mode[k]!=0 || !bframe)) -#define IS_BW ((best8x8pdir[mode][k]==1 || best8x8pdir[mode][k]==2) && (mode!=P8x8 || best8x8mode[k]!=0)) +#define IS_FW ((b8x8info->best8x8pdir[mode][k]==0 || b8x8info->best8x8pdir[mode][k]==2) && (mode!=P8x8 || b8x8info->best8x8mode[k]!=0 || !bframe)) +#define IS_BW ((b8x8info->best8x8pdir[mode][k]==1 || b8x8info->best8x8pdir[mode][k]==2) && (mode!=P8x8 || b8x8info->best8x8mode[k]!=0)) + //--- reference frame arrays --- if (mode==0 || mode==I4MB || mode==I16MB || mode==I8MB) { @@ -857,7 +805,7 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) { for (j = img->block_y; j < img->block_y + 4; j++) { - memcpy(&enc_picture->ref_idx[clist][j][img->block_x], &direct_ref_idx[clist][j][img->block_x], 4 * sizeof(char)); + memcpy(&enc_picture->motion.ref_idx[clist][j][img->block_x], &direct_ref_idx[clist][j][img->block_x], 4 * sizeof(char)); } } } @@ -867,7 +815,7 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) { for (j = img->block_y; j < img->block_y + 4; j++) { - memset(&enc_picture->ref_idx[clist][j][img->block_x],-1, 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[clist][j][img->block_x],-1, 4 * sizeof(char)); } } } @@ -877,12 +825,12 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) if (!mode) // Skip { for (j = img->block_y; j < img->block_y + 4; j++) - memset(&enc_picture->ref_idx[LIST_0][j][img->block_x],0, 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j][img->block_x],0, 4 * sizeof(char)); } else // Intra { for (j = img->block_y; j < img->block_y + 4; j++) - memset(&enc_picture->ref_idx[LIST_0][j][img->block_x],-1, 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j][img->block_x],-1, 4 * sizeof(char)); } } } @@ -890,73 +838,33 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) { if (bframe) { - if (mode == 1) + if (mode == 1 || mode == 2 || mode == 3) { - if (currMB->bi_pred_me && best8x8pdir[mode][0] == 2) + for (block8x8 = 0; block8x8 < 4; block8x8++) { for (clist = LIST_0; clist <= LIST_1; clist++) { - for (j = img->block_y; j < img->block_y + 4;j++) - { - memset(&enc_picture->ref_idx[clist][j][img->block_x], 0, 4 * sizeof(char)); + bestref = (clist == LIST_0) ? b8x8info->best8x8l0ref[mode][block8x8] : b8x8info->best8x8l1ref[mode][block8x8]; + if ( b8x8info->best8x8pdir[mode][block8x8] == 2) + { + if (b8x8info->bipred8x8me[mode][block8x8]) + curref = 0; + else + curref = bestref; } - } - } - else - { - cref[0] = (best8x8pdir[mode][0] == 0 || best8x8pdir[mode][0] == 2) ? best8x8l0ref[mode][0] : -1; - cref[1] = (best8x8pdir[mode][0] == 1 || best8x8pdir[mode][0] == 2) ? best8x8l1ref[mode][0] : -1; - for (clist = LIST_0; clist <= LIST_1; clist++) - { - for (j = img->block_y; j < img->block_y + 4;j++) - { - memset(&enc_picture->ref_idx[clist][j][img->block_x], cref[clist], 4 * sizeof(char)); + else + { + curref = (clist == b8x8info->best8x8pdir[mode][block8x8]) ? bestref : -1; + } + for (block4x4 = 0; block4x4 < 4; block4x4++) + { + block_x = img->block_x + 2 * (block8x8 & 0x01) + (block4x4 & 0x01); + block_y = img->block_y + 2 * (block8x8 >> 1) + (block4x4 >> 1); + enc_picture->motion.ref_idx[clist][block_y][block_x] = curref; } } } } - else if (mode == 2) - { - j = img->block_y; - cref[0] = (best8x8pdir[mode][0] == 0 || best8x8pdir[mode][0] == 2) ? best8x8l0ref[mode][0] : -1; - cref[1] = (best8x8pdir[mode][0] == 1 || best8x8pdir[mode][0] == 2) ? best8x8l1ref[mode][0] : -1; - memset(&enc_picture->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_1][j++][img->block_x], cref[1], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_1][j++][img->block_x], cref[1], 4 * sizeof(char)); - - cref[0] = (best8x8pdir[mode][2] == 0 || best8x8pdir[mode][2] == 2) ? best8x8l0ref[mode][2] : -1; - cref[1] = (best8x8pdir[mode][2] == 1 || best8x8pdir[mode][2] == 2) ? best8x8l1ref[mode][2] : -1; - memset(&enc_picture->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_1][j++][img->block_x], cref[1], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_1][j++][img->block_x], cref[1], 4 * sizeof(char)); - } - else if (mode == 3) - { - j = img->block_y; - i = img->block_x; - cref[0] = (best8x8pdir[mode][0] == 0 || best8x8pdir[mode][0] == 2) ? best8x8l0ref[mode][0] : -1; - cref[1] = (best8x8pdir[mode][0] == 1 || best8x8pdir[mode][0] == 2) ? best8x8l1ref[mode][0] : -1; - enc_picture->ref_idx[LIST_0][j ][i ] = cref[0]; - enc_picture->ref_idx[LIST_1][j ][i++] = cref[1]; - enc_picture->ref_idx[LIST_0][j ][i ] = cref[0]; - enc_picture->ref_idx[LIST_1][j ][i++] = cref[1]; - - cref[0] = (best8x8pdir[mode][1] == 0 || best8x8pdir[mode][1] == 2) ? best8x8l0ref[mode][1] : -1; - cref[1] = (best8x8pdir[mode][1] == 1 || best8x8pdir[mode][1] == 2) ? best8x8l1ref[mode][1] : -1; - enc_picture->ref_idx[LIST_0][j ][i ] = cref[0]; - enc_picture->ref_idx[LIST_1][j ][i++] = cref[1]; - enc_picture->ref_idx[LIST_0][j ][i ] = cref[0]; - enc_picture->ref_idx[LIST_1][j++][i ] = cref[1]; - - memcpy(&enc_picture->ref_idx[LIST_0][j ][img->block_x], &enc_picture->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_1][j++][img->block_x], &enc_picture->ref_idx[LIST_1][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_0][j ][img->block_x], &enc_picture->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_1][j++][img->block_x], &enc_picture->ref_idx[LIST_1][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_0][j ][img->block_x], &enc_picture->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_1][j++][img->block_x], &enc_picture->ref_idx[LIST_1][img->block_y][img->block_x], 4 * sizeof(char)); - } else { for (j=0;j<4;j++) @@ -968,15 +876,15 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) k = 2*(j >> 1) + (i >> 1); l = 2*(j & 0x01) + (i & 0x01); - if(mode == P8x8 && best8x8mode[k]==0) + if(mode == P8x8 && b8x8info->best8x8mode[k]==0) { - enc_picture->ref_idx[LIST_0][block_y][block_x] = direct_ref_idx[LIST_0][block_y][block_x]; - enc_picture->ref_idx[LIST_1][block_y][block_x] = direct_ref_idx[LIST_1][block_y][block_x]; + enc_picture->motion.ref_idx[LIST_0][block_y][block_x] = direct_ref_idx[LIST_0][block_y][block_x]; + enc_picture->motion.ref_idx[LIST_1][block_y][block_x] = direct_ref_idx[LIST_1][block_y][block_x]; } else { - enc_picture->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? best8x8l0ref[mode][k] : -1); - enc_picture->ref_idx[LIST_1][block_y][block_x] = (IS_BW ? best8x8l1ref[mode][k] : -1); + enc_picture->motion.ref_idx[LIST_0][block_y][block_x] = (IS_FW ? b8x8info->best8x8l0ref[mode][k] : -1); + enc_picture->motion.ref_idx[LIST_1][block_y][block_x] = (IS_BW ? b8x8info->best8x8l1ref[mode][k] : -1); } } } @@ -986,36 +894,36 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) { if (mode == 1) { - cref[0] = best8x8pdir[mode][0] == 0 ? best8x8l0ref[mode][0] : -1; + cref[0] = b8x8info->best8x8pdir[mode][0] == 0 ? b8x8info->best8x8l0ref[mode][0] : -1; j = img->block_y; - memset(&enc_picture->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); } else if (mode == 2) { - cref[0] = best8x8pdir[mode][0] == 0 ? best8x8l0ref[mode][0] : -1; + cref[0] = b8x8info->best8x8pdir[mode][0] == 0 ? b8x8info->best8x8l0ref[mode][0] : -1; j = img->block_y; - memset(&enc_picture->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); - cref[0] = best8x8pdir[mode][2] == 0 ? best8x8l0ref[mode][2] : -1; - memset(&enc_picture->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); + cref[0] = b8x8info->best8x8pdir[mode][2] == 0 ? b8x8info->best8x8l0ref[mode][2] : -1; + memset(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char)); + memset(&enc_picture->motion.ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char)); } else if (mode == 3) { j = img->block_y; i = img->block_x; - cref[0] = (best8x8pdir[mode][0] == 0) ? best8x8l0ref[mode][0] : -1; - enc_picture->ref_idx[LIST_0][j ][i++] = cref[0]; - enc_picture->ref_idx[LIST_0][j ][i++] = cref[0]; - cref[0] = (best8x8pdir[mode][1] == 0) ? best8x8l0ref[mode][1] : -1; - enc_picture->ref_idx[LIST_0][j ][i++] = cref[0]; - enc_picture->ref_idx[LIST_0][j++][i ] = cref[0]; - memcpy(&enc_picture->ref_idx[LIST_0][j++][img->block_x], &enc_picture->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_0][j++][img->block_x], &enc_picture->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); - memcpy(&enc_picture->ref_idx[LIST_0][j ][img->block_x], &enc_picture->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); + cref[0] = (b8x8info->best8x8pdir[mode][0] == 0) ? b8x8info->best8x8l0ref[mode][0] : -1; + enc_picture->motion.ref_idx[LIST_0][j ][i++] = cref[0]; + enc_picture->motion.ref_idx[LIST_0][j ][i++] = cref[0]; + cref[0] = (b8x8info->best8x8pdir[mode][1] == 0) ? b8x8info->best8x8l0ref[mode][1] : -1; + enc_picture->motion.ref_idx[LIST_0][j ][i++] = cref[0]; + enc_picture->motion.ref_idx[LIST_0][j++][i ] = cref[0]; + memcpy(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], &enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); + memcpy(&enc_picture->motion.ref_idx[LIST_0][j++][img->block_x], &enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); + memcpy(&enc_picture->motion.ref_idx[LIST_0][j ][img->block_x], &enc_picture->motion.ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char)); } else { @@ -1027,7 +935,7 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) block_x = img->block_x + i; k = 2*(j >> 1) + (i >> 1); l = 2*(j & 0x01) + (i & 0x01); - enc_picture->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? best8x8l0ref[mode][k] : -1); + enc_picture->motion.ref_idx[LIST_0][block_y][block_x] = (IS_FW ? b8x8info->best8x8l0ref[mode][k] : -1); } } } @@ -1041,8 +949,8 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) for (j = img->block_y; j < img->block_y + 4; j++) for (i = img->block_x; i < img->block_x + 4;i++) { - cur_ref = (int) enc_picture->ref_idx[clist][j][i]; - enc_picture->ref_pic_id [clist][j][i] = (cur_ref>=0 + cur_ref = (int) enc_picture->motion.ref_idx[clist][j][i]; + enc_picture->motion.ref_pic_id [clist][j][i] = (cur_ref>=0 ? enc_picture->ref_pic_num[clist + currMB->list_offset][cur_ref] : -1); } @@ -1053,8 +961,8 @@ void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode) for (j = img->block_y; j < img->block_y + 4; j++) for (i = img->block_x; i < img->block_x + 4;i++) { - cur_ref = (int) enc_picture->ref_idx[LIST_0][j][i]; - enc_picture->ref_pic_id [LIST_0][j][i] = (cur_ref>=0 + cur_ref = (int) enc_picture->motion.ref_idx[LIST_0][j][i]; + enc_picture->motion.ref_pic_id [LIST_0][j][i] = (cur_ref>=0 ? enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref] : -1); } @@ -1100,8 +1008,8 @@ void SetCoeffAndReconstruction8x8 (Macroblock* currMB) { k = 2*(j >> 1)+(i >> 1); l = 2*(j & 0x01)+(i & 0x01); - enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i] = ((currMB->b8pdir[k] & 0x01) == 0) ? tr8x8.part8x8l0ref[k] : - 1; - enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x+i] = (currMB->b8pdir[k] > 0) ? tr8x8.part8x8l1ref[k] : - 1; + enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x+i] = ((currMB->b8pdir[k] & 0x01) == 0) ? tr8x8.part8x8l0ref[k] : - 1; + enc_picture->motion.ref_idx[LIST_1][img->block_y+j][img->block_x+i] = (currMB->b8pdir[k] > 0) ? tr8x8.part8x8l1ref[k] : - 1; } } else @@ -1111,7 +1019,7 @@ void SetCoeffAndReconstruction8x8 (Macroblock* currMB) { k = 2*(j >> 1)+(i >> 1); l = 2*(j & 0x01)+(i & 0x01); - enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x+i] = tr8x8.part8x8l0ref[k]; + enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x+i] = tr8x8.part8x8l0ref[k]; } } @@ -1120,9 +1028,9 @@ void SetCoeffAndReconstruction8x8 (Macroblock* currMB) { for (i = img->block_x;i<img->block_x + BLOCK_MULTIPLE;i++) { - cur_ref = (int) enc_picture->ref_idx[LIST_0][j][i]; + cur_ref = (int) enc_picture->motion.ref_idx[LIST_0][j][i]; - enc_picture->ref_pic_id [LIST_0][j][i] =(cur_ref>=0 + enc_picture->motion.ref_pic_id [LIST_0][j][i] =(cur_ref>=0 ? enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref] : -1); } @@ -1134,9 +1042,9 @@ void SetCoeffAndReconstruction8x8 (Macroblock* currMB) { for (i = img->block_x;i<img->block_x + BLOCK_MULTIPLE;i++) { - cur_ref = (int) enc_picture->ref_idx[LIST_1][j][i]; + cur_ref = (int) enc_picture->motion.ref_idx[LIST_1][j][i]; - enc_picture->ref_pic_id [LIST_1][j][i] = (cur_ref>=0 + enc_picture->motion.ref_pic_id [LIST_1][j][i] = (cur_ref>=0 ? enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][cur_ref] : -1); } @@ -1291,6 +1199,12 @@ void SetCoeffAndReconstruction8x8 (Macroblock* currMB) { memcpy (&enc_picture->imgY[img->pix_y+j][img->pix_x],tr4x4.rec_mbY8x8[j], MB_BLOCK_SIZE * sizeof(imgpel)); } + + if (params->rdopt == 3) + { + errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY8x8, 0, MB_BLOCK_SIZE); + } + if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator)) { for (j = 0; j < MB_BLOCK_SIZE; j++) @@ -1323,6 +1237,7 @@ void SetMotionVectorsMB (Macroblock* currMB, int bframe) int i, j, k, l, mode8, pdir8, ref, by, bx; short ******all_mv = img->all_mv; short ******pred_mv = img->pred_mv; + short bipred_me8; int l1_ref; int jdiv, jmod; @@ -1341,17 +1256,17 @@ void SetMotionVectorsMB (Macroblock* currMB, int bframe) bx = img->block_x+i; pdir8 = currMB->b8pdir[k]; - ref = enc_picture->ref_idx[LIST_0][by][bx]; + ref = enc_picture->motion.ref_idx[LIST_0][by][bx]; if (pdir8>=0) { - enc_picture->mv[LIST_0][by][bx][0] = all_mv [LIST_0][ ref][mode8][j][i][0]; - enc_picture->mv[LIST_0][by][bx][1] = all_mv [LIST_0][ ref][mode8][j][i][1]; + enc_picture->motion.mv[LIST_0][by][bx][0] = all_mv [LIST_0][ ref][mode8][j][i][0]; + enc_picture->motion.mv[LIST_0][by][bx][1] = all_mv [LIST_0][ ref][mode8][j][i][1]; } else { - enc_picture->mv[LIST_0][by][bx][0] = 0; - enc_picture->mv[LIST_0][by][bx][1] = 0; + enc_picture->motion.mv[LIST_0][by][bx][0] = 0; + enc_picture->motion.mv[LIST_0][by][bx][1] = 0; } } } @@ -1366,50 +1281,55 @@ void SetMotionVectorsMB (Macroblock* currMB, int bframe) for (i = 0; i<4; i++) { mode8 = currMB->b8mode[k=2*jdiv+(i>>1)]; + bipred_me8 = currMB->bipred_me[k]; l = 2*jmod + (i & 0x01); bx = img->block_x+i; pdir8 = currMB->b8pdir[k]; - ref = enc_picture->ref_idx[LIST_0][by][bx]; - l1_ref = enc_picture->ref_idx[LIST_1][by][bx]; + ref = enc_picture->motion.ref_idx[LIST_0][by][bx]; + l1_ref = enc_picture->motion.ref_idx[LIST_1][by][bx]; - if (currMB->bi_pred_me && (pdir8 == 2) && currMB->mb_type==1) + if ( bipred_me8 && (pdir8 == 2) && is_bipred_enabled(currMB->mb_type)) { - all_mv = currMB->bi_pred_me == 1 ? img->bipred_mv1 : img->bipred_mv2; + all_mv = img->bipred_mv[bipred_me8 - 1]; ref = 0; l1_ref = 0; } + else + { + all_mv = img->all_mv; + } if (pdir8==-1) // intra { - enc_picture->mv[LIST_0][by][bx][0] = 0; - enc_picture->mv[LIST_0][by][bx][1] = 0; - enc_picture->mv[LIST_1][by][bx][0] = 0; - enc_picture->mv[LIST_1][by][bx][1] = 0; + enc_picture->motion.mv[LIST_0][by][bx][0] = 0; + enc_picture->motion.mv[LIST_0][by][bx][1] = 0; + enc_picture->motion.mv[LIST_1][by][bx][0] = 0; + enc_picture->motion.mv[LIST_1][by][bx][1] = 0; } else if (pdir8==0) // list 0 { - enc_picture->mv[LIST_0][by][bx][0] = all_mv [LIST_0][ ref][mode8][j][i][0]; - enc_picture->mv[LIST_0][by][bx][1] = all_mv [LIST_0][ ref][mode8][j][i][1]; - enc_picture->mv[LIST_1][by][bx][0] = 0; - enc_picture->mv[LIST_1][by][bx][1] = 0; - enc_picture->ref_idx[LIST_1][by][bx] = -1; + enc_picture->motion.mv[LIST_0][by][bx][0] = all_mv [LIST_0][ ref][mode8][j][i][0]; + enc_picture->motion.mv[LIST_0][by][bx][1] = all_mv [LIST_0][ ref][mode8][j][i][1]; + enc_picture->motion.mv[LIST_1][by][bx][0] = 0; + enc_picture->motion.mv[LIST_1][by][bx][1] = 0; + enc_picture->motion.ref_idx[LIST_1][by][bx] = -1; } else if (pdir8==1) // list 1 { - enc_picture->mv[LIST_0][by][bx][0] = 0; - enc_picture->mv[LIST_0][by][bx][1] = 0; - enc_picture->ref_idx[LIST_0][by][bx] = -1; - enc_picture->mv[LIST_1][by][bx][0] = all_mv [LIST_1][l1_ref][mode8][j][i][0]; - enc_picture->mv[LIST_1][by][bx][1] = all_mv [LIST_1][l1_ref][mode8][j][i][1]; + enc_picture->motion.mv[LIST_0][by][bx][0] = 0; + enc_picture->motion.mv[LIST_0][by][bx][1] = 0; + enc_picture->motion.ref_idx[LIST_0][by][bx] = -1; + enc_picture->motion.mv[LIST_1][by][bx][0] = all_mv [LIST_1][l1_ref][mode8][j][i][0]; + enc_picture->motion.mv[LIST_1][by][bx][1] = all_mv [LIST_1][l1_ref][mode8][j][i][1]; } else if (pdir8==2) // bipredictive { - enc_picture->mv[LIST_0][by][bx][0] = all_mv [LIST_0][ ref][mode8][j][i][0]; - enc_picture->mv[LIST_0][by][bx][1] = all_mv [LIST_0][ ref][mode8][j][i][1]; - enc_picture->mv[LIST_1][by][bx][0] = all_mv [LIST_1][l1_ref][mode8][j][i][0]; - enc_picture->mv[LIST_1][by][bx][1] = all_mv [LIST_1][l1_ref][mode8][j][i][1]; + enc_picture->motion.mv[LIST_0][by][bx][0] = all_mv [LIST_0][ ref][mode8][j][i][0]; + enc_picture->motion.mv[LIST_0][by][bx][1] = all_mv [LIST_0][ ref][mode8][j][i][1]; + enc_picture->motion.mv[LIST_1][by][bx][0] = all_mv [LIST_1][l1_ref][mode8][j][i][0]; + enc_picture->motion.mv[LIST_1][by][bx][1] = all_mv [LIST_1][l1_ref][mode8][j][i][1]; } else { @@ -1457,7 +1377,7 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to int use_of_cc = (img->type!=I_SLICE && params->symbol_mode!=CABAC); int cc_rate, dummy; double dummy_d; - imgpel (*curr_mpr)[16] = img->mpr[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; imgpel (*curr_mpr_16x16)[16][16] = img->mpr_16x16[0]; //===== @@ -1545,8 +1465,8 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to { j1 = j + img->opix_c_y; j2 = j + img->pix_c_y; - memcpy(&enc_picture->imgUV[0][j2][img->opix_c_x], &imgUV_org[0][j1][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel)); - memcpy(&enc_picture->imgUV[1][j2][img->opix_c_x], &imgUV_org[1][j1][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[0][j2][img->opix_c_x], &pImgOrg[1][j1][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel)); + memcpy(&enc_picture->imgUV[1][j2][img->opix_c_x], &pImgOrg[2][j1][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel)); } } for (j=0;j<4;j++) @@ -1558,7 +1478,9 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to if (params->rdopt==3 && img->type!=B_SLICE) { // We need the reconstructed prediction residue for the simulated decoders. - compute_residue_mb (mode == I16MB ? i16mode : -1); + // Should we be handing imgY here or p_curr_img instead of p_img[0]? This could make it more generic + ////compute_residue_mb (img, &enc_picture->p_img[0][img->pix_y], decs->res_img[0], mode == I16MB ? i16mode : -1); + compute_residue_block (img, &enc_picture->p_curr_img[img->pix_y], decs->res_img[0], mode == I16MB ? img->mpr_16x16[0][i16mode] : img->mb_pred[0], 0, 16); } //Rate control @@ -1567,7 +1489,7 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to if (mode == I16MB) memcpy(pred, curr_mpr_16x16[i16mode], MB_PIXELS * sizeof(imgpel)); else - memcpy(pred, curr_mpr, MB_PIXELS * sizeof(imgpel)); + memcpy(pred, mb_pred, MB_PIXELS * sizeof(imgpel)); } img->i16offset = 0; @@ -1583,20 +1505,30 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to //===== GET DISTORTION //===== // LUMA - if (params->rdopt==3 && img->type!=B_SLICE) + if (params->rdopt == 3 && img->type!=B_SLICE) { - for (k = 0; k<params->NoOfDecoders ;k++) + if (mode != P8x8) + { + for (k = 0; k<params->NoOfDecoders ;k++) + { + decode_one_mb (img, enc_picture, k, currMB); + distortion += compute_SSE(&pCurImg[img->opix_y], &enc_picture->p_dec_img[0][k][img->opix_y], img->opix_x, img->opix_x, MB_BLOCK_SIZE, MB_BLOCK_SIZE); + } + } + else { - decode_one_mb (k, currMB); - distortion += compute_SSE(&pCurImg[img->opix_y], &decs->decY[k][img->opix_y], img->opix_x, img->opix_x, MB_BLOCK_SIZE, MB_BLOCK_SIZE); + for (k = 0; k<params->NoOfDecoders ;k++) + { + distortion += compute_SSE(&pCurImg[img->opix_y], &enc_picture->p_dec_img[0][k][img->opix_y], img->opix_x, img->opix_x, MB_BLOCK_SIZE, MB_BLOCK_SIZE); + } } distortion /= params->NoOfDecoders; if ((img->yuv_format != YUV400) && (active_sps->chroma_format_idc != YUV444)) { // CHROMA - distortion += compute_SSE(&imgUV_org[0][img->opix_c_y], &enc_picture->imgUV[0][img->pix_c_y], img->opix_c_x, img->pix_c_x, img->mb_cr_size_y, img->mb_cr_size_x); - distortion += compute_SSE(&imgUV_org[1][img->opix_c_y], &enc_picture->imgUV[1][img->pix_c_y], img->opix_c_x, img->pix_c_x, img->mb_cr_size_y, img->mb_cr_size_x); + distortion += compute_SSE(&pImgOrg[1][img->opix_c_y], &enc_picture->imgUV[0][img->pix_c_y], img->opix_c_x, img->pix_c_x, img->mb_cr_size_y, img->mb_cr_size_x); + distortion += compute_SSE(&pImgOrg[2][img->opix_c_y], &enc_picture->imgUV[1][img->pix_c_y], img->opix_c_x, img->pix_c_x, img->mb_cr_size_y, img->mb_cr_size_x); } } else @@ -1644,7 +1576,7 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to if (rdcost >= *min_rdcost || ((currMB->qp_scaled[0]) == 0 && img->lossless_qpprime_flag == 1 && distortion != 0)) - { + { #if FASTMODE // Reordering RDCost comparison order of mode 0 and mode 1 in P_SLICE // if RDcost of mode 0 and mode 1 is same, we choose best_mode is 0 @@ -1681,111 +1613,6 @@ int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to return 1; } -/*! - ************************************************************************************* - * \brief - * Store adaptive rounding parameters - ************************************************************************************* - */ -void store_adaptive_rounding_parameters (Macroblock *currMB, int mode) -{ - int j; - int is_inter = (mode != I4MB)&&(mode != I16MB)&&(mode != I8MB); - - if (currMB->luma_transform_size_8x8_flag) - { - if ((mode == P8x8)) - memcpy(&(bestInterFAdjust8x8[0][0]),&(img->fadjust8x8[2][0][0]), MB_PIXELS * sizeof(int)); - else if (is_inter) - memcpy(&(bestInterFAdjust8x8[0][0]),&(img->fadjust8x8[0][0][0]), MB_PIXELS * sizeof(int)); - else - memcpy(&(bestIntraFAdjust8x8[0][0]),&(img->fadjust8x8[1][0][0]), MB_PIXELS * sizeof(int)); - } - else - { - if ((mode == P8x8)) - memcpy(&(bestInterFAdjust4x4[0][0]),&(img->fadjust4x4[3][0][0]),MB_PIXELS * sizeof(int)); - else if (is_inter) - memcpy(&(bestInterFAdjust4x4[0][0]),&(img->fadjust4x4[0][0][0]),MB_PIXELS * sizeof(int)); - else - memcpy(&(bestIntraFAdjust4x4[0][0]),&(img->fadjust4x4[1 + mode == I16MB][0][0]),MB_PIXELS * sizeof(int)); - } - - if (img->P444_joined) - { - if (currMB->luma_transform_size_8x8_flag) - { - if ((mode == P8x8)) - { - memcpy(&(bestInterFAdjust8x8Cr[0][0][0]),&(img->fadjust8x8Cr[0][2][0][0]),MB_PIXELS * sizeof(int)); - memcpy(&(bestInterFAdjust8x8Cr[1][0][0]),&(img->fadjust8x8Cr[1][2][0][0]),MB_PIXELS * sizeof(int)); - } - else if (is_inter) - { - memcpy(&(bestInterFAdjust8x8Cr[0][0][0]),&(img->fadjust8x8Cr[0][0][0][0]),MB_PIXELS * sizeof(int)); - memcpy(&(bestInterFAdjust8x8Cr[1][0][0]),&(img->fadjust8x8Cr[1][0][0][0]),MB_PIXELS * sizeof(int)); - } - else - { - memcpy(&(bestIntraFAdjust8x8Cr[0][0][0]),&(img->fadjust8x8Cr[0][1][0][0]),MB_PIXELS * sizeof(int)); - memcpy(&(bestIntraFAdjust8x8Cr[1][0][0]),&(img->fadjust8x8Cr[1][1][0][0]),MB_PIXELS * sizeof(int)); - } - } - else - { - if ((mode == P8x8)) - { - memcpy(&(bestInterFAdjust4x4Cr[0][0][0]),&(img->fadjust4x4Cr[0][3][0][0]),MB_PIXELS * sizeof(int)); - memcpy(&(bestInterFAdjust4x4Cr[1][0][0]),&(img->fadjust4x4Cr[1][3][0][0]),MB_PIXELS * sizeof(int)); - } - else if (is_inter) - { - memcpy(&(bestInterFAdjust4x4Cr[0][0][0]),&(img->fadjust4x4Cr[0][0][0][0]),MB_PIXELS * sizeof(int)); - memcpy(&(bestInterFAdjust4x4Cr[1][0][0]),&(img->fadjust4x4Cr[1][0][0][0]),MB_PIXELS * sizeof(int)); - } - else - { - memcpy(&(bestIntraFAdjust4x4Cr[0][0][0]),&(img->fadjust4x4Cr[0][1 + mode == I16MB][0][0]),MB_PIXELS * sizeof(int)); - memcpy(&(bestIntraFAdjust4x4Cr[1][0][0]),&(img->fadjust4x4Cr[1][1 + mode == I16MB][0][0]),MB_PIXELS * sizeof(int)); - } - } - } - if ( (params->yuv_format == YUV420 || params->yuv_format == YUV422) && (params->AdaptRndChroma)) - { - if (currMB->luma_transform_size_8x8_flag && mode == P8x8) - { - for (j = 0; j < img->mb_cr_size_y; j++) - { - memcpy(bestInterFAdjust4x4Cr[0][j],img->fadjust8x8Cr[0][0][j],img->mb_cr_size_x * sizeof(int)); - memcpy(bestInterFAdjust4x4Cr[1][j],img->fadjust8x8Cr[1][0][j],img->mb_cr_size_x * sizeof(int)); - } - } - else if (mode == P8x8) - { - for (j = 0; j < img->mb_cr_size_y; j++) - { - memcpy(bestInterFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][2][j],img->mb_cr_size_x * sizeof(int)); - memcpy(bestInterFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][2][j],img->mb_cr_size_x * sizeof(int)); - } - } - else if (is_inter) - { - for (j = 0; j < img->mb_cr_size_y; j++) - { - memcpy(bestInterFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][0][j],img->mb_cr_size_x * sizeof(int)); - memcpy(bestInterFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][0][j],img->mb_cr_size_x * sizeof(int)); - } - } - else - { - for (j = 0; j < img->mb_cr_size_y; j++) - { - memcpy(bestIntraFAdjust4x4Cr[0][j],img->fadjust4x4Cr[0][1][j],img->mb_cr_size_x * sizeof(int)); - memcpy(bestIntraFAdjust4x4Cr[1][j],img->fadjust4x4Cr[1][1][j],img->mb_cr_size_x * sizeof(int)); - } - } - } -} /*! ************************************************************************************* @@ -1795,18 +1622,17 @@ void store_adaptive_rounding_parameters (Macroblock *currMB, int mode) */ void store_macroblock_parameters (Macroblock *currMB, int mode) { - int i, j, k, ****i4p, ***i3p; - int bframe = (img->type==B_SLICE); + int j, ****i4p, ***i3p; + int bframe = (img->type==B_SLICE); //--- store best mode --- best_mode = mode; best_c_imode = currMB->c_ipred_mode; best_i16offset = img->i16offset; - // If condition is not really necessary. - bi_pred_me = (mode == 1) ? currMB->bi_pred_me : 0; - + memcpy(b8mode, currMB->b8mode, BLOCK_MULTIPLE * sizeof(short)); + memcpy(b8bipred_me, currMB->bipred_me, BLOCK_MULTIPLE * sizeof(short)); memcpy(b8pdir, currMB->b8pdir, BLOCK_MULTIPLE * sizeof(short)); memcpy(b4_intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char)); memcpy(b8_intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char)); @@ -1859,17 +1685,9 @@ void store_macroblock_parameters (Macroblock *currMB, int mode) } //--- store results of decoders --- - if (params->rdopt==3 && img->type!=B_SLICE) + if (params->rdopt == 3 && img->type!=B_SLICE) { - for (k = 0; k<params->NoOfDecoders; k++) - { - for (j=img->pix_y; j<img->pix_y+16; j++) - for (i=img->pix_x; i<img->pix_x+16; i++) - { - // Keep the decoded values of each MB for updating the ref frames - decs->decY_best[k][j][i] = decs->decY[k][j][i]; - } - } + errdo_store_best_block(img, decs->dec_mbY, enc_picture->p_dec_img[0], 0, 0, MB_BLOCK_SIZE); } //--- coeff, cbp, kac --- @@ -1894,12 +1712,12 @@ void store_macroblock_parameters (Macroblock *currMB, int mode) for (j = 0; j<4; j++) - memcpy(l0_refframe[j],&enc_picture->ref_idx[LIST_0][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char)); + memcpy(l0_refframe[j],&enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char)); if (bframe) { for (j = 0; j<4; j++) - memcpy(l1_refframe[j],&enc_picture->ref_idx[LIST_1][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char)); + memcpy(l1_refframe[j],&enc_picture->motion.ref_idx[LIST_1][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char)); } } @@ -1920,7 +1738,7 @@ void set_stored_macroblock_parameters (Macroblock *currMB) int i, j, k, ****i4p, ***i3p; int block_x, block_y; char **ipredmodes = img->ipredmode; - short *cur_mv; + short *cur_mv, total_bipred_me; //===== reconstruction values ===== @@ -2017,6 +1835,8 @@ void set_stored_macroblock_parameters (Macroblock *currMB) memcpy(currMB->b8mode,b8mode, BLOCK_MULTIPLE * sizeof(short)); memcpy(currMB->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(short)); + memcpy(currMB->bipred_me,b8bipred_me, BLOCK_MULTIPLE * sizeof(short)); + if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) { @@ -2024,9 +1844,6 @@ void set_stored_macroblock_parameters (Macroblock *currMB) memcpy(rdopt->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(short)); } - currMB->bi_pred_me = currMB->mb_type == 1 ? bi_pred_me : 0; - - //if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size if (mode == P8x8 && !luma_transform_size_8x8_flag && params->Transform8x8Mode) RestoreMV8x8(1); @@ -2051,10 +1868,9 @@ void set_stored_macroblock_parameters (Macroblock *currMB) rdopt->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag; - if (params->rdopt==3 && img->type!=B_SLICE) + if (params->rdopt == 3 && img->type!=B_SLICE) { - //! save the MB Mode of every macroblock - decs->dec_mb_mode[img->mb_y][img->mb_x] = mode; + errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY, 0, MB_BLOCK_SIZE); } //==== reference frames ===== @@ -2069,26 +1885,24 @@ void set_stored_macroblock_parameters (Macroblock *currMB) // backward prediction or intra if ((currMB->b8pdir[k] == 1) || IS_INTRA(currMB)) { - enc_picture->ref_idx [LIST_0][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = -1; - enc_picture->mv [LIST_0][block_y][block_x][0] = 0; - enc_picture->mv [LIST_0][block_y][block_x][1] = 0; + enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = -1; + enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = -1; + enc_picture->motion.mv [LIST_0][block_y][block_x][0] = 0; + enc_picture->motion.mv [LIST_0][block_y][block_x][1] = 0; if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_0][j][i] = -1; } else { - if (currMB->bi_pred_me && (currMB->b8pdir[k] == 2) && currMB->mb_type==1) + if (currMB->bipred_me[k] && (currMB->b8pdir[k] == 2) && is_bipred_enabled(currMB->mb_type)) { - cur_mv = currMB->bi_pred_me == 1 - ? img->bipred_mv1[LIST_0][0][currMB->b8mode[k]][j][i] - : img->bipred_mv2[LIST_0][0][currMB->b8mode[k]][j][i]; + cur_mv = img->bipred_mv[currMB->bipred_me[k] - 1][LIST_0][0][currMB->b8mode[k]][j][i]; - enc_picture->ref_idx [LIST_0][block_y][block_x] = 0; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0]; - enc_picture->mv [LIST_0][block_y][block_x][0] = cur_mv[0]; - enc_picture->mv [LIST_0][block_y][block_x][1] = cur_mv[1]; + enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = 0; + enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0]; + enc_picture->motion.mv [LIST_0][block_y][block_x][0] = cur_mv[0]; + enc_picture->motion.mv [LIST_0][block_y][block_x][1] = cur_mv[1]; if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_0][j][i] = 0; @@ -2096,9 +1910,9 @@ void set_stored_macroblock_parameters (Macroblock *currMB) else { char cur_ref = l0_refframe[j][i]; - enc_picture->ref_idx [LIST_0][block_y][block_x] = cur_ref; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref]; - memcpy(enc_picture->mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][(short)cur_ref][currMB->b8mode[k]][j][i], 2 * sizeof(short)); + enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = cur_ref; + enc_picture->motion.ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref]; + memcpy(enc_picture->motion.mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][(short)cur_ref][currMB->b8mode[k]][j][i], 2 * sizeof(short)); if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_0][j][i] = cur_ref; @@ -2108,10 +1922,10 @@ void set_stored_macroblock_parameters (Macroblock *currMB) // forward prediction or intra if ((currMB->b8pdir[k] == 0) || IS_INTRA(currMB)) { - enc_picture->ref_idx [LIST_1][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = -1; - enc_picture->mv [LIST_1][block_y][block_x][0] = 0; - enc_picture->mv [LIST_1][block_y][block_x][1] = 0; + enc_picture->motion.ref_idx [LIST_1][block_y][block_x] = -1; + enc_picture->motion.ref_pic_id [LIST_1][block_y][block_x] = -1; + enc_picture->motion.mv [LIST_1][block_y][block_x][0] = 0; + enc_picture->motion.mv [LIST_1][block_y][block_x][1] = 0; if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_1][j][i] = -1; @@ -2132,35 +1946,33 @@ void set_stored_macroblock_parameters (Macroblock *currMB) // forward if (IS_INTRA(currMB)||(currMB->b8pdir[k] == 0)) { - enc_picture->ref_idx [LIST_1][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = -1; - enc_picture->mv [LIST_1][block_y][block_x][0] = 0; - enc_picture->mv [LIST_1][block_y][block_x][1] = 0; + enc_picture->motion.ref_idx [LIST_1][block_y][block_x] = -1; + enc_picture->motion.ref_pic_id [LIST_1][block_y][block_x] = -1; + enc_picture->motion.mv [LIST_1][block_y][block_x][0] = 0; + enc_picture->motion.mv [LIST_1][block_y][block_x][1] = 0; if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_1][j][i] = -1; } else { - if (currMB->bi_pred_me && (currMB->b8pdir[k] == 2) && currMB->mb_type==1) + if (currMB->bipred_me[k] && (currMB->b8pdir[k] == 2) && is_bipred_enabled(currMB->mb_type)) { - cur_mv = currMB->bi_pred_me == 1 - ? img->bipred_mv1[LIST_1][0][currMB->b8mode[k]][j][i] - : img->bipred_mv2[LIST_1][0][currMB->b8mode[k]][j][i]; + cur_mv = img->bipred_mv[currMB->bipred_me[k] - 1][LIST_1][0][currMB->b8mode[k]][j][i]; - enc_picture->ref_idx [LIST_1][block_y][block_x] = 0; - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][0]; - enc_picture->mv [LIST_1][block_y][block_x][0] = cur_mv[0]; - enc_picture->mv [LIST_1][block_y][block_x][1] = cur_mv[1]; + enc_picture->motion.ref_idx [LIST_1][block_y][block_x] = 0; + enc_picture->motion.ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][0]; + enc_picture->motion.mv [LIST_1][block_y][block_x][0] = cur_mv[0]; + enc_picture->motion.mv [LIST_1][block_y][block_x][1] = cur_mv[1]; if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_1][j][i] = 0; } else { - enc_picture->ref_idx [LIST_1][block_y][block_x] = l1_refframe[j][i]; - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][(short)l1_refframe[j][i]]; - memcpy(enc_picture->mv [LIST_1][block_y][block_x], img->all_mv[LIST_1][(short)l1_refframe[j][i]][currMB->b8mode[k]][j][i], 2 * sizeof(short)); + enc_picture->motion.ref_idx [LIST_1][block_y][block_x] = l1_refframe[j][i]; + enc_picture->motion.ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][(short)l1_refframe[j][i]]; + memcpy(enc_picture->motion.mv [LIST_1][block_y][block_x], img->all_mv[LIST_1][(short)l1_refframe[j][i]][currMB->b8mode[k]][j][i], 2 * sizeof(short)); if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1)) rdopt->refar[LIST_1][j][i] = l1_refframe[j][i]; @@ -2210,9 +2022,71 @@ void set_stored_macroblock_parameters (Macroblock *currMB) //==== motion vectors ===== SetMotionVectorsMB (currMB, bframe); + total_bipred_me = 0; + + for (i = 0; i < 4; i++) + { + total_bipred_me += currMB->bipred_me[i]; + } + + if (total_bipred_me && currMB->mb_type != 1) + { + UpdateMotionVectorPredictor(currMB); + //printf("new mode"); + } + } +/*! + ************************************************************************************* + * \brief + * Update motion vector predictors if biprediction mode is selected (B_SLICE only) + ************************************************************************************* + */ +void UpdateMotionVectorPredictor(Macroblock* currMB) +{ + int v = 0, h = 0, block_x, block_y, list, i, ref; + short * pred_mv; + int parttype = (currMB->mb_type<4?currMB->mb_type:4); + int bsx = params->blc_size[parttype][0]; + int bsy = params->blc_size[parttype][1]; + int step_h = (params->part_size[parttype][0]); + int step_v = (params->part_size[parttype][1]); + + for (i = 0; i < 4; i++) + { + if (currMB->bipred_me[i]) + { + v = i >> 1; + h = i & 0x01; + break; + } + } + while(1) + { + block_x = img->block_x + h; + block_y = img->block_y + v; + for (list = 0; list < 2; list++) + { + ref = enc_picture->motion.ref_idx[list][block_y][block_x]; + ref = (ref < 0 )? 0 : ref; + pred_mv = img->pred_mv[list][ref][parttype][v][h]; + SetMotionVectorPredictor (currMB, pred_mv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, list, h << 2, v << 2, bsx, bsy); + } + + v += step_v; + h += step_h; + if (v >= 4 && h >= 4) + break; + if (v >= 4) + v = 0; + if (h >= 4) + h = 0; + } + +} + /*! ************************************************************************************* @@ -2220,9 +2094,9 @@ void set_stored_macroblock_parameters (Macroblock *currMB) * Set reference frames and motion vectors ************************************************************************************* */ -void SetRefAndMotionVectors (Macroblock *currMB, int block, int mode, int pdir, int fwref, int bwref) +void SetRefAndMotionVectors (Macroblock *currMB, int block, int mode, int pdir, int fwref, int bwref, short bipred_me) { - int i, j=0; + int k, i, j=0; int bslice = (img->type==B_SLICE); int pmode = (mode==1||mode==2||mode==3?mode:4); int j0 = ((block >> 1)<<1); @@ -2231,108 +2105,174 @@ void SetRefAndMotionVectors (Macroblock *currMB, int block, int mode, int pdir, int i1 = i0 + (params->part_size[pmode][0]); int block_x, block_y; short *cur_mv; + int64 ref_pic_num; + char *ref_idx; - if (pdir<0) + if (pdir < 0) { - for (j = img->block_y + j0; j < img->block_y + j1; j++) + for (k = LIST_0; k <= LIST_1; k++) { - for (i=img->block_x + i0; i<img->block_x +i1; i++) + for (j = img->block_y + j0; j < img->block_y + j1; j++) { - enc_picture->ref_pic_id[LIST_0][j][i] = -1; - enc_picture->ref_pic_id[LIST_1][j][i] = -1; + for (i=img->block_x + i0; i<img->block_x +i1; i++) + enc_picture->motion.ref_pic_id[k][j][i] = -1; + + memset(&enc_picture->motion.ref_idx[k][j][img->block_x + i0], -1, (params->part_size[pmode][0]) * sizeof(char)); + memset(enc_picture->motion.mv [k][j][img->block_x + i0], 0, 2*(params->part_size[pmode][0]) * sizeof(short)); } - memset(&enc_picture->ref_idx[LIST_0][j][img->block_x + i0], -1, (params->part_size[pmode][0]) * sizeof(char)); - memset(&enc_picture->ref_idx[LIST_1][j][img->block_x + i0], -1, (params->part_size[pmode][0]) * sizeof(char)); - memset(enc_picture->mv[LIST_0][j][img->block_x + i0], 0, 2*(params->part_size[pmode][0]) * sizeof(short)); - memset(enc_picture->mv[LIST_1][j][img->block_x + i0], 0, 2*(params->part_size[pmode][0]) * sizeof(short)); } return; } if (!bslice) { - for (j=j0; j<j1; j++) + int64 ref_pic_num = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref]; + for (j = j0; j < j1; j++) { block_y = img->block_y + j; - memset(&enc_picture->ref_idx [LIST_0][block_y][img->block_x + i0], fwref, (params->part_size[pmode][0]) * sizeof(char)); - for (i=i0; i<i1; i++) - { - block_x = img->block_x + i; - memcpy(enc_picture->mv [LIST_0][block_y][block_x], img->all_mv [LIST_0][fwref][mode][j][i], 2 * sizeof(short)); - enc_picture->ref_pic_id[LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref]; - } + for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++) + enc_picture->motion.ref_pic_id[LIST_0][block_y][block_x] = ref_pic_num; + + memset(&enc_picture->motion.ref_idx[LIST_0][block_y][img->block_x + i0], fwref, (params->part_size[pmode][0]) * sizeof(char)); + memcpy(enc_picture->motion.mv [LIST_0][block_y][img->block_x + i0], img->all_mv[LIST_0][fwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short)); } return; } - else + else //bslice { - for (j=j0; j<j1; j++) + if ((pdir == 0 || pdir == 2)) { - block_y = img->block_y + j; - for (i=i0; i<i1; i++) + if (bipred_me && (pdir == 2) && is_bipred_enabled(mode)) { - block_x = img->block_x + i; - if (mode==0) - { - pdir = direct_pdir[block_y][block_x]; - fwref = direct_ref_idx[LIST_0][block_y][block_x]; - bwref = direct_ref_idx[LIST_1][block_y][block_x]; - } - - if ((pdir==0 || pdir==2)) + for (j=j0; j<j1; j++) { - if (currMB->bi_pred_me && (pdir == 2) && mode == 1) + block_y = img->block_y + j; + for (i=i0; i<i1; i++) { - cur_mv = currMB->bi_pred_me == 1 - ? img->bipred_mv1[LIST_0][0][mode][j][i] - : img->bipred_mv2[LIST_0][0][mode][j][i]; - - enc_picture->mv [LIST_0][block_y][block_x][0] = cur_mv[0]; - enc_picture->mv [LIST_0][block_y][block_x][1] = cur_mv[1]; - enc_picture->ref_idx [LIST_0][block_y][block_x] = 0; - enc_picture->ref_pic_id[LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][0]; + block_x = img->block_x + i; + + cur_mv = img->bipred_mv[bipred_me - 1][LIST_0][0][mode][j][i]; + + enc_picture->motion.mv [LIST_0][block_y][block_x][0] = cur_mv[0]; + enc_picture->motion.mv [LIST_0][block_y][block_x][1] = cur_mv[1]; + enc_picture->motion.ref_idx [LIST_0][block_y][block_x] = 0; + enc_picture->motion.ref_pic_id[LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][0]; } - else + } + } + else + { + if (mode==0) + { + for (j=j0; j<j1; j++) { - memcpy(enc_picture->mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][fwref][mode][j][i], 2 * sizeof(short)); - enc_picture->ref_idx [LIST_0][block_y][block_x] = fwref; - enc_picture->ref_pic_id[LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][(short)enc_picture->ref_idx[LIST_0][block_y][block_x]]; + block_y = img->block_y + j; + ref_idx = enc_picture->motion.ref_idx[LIST_0][block_y]; + memcpy(&ref_idx[img->block_x + i0], &direct_ref_idx[LIST_0][block_y][img->block_x + i0], (i1 - i0) * sizeof(char)); + memcpy(&enc_picture->motion.mv[LIST_0][block_y][img->block_x + i0][0], img->all_mv[LIST_0][fwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short)); + for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++) + { + enc_picture->motion.ref_pic_id[LIST_0][block_y][block_x] = + enc_picture->ref_pic_num[LIST_0+currMB->list_offset][(short)ref_idx[block_x]]; + } } } else { - enc_picture->mv [LIST_0][block_y][block_x][0] = 0; - enc_picture->mv [LIST_0][block_y][block_x][1] = 0; - enc_picture->ref_idx [LIST_0][block_y][block_x] = -1; - enc_picture->ref_pic_id[LIST_0][block_y][block_x] = -1; + for (j=j0; j<j1; j++) + { + block_y = img->block_y + j; + ref_pic_num = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref]; + memcpy(&enc_picture->motion.mv[LIST_0][block_y][img->block_x + i0][0], img->all_mv[LIST_0][fwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short)); + memset(&enc_picture->motion.ref_idx[LIST_0][block_y][img->block_x + i0], fwref, (i1 - i0) * sizeof(char)); + for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++) + { + enc_picture->motion.ref_pic_id[LIST_0][block_y][block_x] = ref_pic_num ; + } + } } + } + } + else + { + for (j=j0; j<j1; j++) + { + block_y = img->block_y + j; + for (i=img->block_x + i0; i<img->block_x +i1; i++) + enc_picture->motion.ref_pic_id[LIST_0][block_y][i] = -1; - if ((pdir==1 || pdir==2)) + memset(&enc_picture->motion.ref_idx[LIST_0][block_y][img->block_x + i0], -1, (i1 - i0) * sizeof(char)); + memset(enc_picture->motion.mv[LIST_0][block_y][img->block_x + i0], 0, 2 * (i1 - i0) * sizeof(short)); + } + } + + + if ((pdir==1 || pdir==2)) + { + + if (bipred_me && (pdir == 2) && is_bipred_enabled(mode)) + { + for (j=j0; j<j1; j++) { - if (currMB->bi_pred_me && (pdir == 2) && mode == 1) + block_y = img->block_y + j; + + for (i=i0; i<i1; i++) { - cur_mv = currMB->bi_pred_me == 1 - ? img->bipred_mv1[LIST_1][0][mode][j][i] - : img->bipred_mv2[LIST_1][0][mode][j][i]; - - enc_picture->mv [LIST_1][block_y][block_x][0] = cur_mv[0]; - enc_picture->mv [LIST_1][block_y][block_x][1] = cur_mv[1]; - enc_picture->ref_idx [LIST_1][block_y][block_x] = 0; - enc_picture->ref_pic_id[LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][0]; + block_x = img->block_x + i; + + cur_mv = img->bipred_mv[bipred_me - 1][LIST_1][0][mode][j][i]; + + enc_picture->motion.mv [LIST_1][block_y][block_x][0] = cur_mv[0]; + enc_picture->motion.mv [LIST_1][block_y][block_x][1] = cur_mv[1]; + enc_picture->motion.ref_idx [LIST_1][block_y][block_x] = 0; + enc_picture->motion.ref_pic_id[LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][0]; } - else + } + } + else + { + if (mode==0) + { + for (j=j0; j<j1; j++) { - memcpy(enc_picture->mv [LIST_1][block_y][block_x], img->all_mv[LIST_1][bwref][mode][j][i], 2 * sizeof(short)); - enc_picture->ref_idx [LIST_1][block_y][block_x] = bwref; - enc_picture->ref_pic_id[LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][(short)enc_picture->ref_idx[LIST_1][block_y][block_x]]; + block_y = img->block_y + j; + + ref_idx = enc_picture->motion.ref_idx[LIST_1][block_y]; + memcpy(&ref_idx[img->block_x + i0], &direct_ref_idx[LIST_1][block_y][img->block_x + i0], (i1 - i0) * sizeof(char)); + memcpy(&enc_picture->motion.mv[LIST_1][block_y][img->block_x + i0][0], img->all_mv[LIST_1][(int) ref_idx[img->block_x + i0]][mode][j][i0], 2 * (i1 - i0) * sizeof(short)); + for (i=i0; i<i1; i++) + { + block_x = img->block_x + i; + enc_picture->motion.ref_pic_id[LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][(short)ref_idx[block_x]]; + } } } else { - enc_picture->mv [LIST_1][block_y][block_x][0] = 0; - enc_picture->mv [LIST_1][block_y][block_x][1] = 0; - enc_picture->ref_idx [LIST_1][block_y][block_x] = -1; - enc_picture->ref_pic_id[LIST_1][block_y][block_x] = -1; + for (j=j0; j<j1; j++) + { + block_y = img->block_y + j; + ref_pic_num = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][bwref]; + memcpy(&enc_picture->motion.mv[LIST_1][block_y][img->block_x + i0][0], img->all_mv[LIST_1][bwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short)); + memset(&enc_picture->motion.ref_idx[LIST_1][block_y][img->block_x + i0], bwref, (i1 - i0) * sizeof(char)); + for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++) + { + enc_picture->motion.ref_pic_id[LIST_1][block_y][block_x] = ref_pic_num ; + } + } + } + } + } + else + { + for (j=j0; j<j1; j++) + { + block_y = img->block_y + j; + memset(enc_picture->motion.mv[LIST_1][block_y][img->block_x + i0], 0, 2 * (i1 - i0) * sizeof(short)); + memset(&enc_picture->motion.ref_idx[LIST_1][block_y][img->block_x + i0], -1, (i1 - i0) * sizeof(char)); + for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++) + { + enc_picture->motion.ref_pic_id[LIST_1][block_y][block_x] = -1; } } } @@ -2666,12 +2606,12 @@ int GetBestTransformP8x8() mb_x = (block8x8 & 0x01) << 3; //===== loop over 4x4 blocks ===== k=0; - for (block_y=mb_y; block_y<mb_y+8; block_y+=4) + for (block_y = mb_y; block_y < mb_y + 8; block_y += 4) { pic_pix_y = img->opix_y + block_y; //get cost for transform size 4x4 - for (block_x=mb_x; block_x<mb_x+8; block_x+=4) + for (block_x = mb_x; block_x<mb_x + 8; block_x += 4) { pic_pix_x = img->opix_x + block_x; @@ -2749,15 +2689,14 @@ void set_mbaff_parameters(Macroblock *currMB) { for (j = 0; j < BLOCK_MULTIPLE; j++) { - memcpy(rdopt->refar[LIST_0][j],&enc_picture->ref_idx[LIST_0][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char)); - memcpy(rdopt->refar[LIST_1][j],&enc_picture->ref_idx[LIST_1][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char)); + memcpy(rdopt->refar[LIST_0][j],&enc_picture->motion.ref_idx[LIST_0][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char)); + memcpy(rdopt->refar[LIST_1][j],&enc_picture->motion.ref_idx[LIST_1][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char)); } - rdopt->bi_pred_me = currMB->bi_pred_me; } else { for (j = 0; j < BLOCK_MULTIPLE; j++) - memcpy(rdopt->refar[LIST_0][j],&enc_picture->ref_idx[LIST_0][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char)); + memcpy(rdopt->refar[LIST_0][j],&enc_picture->motion.ref_idx[LIST_0][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char)); } memcpy(rdopt->intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char)); @@ -2790,303 +2729,137 @@ void reset_coding_state_cs_cm(Macroblock *currMB) reset_coding_state(currMB, cs_cm); } -/*! -************************************************************************ -* \brief -* update rounding offsets based on JVT-N011 -************************************************************************ -*/ -void update_offset_params(Macroblock *currMB, int mode, int luma_transform_size_8x8_flag) -{ - int is_inter = (mode != I4MB)&&(mode != I16MB) && (mode != I8MB); - int luma_pos = AdaptRndPos[(is_inter<<1) + luma_transform_size_8x8_flag][img->type]; - int i,j; - int qp = currMB->qp + img->bitdepth_luma_qp_scale - MIN_QP; - int cur_qp = params->AdaptRoundingFixed ? 0 : qp; - int temp = 0; - int offsetRange = 1 << (OffsetBits - 1); - int blk_mask = 0x03 + (luma_transform_size_8x8_flag<<2); - int blk_shift = 2 + luma_transform_size_8x8_flag; - short **offsetList = luma_transform_size_8x8_flag ? OffsetList8x8[cur_qp] : OffsetList4x4[cur_qp]; - - int **fAdjust = is_inter - ? (luma_transform_size_8x8_flag ? bestInterFAdjust8x8 : bestInterFAdjust4x4) - : (luma_transform_size_8x8_flag ? bestIntraFAdjust8x8 : bestIntraFAdjust4x4); - - if( (active_sps->chroma_format_idc == YUV444)&&IS_INDEPENDENT(params) ) - { - if( luma_transform_size_8x8_flag ) // 8x8 - luma_pos += 5 * img->colour_plane_id; - else // 4x4 - luma_pos += img->colour_plane_id; - } - - for (j=0; j < MB_BLOCK_SIZE; j++) - { - int j_pos = ((j & blk_mask)<<blk_shift); - for (i=0; i < MB_BLOCK_SIZE; i++) - { - temp = j_pos + (i & blk_mask); - offsetList[luma_pos][temp] += fAdjust[j][i]; - offsetList[luma_pos][temp] = iClip3(0, offsetRange, offsetList[luma_pos][temp]); - } - } - - if(img->P444_joined) - { - int ***fAdjustCbCr = (int ***) (is_inter - ? (luma_transform_size_8x8_flag ? bestInterFAdjust8x8Cr : bestInterFAdjust4x4Cr) - : (luma_transform_size_8x8_flag ? bestIntraFAdjust8x8Cr : bestIntraFAdjust4x4Cr)); - int uv; - - for(uv=0; uv<2; uv++) - { - luma_pos = AdaptRndPos[(is_inter<<1) + luma_transform_size_8x8_flag][img->type]; - if(luma_transform_size_8x8_flag ) // 8x8 - luma_pos += 5 * (uv+1); - else // 4x4 - luma_pos += (uv+1); - for (j=0; j < MB_BLOCK_SIZE; j++) - { - int j_pos = ((j & blk_mask)<<blk_shift); - for (i=0; i < MB_BLOCK_SIZE; i++) - { - temp = j_pos + (i & blk_mask); - offsetList[luma_pos][temp] += fAdjustCbCr[uv][j][i]; - offsetList[luma_pos][temp] = iClip3(0,offsetRange,offsetList[luma_pos][temp]); - } - } - } - } - - if ((params->yuv_format == YUV420 || params->yuv_format == YUV422 )&&(params->AdaptRndChroma)) - { - int u_pos = AdaptRndCrPos[is_inter][img->type]; - int v_pos = u_pos + 1; - int jpos; - - int ***fAdjustCr = is_inter ? bestInterFAdjust4x4Cr : bestIntraFAdjust4x4Cr; - - for (j = 0; j < img->mb_cr_size_y; j++) - { - jpos = ((j & 0x03)<<2); - for (i = 0; i < img->mb_cr_size_x; i++) - { - temp = jpos + (i & 0x03); - OffsetList4x4[cur_qp][u_pos][temp] += fAdjustCr[0][j][i]; - OffsetList4x4[cur_qp][u_pos][temp] = iClip3(0,offsetRange,OffsetList4x4[cur_qp][u_pos][temp]); - OffsetList4x4[cur_qp][v_pos][temp] += fAdjustCr[1][j][i]; - OffsetList4x4[cur_qp][v_pos][temp] = iClip3(0,offsetRange,OffsetList4x4[cur_qp][v_pos][temp]); - } - } - } -} - -void assign_enc_picture_params(int mode, char best_pdir, int block, int list_offset, int best_l0_ref, int best_l1_ref, int bframe) +void assign_enc_picture_params(int mode, char best_pdir, int block, int list_offset, int best_l0_ref, int best_l1_ref, int bframe, short bipred_me) { int i,j; int block_x, block_y; - short *cur_mv; - - if (mode==1) + int list, maxlist, bestref; + short ***curr_mv = NULL; + int64 curr_ref_idx = 0; + + int start_x = 0, start_y = 0, end_x = BLOCK_MULTIPLE, end_y = BLOCK_MULTIPLE; + switch (mode) { - if (best_pdir==1) - { - for (j=img->block_y+(block&2); j<img->block_y+(block&2) + BLOCK_MULTIPLE; j++) - { - block_x = img->block_x+(block&1)*2; - - memset(&enc_picture->ref_idx[LIST_0][j][block_x], -1 , BLOCK_MULTIPLE * sizeof(char)); - memset(enc_picture->mv [LIST_0][j][block_x], 0 , 2 * BLOCK_MULTIPLE * sizeof(short)); - for (i=block_x; i<block_x + BLOCK_MULTIPLE; i++) - { - enc_picture->ref_pic_id [LIST_0][j][i] = -1; - } - } - } - else if (img->bi_pred_me[mode]) + case 1: + start_x = 0; + start_y = 0; + end_x = BLOCK_MULTIPLE; + end_y = BLOCK_MULTIPLE; + break; + case 2: + start_x = 0; + start_y = block * 2; + end_x = BLOCK_MULTIPLE; + end_y = (block + 1) * 2; + break; + case 3: + start_x = block * 2; + start_y = 0; + end_x = (block + 1) * 2; + end_y = BLOCK_MULTIPLE; + break; + default: + break; + } + + maxlist = bframe ? 1: 0; + for (list = 0; list <= maxlist; list++) + { + bestref = (list == 0) ? best_l0_ref : best_l1_ref; + switch (bipred_me) + { + case 0: + curr_mv = img->all_mv[list][bestref][mode]; + curr_ref_idx = enc_picture->ref_pic_num[list + list_offset][bestref]; + break; + case 1: + curr_mv = img->bipred_mv[0][list][0][mode] ; //best_l0_ref has to be zero in this case + curr_ref_idx = enc_picture->ref_pic_num[list + list_offset][0]; + break; + case 2: + curr_mv = img->bipred_mv[1][list][0][mode] ; //best_l0_ref has to be zero in this case + curr_ref_idx = enc_picture->ref_pic_num[list + list_offset][0]; + break; + default: + break; + } + + for (j = start_y; j < end_y; j++) { - for (j=0; j<BLOCK_MULTIPLE; j++) + block_y = img->block_y + j; + for (i = start_x; i < end_x; i++) { - block_y = img->block_y+(block&2)+j; - block_x = img->block_x+(block&1)*2; - memset(&enc_picture->ref_idx[LIST_0][block_y][block_x], 0, BLOCK_MULTIPLE * sizeof(char)); - for (i=0; i<BLOCK_MULTIPLE; i++) + block_x = img->block_x + i; + if ((best_pdir != 2) && (best_pdir != list)) { - cur_mv = img->bi_pred_me[mode] == 1 - ? img->bipred_mv1[LIST_0][0][mode][i][j] - : img->bipred_mv2[LIST_0][0][mode][i][j]; - - enc_picture->ref_pic_id [LIST_0][block_y][block_x + i] = enc_picture->ref_pic_num[LIST_0 + list_offset][0]; - enc_picture->mv [LIST_0][block_y][block_x + i][0] = cur_mv[0]; - enc_picture->mv [LIST_0][block_y][block_x + i][1] = cur_mv[1]; + enc_picture->motion.ref_idx [list][block_y][block_x] = -1; + enc_picture->motion.ref_pic_id [list][block_y][block_x] = -1; + enc_picture->motion.mv [list][block_y][block_x][0] = 0; + enc_picture->motion.mv [list][block_y][block_x][1] = 0; } - } - } - else - { - for (j=0; j<BLOCK_MULTIPLE; j++) + else { - block_y = img->block_y+(block&2)+j; - block_x = img->block_x+(block&1)*2; - memset(&enc_picture->ref_idx[LIST_0][block_y][block_x], best_l0_ref , BLOCK_MULTIPLE * sizeof(char)); - for (i=0; i<BLOCK_MULTIPLE; i++) - { - enc_picture->ref_pic_id [LIST_0][block_y][block_x + i] = enc_picture->ref_pic_num[LIST_0 + list_offset][best_l0_ref]; - memcpy(enc_picture->mv [LIST_0][block_y][block_x + i], img->all_mv[LIST_0][best_l0_ref][mode][j][i], 2 * sizeof(short)); + enc_picture->motion.ref_pic_id [list][block_y][block_x] = curr_ref_idx; + enc_picture->motion.mv [list][block_y][block_x][0] = curr_mv[j][i][0]; + enc_picture->motion.mv [list][block_y][block_x][1] = curr_mv[j][i][1]; } } } + } +} - if (bframe) - { - if (best_pdir==0) - { - for (j=img->block_y+(block&2); j<img->block_y+(block&2) + BLOCK_MULTIPLE; j++) - { - block_x = img->block_x+(block&1)*2; - memset(&enc_picture->ref_idx[LIST_1][j][block_x], -1 , BLOCK_MULTIPLE * sizeof(char)); - memset(enc_picture->mv[LIST_1][j][block_x], 0 , 2 * BLOCK_MULTIPLE * sizeof(short)); - for (i=block_x; i<block_x + BLOCK_MULTIPLE; i++) - { - enc_picture->ref_pic_id [LIST_1][j][i] = -1; - } - } - } - else - { - if (img->bi_pred_me[mode]) - { - for (j=0; j<BLOCK_MULTIPLE; j++) - { - block_y = img->block_y+(block&2)+j; - block_x = img->block_x+(block&1)*2; - memset(&enc_picture->ref_idx[LIST_1][block_y][block_x], 0, BLOCK_MULTIPLE * sizeof(char)); - for (i=0; i<BLOCK_MULTIPLE; i++) - { - cur_mv = (img->bi_pred_me[mode] == 1) - ? img->bipred_mv1[LIST_1][0][mode][i][j] - : img->bipred_mv2[LIST_1][0][mode][i][j]; - - enc_picture->ref_pic_id [LIST_1][block_y][block_x + i] = - enc_picture->ref_pic_num[LIST_1 + list_offset][0]; - enc_picture->mv [LIST_1][block_y][block_x + i][0] = cur_mv[0]; - enc_picture->mv [LIST_1][block_y][block_x + i][1] = cur_mv[1]; - } - } - } - else - { - for (j=0; j<BLOCK_MULTIPLE; j++) - { - block_y = img->block_y+(block&2)+j; - block_x = img->block_x+(block&1)*2; - memset(&enc_picture->ref_idx[LIST_1][block_y][block_x], best_l1_ref, BLOCK_MULTIPLE * sizeof(char)); - for (i=0; i<BLOCK_MULTIPLE; i++) - { - if(best_l1_ref>=0) - { - enc_picture->ref_pic_id [LIST_1][block_y][block_x + i] = enc_picture->ref_pic_num[LIST_1 + list_offset][best_l1_ref]; - memcpy(enc_picture->mv [LIST_1][block_y][block_x + i], img->all_mv[LIST_1][best_l1_ref][mode][j][i], 2 * sizeof(short)); - } - else - { - enc_picture->ref_pic_id [LIST_1][block_y][block_x + i] = enc_picture->ref_pic_num[LIST_1 + list_offset][0]; - } - } - } - } - } - } +/*! + ************************************************************************************* + * \brief + * Set block 8x8 mode information + ************************************************************************************* + */ +void set_block8x8_info(Block8x8Info *b8x8info, int mode, int block, char best_ref[2], char best_pdir, short bipred_me) +{ + int i; + //----- set reference frame and direction parameters ----- + if (mode==3) + { + b8x8info->best8x8l0ref [3][block ] = b8x8info->best8x8l0ref [3][ block+2] = best_ref[LIST_0]; + b8x8info->best8x8pdir [3][block ] = b8x8info->best8x8pdir [3][ block+2] = best_pdir; + b8x8info->best8x8l1ref [3][block ] = b8x8info->best8x8l1ref [3][ block+2] = best_ref[LIST_1]; + b8x8info->bipred8x8me [3][block ] = b8x8info->bipred8x8me [3][block+2 ] = bipred_me; } else if (mode==2) { - for (j=0; j<2; j++) - { - block_y = img->block_y + block * 2 + j; - for (i=0; i<BLOCK_MULTIPLE; i++) - { - block_x = img->block_x + i; - if (best_pdir==1) - { - enc_picture->ref_idx [LIST_0][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = -1; - enc_picture->mv [LIST_0][block_y][block_x][0] = 0; - enc_picture->mv [LIST_0][block_y][block_x][1] = 0; - } - else - { - enc_picture->ref_idx [LIST_0][block_y][block_x] = best_l0_ref; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + list_offset][best_l0_ref]; - memcpy(enc_picture->mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][best_l0_ref][mode][j+block*2][i], 2 * sizeof(short)); - } - - if (bframe) - { - if (best_pdir==0) - { - enc_picture->ref_idx [LIST_1][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = -1; - memset(enc_picture->mv [LIST_1][block_y][block_x], 0, 2 * sizeof(short)); - } - else - { - enc_picture->ref_idx[LIST_1][block_y][block_x] = best_l1_ref; - if(best_l1_ref>=0) - { - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + list_offset][best_l1_ref]; - memcpy(enc_picture->mv [LIST_1][block_y][block_x], img->all_mv[LIST_1][best_l1_ref][mode][j+ block*2][i], 2 * sizeof(short)); - } - } - } - } - } + b8x8info->best8x8l0ref [2][2*block] = b8x8info->best8x8l0ref [2][2*block+1] = best_ref[LIST_0]; + b8x8info->best8x8pdir [2][2*block] = b8x8info->best8x8pdir [2][2*block+1] = best_pdir; + b8x8info->best8x8l1ref [2][2*block] = b8x8info->best8x8l1ref [2][2*block+1] = best_ref[LIST_1]; + b8x8info->bipred8x8me [2][2*block ] = b8x8info->bipred8x8me[2][2*block+1 ] = bipred_me; } else { - for (j=0; j<BLOCK_MULTIPLE; j++) - { - block_y = img->block_y+j; - for (i=0; i<2; i++) - { - block_x = img->block_x + block*2 + i; - if (best_pdir==1) - { - enc_picture->ref_idx [LIST_0][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = -1; - memset(enc_picture->mv [LIST_0][block_y][block_x], 0, 2 * sizeof(short)); - } - else - { - enc_picture->ref_idx [LIST_0][block_y][block_x] = best_l0_ref; - enc_picture->ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + list_offset][best_l0_ref]; - memcpy(enc_picture->mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][best_l0_ref][mode][j][block*2+i], 2 * sizeof(short)); - } - - if (bframe) - { - if (best_pdir==0) - { - enc_picture->ref_idx [LIST_1][block_y][block_x] = -1; - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = -1; - memset(enc_picture->mv [LIST_1][block_y][block_x], 0, 2 * sizeof(short)); - } - else - { - enc_picture->ref_idx[LIST_1][block_y][block_x] = best_l1_ref; - if(best_l1_ref>=0) - { - enc_picture->ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + list_offset][best_l1_ref]; - memcpy(enc_picture->mv[LIST_1][block_y][block_x], img->all_mv[LIST_1][best_l1_ref][mode][j][block*2+i], 2 * sizeof(short)); - } - } - } - } - } + memset(&b8x8info->best8x8l0ref [1][0], best_ref[LIST_0], 4 * sizeof(char)); + memset(&b8x8info->best8x8l1ref [1][0], best_ref[LIST_1], 4 * sizeof(char)); + memset(&b8x8info->best8x8pdir [1][0], best_pdir, 4 * sizeof(char)); + for (i = 0; i< 4; i++) + b8x8info->bipred8x8me [1][i] = bipred_me; } } +/*! + ************************************************************************************* + * \brief + * Set block 8x8 mode information for P8x8 mode + ************************************************************************************* + */ +void set_subblock8x8_info(Block8x8Info *b8x8info,int mode, int block, RD_8x8DATA *tr) +{ + b8x8info->best8x8mode [block] = tr->part8x8mode [block]; + b8x8info->best8x8pdir [mode][block] = tr->part8x8pdir [block]; + b8x8info->best8x8l0ref [mode][block] = tr->part8x8l0ref [block]; + b8x8info->best8x8l1ref [mode][block] = tr->part8x8l1ref [block]; + b8x8info->bipred8x8me [mode][block] = tr->part8x8bipred[block]; +} + + + void update_refresh_map(int intra, int intra1, Macroblock *currMB) { if (params->RestrictRef==1) @@ -3099,7 +2872,7 @@ void update_refresh_map(int intra, int intra1, Macroblock *currMB) refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra ? 1 : 0); refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra ? 1 : 0); } - else if (params->rdopt==3) + else if (params->rdopt == 3) { refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0); refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0); @@ -3172,43 +2945,7 @@ void generate_pred_error(imgpel **cur_img, imgpel prd_img[16][16], imgpel cur_pr } } -void store_adaptive_rounding (int block_y, int block_x) -{ - int j; - for (j = block_y; j < block_y + 4; j++) - memcpy(&fadjust4x4[j][block_x],&img->fadjust4x4[1][j][block_x], BLOCK_SIZE * sizeof(int)); - if (img->P444_joined) - { - for (j = block_y; j < block_y + 4; j++) - { - memcpy(&fadjust4x4Cr[0][j][block_x],&img->fadjust4x4Cr[0][1][j][block_x], BLOCK_SIZE * sizeof(int)); - } - for (j = block_y; j < block_y + 4; j++) - { - memcpy(&fadjust4x4Cr[1][j][block_x],&img->fadjust4x4Cr[1][1][j][block_x], BLOCK_SIZE * sizeof(int)); - } - } -} -void update_adaptive_rounding(int block_y, int block_x) -{ - int j; - - for (j = block_y; j < block_y + BLOCK_SIZE; j++) - memcpy (&img->fadjust4x4[1][j][block_x],&fadjust4x4[j][block_x], BLOCK_SIZE * sizeof(int)); - - if (img->P444_joined) - { - for (j = 0; j < block_y + BLOCK_SIZE; j++) - { - memcpy (&img->fadjust4x4Cr[0][1][j][block_x],&fadjust4x4Cr[0][j][block_x], BLOCK_SIZE * sizeof(int)); - } - for (j = 0; j < block_y + BLOCK_SIZE; j++) - { - memcpy (&img->fadjust4x4Cr[1][1][j][block_x],&fadjust4x4Cr[1][j][block_x], BLOCK_SIZE * sizeof(int)); - } - } -} diff --git a/lencod/src/rdpicdecision.c b/lencod/src/rdpicdecision.c index 3eed085..1d681b3 100644 --- a/lencod/src/rdpicdecision.c +++ b/lencod/src/rdpicdecision.c @@ -46,19 +46,16 @@ int picture_coding_decision (Picture *picture1, Picture *picture2, int qp) double lambda_picture; int spframe = (img->type == SP_SLICE); int bframe = (img->type == B_SLICE); - double snr_picture1, snr_picture2; - int bit_picture1, bit_picture2; + double sse_picture1, sse_picture2; if (params->successive_Bframe) lambda_picture = (qp < 20 ? 0.55 : 0.68) * pow (2, (qp - SHIFT_QP) / 3.0) * (bframe || spframe ? 2 : 1); else lambda_picture = (qp < 20 ? 0.55 : 0.68) * pow (2, (qp - SHIFT_QP) / 3.0); - snr_picture1 = picture1->distortion_y + picture1->distortion_u + picture1->distortion_v; - snr_picture2 = picture2->distortion_y + picture2->distortion_u + picture2->distortion_v; - bit_picture2 = picture2->bits_per_picture; - bit_picture1 = picture1->bits_per_picture; - - return rd_pic_decision(snr_picture1, snr_picture2, bit_picture1, bit_picture2, lambda_picture); + sse_picture1 = picture1->distortion.value[0] + picture1->distortion.value[1] + picture1->distortion.value[2]; + sse_picture2 = picture2->distortion.value[0] + picture2->distortion.value[1] + picture2->distortion.value[2]; + + return rd_pic_decision(sse_picture1, sse_picture2, picture1->bits_per_picture, picture2->bits_per_picture, lambda_picture); } diff --git a/lencod/src/refbuf.c b/lencod/src/refbuf.c index 4502b9f..1932cd9 100644 --- a/lencod/src/refbuf.c +++ b/lencod/src/refbuf.c @@ -4,7 +4,7 @@ * \file refbuf.c * * \brief - * Declarations of teh reference frame buffer types and functions + * Declarations of the reference frame buffer types and functions ************************************************************************ */ diff --git a/lencod/src/report.c b/lencod/src/report.c new file mode 100644 index 0000000..67d56a9 --- /dev/null +++ b/lencod/src/report.c @@ -0,0 +1,1181 @@ +/*! + * \file + * report.c + * \brief + * Report related files() + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Suehring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + *********************************************************************** + */ + +#include "contributors.h" + +#include <time.h> +#include <math.h> +#include <sys/timeb.h> +#include "global.h" + +#include "context_ini.h" +#include "explicit_gop.h" +#include "filehandle.h" +#include "fmo.h" +#include "image.h" +#include "intrarefresh.h" +#include "leaky_bucket.h" +#include "me_epzs.h" +#include "output.h" +#include "parset.h" +#include "report.h" + + +StatParameters statistics, *stats = &statistics; +DistortionParams distortions, *dist = &distortions; +static char DistortionType[3][20] = {"SAD", "SSE", "Hadamard SAD"}; + +extern int frame_statistic_start; +extern ColocatedParams *Co_located; +extern ColocatedParams *Co_located_JV[MAX_PLANE]; //!< Co_located to be used during 4:4:4 independent mode encoding +extern void Clear_Motion_Search_Module (void); +void report_log_mode(InputParameters *params, StatParameters *stats, int64 bit_use[NUM_SLICE_TYPES][2]); +/*! + ************************************************************************ + * \brief + * Reports frame statistical data to a stats file + ************************************************************************ + */ +void report_frame_statistic() +{ + FILE *p_stat_frm = NULL; + static int64 last_mode_use [NUM_SLICE_TYPES][MAXMODE]; + static int64 last_mode_use_transform[NUM_SLICE_TYPES][MAXMODE][2]; + static int last_b8_mode_0[NUM_SLICE_TYPES][2]; + static int last_mode_chroma_use[4]; + static int64 last_bit_ctr_n = 0; + int i; + char name[30]; + int bitcounter; + +#ifndef WIN32 + time_t now; + struct tm *l_time; + char string[1000]; +#else + char timebuf[128]; +#endif + + // write to log file + if ((p_stat_frm = fopen("stat_frame.dat", "r")) == 0) // check if file exists + { + if ((p_stat_frm = fopen("stat_frame.dat", "a")) == NULL) // append new statistic at the end + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "stat_frame.dat.dat"); + error(errortext, 500); + } + else // Create header for new log file + { + fprintf(p_stat_frm, " --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); + fprintf(p_stat_frm, "| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n"); + fprintf(p_stat_frm, " --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); + } + } + else + { + fclose (p_stat_frm); + if ((p_stat_frm = fopen("stat_frame.dat", "a")) == NULL) // File exists, just open for appending + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "stat_frame.dat.dat"); + error(errortext, 500); + } + } + + if (frame_statistic_start) + { + fprintf(p_stat_frm, "| ver | Date | Time | Sequence |Frm | QP |P/MbInt| Bits | SNRY | SNRU | SNRV | I4 | I8 | I16 | IC0 | IC1 | IC2 | IC3 | PI4 | PI8 | PI16 | P0 | P1 | P2 | P3 | P1*4*| P1*8*| P2*4*| P2*8*| P3*4*| P3*8*| P8 | P8:4 | P4*4*| P4*8*| P8:5 | P8:6 | P8:7 | BI4 | BI8 | BI16 | B0 | B1 | B2 | B3 | B0*4*| B0*8*| B1*4*| B1*8*| B2*4*| B2*8*| B3*4*| B3*8*| B8 | B8:0 |B80*4*|B80*8*| B8:4 | B4*4*| B4*8*| B8:5 | B8:6 | B8:7 |\n"); + fprintf(p_stat_frm, " ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); + } + + //report + fprintf(p_stat_frm, "|%4s/%s", VERSION, EXT_VERSION); + +#ifdef WIN32 + _strdate( timebuf ); + fprintf(p_stat_frm, "| %1.5s |", timebuf); + + _strtime( timebuf); + fprintf(p_stat_frm, " % 1.5s |", timebuf); +#else + now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time' + time (&now); + l_time = localtime (&now); + strftime (string, sizeof string, "%d-%b-%Y", l_time); + fprintf(p_stat_frm, "| %1.5s |", string ); + + strftime (string, sizeof string, "%H:%M:%S", l_time); + fprintf(p_stat_frm, " %1.5s |", string); +#endif + + for (i=0;i<30;i++) + name[i]=params->infile[i + imax(0,(int) (strlen(params->infile)- 30))]; // write last part of path, max 30 chars + + fprintf(p_stat_frm, "%30.30s|", name); + fprintf(p_stat_frm, "%3d |", frame_no); + fprintf(p_stat_frm, "%3d |", img->qp); + fprintf(p_stat_frm, " %d/%d |", params->PicInterlace, params->MbInterlace); + + + if (img->frm_number == 0 && img->frame_num == 0) + { + bitcounter = (int) stats->bit_counter[I_SLICE]; + } + else + { + bitcounter = (int) (stats->bit_ctr_n - last_bit_ctr_n); + last_bit_ctr_n = stats->bit_ctr_n; + } + + //report bitrate + fprintf(p_stat_frm, " %9d|", bitcounter); + + //report snr's + fprintf(p_stat_frm, " %2.4f| %2.4f| %2.4f|", dist->metric[PSNR].value[0], dist->metric[PSNR].value[1], dist->metric[PSNR].value[2]); + + //report modes + //I-Modes + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I4MB ] - last_mode_use[I_SLICE][I4MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I8MB ] - last_mode_use[I_SLICE][I8MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I16MB] - last_mode_use[I_SLICE][I16MB]); + + //chroma intra mode + fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[0] - last_mode_chroma_use[0]); + fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[1] - last_mode_chroma_use[1]); + fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[2] - last_mode_chroma_use[2]); + fprintf(p_stat_frm, " %5d|", stats->intra_chroma_mode[3] - last_mode_chroma_use[3]); + + //P-Modes + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I4MB ] - last_mode_use[P_SLICE][I4MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I8MB ] - last_mode_use[P_SLICE][I8MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I16MB] - last_mode_use[P_SLICE][I16MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][0 ] - last_mode_use[P_SLICE][0 ]); + + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][1 ] - last_mode_use[P_SLICE][1 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][2 ] - last_mode_use[P_SLICE][2 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][3 ] - last_mode_use[P_SLICE][3 ]); + + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][1][0] - last_mode_use_transform[P_SLICE][1][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][1][1] - last_mode_use_transform[P_SLICE][1][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][2][0] - last_mode_use_transform[P_SLICE][2][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][2][1] - last_mode_use_transform[P_SLICE][2][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][3][0] - last_mode_use_transform[P_SLICE][3][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][3][1] - last_mode_use_transform[P_SLICE][3][1]); + + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][P8x8 ] - last_mode_use[P_SLICE][P8x8]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][4 ] - last_mode_use[P_SLICE][4 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][4][0] - last_mode_use_transform[P_SLICE][4][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][4][1] - last_mode_use_transform[P_SLICE][4][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][5 ] - last_mode_use[P_SLICE][5 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][6 ] - last_mode_use[P_SLICE][6 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][7 ] - last_mode_use[P_SLICE][7 ]); + + //B-Modes + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I4MB ] - last_mode_use[B_SLICE][I4MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I8MB ] - last_mode_use[B_SLICE][I8MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I16MB] - last_mode_use[B_SLICE][I16MB]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][0 ] - last_mode_use[B_SLICE][0 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][1 ] - last_mode_use[B_SLICE][1 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][2 ] - last_mode_use[B_SLICE][2 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][3 ] - last_mode_use[B_SLICE][3 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][0][0] - last_mode_use_transform[B_SLICE][0][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][0][1] - last_mode_use_transform[B_SLICE][0][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][1][0] - last_mode_use_transform[B_SLICE][1][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][1][1] - last_mode_use_transform[B_SLICE][1][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][2][0] - last_mode_use_transform[B_SLICE][2][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][2][1] - last_mode_use_transform[B_SLICE][2][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][3][0] - last_mode_use_transform[B_SLICE][3][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][3][1] - last_mode_use_transform[B_SLICE][3][1]); + + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][P8x8] - last_mode_use[B_SLICE][P8x8]); + fprintf(p_stat_frm, " %d|", (stats->b8_mode_0_use [B_SLICE][0]+stats->b8_mode_0_use [B_SLICE][1]) - (last_b8_mode_0[B_SLICE][0]+last_b8_mode_0[B_SLICE][1])); + fprintf(p_stat_frm, " %5d|", stats->b8_mode_0_use [B_SLICE][0] - last_b8_mode_0[B_SLICE][0]); + fprintf(p_stat_frm, " %5d|", stats->b8_mode_0_use [B_SLICE][1] - last_b8_mode_0[B_SLICE][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][4 ] - last_mode_use[B_SLICE][4 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][4][0] - last_mode_use_transform[B_SLICE][4][0]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][4][1] - last_mode_use_transform[B_SLICE][4][1]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][5 ] - last_mode_use[B_SLICE][5 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][6 ] - last_mode_use[B_SLICE][6 ]); + fprintf(p_stat_frm, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][7 ] - last_mode_use[B_SLICE][7 ]); + + fprintf(p_stat_frm, "\n"); + + //save the last results + memcpy(last_mode_use[I_SLICE], stats->mode_use[I_SLICE], MAXMODE * sizeof(int64)); + memcpy(last_mode_use[P_SLICE], stats->mode_use[P_SLICE], MAXMODE * sizeof(int64)); + memcpy(last_mode_use[B_SLICE], stats->mode_use[B_SLICE], MAXMODE * sizeof(int64)); + memcpy(last_mode_use_transform[P_SLICE], stats->mode_use_transform[P_SLICE], 2 * MAXMODE * sizeof(int64)); + memcpy(last_mode_use_transform[B_SLICE], stats->mode_use_transform[B_SLICE], 2 * MAXMODE * sizeof(int64)); + memcpy(last_b8_mode_0[B_SLICE], stats->b8_mode_0_use[B_SLICE], 2 * sizeof(int)); + memcpy(last_mode_chroma_use, stats->intra_chroma_mode, 4 * sizeof(int)); + + frame_statistic_start = 0; + fclose(p_stat_frm); +} + + +double report_slice_pred_stats(FILE *p_stat, StatParameters *stats, int slice_type, double bit_use, char *slice_name) +{ + fprintf(p_stat,"\n ---------------------|----------------|-----------------|"); + fprintf(p_stat,"\n %8s | Mode used | MotionInfo bits |", slice_name); + fprintf(p_stat,"\n ---------------------|----------------|-----------------|"); + fprintf(p_stat,"\n Mode 0 (copy) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[slice_type][0 ], (double)stats->bit_use_mode[slice_type][0 ] / bit_use); + fprintf(p_stat,"\n Mode 1 (16x16) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[slice_type][1 ], (double)stats->bit_use_mode[slice_type][1 ] / bit_use); + fprintf(p_stat,"\n Mode 2 (16x8) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[slice_type][2 ], (double)stats->bit_use_mode[slice_type][2 ] / bit_use); + fprintf(p_stat,"\n Mode 3 (8x16) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[slice_type][3 ], (double)stats->bit_use_mode[slice_type][3 ] / bit_use); + fprintf(p_stat,"\n Mode 4 (8x8) | %5" FORMAT_OFF_T " | %8.2f |", stats->mode_use[slice_type][P8x8], (double)stats->bit_use_mode[slice_type][P8x8] / bit_use); + fprintf(p_stat,"\n Mode 5 intra 4x4 | %5" FORMAT_OFF_T " |-----------------|", stats->mode_use[slice_type][I4MB]); + fprintf(p_stat,"\n Mode 6 intra 8x8 | %5" FORMAT_OFF_T " |", stats->mode_use[slice_type][I8MB]); + fprintf(p_stat,"\n Mode 7+ intra 16x16 | %5" FORMAT_OFF_T " |", stats->mode_use[slice_type][I16MB]); + fprintf(p_stat,"\n Mode intra IPCM | %5" FORMAT_OFF_T " |", stats->mode_use[slice_type][IPCM ]); + + return (double)(stats->bit_use_mode[slice_type][0] + stats->bit_use_mode[slice_type][1] + stats->bit_use_mode[slice_type][2] + + stats->bit_use_mode[slice_type][3] + stats->bit_use_mode[slice_type][P8x8]) / bit_use; +} + +/*! + *********************************************************************** + * \brief + * Terminates and reports statistics on error. + * + *********************************************************************** + */ +void report_stats_on_error(void) +{ + params->no_frames = img->frm_number; + free_encoder_memory(img); + exit (-1); +} + + +void report_stats(InputParameters *params, StatParameters *stats, int64 bit_use[NUM_SLICE_TYPES][2], float frame_rate) +{ + FILE *p_stat; //!< status file for the last encoding session + double mean_motion_info_bit_use[NUM_SLICE_TYPES] = {0.0}; + int i; + + if (strlen(params->StatsFile) == 0) + strcpy (params->StatsFile,"stats.dat"); + + if ((p_stat = fopen(params->StatsFile, "wt")) == 0) + { + snprintf(errortext, ET_SIZE, "Error open file %s", params->StatsFile); + error(errortext, 500); + } + + fprintf(p_stat," -------------------------------------------------------------- \n"); + fprintf(p_stat," This file contains statistics for the last encoded sequence \n"); + fprintf(p_stat," -------------------------------------------------------------- \n"); + fprintf(p_stat, " Sequence : %s\n", params->infile); + fprintf(p_stat, " No.of coded pictures : %4d\n", stats->frame_counter); + fprintf(p_stat, " Freq. for encoded bitstream : %4.0f\n", frame_rate); + + fprintf(p_stat, " I Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_st[I_SLICE] / 1000); + fprintf(p_stat, " P Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_st[P_SLICE] / 1000); + fprintf(p_stat, " B Slice Bitrate(kb/s) : %6.2f\n", stats->bitrate_st[B_SLICE] / 1000); + fprintf(p_stat, " Total Bitrate(kb/s) : %6.2f\n", stats->bitrate / 1000); + + for (i = 0; i < 3; i++) + { + fprintf(p_stat," ME Level %1d Metric : %s\n", i, DistortionType[params->MEErrorMetric[i]]); + } + fprintf(p_stat," Mode Decision Metric : %s\n", DistortionType[params->ModeDecisionMetric]); + + switch ( params->ChromaMEEnable ) + { + case 1: + fprintf(p_stat," ME for components : YCbCr\n"); + break; + default: + fprintf(p_stat," ME for components : Y\n"); + break; + } + + fprintf(p_stat, " Image format : %dx%d\n", params->output.width, params->output.height); + + if (params->intra_upd) + fprintf(p_stat," Error robustness : On\n"); + else + fprintf(p_stat," Error robustness : Off\n"); + + fprintf(p_stat, " Search range : %d\n", params->search_range); + + fprintf(p_stat, " Total number of references : %d\n", params->num_ref_frames); + fprintf(p_stat, " References for P slices : %d\n", params->P_List0_refs ? params->P_List0_refs : params->num_ref_frames); + + if (stats->frame_ctr[B_SLICE]!=0) + { + fprintf(p_stat, " List0 refs for B slices : %d\n", params->B_List0_refs ? params->B_List0_refs : params->num_ref_frames); + fprintf(p_stat, " List1 refs for B slices : %d\n", params->B_List1_refs ? params->B_List1_refs : params->num_ref_frames); + } + + fprintf(p_stat, " Profile/Level IDC : (%d,%d)\n", params->ProfileIDC, params->LevelIDC); + if (params->symbol_mode == CAVLC) + fprintf(p_stat, " Entropy coding method : CAVLC\n"); + else + fprintf(p_stat, " Entropy coding method : CABAC\n"); + + if (params->MbInterlace) + fprintf(p_stat, " MB Field Coding : On \n"); + + if (params->SearchMode == EPZS) + EPZSOutputStats(params, p_stat, 1); + + if (params->full_search == 2) + fprintf(p_stat," Search range restrictions : none\n"); + else if (params->full_search == 1) + fprintf(p_stat," Search range restrictions : older reference frames\n"); + else + fprintf(p_stat," Search range restrictions : smaller blocks and older reference frames\n"); + + if (params->rdopt) + fprintf(p_stat," RD-optimized mode decision : used\n"); + else + fprintf(p_stat," RD-optimized mode decision : not used\n"); + + fprintf(p_stat,"\n ---------------------|----------------|---------------|"); + fprintf(p_stat,"\n Item | Intra | All frames |"); + fprintf(p_stat,"\n ---------------------|----------------|---------------|"); + fprintf(p_stat,"\n SNR Y(dB) |"); + fprintf(p_stat," %5.2f |", dist->metric[PSNR].avslice[I_SLICE][0]); + fprintf(p_stat," %5.2f |", dist->metric[PSNR].average[0]); + fprintf(p_stat,"\n SNR U/V (dB) |"); + fprintf(p_stat," %5.2f/%5.2f |", dist->metric[PSNR].avslice[I_SLICE][1], dist->metric[PSNR].avslice[I_SLICE][2]); + fprintf(p_stat," %5.2f/%5.2f |", dist->metric[PSNR].average[1], dist->metric[PSNR].average[2]); + fprintf(p_stat,"\n ---------------------|----------------|---------------|"); + fprintf(p_stat,"\n"); + + // QUANT. + fprintf(p_stat,"\n Average quant |"); + fprintf(p_stat," %5d |", iabs(params->qp0)); + fprintf(p_stat," %5.2f |", (float)stats->quant1/dmax(1.0,(float)stats->quant0)); + fprintf(p_stat,"\n ---------------------|----------------|---------------|---------------|"); + fprintf(p_stat,"\n SNR | I | P | B |"); + fprintf(p_stat,"\n ---------------------|----------------|---------------|---------------|"); + fprintf(p_stat,"\n SNR Y(dB) | %5.3f | %5.3f | %5.3f |", + dist->metric[PSNR].avslice[I_SLICE][0], dist->metric[PSNR].avslice[P_SLICE][0], dist->metric[PSNR].avslice[B_SLICE][0]); + fprintf(p_stat,"\n SNR U(dB) | %5.3f | %5.3f | %5.3f |", + dist->metric[PSNR].avslice[I_SLICE][1], dist->metric[PSNR].avslice[P_SLICE][1], dist->metric[PSNR].avslice[B_SLICE][1]); + fprintf(p_stat,"\n SNR V(dB) | %5.3f | %5.3f | %5.3f |", + dist->metric[PSNR].avslice[I_SLICE][2], dist->metric[PSNR].avslice[P_SLICE][2], dist->metric[PSNR].avslice[B_SLICE][2]); + fprintf(p_stat,"\n ---------------------|----------------|---------------|---------------|"); + fprintf(p_stat,"\n"); + + // MODE + fprintf(p_stat,"\n ---------------------|----------------|"); + fprintf(p_stat,"\n Intra | Mode used |"); + fprintf(p_stat,"\n ---------------------|----------------|"); + fprintf(p_stat,"\n Mode 0 intra 4x4 | %5" FORMAT_OFF_T " |", stats->mode_use[I_SLICE][I4MB ]); + fprintf(p_stat,"\n Mode 1 intra 8x8 | %5" FORMAT_OFF_T " |", stats->mode_use[I_SLICE][I8MB ]); + fprintf(p_stat,"\n Mode 2+ intra 16x16 | %5" FORMAT_OFF_T " |", stats->mode_use[I_SLICE][I16MB]); + fprintf(p_stat,"\n Mode intra IPCM | %5" FORMAT_OFF_T " |", stats->mode_use[I_SLICE][IPCM ]); + + // P slices + if (stats->frame_ctr[P_SLICE]!=0) + { + mean_motion_info_bit_use[P_SLICE] = report_slice_pred_stats(p_stat, stats, P_SLICE,(double) bit_use[P_SLICE][0], "P Slice "); + } + // B slices + if (stats->frame_ctr[B_SLICE]!=0) + { + mean_motion_info_bit_use[B_SLICE] = report_slice_pred_stats(p_stat, stats, B_SLICE,(double) bit_use[B_SLICE][0], "B Slice "); + } + // SP slices + if (stats->frame_ctr[SP_SLICE]!=0) + { + mean_motion_info_bit_use[SP_SLICE] = report_slice_pred_stats(p_stat, stats, SP_SLICE,(double) bit_use[SP_SLICE][0], "SP Slice"); + } + + + fprintf(p_stat,"\n ---------------------|----------------|"); + fprintf(p_stat,"\n"); + + fprintf(p_stat,"\n ---------------------|----------------|----------------|----------------|"); + fprintf(p_stat,"\n Bit usage: | Intra | Inter | B frame |"); + fprintf(p_stat,"\n ---------------------|----------------|----------------|----------------|"); + + fprintf(p_stat,"\n Header |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_header[I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_header[P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_header[B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Mode |"); + fprintf(p_stat," %10.2f |", (float)stats->bit_use_mb_type[I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float)stats->bit_use_mb_type[P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float)stats->bit_use_mb_type[B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Motion Info |"); + fprintf(p_stat," ./. |"); + fprintf(p_stat," %10.2f |", mean_motion_info_bit_use[P_SLICE]); + fprintf(p_stat," %10.2f |", mean_motion_info_bit_use[B_SLICE]); + + fprintf(p_stat,"\n CBP Y/C |"); + fprintf(p_stat," %10.2f |", (float) stats->tmp_bit_use_cbp[I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->tmp_bit_use_cbp[P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->tmp_bit_use_cbp[B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Coeffs. Y |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[0][I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[0][P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[0][B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Coeffs. C |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeffC[I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeffC[P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeffC[B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Coeffs. CB |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[1][I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[1][P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[1][B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Coeffs. CB |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[2][I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[2][P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_coeff[2][B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Delta quant |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_delta_quant[I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_delta_quant[P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_delta_quant[B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n Stuffing Bits |"); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_stuffingBits[I_SLICE] / bit_use[I_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_stuffingBits[P_SLICE] / bit_use[P_SLICE][0]); + fprintf(p_stat," %10.2f |", (float) stats->bit_use_stuffingBits[B_SLICE] / bit_use[B_SLICE][0]); + + fprintf(p_stat,"\n ---------------------|----------------|----------------|----------------|"); + fprintf(p_stat,"\n average bits/frame |"); + fprintf(p_stat," %10.2f |", (float) bit_use[I_SLICE][1] / (float) bit_use[I_SLICE][0] ); + fprintf(p_stat," %10.2f |", (float) bit_use[P_SLICE][1] / (float) bit_use[P_SLICE][0] ); + fprintf(p_stat," %10.2f |", (float) bit_use[B_SLICE][1] / (float) bit_use[B_SLICE][0] ); + fprintf(p_stat,"\n ---------------------|----------------|----------------|----------------|"); + fprintf(p_stat,"\n"); + + fclose(p_stat); +} + + +void report_log(InputParameters *params, StatParameters *stats, float frame_rate) +{ + char name[40]; + int i; +#ifndef WIN32 + time_t now; + struct tm *l_time; + char string[1000]; +#else + char timebuf[128]; +#endif + + if ((p_log = fopen("log.dat", "r")) == 0) // check if file exists + { + if ((p_log = fopen("log.dat", "a")) == NULL) // append new statistic at the end + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "log.dat"); + error(errortext, 500); + } + else // Create header for new log file + { + fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); + fprintf(p_log,"| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n"); + fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); + fprintf(p_log,"| ver | Date | Time | Sequence | #Img |P/MbInt| QPI| QPP| QPB| Format |Iperiod| #B | FMES | Hdmd | S.R |#Ref | Freq |Coding|RD-opt|Intra upd|8x8Tr| SNRY 1| SNRU 1| SNRV 1| SNRY N| SNRU N| SNRV N|#Bitr I|#Bitr P|#Bitr B|#Bitr IPB| Total Time | Me Time |\n"); + fprintf(p_log," ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ \n"); + + } + } + else + { + fclose (p_log); + if ((p_log = fopen("log.dat", "a")) == NULL) // File exists, just open for appending + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "log.dat"); + error(errortext, 500); + } + } + fprintf(p_log,"|%5s/%-5s", VERSION, EXT_VERSION); + +#ifdef WIN32 + _strdate( timebuf ); + fprintf(p_log,"| %1.5s |", timebuf ); + + _strtime( timebuf); + fprintf(p_log," % 1.5s |", timebuf); +#else + now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time' + time (&now); + l_time = localtime (&now); + strftime (string, sizeof string, "%d-%b-%Y", l_time); + fprintf(p_log,"| %1.5s |", string ); + + strftime (string, sizeof string, "%H:%M:%S", l_time); + fprintf(p_log," %1.5s |", string ); +#endif + + for (i=0; i < 40; i++) + name[i] = params->infile[i + imax(0, ((int) strlen(params->infile)) - 40)]; // write last part of path, max 40 chars + fprintf(p_log,"%40.40s|",name); + + fprintf(p_log,"%5d | %d/%d |", params->no_frames, params->PicInterlace, params->MbInterlace); + fprintf(p_log," %-3d| %-3d| %-3d|", params->qp0, params->qpN, params->qpB); + + fprintf(p_log,"%4dx%-4d|", params->output.width, params->output.height); + fprintf(p_log," %3d |%3d |", params->intra_period, stats->successive_Bframe); + + + switch( params->SearchMode ) + { + case UM_HEX: + fprintf(p_log," HEX |"); + break; + case UM_HEX_SIMPLE: + fprintf(p_log," SHEX |"); + break; + case EPZS: + fprintf(p_log," EPZS |"); + break; + case FAST_FULL_SEARCH: + fprintf(p_log," FFS |"); + break; + default: + fprintf(p_log," FS |"); + break; + } + + fprintf(p_log," %1d%1d%1d |", params->MEErrorMetric[F_PEL], params->MEErrorMetric[H_PEL], params->MEErrorMetric[Q_PEL]); + + fprintf(p_log," %3d | %2d |", params->search_range, params->num_ref_frames ); + + fprintf(p_log," %5.2f|", (img->framerate *(float) (stats->successive_Bframe + 1)) / (float)(params->jumpd + 1)); + + if (params->symbol_mode == CAVLC) + fprintf(p_log," CAVLC|"); + else + fprintf(p_log," CABAC|"); + + fprintf(p_log," %d |", params->rdopt); + + if (params->intra_upd == 1) + fprintf(p_log," ON |"); + else + fprintf(p_log," OFF |"); + + fprintf(p_log," %d |", params->Transform8x8Mode); + + fprintf(p_log,"%7.3f|%7.3f|%7.3f|", + dist->metric[PSNR].avslice[I_SLICE][0], + dist->metric[PSNR].avslice[I_SLICE][1], + dist->metric[PSNR].avslice[I_SLICE][2]); + fprintf(p_log,"%7.3f|%7.3f|%7.3f|", dist->metric[PSNR].average[0],dist->metric[PSNR].average[1],dist->metric[PSNR].average[2]); + /* + fprintf(p_log,"%-5.3f|%-5.3f|%-5.3f|", dist->metric[PSNR].avslice[I_SLICE][0], dist->metric[PSNR].avslice[I_SLICE][1], dist->metric[PSNR].avslice[I_SLICE][2]); + fprintf(p_log,"%-5.3f|%-5.3f|%-5.3f|", dist->metric[PSNR].avslice[P_SLICE][0], dist->metric[PSNR].avslice[P_SLICE][1], dist->metric[PSNR].avslice[P_SLICE][2]); + fprintf(p_log,"%-5.3f|%-5.3f|%-5.3f|", dist->metric[PSNR].avslice[B_SLICE][0], dist->metric[PSNR].avslice[B_SLICE][1], dist->metric[PSNR].avslice[B_SLICE][2]); + */ + fprintf(p_log,"%7.0f|%7.0f|%7.0f|%9.0f|", stats->bitrate_st[I_SLICE],stats->bitrate_st[P_SLICE],stats->bitrate_st[B_SLICE], stats->bitrate); + + fprintf(p_log," %12d | %12d |", (int)tot_time,(int)me_tot_time); + + + fprintf(p_log,"\n"); + + fclose(p_log); + + p_log = fopen("data.txt", "a"); + + if ((stats->successive_Bframe != 0) && (stats->frame_ctr[B_SLICE] != 0)) // B picture used + { + fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5" FORMAT_OFF_T " " + "%2.2f %2.2f %2.2f %5d " + "%2.2f %2.2f %2.2f %5" FORMAT_OFF_T " %5" FORMAT_OFF_T " %.3f\n", + params->no_frames, params->qp0, params->qpN, + dist->metric[PSNR].avslice[I_SLICE][0], + dist->metric[PSNR].avslice[I_SLICE][1], + dist->metric[PSNR].avslice[I_SLICE][2], + stats->bit_counter[I_SLICE], + 0.0, + 0.0, + 0.0, + 0, + dist->metric[PSNR].average[0], + dist->metric[PSNR].average[1], + dist->metric[PSNR].average[2], + (stats->bit_counter[I_SLICE] + stats->bit_ctr) / stats->frame_counter, + stats->bit_counter[B_SLICE] / stats->frame_ctr[B_SLICE], + (double) 0.001 * tot_time / (stats->frame_counter)); + } + else + { + if (params->no_frames != 0) + fprintf(p_log, "%3d %2d %2d %2.2f %2.2f %2.2f %5" FORMAT_OFF_T " " + "%2.2f %2.2f %2.2f %5d " + "%2.2f %2.2f %2.2f %5" FORMAT_OFF_T " %5d %.3f\n", + params->no_frames, params->qp0, params->qpN, + dist->metric[PSNR].avslice[I_SLICE][0], + dist->metric[PSNR].avslice[I_SLICE][1], + dist->metric[PSNR].avslice[I_SLICE][2], + stats->bit_counter[I_SLICE], + 0.0, + 0.0, + 0.0, + 0, + dist->metric[PSNR].average[0], + dist->metric[PSNR].average[1], + dist->metric[PSNR].average[2], + (stats->bit_counter[I_SLICE] + stats->bit_ctr)/ stats->frame_counter, + 0, + (double)0.001*tot_time/params->no_frames); + } + + fclose(p_log); +} + +/*! + ************************************************************************ + * \brief + * Reports the gathered information to appropriate outputs + * \par Input: + * struct inp_par *inp, \n + * ImageParameters *img, \n + * struct stat_par *stats, \n + * + * \par Output: + * None + ************************************************************************ + */ +void report( ImageParameters *img, InputParameters *params, StatParameters *stats) +{ + int64 bit_use[NUM_SLICE_TYPES][2]; + int i,j; + int64 total_bits; + float frame_rate; + + bit_use[ I_SLICE][0] = stats->frame_ctr[I_SLICE]; + bit_use[ P_SLICE][0] = imax(stats->frame_ctr[P_SLICE ] + stats->frame_ctr[SP_SLICE], 1); + bit_use[ B_SLICE][0] = imax(stats->frame_ctr[B_SLICE ], 1); + bit_use[SP_SLICE][0] = imax(stats->frame_ctr[SP_SLICE], 1); + + // Accumulate bit usage for inter and intra frames + for (j=0; j < NUM_SLICE_TYPES; j++) + { + bit_use[j][1] = 0; + } + + for (j=0; j < NUM_SLICE_TYPES; j++) + { + for(i=0; i < MAXMODE; i++) + bit_use[j][1] += stats->bit_use_mode[j][i]; + + bit_use[j][1] += stats->bit_use_header[j]; + bit_use[j][1] += stats->bit_use_mb_type[j]; + bit_use[j][1] += stats->tmp_bit_use_cbp[j]; + bit_use[j][1] += stats->bit_use_coeffC[j]; + bit_use[j][1] += stats->bit_use_coeff[0][j]; + bit_use[j][1] += stats->bit_use_coeff[1][j]; + bit_use[j][1] += stats->bit_use_coeff[2][j]; + bit_use[j][1] += stats->bit_use_delta_quant[j]; + bit_use[j][1] += stats->bit_use_stuffingBits[j]; + } + + frame_rate = (img->framerate *(float)(stats->successive_Bframe + 1)) / (float) (params->jumpd + 1); + + //! Currently adding NVB bits on P rate. Maybe additional stats info should be created instead and added in log file + stats->bitrate_st[ I_SLICE] = (stats->bit_counter[ I_SLICE]) * (frame_rate) / (float) (stats->frame_counter); + stats->bitrate_st[ P_SLICE] = (stats->bit_counter[ P_SLICE]) * (frame_rate) / (float) (stats->frame_counter); + stats->bitrate_st[ B_SLICE] = (stats->bit_counter[ B_SLICE]) * (frame_rate) / (float) (stats->frame_counter); + stats->bitrate_st[SP_SLICE] = (stats->bit_counter[SP_SLICE]) * (frame_rate) / (float) (stats->frame_counter); + + switch (params->Verbose) + { + case 0: + case 1: + default: + fprintf(stdout,"------------------ Average data all frames -----------------------------------\n\n"); + break; + case 2: + fprintf(stdout,"------------------------------------ Average data all frames ---------------------------------\n\n"); + break; + } + + if (params->Verbose != 0) + { + DistMetric *snr = &dist->metric[PSNR ]; + DistMetric *sse = &dist->metric[SSE ]; + DistMetric *snr_rgb = &dist->metric[PSNR_RGB]; + DistMetric *sse_rgb = &dist->metric[SSE_RGB ]; + + int impix = params->output.size_cmp[0]; + int impix_cr = params->output.size_cmp[1]; + + float csnr_y = psnr(img->max_imgpel_value_comp_sq[0], impix , sse->average[0]); + float csnr_u = psnr(img->max_imgpel_value_comp_sq[1], impix_cr, sse->average[1]); + float csnr_v = psnr(img->max_imgpel_value_comp_sq[2], impix_cr, sse->average[2]); + + fprintf(stdout, " Total encoding time for the seq. : %.3f sec (%.2f fps)\n", tot_time*0.001, 1000.0 * (stats->frame_counter) / tot_time); + fprintf(stdout, " Total ME time for sequence : %.3f sec \n\n", me_tot_time*0.001); + + fprintf(stdout," Y { PSNR (dB), cSNR (dB), MSE } : { %5.2f, %5.2f, %5.2f }\n", + snr->average[0], csnr_y, sse->average[0]/impix); + fprintf(stdout," U { PSNR (dB), cSNR (dB), MSE } : { %5.2f, %5.2f, %5.2f }\n", + snr->average[1], csnr_u, sse->average[1]/impix_cr); + fprintf(stdout," V { PSNR (dB), cSNR (dB), MSE } : { %5.2f, %5.2f, %5.2f }\n", + snr->average[2], csnr_v, sse->average[2]/impix_cr); + + if(params->DistortionYUVtoRGB == 1) + { + float csnr_r = psnr(img->max_imgpel_value_comp_sq[0], impix, sse_rgb->average[0]); + float csnr_g = psnr(img->max_imgpel_value_comp_sq[1], impix, sse_rgb->average[1]); + float csnr_b = psnr(img->max_imgpel_value_comp_sq[2], impix, sse_rgb->average[2]); + + fprintf(stdout," R { PSNR (dB), cSNR (dB), MSE } : { %5.2f, %5.2f, %5.2f }\n", + snr_rgb->average[0], csnr_r, sse_rgb->average[0]/impix); + fprintf(stdout," G { PSNR (dB), cSNR (dB), MSE } : { %5.2f, %5.2f, %5.2f }\n", + snr_rgb->average[1], csnr_g, sse_rgb->average[1]/impix); + fprintf(stdout," B { PSNR (dB), cSNR (dB), MSE } : { %5.2f, %5.2f, %5.2f }\n", + snr_rgb->average[2], csnr_b, sse_rgb->average[2]/impix); + } + + if (params->Distortion[SSIM] == 1) + { + if(params->DistortionYUVtoRGB == 1) + { + fprintf(stdout," SSIM {Y, R} : { %5.4f, %5.4f }\n", dist->metric[SSIM].average[0], dist->metric[SSIM_RGB].average[0]); + fprintf(stdout," SSIM {U, G} : { %5.4f, %5.4f }\n", dist->metric[SSIM].average[1], dist->metric[SSIM_RGB].average[1]); + fprintf(stdout," SSIM {V, B} : { %5.4f, %5.4f }\n", dist->metric[SSIM].average[2], dist->metric[SSIM_RGB].average[2]); + } + else + { + fprintf(stdout," Y SSIM : %5.4f\n", dist->metric[SSIM].average[0]); + fprintf(stdout," U SSIM : %5.4f\n", dist->metric[SSIM].average[1]); + fprintf(stdout," V SSIM : %5.4f\n", dist->metric[SSIM].average[2]); + } + } + if (params->Distortion[MS_SSIM] == 1) + { + if(params->DistortionYUVtoRGB == 1) + { + fprintf(stdout," MS-SSIM {Y, R} : { %5.4f, %5.4f }\n", dist->metric[MS_SSIM].average[0], dist->metric[MS_SSIM_RGB].average[0]); + fprintf(stdout," MS-SSIM {U, G} : { %5.4f, %5.4f }\n", dist->metric[MS_SSIM].average[1], dist->metric[MS_SSIM_RGB].average[1]); + fprintf(stdout," MS-SSIM {V, B} : { %5.4f, %5.4f }\n", dist->metric[MS_SSIM].average[2], dist->metric[MS_SSIM_RGB].average[2]); + } + else + { + fprintf(stdout," Y MS-SSIM : %5.4f\n", dist->metric[MS_SSIM].average[0]); + fprintf(stdout," U MS-SSIM : %5.4f\n", dist->metric[MS_SSIM].average[1]); + fprintf(stdout," V MS-SSIM : %5.4f\n", dist->metric[MS_SSIM].average[2]); + } + } + fprintf(stdout,"\n"); + } + else + fprintf(stdout, " Total encoding time for the seq. : %.3f sec (%.2f fps)\n\n", tot_time*0.001, 1000.0 * (stats->frame_counter) / tot_time); + + total_bits = stats->bit_ctr_parametersets; + for (i = 0; i < NUM_SLICE_TYPES; i++) + total_bits += stats->bit_counter[i]; + + if (stats->frame_ctr[B_SLICE] != 0) + { + fprintf(stdout, " Total bits : %" FORMAT_OFF_T " (I %" FORMAT_OFF_T ", P %" FORMAT_OFF_T ", B %" FORMAT_OFF_T " NVB %d) \n", + total_bits, stats->bit_counter[I_SLICE], stats->bit_counter[P_SLICE], stats->bit_counter[B_SLICE], stats->bit_ctr_parametersets); + } + else if (params->sp_periodicity == 0) + { + fprintf(stdout, " Total bits : %" FORMAT_OFF_T " (I %" FORMAT_OFF_T ", P %" FORMAT_OFF_T ", NVB %d) \n", + total_bits, stats->bit_counter[I_SLICE], stats->bit_counter[P_SLICE], stats->bit_ctr_parametersets); + } + else + { + fprintf(stdout, " Total bits : %" FORMAT_OFF_T " (I %" FORMAT_OFF_T ", P %" FORMAT_OFF_T ", NVB %d) \n", + total_bits, stats->bit_counter[I_SLICE], stats->bit_counter[P_SLICE], stats->bit_ctr_parametersets); + } + + frame_rate = (img->framerate *(float)(stats->successive_Bframe + 1)) / (float) (params->jumpd + 1); + + stats->bitrate= ((float) total_bits * frame_rate) / ((float) (stats->frame_counter)); + fprintf(stdout, " Bit rate (kbit/s) @ %2.2f Hz : %5.2f\n", frame_rate, stats->bitrate / 1000); + + fprintf(stdout, " Bits to avoid Startcode Emulation : %d \n", stats->bit_ctr_emulationprevention); + fprintf(stdout, " Bits for parameter sets : %d \n\n", stats->bit_ctr_parametersets); + + switch (params->Verbose) + { + case 0: + case 1: + default: + fprintf(stdout,"-------------------------------------------------------------------------------\n"); + break; + case 2: + fprintf(stdout,"------------------------------------------------------------------------------------------------\n"); + break; + } + fprintf(stdout,"Exit JM %s encoder ver %s ", JM, VERSION); + fprintf(stdout,"\n"); + + // status file + report_stats(params, stats, bit_use, frame_rate); + + // write to log file + report_log(params, stats, frame_rate); + + if (params->ReportFrameStats) + { + if ((p_log = fopen("stat_frame.dat", "a")) == NULL) // append new statistic at the end + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "stat_frame.dat.dat"); + // error(errortext, 500); + } + else + { + fprintf(p_log," --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); + fclose(p_log); + } + report_log_mode(params, stats, bit_use); + } +} + + +/*! + ************************************************************************ + * \brief + * Prints the header of the protocol. + * \par Input: + * struct inp_par *inp + * \par Output: + * none + ************************************************************************ + */ +void information_init ( ImageParameters *img, InputParameters *params, StatParameters *stats) +{ + int i; + static char yuv_types[4][10] = {"YUV 4:0:0", "YUV 4:2:0", "YUV 4:2:2", "YUV 4:4:4"}; + switch (params->Verbose) + { + case 0: + case 1: + default: + printf("------------------------------- JM %4.4s %7.7s -------------------------------\n", VERSION, EXT_VERSION); + break; + case 2: + printf("--------------------------------------- JM %4.4s %7.7s ----------------------------------------\n", VERSION, EXT_VERSION); + break; + } + + fprintf(stdout, " Input YUV file : %s \n", params->infile); + fprintf(stdout, " Output H.264 bitstream : %s \n", params->outfile); + if (p_dec != -1) + fprintf(stdout, " Output YUV file : %s \n", params->ReconFile); + fprintf(stdout, " YUV Format : %s \n", &yuv_types[img->yuv_format][0]);//img->yuv_format==YUV422?"YUV 4:2:2":(img->yuv_format==YUV444)?"YUV 4:4:4":"YUV 4:2:0"); + fprintf(stdout, " Frames to be encoded I-P/B : %d/%d\n", params->no_frames, (params->successive_Bframe*(params->no_frames-1))); + if (params->Verbose != 0) + { + fprintf(stdout, " Freq. for encoded bitstream : %1.0f\n", img->framerate/(float)(params->jumpd+1)); + fprintf(stdout, " PicInterlace / MbInterlace : %d/%d\n", params->PicInterlace, params->MbInterlace); + fprintf(stdout, " Transform8x8Mode : %d\n", params->Transform8x8Mode); + + for (i=0; i<3; i++) + { + fprintf(stdout," ME Metric for Refinement Level %1d : %s\n", i, DistortionType[params->MEErrorMetric[i]]); + } + fprintf(stdout, " Mode Decision Metric : %s\n", DistortionType[params->ModeDecisionMetric]); + + switch ( params->ChromaMEEnable ) + { + case 1: + fprintf(stdout," Motion Estimation for components : YCbCr\n"); + break; + default: + fprintf(stdout," Motion Estimation for components : Y\n"); + break; + } + + fprintf(stdout, " Image format : %dx%d (%dx%d)\n", params->output.width, params->output.height, img->width,img->height); + + if (params->intra_upd) + fprintf(stdout," Error robustness : On\n"); + else + fprintf(stdout," Error robustness : Off\n"); + fprintf(stdout, " Search range : %d\n", params->search_range); + + fprintf(stdout, " Total number of references : %d\n", params->num_ref_frames); + fprintf(stdout, " References for P slices : %d\n", params->P_List0_refs ? params->P_List0_refs : params->num_ref_frames); + fprintf(stdout, " List0 references for B slices : %d\n", params->B_List0_refs ? params->B_List0_refs : params->num_ref_frames); + fprintf(stdout, " List1 references for B slices : %d\n", params->B_List1_refs ? params->B_List1_refs : params->num_ref_frames); + + // Sequence Type + fprintf(stdout, " Sequence type :"); + if (stats->successive_Bframe > 0 && params->HierarchicalCoding) + { + fprintf(stdout, " Hierarchy (QP: I %d, P %d, B %d) \n", + params->qp0, params->qpN, params->qpB); + } + else if (stats->successive_Bframe > 0) + { + char seqtype[80]; + int i,j; + + strcpy (seqtype,"I"); + + for (j=0; j < 2; j++) + { + for (i=0; i < stats->successive_Bframe; i++) + { + if (params->BRefPictures) + strncat(seqtype,"-RB", imax(0, (int) (79 - strlen(seqtype)))); + else + strncat(seqtype,"-B", imax(0, (int) (79 - strlen(seqtype)))); + } + strncat(seqtype,"-P", imax(0, (int) (79 - strlen(seqtype)))); + } + if (params->BRefPictures) + fprintf(stdout, " %s (QP: I %d, P %d, RB %d) \n", seqtype, params->qp0, params->qpN, iClip3(0, 51, params->qpB + params->qpBRSOffset)); + else + fprintf(stdout, " %s (QP: I %d, P %d, B %d) \n", seqtype, params->qp0, params->qpN, params->qpB); + } + else if (stats->successive_Bframe == 0 && params->sp_periodicity == 0) + fprintf(stdout, " IPPP (QP: I %d, P %d) \n", params->qp0, params->qpN); + else + fprintf(stdout, " I-P-P-SP-P (QP: I %d, P %d, SP (%d, %d)) \n", params->qp0, params->qpN, params->qpsp, params->qpsp_pred); + + // report on entropy coding method + if (params->symbol_mode == CAVLC) + fprintf(stdout," Entropy coding method : CAVLC\n"); + else + fprintf(stdout," Entropy coding method : CABAC\n"); + + fprintf(stdout, " Profile/Level IDC : (%d,%d)\n", params->ProfileIDC, params->LevelIDC); + + if (params->SearchMode == UM_HEX) + fprintf(stdout, " Motion Estimation Scheme : HEX\n"); + else if (params->SearchMode == UM_HEX_SIMPLE) + fprintf(stdout, " Motion Estimation Scheme : SHEX\n"); + else if (params->SearchMode == EPZS) + { + fprintf(stdout, " Motion Estimation Scheme : EPZS\n"); + EPZSOutputStats(params, stdout, 0); + } + else if (params->SearchMode == FAST_FULL_SEARCH) + fprintf(stdout, " Motion Estimation Scheme : Fast Full Search\n"); + else + fprintf(stdout, " Motion Estimation Scheme : Full Search\n"); + + if (params->full_search == 2) + fprintf(stdout," Search range restrictions : none\n"); + else if (params->full_search == 1) + fprintf(stdout," Search range restrictions : older reference frames\n"); + else + fprintf(stdout," Search range restrictions : smaller blocks and older reference frames\n"); + + if (params->rdopt) + fprintf(stdout," RD-optimized mode decision : used\n"); + else + fprintf(stdout," RD-optimized mode decision : not used\n"); + + switch(params->partition_mode) + { + case PAR_DP_1: + fprintf(stdout," Data Partitioning Mode : 1 partition \n"); + break; + case PAR_DP_3: + fprintf(stdout," Data Partitioning Mode : 3 partitions \n"); + break; + default: + fprintf(stdout," Data Partitioning Mode : not supported\n"); + break; + } + + switch(params->of_mode) + { + case PAR_OF_ANNEXB: + fprintf(stdout," Output File Format : H.264/AVC Annex B Byte Stream Format \n"); + break; + case PAR_OF_RTP: + fprintf(stdout," Output File Format : RTP Packet File Format \n"); + break; + default: + fprintf(stdout," Output File Format : not supported\n"); + break; + } + } + + + switch (params->Verbose) + { + case 0: + default: + printf("-------------------------------------------------------------------------------\n"); + printf("\nEncoding. Please Wait.\n\n"); + break; + case 1: + printf("-------------------------------------------------------------------------------\n"); + printf(" Frame Bit/pic QP SnrY SnrU SnrV Time(ms) MET(ms) Frm/Fld Ref \n"); + printf("-------------------------------------------------------------------------------\n"); + break; + case 2: + if (params->Distortion[SSIM] == 1) + { + printf("------------------------------------------------------------------------------------------------------------------------\n"); + printf(" Frame Bit/pic WP QP QL SnrY SnrU SnrV SsimY SsimU SsimV Time(ms) MET(ms) Frm/Fld I D L0 L1 RDP Ref\n"); + printf("------------------------------------------------------------------------------------------------------------------------\n"); + } + else + { + printf("------------------------------------------------------------------------------------------------\n"); + printf(" Frame Bit/pic WP QP QL SnrY SnrU SnrV Time(ms) MET(ms) Frm/Fld I D L0 L1 RDP Ref\n"); + printf("------------------------------------------------------------------------------------------------\n"); + } + break; + + } +} + +/*! + ************************************************************************ + * \brief + * Report mode distribution of the sequence to log_mode.dat + ************************************************************************ + */ +void report_log_mode(InputParameters *params, StatParameters *stats, int64 bit_use[NUM_SLICE_TYPES][2]) +{ + FILE *p_stat; //!< status file for the last encoding session + int i; + char name[40]; +#ifndef WIN32 + time_t now; + struct tm *l_time; + char string[1000]; +#else + char timebuf[128]; +#endif + + if ((p_stat = fopen("log_mode.dat", "r")) == 0) // check if file exists + { + if ((p_stat = fopen("log_mode.dat", "a")) == NULL) // append new statistic at the end + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "log_mode.dat"); + error(errortext, 500); + } + else // Create header for new log file + { + fprintf(p_stat, " ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); + fprintf(p_stat,"| Encoder statistics. This file is generated during first encoding session, new sessions will be appended |\n"); + fprintf(p_stat, " ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); + fprintf(p_stat, "| ver | Date | Time | Sequence | QP | I4 | I8 | I16 | IC0 | IC1 | IC2 | IC3 | PI4 | PI8 | PI16 | P0 | P1 | P2 | P3 | P1*4*| P1*8*| P2*4*| P2*8*| P3*4*| P3*8*| P8 | P8:4 | P4*4*| P4*8*| P8:5 | P8:6 | P8:7 | BI4 | BI8 | BI16 | B0 | B1 | B2 | B3 | B0*4*| B0*8*| B1*4*| B1*8*| B2*4*| B2*8*| B3*4*| B3*8*| B8 | B8:0 |B80*4*|B80*8*| B8:4 | B4*4*| B4*8*| B8:5 | B8:6 | B8:7 |\n"); + fprintf(p_stat, " ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n"); + } + } + else + { + fclose (p_stat); + if ((p_stat = fopen("log_mode.dat", "a")) == NULL) // File exists, just open for appending + { + snprintf(errortext, ET_SIZE, "Error open file %s \n", "log_mode.dat"); + error(errortext, 500); + } + } + + //report + fprintf(p_stat, "|%4s/%s", VERSION, EXT_VERSION); + +#ifdef WIN32 + _strdate( timebuf ); + fprintf(p_stat, "| %1.5s |", timebuf); + + _strtime( timebuf); + fprintf(p_stat, " % 1.5s |", timebuf); +#else + now = time ((time_t *) NULL); // Get the system time and put it into 'now' as 'calender time' + time (&now); + l_time = localtime (&now); + strftime (string, sizeof string, "%d-%b-%Y", l_time); + fprintf(p_stat, "| %1.5s |", string ); + + strftime (string, sizeof string, "%H:%M:%S", l_time); + fprintf(p_stat, " %1.5s |", string); +#endif + + for (i=0;i<30;i++) + name[i]=params->infile[i + imax(0,(int) (strlen(params->infile)- 30))]; // write last part of path, max 30 chars + + fprintf(p_stat, "%30.30s|", name); + fprintf(p_stat, "%3d |", img->qp); + + //report modes + //I-Modes + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I4MB ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I8MB ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[I_SLICE][I16MB]); + + //chroma intra mode + fprintf(p_stat, " %5d|", stats->intra_chroma_mode[0]); + fprintf(p_stat, " %5d|", stats->intra_chroma_mode[1]); + fprintf(p_stat, " %5d|", stats->intra_chroma_mode[2]); + fprintf(p_stat, " %5d|", stats->intra_chroma_mode[3]); + + //P-Modes + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I4MB ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I8MB ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][I16MB]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][0 ]); + + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][1 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][2 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][3 ]); + + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][1][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][1][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][2][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][2][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][3][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][3][1]); + + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][P8x8 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][4 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][4][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[P_SLICE][4][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][5 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][6 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[P_SLICE][7 ]); + + //B-Modes + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I4MB ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I8MB ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][I16MB]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][0 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][1 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][2 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][3 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][0][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][0][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][1][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][1][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][2][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][2][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][3][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][3][1]); + + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][P8x8]); + fprintf(p_stat, " %d|", (stats->b8_mode_0_use [B_SLICE][0]+stats->b8_mode_0_use [B_SLICE][1])); + fprintf(p_stat, " %5d|", stats->b8_mode_0_use [B_SLICE][0]); + fprintf(p_stat, " %5d|", stats->b8_mode_0_use [B_SLICE][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][4 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][4][0]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use_transform[B_SLICE][4][1]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][5 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][6 ]); + fprintf(p_stat, " %5" FORMAT_OFF_T "|", stats->mode_use[B_SLICE][7 ]); + + fprintf(p_stat, "\n"); + fclose(p_stat); +} + + diff --git a/lencod/src/slice.c b/lencod/src/slice.c index d7aaa35..dfbbfd8 100644 --- a/lencod/src/slice.c +++ b/lencod/src/slice.c @@ -32,23 +32,26 @@ #include "macroblock.h" #include "symbol.h" #include "context_ini.h" +#include "enc_statistics.h" #include "ratectl.h" #include "me_epzs.h" #include "wp.h" +#include "slice.h" #include "q_offsets.h" #include "conformance.h" #include "rdo_quant.h" +#include "wp_mcprec.h" + // Local declarations static Slice *malloc_slice(); static void free_slice(Slice *slice); - static void set_ref_pic_num(); + extern ColocatedParams *Co_located; extern StorablePicture **listX[6]; -void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no); //! convert from H.263 QP to H.264 quant given by: quant=pow(2,QP/6) const int QP2QUANT[40]= @@ -137,8 +140,6 @@ int start_slice() return header_len; } - - /*! ************************************************************************ * \brief @@ -300,6 +301,7 @@ int encode_one_slice (int SliceGroupId, Picture *pic, int TotalCodedMBs) } else { + img->masterQP = img->qp; encode_one_macroblock (currMB); write_one_macroblock (currMB, 1, prev_recode_mb); } @@ -645,9 +647,9 @@ void init_slice (int start_mb_addr) img->currentSlice = currSlice; - currSlice->picture_id = img->tr % 256; - currSlice->qp = img->qp; - currSlice->start_mb_nr = start_mb_addr; + currSlice->picture_id = img->tr % 256; + currSlice->qp = img->qp; + currSlice->start_mb_nr = start_mb_addr; currSlice->slice_too_big = dummy_slice_too_big; for (i = 0; i < currSlice->max_part_nr; i++) @@ -700,11 +702,25 @@ void init_slice (int start_mb_addr) img->num_ref_idx_l0_active = listXsize[0]; img->num_ref_idx_l1_active = listXsize[1]; - //Perform memory management based on poc distances - //if (img->nal_reference_idc && params->HierarchicalCoding && params->PocMemoryManagement && dpb.ref_frames_in_buffer==active_sps->num_ref_frames) - if (img->nal_reference_idc && params->PocMemoryManagement && dpb.ref_frames_in_buffer==active_sps->num_ref_frames) + if ( params->WPMCPrecision && params->WPMCPrecFullRef ) { - poc_based_ref_management(img->frame_num); + wpxAdaptRefNum(img); + } + + //Perform memory management based on poc distances + + if (img->nal_reference_idc && params->PocMemoryManagement) + { + if (img->structure == FRAME && dpb.ref_frames_in_buffer==active_sps->num_ref_frames) + { + poc_based_ref_management_frame_pic(img->frame_num); + } + else if (img->structure == TOP_FIELD && dpb.ref_frames_in_buffer==active_sps->num_ref_frames) + { + poc_based_ref_management_field_pic((img->frame_num << 1) + 1); + } + else if (img->structure == BOTTOM_FIELD) + poc_based_ref_management_field_pic((img->frame_num << 1) + 1); } if (params->EnableOpenGOP) @@ -730,32 +746,48 @@ void init_slice (int start_mb_addr) init_ref_pic_list_reordering(); - // Perform reordering based on poc distances for HierarchicalCoding - if ( img->type == P_SLICE && params->ReferenceReorder) + // reference list reordering + if ( (img->type == P_SLICE || img->type == B_SLICE) && + params->WPMCPrecision && pWPX->curr_wp_rd_pass->algorithm != WP_REGULAR ) { - int i, num_ref; + wpxReorderLists( img, currSlice ); + } + else + { + // Perform reordering based on poc distances for HierarchicalCoding + if ( img->type == P_SLICE && params->ReferenceReorder) + { + int i, num_ref; - alloc_ref_pic_list_reordering_buffer(currSlice); + alloc_ref_pic_list_reordering_buffer(currSlice); - for (i = 0; i < img->num_ref_idx_l0_active + 1; i++) - { - currSlice->reordering_of_pic_nums_idc_l0[i] = 3; - currSlice->abs_diff_pic_num_minus1_l0[i] = 0; - currSlice->long_term_pic_idx_l0[i] = 0; - } + for (i = 0; i < img->num_ref_idx_l0_active + 1; i++) + { + currSlice->reordering_of_pic_nums_idc_l0[i] = 3; + currSlice->abs_diff_pic_num_minus1_l0[i] = 0; + currSlice->long_term_pic_idx_l0[i] = 0; + } - num_ref = img->num_ref_idx_l0_active; - - poc_ref_pic_reorder(listX[LIST_0], num_ref, - currSlice->reordering_of_pic_nums_idc_l0, - currSlice->abs_diff_pic_num_minus1_l0, - currSlice->long_term_pic_idx_l0, LIST_0); - // reference picture reordering - reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0], - img->num_ref_idx_l0_active - 1, - currSlice->reordering_of_pic_nums_idc_l0, - currSlice->abs_diff_pic_num_minus1_l0, - currSlice->long_term_pic_idx_l0); + num_ref = img->num_ref_idx_l0_active; + if ( img->structure == FRAME ) + poc_ref_pic_reorder_frame(listX[LIST_0], num_ref, + currSlice->reordering_of_pic_nums_idc_l0, + currSlice->abs_diff_pic_num_minus1_l0, + currSlice->long_term_pic_idx_l0, LIST_0); + else + { + poc_ref_pic_reorder_field(listX[LIST_0], num_ref, + currSlice->reordering_of_pic_nums_idc_l0, + currSlice->abs_diff_pic_num_minus1_l0, + currSlice->long_term_pic_idx_l0, LIST_0); + } + //reference picture reordering + reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0], + img->num_ref_idx_l0_active - 1, + currSlice->reordering_of_pic_nums_idc_l0, + currSlice->abs_diff_pic_num_minus1_l0, + currSlice->long_term_pic_idx_l0); + } } //if (img->MbaffFrameFlag) @@ -769,10 +801,10 @@ void init_slice (int start_mb_addr) if (img->type==P_SLICE || img->type==SP_SLICE) { int wp_type = (params->GenerateMultiplePPS && params->RDPictureDecision) && (enc_picture != enc_frame_picture[1]); - EstimateWPPSlice (wp_type); + EstimateWPPSlice (img, params, wp_type); } else - EstimateWPBSlice (); + EstimateWPBSlice (img, params); } set_ref_pic_num(); @@ -790,7 +822,7 @@ void init_slice (int start_mb_addr) } if (img->type != I_SLICE && params->SearchMode == EPZS) - EPZSSliceInit(EPZSCo_located, listX); + EPZSSliceInit(params, img, EPZSCo_located, listX); if (params->symbol_mode == CAVLC) { @@ -802,19 +834,20 @@ void init_slice (int start_mb_addr) switch (listXsize[i]) { case 0: - writeRefFrame[i] = NULL; + writeRefFrame[i] = NULL; break; case 1: - writeRefFrame[i] = writeSE_Dummy; + writeRefFrame[i] = writeSE_Dummy; break; case 2: - writeRefFrame[i] = writeSE_invFlag; + writeRefFrame[i] = writeSE_invFlag; break; default: - writeRefFrame[i] = writeSE_UVLC; + writeRefFrame[i] = writeSE_UVLC; break; } } + writeMVD = writeSE_SVLC; writeCBP = writeCBP_VLC; writeDquant = writeSE_SVLC; @@ -832,12 +865,12 @@ void init_slice (int start_mb_addr) switch (listXsize[i]) { case 0: - writeRefFrame[i] = NULL; + writeRefFrame[i] = NULL; case 1: - writeRefFrame[i] = writeSE_Dummy; + writeRefFrame[i] = writeSE_Dummy; break; default: - writeRefFrame[i] = writeRefFrame_CABAC; + writeRefFrame[i] = writeRefFrame_CABAC; } } writeMVD = writeMVD_CABAC; @@ -1001,7 +1034,7 @@ static void free_slice(Slice *slice) } } -void set_ref_pic_num() +static void set_ref_pic_num() { int i,j; StorablePicture *this_ref; @@ -1020,7 +1053,7 @@ void set_ref_pic_num() for (i=0;i<listXsize[LIST_1];i++) { this_ref = listX[LIST_1][i]; - enc_picture->ref_pic_num [LIST_1][i] = this_ref->poc *2 + ((this_ref->structure==BOTTOM_FIELD)?1:0); + enc_picture->ref_pic_num [LIST_1][i] = this_ref->poc * 2 + ((this_ref->structure==BOTTOM_FIELD)?1:0); enc_picture->frm_ref_pic_num [LIST_1][i] = this_ref->frame_poc * 2; enc_picture->top_ref_pic_num [LIST_1][i] = this_ref->top_poc * 2; enc_picture->bottom_ref_pic_num [LIST_1][i] = this_ref->bottom_poc * 2 + 1; @@ -1046,9 +1079,9 @@ void set_ref_pic_num() * decide reference picture reordering, Frame only ************************************************************************ */ -void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no) +void poc_ref_pic_reorder_frame(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no) { - unsigned i,j,k; + unsigned int i,j,k; int currPicNum, picNumLXPred; @@ -1062,17 +1095,10 @@ void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, int abs_poc_dist; int maxPicNum; + unsigned int numRefs; - if (img->structure==FRAME) - { - maxPicNum = max_frame_num; - currPicNum = img->frame_num; - } - else - { - maxPicNum = 2 * max_frame_num; - currPicNum = 2 * img->frame_num + 1; - } + maxPicNum = max_frame_num; + currPicNum = img->frame_num; picNumLXPred = currPicNum; @@ -1086,8 +1112,10 @@ void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, // to a potential reordering list. For each one of these // references compute the poc distance compared to current // frame. + numRefs = dpb.ref_frames_in_buffer; for (i=0; i<dpb.ref_frames_in_buffer; i++) { + poc_diff[i] = 0xFFFF; re_order[i] = dpb.fs_ref[i]->frame->pic_num; if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term)) @@ -1106,9 +1134,9 @@ void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, } // now sort these references based on poc (temporal) distance - for (i=0; i< dpb.ref_frames_in_buffer-1; i++) + for (i = 0; i< numRefs - 1; i++) { - for (j=i+1; j< dpb.ref_frames_in_buffer; j++) + for (j = i + 1; j < numRefs; j++) { if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i])) { @@ -1125,6 +1153,16 @@ void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, } } } + // populate list with selections from the pre-analysis stage + if ( params->WPMCPrecision + && pWPX->curr_wp_rd_pass->algorithm != WP_REGULAR + && pWPX->num_wp_ref_list[list_no] ) + { + for (i=0; i<num_ref_idx_lX_active; i++) + { + re_order[i] = pWPX->wp_ref_list[list_no][i].PicNum; + } + } // Check versus default list to see if any // change has happened @@ -1203,118 +1241,311 @@ void poc_ref_pic_reorder(StorablePicture **list, unsigned num_ref_idx_lX_active, } } +/*! +************************************************************************ +* \brief +* decide reference picture reordering, Field only +************************************************************************ +*/ +void poc_ref_pic_reorder_field(StorablePicture **list, unsigned num_ref_idx_lX_active, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx, int list_no) +{ + unsigned int i,j,k; + int currPicNum, picNumLXPred; -void SetLagrangianMultipliers() -{ - int qp, j, k; - double qp_temp; - double lambda_scale = 1.0 - dClip3(0.0,0.5,0.05 * (double) params->jumpd);; + int default_order[32]; + int re_order[32]; + int tmp_reorder[32]; + int list_sign[32]; + int poc_diff[32]; + int fld_type[32]; + + int reorder_stop, no_reorder; + int tmp_value, diff; - if (params->rdopt) // RDOPT on computation of Lagrangian multipliers + int abs_poc_dist; + int maxPicNum; + unsigned int numRefs; + + int field_used[2] = {1, 2}; + int fld, idx, num_flds; + + unsigned int top_idx = 0; + unsigned int bot_idx = 0; + unsigned int list_size = 0; + + StorablePicture *pField[2]; // 0: TOP_FIELD, 1: BOTTOM_FIELD + FrameStore *pFrameStore; + + maxPicNum = 2 * max_frame_num; + currPicNum = 2 * img->frame_num + 1; + + picNumLXPred = currPicNum; + + // First assign default list order. + for (i=0; i<num_ref_idx_lX_active; i++) { - for (j = 0; j < 5; j++) + default_order[i] = list[i]->pic_num; + } + + // Now access all references in buffer and assign them + // to a potential reordering list. For each one of these + // references compute the poc distance compared to current + // frame. + // look for eligible fields + idx = 0; + + for (i=0; i<dpb.ref_frames_in_buffer; i++) + { + pFrameStore = dpb.fs_ref[i]; + pField[0] = pFrameStore->top_field; + pField[1] = pFrameStore->bottom_field; + num_flds = (img->structure == BOTTOM_FIELD && (enc_picture->poc == (pField[0]->poc + 1) ) ) ? 1 : 2; + + poc_diff[2*i ] = 0xFFFF; + poc_diff[2*i + 1] = 0xFFFF; + + for ( fld = 0; fld < num_flds; fld++ ) { - for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++) + if ( (pFrameStore->is_used & field_used[fld]) && pField[fld]->used_for_reference && !(pField[fld]->is_long_term) ) { - qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP; + abs_poc_dist = iabs(pField[fld]->poc - enc_picture->poc) ; + poc_diff[idx] = abs_poc_dist; + re_order[idx] = pField[fld]->pic_num; + fld_type[idx] = fld + 1; - if (params->UseExplicitLambdaParams == 1) // consideration of explicit lambda weights. + if (list_no == LIST_0) { - img->lambda_md[j][qp] = params->LambdaWeight[j] * pow (2, qp_temp/3.0); - // Scale lambda due to hadamard qpel only consideration - img->lambda_md[j][qp] = ( (params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp]; - - for (k = F_PEL; k <= Q_PEL; k++) - { - img->lambda_me[j][qp][k] = params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]); - img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]); - } + list_sign[idx] = (enc_picture->poc < pField[fld]->poc) ? +1 : -1; + } + else + { + list_sign[idx] = (enc_picture->poc > pField[fld]->poc) ? +1 : -1; + } + idx++; + } + } + } + numRefs = idx; - if (j == B_SLICE) - { - img->lambda_md[5][qp] = params->LambdaWeight[5] * pow (2, qp_temp/3.0); - img->lambda_md[5][qp] = ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[5][qp]; + // now sort these references based on poc (temporal) distance + for (i=0; i < numRefs-1; i++) + { + for (j = (i + 1); j < numRefs; j++) + { + if (poc_diff[i] > poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i])) + { + // poc_diff + tmp_value = poc_diff[i]; + poc_diff[i] = poc_diff[j]; + poc_diff[j] = tmp_value; + // re_order (PicNum) + tmp_value = re_order[i]; + re_order[i] = re_order[j]; + re_order[j] = tmp_value; + // list_sign + tmp_value = list_sign[i]; + list_sign[i] = list_sign[j]; + list_sign[j] = tmp_value; + // fld_type + tmp_value = fld_type[i]; + fld_type[i] = fld_type[j]; + fld_type[j] = tmp_value ; + } + } + } - for (k = F_PEL; k <= Q_PEL; k++) - { - img->lambda_me[5][qp][k] = params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[5][qp] : sqrt(img->lambda_md[5][qp]); - img->lambda_mf[5][qp][k] = LAMBDA_FACTOR (img->lambda_me[5][qp][k]); - } - } + if (img->structure == TOP_FIELD) + { + while ((top_idx < numRefs)||(bot_idx < numRefs)) + { + for ( ; top_idx < numRefs; top_idx++) + { + if ( fld_type[top_idx] == TOP_FIELD ) + { + tmp_reorder[list_size] = re_order[top_idx]; + list_size++; + top_idx++; + break; } - else if (params->UseExplicitLambdaParams == 2) // consideration of fixed lambda values. + } + for ( ; bot_idx < numRefs; bot_idx++) + { + if ( fld_type[bot_idx] == BOTTOM_FIELD ) + { + tmp_reorder[list_size] = re_order[bot_idx]; + list_size++; + bot_idx++; + break; + } + } + } + } + if (img->structure == BOTTOM_FIELD) + { + while ((top_idx < numRefs)||(bot_idx < numRefs)) + { + for ( ; bot_idx < numRefs; bot_idx++) + { + if ( fld_type[bot_idx] == BOTTOM_FIELD ) { - img->lambda_md[j][qp] = params->FixedLambda[j]; - // Scale lambda due to hadamard qpel only consideration - img->lambda_md[j][qp] = ( (params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp]; + tmp_reorder[list_size] = re_order[bot_idx]; + list_size++; + bot_idx++; + break; + } + } + for ( ; top_idx < numRefs; top_idx++) + { + if ( fld_type[top_idx] == TOP_FIELD ) + { + tmp_reorder[list_size] = re_order[top_idx]; + list_size++; + top_idx++; + break; + } + } + } + } - for (k = F_PEL; k <= Q_PEL; k++) - { - img->lambda_me[j][qp][k] = params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]); - img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]); - } + // copy to final matrix + list_size = imin( list_size, 32 ); + for ( i = 0; i < list_size; i++ ) + { + re_order[i] = tmp_reorder[i]; + } - if (j == B_SLICE) - { - img->lambda_md[5][qp] = params->FixedLambda[5]; - img->lambda_md[5][qp] = ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[5][qp]; + // Check versus default list to see if any + // change has happened + no_reorder = 1; + for (i=0; i<num_ref_idx_lX_active; i++) + { + if (default_order[i] != re_order[i]) + { + no_reorder = 0; + } + } - for (k = F_PEL; k <= Q_PEL; k++) - { - img->lambda_me[5][qp][k] = params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[5][qp] : sqrt(img->lambda_md[5][qp]); - img->lambda_mf[5][qp][k] = LAMBDA_FACTOR (img->lambda_me[5][qp][k]); - } - } + // If different, then signal reordering + if (no_reorder == 0) + { + for (i=0; i<num_ref_idx_lX_active; i++) + { + diff = re_order[i] - picNumLXPred; + if (diff <= 0) + { + reordering_of_pic_nums_idc[i] = 0; + abs_diff_pic_num_minus1[i] = iabs(diff)-1; + if (abs_diff_pic_num_minus1[i] < 0) + abs_diff_pic_num_minus1[i] = maxPicNum -1; + } + else + { + reordering_of_pic_nums_idc[i] = 1; + abs_diff_pic_num_minus1[i] = iabs(diff)-1; + } + picNumLXPred = re_order[i]; + + tmp_reorder[i] = re_order[i]; + + k = i; + for (j = i; j < num_ref_idx_lX_active; j++) + { + if (default_order[j] != re_order[i]) + { + ++k; + tmp_reorder[k] = default_order[j]; } - else + } + reorder_stop = 1; + for(j=i+1; j<num_ref_idx_lX_active; j++) + { + if (tmp_reorder[j] != re_order[j]) { - if (params->successive_Bframe>0) - img->lambda_md[j][qp] = 0.68 * pow (2, qp_temp/3.0) - * (j == B_SLICE ? dClip3(2.00,4.00,(qp_temp / 6.0)) : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0); - else - img->lambda_md[j][qp] = 0.85 * pow (2, qp_temp/3.0) - * ( (j == B_SLICE) ? 4.0 : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0); - // Scale lambda due to hadamard qpel only consideration - img->lambda_md[j][qp] = ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp]; - img->lambda_md[j][qp] = (j == B_SLICE && params->BRefPictures == 2 && img->b_frame_to_code == 0 ? 0.50 : 1.00) * img->lambda_md[j][qp]; - - if (j == B_SLICE) - { - img->lambda_md[5][qp] = img->lambda_md[j][qp]; + reorder_stop = 0; + break; + } + } - if (params->HierarchicalCoding == 2) - img->lambda_md[5][qp] *= (1.0 - dmin(0.4,0.2 * (double) gop_structure[img->b_frame_to_code-1].hierarchy_layer)) ; - else - img->lambda_md[5][qp] *= 0.80; + if (reorder_stop==1) + { + ++i; + break; + } - img->lambda_md[5][qp] *= lambda_scale; + memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int)); + } + reordering_of_pic_nums_idc[i] = 3; - for (k = F_PEL; k <= Q_PEL; k++) - { - img->lambda_me[5][qp][k] = params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[5][qp] : sqrt(img->lambda_md[5][qp]); - img->lambda_mf[5][qp][k] = LAMBDA_FACTOR (img->lambda_me[5][qp][k]); - } - } - else - img->lambda_md[j][qp] *= lambda_scale; + memcpy ( default_order, tmp_reorder, num_ref_idx_lX_active * sizeof(int)); - for (k = F_PEL; k <= Q_PEL; k++) - { - img->lambda_me[j][qp][k] = params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]); - img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]); - } + if (list_no==0) + { + img->currentSlice->ref_pic_list_reordering_flag_l0 = 1; + } + else + { + img->currentSlice->ref_pic_list_reordering_flag_l1 = 1; + } + } +} - if (params->CtxAdptLagrangeMult == 1) +void UpdateMELambda(ImageParameters *img) +{ + int j, k, qp; + if (params->UpdateLambdaChromaME) + { + for (j = 0; j < 6; j++) + { + for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++) + { + for (k = 0; k < 3; k++) + { + if ((params->MEErrorMetric[k] == ERROR_SAD) && (params->ChromaMEEnable)) { - int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp - 4) : imax(0, qp - 6); - img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0); + switch(params->yuv_format) + { + case YUV420: + img->lambda_mf[j][qp][k] = (3 * img->lambda_mf[j][qp][k] + 1) >> 1; + img->lambda_me[j][qp][k] *= 1.5; + break; + case YUV422: + img->lambda_mf[j][qp][k] *= 2; + img->lambda_me[j][qp][k] *= 2.0; + break; + case YUV444: + img->lambda_mf[j][qp][k] *= 3; + img->lambda_me[j][qp][k] *= 3.0; + break; + default: + break; + } } } } } } - else // RDOPT off computation of Lagrangian multipliers +} + +void SetLambda(int j, int qp, double lambda_scale) +{ + int k; + img->lambda_md[j][qp] *= lambda_scale; + + for (k = F_PEL; k <= Q_PEL; k++) + { + img->lambda_me[j][qp][k] = (params->MEErrorMetric[k] == ERROR_SSE) ? img->lambda_md[j][qp] : sqrt(img->lambda_md[j][qp]); + img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]); + } +} + +void SetLagrangianMultipliersOn() +{ + int qp, j; + double qp_temp; + double lambda_scale = 1.0 - dClip3(0.0,0.5,0.05 * (double) params->jumpd);; + + if (params->UseExplicitLambdaParams == 1) // consideration of explicit lambda weights. { for (j = 0; j < 6; j++) { @@ -1322,32 +1553,110 @@ void SetLagrangianMultipliers() { qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP; - if (params->UseExplicitLambdaParams == 1) // consideration of explicit lambda weights. - { - img->lambda_md[j][qp] = sqrt(params->LambdaWeight[j] * pow (2, qp_temp/3.0)); - } - else if (params->UseExplicitLambdaParams == 2) // consideration of explicit lambda - { - img->lambda_md[j][qp] = sqrt(params->FixedLambda[j]); - } + img->lambda_md[j][qp] = params->LambdaWeight[j] * pow (2, qp_temp/3.0); + SetLambda(j, qp, ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95)); + } + } + } + else if (params->UseExplicitLambdaParams == 2) // consideration of fixed lambda values. + { + for (j = 0; j < 6; j++) + { + for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++) + { + qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP; + + img->lambda_md[j][qp] = params->FixedLambda[j]; + SetLambda(j, qp, ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95)); + } + } + } + else + { + for (j = 0; j < 5; j++) + { + for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++) + { + qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP; + + if (params->successive_Bframe > 0) + img->lambda_md[j][qp] = 0.68 * pow (2, qp_temp/3.0) + * (j == B_SLICE && img->b_frame_to_code != 0 ? dClip3(2.00, 4.00, (qp_temp / 6.0)) : (j == SP_SLICE) ? dClip3(1.4,3.0,(qp_temp / 12.0)) : 1.0); else - { - img->lambda_md[j][qp] = QP2QUANT[imax(0,qp - SHIFT_QP)]; - } - for (k = F_PEL; k <= Q_PEL; k++) + img->lambda_md[j][qp] = 0.85 * pow (2, qp_temp/3.0) * ((j == SP_SLICE) ? dClip3(1.4, 3.0,(qp_temp / 12.0)) : 1.0); + + // Scale lambda due to hadamard qpel only consideration + img->lambda_md[j][qp] = ((params->MEErrorMetric[H_PEL] == ERROR_SATD && params->MEErrorMetric[Q_PEL] == ERROR_SATD) ? 1.00 : 0.95) * img->lambda_md[j][qp]; + //img->lambda_md[j][qp] = (j == B_SLICE && params->BRefPictures == 2 && img->b_frame_to_code == 0 ? 0.50 : 1.00) * img->lambda_md[j][qp]; + + if (j == B_SLICE) { - img->lambda_me[j][qp][k] = img->lambda_md[j][qp]; - img->lambda_me[j][qp][k] *= params->MEErrorMetric[k] == ERROR_SSE ? img->lambda_me[j][qp][k] : 1; - img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]); + img->lambda_md[5][qp] = img->lambda_md[j][qp]; + + if (img->b_frame_to_code != 0) + { + if (params->HierarchicalCoding == 2) + img->lambda_md[5][qp] *= (1.0 - dmin(0.4, 0.2 * (double) gop_structure[img->b_frame_to_code-1].hierarchy_layer)); + else + img->lambda_md[5][qp] *= 0.80; + + } + SetLambda(5, qp, lambda_scale); } + else + img->lambda_md[j][qp] *= lambda_scale; + + SetLambda(j, qp, 1.0); if (params->CtxAdptLagrangeMult == 1) { - int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp-4) : imax(0, qp-6); + int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp - 4) : imax(0, qp - 6); img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0); } } } } + + UpdateMELambda(img); } + +void SetLagrangianMultipliersOff() +{ + int qp, j, k; + double qp_temp; + + for (j = 0; j < 6; j++) + { + for (qp = -img->bitdepth_luma_qp_scale; qp < 52; qp++) + { + qp_temp = (double)qp + img->bitdepth_luma_qp_scale - SHIFT_QP; + + switch (params->UseExplicitLambdaParams) + { + case 1: // explicit lambda weights + img->lambda_md[j][qp] = sqrt(params->LambdaWeight[j] * pow (2, qp_temp/3.0)); + break; + case 2: // explicit lambda + img->lambda_md[j][qp] = sqrt(params->FixedLambda[j]); + break; + default: + img->lambda_md[j][qp] = QP2QUANT[imax(0,qp - SHIFT_QP)]; + break; + } + + for (k = F_PEL; k <= Q_PEL; k++) + { + img->lambda_me[j][qp][k] = (params->MEErrorMetric[k] == ERROR_SSE) ? (img->lambda_md[j][qp] * img->lambda_md[j][qp]) : img->lambda_md[j][qp]; + img->lambda_mf[j][qp][k] = LAMBDA_FACTOR (img->lambda_me[j][qp][k]); + } + + if (params->CtxAdptLagrangeMult == 1) + { + int lambda_qp = (qp >= 32 && !params->RCEnable) ? imax(0, qp-4) : imax(0, qp-6); + img->lambda_mf_factor[j][qp] = log (img->lambda_me[j][lambda_qp][Q_PEL] + 1.0) / log (2.0); + } + } + } + UpdateMELambda(img); +} diff --git a/lencod/src/transform8x8.c b/lencod/src/transform8x8.c index b9640fb..a463007 100644 --- a/lencod/src/transform8x8.c +++ b/lencod/src/transform8x8.c @@ -39,137 +39,6 @@ int cofAC8x8_chroma[2][4][2][18]; static int diff64[64]; -const int quant_coef8[6][8][8] = -{ - { - {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, - {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, - {13107, 12222, 16777, 12222, 13107, 12222, 16777, 12222}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428}, - {16777, 15481, 20972, 15481, 16777, 15481, 20972, 15481}, - {12222, 11428, 15481, 11428, 12222, 11428, 15481, 11428} - }, - { - {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, - {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, - {11916, 11058, 14980, 11058, 11916, 11058, 14980, 11058}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826}, - {14980, 14290, 19174, 14290, 14980, 14290, 19174, 14290}, - {11058, 10826, 14290, 10826, 11058, 10826, 14290, 10826} - }, - { - {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, - {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, - {10082, 9675, 12710, 9675, 10082, 9675, 12710, 9675}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943}, - {12710, 11985, 15978, 11985, 12710, 11985, 15978, 11985}, - {9675, 8943, 11985, 8943, 9675, 8943, 11985, 8943} - }, - { - { 9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931}, - { 8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, - {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259}, - { 8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, - { 9362, 8931, 11984, 8931, 9362, 8931, 11984, 8931}, - { 8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228}, - {11984, 11259, 14913, 11259, 11984, 11259, 14913, 11259}, - { 8931, 8228, 11259, 8228, 8931, 8228, 11259, 8228} - }, - { - {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, - {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, - {8192, 7740, 10486, 7740, 8192, 7740, 10486, 7740}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346}, - {10486, 9777, 13159, 9777, 10486, 9777, 13159, 9777}, - {7740, 7346, 9777, 7346, 7740, 7346, 9777, 7346} - }, - { - {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, - {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, - {7282, 6830, 9118, 6830, 7282, 6830, 9118, 6830}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428}, - {9118, 8640, 11570, 8640, 9118, 8640, 11570, 8640}, - {6830, 6428, 8640, 6428, 6830, 6428, 8640, 6428} - } -}; - - -const int dequant_coef8[6][8][8] = -{ - { - {20, 19, 25, 19, 20, 19, 25, 19}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {25, 24, 32, 24, 25, 24, 32, 24}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {20, 19, 25, 19, 20, 19, 25, 19}, - {19, 18, 24, 18, 19, 18, 24, 18}, - {25, 24, 32, 24, 25, 24, 32, 24}, - {19, 18, 24, 18, 19, 18, 24, 18} - }, - { - {22, 21, 28, 21, 22, 21, 28, 21}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {22, 21, 28, 21, 22, 21, 28, 21}, - {21, 19, 26, 19, 21, 19, 26, 19}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {21, 19, 26, 19, 21, 19, 26, 19} - }, - { - {26, 24, 33, 24, 26, 24, 33, 24}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {33, 31, 42, 31, 33, 31, 42, 31}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {26, 24, 33, 24, 26, 24, 33, 24}, - {24, 23, 31, 23, 24, 23, 31, 23}, - {33, 31, 42, 31, 33, 31, 42, 31}, - {24, 23, 31, 23, 24, 23, 31, 23} - }, - { - {28, 26, 35, 26, 28, 26, 35, 26}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {35, 33, 45, 33, 35, 33, 45, 33}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {28, 26, 35, 26, 28, 26, 35, 26}, - {26, 25, 33, 25, 26, 25, 33, 25}, - {35, 33, 45, 33, 35, 33, 45, 33}, - {26, 25, 33, 25, 26, 25, 33, 25} - }, - { - {32, 30, 40, 30, 32, 30, 40, 30}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {40, 38, 51, 38, 40, 38, 51, 38}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {32, 30, 40, 30, 32, 30, 40, 30}, - {30, 28, 38, 28, 30, 28, 38, 28}, - {40, 38, 51, 38, 40, 38, 51, 38}, - {30, 28, 38, 28, 30, 28, 38, 28} - }, - { - {36, 34, 46, 34, 36, 34, 46, 34}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {46, 43, 58, 43, 46, 43, 58, 43}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {36, 34, 46, 34, 36, 34, 46, 34}, - {34, 32, 43, 32, 34, 32, 43, 32}, - {46, 43, 58, 43, 46, 43, 58, 43}, - {34, 32, 43, 32, 34, 32, 43, 32} - } - -}; - - //! single scan pattern //static const byte SNGL_SCAN8x8[64][2] = { const byte SNGL_SCAN8x8[64][2] = { @@ -226,30 +95,37 @@ static int **fadjust8x8 = NULL; ************************************************************************ */ //For residual DPCM -int Residual_DPCM_8x8(int ipmode, int m7[16][16], int block_y, int block_x) +int Residual_DPCM_8x8(int ipmode, int ores[16][16], int rres[16][16],int block_y, int block_x) { int i,j; int temp[8][8]; if(ipmode==VERT_PRED) - { + { + + for (j=0; j<8; j++) + temp[0][j] = ores[block_y][block_x+j]; + for (i=1; i<8; i++) for (j=0; j<8; j++) - temp[i][j] = m7[block_y+i][block_x+j] - m7[block_y+i-1][block_x+j]; + temp[i][j] = ores[block_y+i][block_x+j] - ores[block_y+i-1][block_x+j]; - for (i=1; i<8; i++) - for (j=0; j<8; j++) - m7[block_y+i][block_x+j] = temp[i][j]; + for (i = 0; i < 8; i++) + for (j = 0; j < 8; j++) + rres[block_y+i][block_x+j] = temp[i][j]; } else //HOR_PRED { for (i=0; i<8; i++) - for (j=1; j<8; j++) - temp[i][j] = m7[block_y+i][block_x+j] - m7[block_y+i][block_x+j-1]; + temp[i][0] = ores[block_y + i][block_x]; for (i=0; i<8; i++) for (j=1; j<8; j++) - m7[block_y+i][block_x+j] = temp[i][j]; + temp[i][j] = ores[block_y+i][block_x+j] - ores[block_y+i][block_x+j-1]; + + for (i=0; i<8; i++) + for (j=0; j<8; j++) + rres[block_y+i][block_x+j] = temp[i][j]; } return 0; } @@ -389,8 +265,8 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_Low (Macroblock *currMB, int b8, dou imgpel *img_org, *img_prd; int *residual; int left_available, up_available, all_available; - int (*curr_res)[16] = img->m7[0]; - imgpel (*curr_mpr)[16] = img->mpr[0]; + int (*mb_ores)[16] = img->mb_ores[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; int *mb_size = img->mb_size[IS_LUMA]; char upMode; @@ -478,8 +354,8 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_Low (Macroblock *currMB, int b8, dou { for (i=0; i<8; i++) { - img->mpr[k][block_y+j][block_x+i] = img->mpr_8x8[k][best_ipmode][j][i]; - img->m7[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][best_ipmode][j][i]; + img->mb_pred[k][block_y+j][block_x+i] = img->mpr_8x8[k][best_ipmode][j][i]; + img->mb_ores[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][best_ipmode][j][i]; } } ipmode_DPCM=best_ipmode; @@ -500,10 +376,10 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_Low (Macroblock *currMB, int b8, dou // get prediction and prediction error for (j = block_y; j < block_y + 8; j++) { - memcpy(&curr_mpr[j][block_x],img->mpr_8x8[0][best_ipmode][j - block_y], 8 * sizeof(imgpel)); + memcpy(&mb_pred[j][block_x],img->mpr_8x8[0][best_ipmode][j - block_y], 8 * sizeof(imgpel)); img_org = &pCurImg[img->opix_y+j][pic_opix_x]; - img_prd = &curr_mpr[j][block_x]; - residual = &curr_res[j][block_x]; + img_prd = &mb_pred[j][block_x]; + residual = &mb_ores[j][block_x]; for (i=0; i<8; i++) { *residual++ = *img_org++ - *img_prd++; @@ -545,8 +421,8 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_High (Macroblock *currMB, int b8, do extern int ****cofAC8x8CbCr[2]; int uv, c_nzCbCr[3]; int left_available, up_available, all_available; - int (*curr_res)[16] = img->m7[0]; - imgpel (*curr_mpr)[16] = img->mpr[0]; + int (*mb_ores)[16] = img->mb_ores[0]; + imgpel (*mb_pred)[16] = img->mb_pred[0]; int *mb_size = img->mb_size[IS_LUMA]; char upMode; @@ -603,10 +479,10 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_High (Macroblock *currMB, int b8, do // get prediction and prediction error for (j=block_y; j < block_y + 8; j++) { - memcpy(&curr_mpr[j][block_x],img->mpr_8x8[0][ipmode][j - block_y], 8 * sizeof(imgpel)); + memcpy(&mb_pred[j][block_x],img->mpr_8x8[0][ipmode][j - block_y], 8 * sizeof(imgpel)); img_org = &pCurImg[img->opix_y+j][pic_opix_x]; - img_prd = &curr_mpr[j][block_x]; - residual = &curr_res[j][block_x]; + img_prd = &mb_pred[j][block_x]; + residual = &mb_ores[j][block_x]; for (i=0; i<8; i++) { *residual++ = *img_org++ - *img_prd++; @@ -618,10 +494,11 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_High (Macroblock *currMB, int b8, do { for (j=0; j<8; j++) { - memcpy(&img->mpr[k][block_y+j][block_x],img->mpr_8x8[k][ipmode][j], 8 * sizeof(imgpel)); + memcpy(&img->mb_pred[k][block_y+j][block_x],img->mpr_8x8[k][ipmode][j], 8 * sizeof(imgpel)); for (i=0; i<8; i++) { - img->m7[k][block_y+j][block_x+i] = (int) (pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - img->mpr_8x8[k][ipmode][j][i]); + img->mb_ores[k][block_y+j][block_x+i] = (int) (pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - img->mpr_8x8[k][ipmode][j][i]); + img->mb_ores[k][block_y+j][block_x+i] = img->mb_ores[k][block_y+j][block_x+i]; // line is temporary until we fix code to use img->mb_ores } } } @@ -703,8 +580,8 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_High (Macroblock *currMB, int b8, do { for (i=0; i<8; i++) { - img->mpr[k][block_y+j][block_x+i] = img->mpr_8x8[k][best_ipmode][j][i]; - img->m7[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][best_ipmode][j][i]; + img->mb_pred[k][block_y+j][block_x+i] = img->mpr_8x8[k][best_ipmode][j][i]; + img->mb_ores[k][block_y+j][block_x+i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][best_ipmode][j][i]; } } ipmode_DPCM = best_ipmode; @@ -744,7 +621,7 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_High (Macroblock *currMB, int b8, do for (y=0; y<8; y++) { memcpy(&enc_picture->imgY[pic_pix_y + y][pic_pix_x], rec8x8[0][y], 8 * sizeof(imgpel)); - memcpy(&curr_mpr[block_y + y][block_x], img->mpr_8x8[0][best_ipmode][y], 8 * sizeof(imgpel)); + memcpy(&mb_pred[block_y + y][block_x], img->mpr_8x8[0][best_ipmode][y], 8 * sizeof(imgpel)); } if (img->P444_joined) { @@ -757,8 +634,8 @@ int Mode_Decision_for_new_8x8IntraBlocks_JM_High (Macroblock *currMB, int b8, do { memcpy(&enc_picture->imgUV[0][pic_pix_y+y][pic_pix_x], rec8x8[1][y], 8 * sizeof(imgpel)); memcpy(&enc_picture->imgUV[1][pic_pix_y+y][pic_pix_x], rec8x8[2][y], 8 * sizeof(imgpel)); - memcpy(&img->mpr[1][block_y+y][block_x], img->mpr_8x8[1][best_ipmode][y], 8 * sizeof(imgpel)); - memcpy(&img->mpr[2][block_y+y][block_x], img->mpr_8x8[2][best_ipmode][y], 8 * sizeof(imgpel)); + memcpy(&img->mb_pred[1][block_y+y][block_x], img->mpr_8x8[1][best_ipmode][y], 8 * sizeof(imgpel)); + memcpy(&img->mb_pred[2][block_y+y][block_x], img->mpr_8x8[2][best_ipmode][y], 8 * sizeof(imgpel)); } } @@ -1542,7 +1419,7 @@ double RDCost_for_8x8IntraBlocks(Macroblock *currMB, int *nonzero, int b8, int i if(img->P444_joined) { ColorPlane k; - ipmode_DPCM = NO_INTRA_PMODE; //For residual DPCM + for (k = PLANE_U; k <= PLANE_V; k++) { select_plane(k); @@ -1550,13 +1427,14 @@ double RDCost_for_8x8IntraBlocks(Macroblock *currMB, int *nonzero, int b8, int i { for (i=0; i<8; i++) { - img->mpr[k][block_y+j][block_x+i] = img->mpr_8x8[k][ipmode][j][i]; - img->m7[k][j][i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][ipmode][j][i]; + img->mb_pred[k][block_y+j][block_x+i] = img->mpr_8x8[k][ipmode][j][i]; + img->mb_ores[k][j][i] = pImgOrg[k][img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr_8x8[k][ipmode][j][i]; } }*/ c_nzCbCr[k ]= pDCT_8x8(currMB, k, b8, &dummy,1); distortion += compute_SSE(&pImgOrg[k][pic_opix_y], &enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x, 8, 8); } + ipmode_DPCM = NO_INTRA_PMODE; select_plane(PLANE_Y); } else if( img->yuv_format==YUV444 && IS_INDEPENDENT(params) ) //For residual DPCM @@ -1646,8 +1524,9 @@ int dct_8x8(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intr int* ACLevel = img->cofAC[pl_off][0][0]; int* ACRun = img->cofAC[pl_off][0][1]; imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int max_imgpel_value = img->max_imgpel_value; int qp = currMB->qp_scaled[pl]; @@ -1662,25 +1541,25 @@ int dct_8x8(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intr fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL; // Forward 8x8 transform - forward8x8(curr_res, curr_res, block_y, block_x); + forward8x8(mb_ores, mb_rres, block_y, block_x); // Quantization process - nonzero = quant_8x8(&curr_res[block_y], block_y, block_x, qp, ACLevel, ACRun, fadjust8x8, + nonzero = quant_8x8(&mb_rres[block_y], block_y, block_x, qp, ACLevel, ACRun, fadjust8x8, levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST8x8[params->disthres]); if (nonzero) { // Inverse 8x8 transform - inverse8x8(curr_res, curr_res, block_y, block_x); + inverse8x8(mb_rres, mb_rres, block_y, block_x); // generate final block - SampleReconstruct (img_enc, curr_mpr, curr_res, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8); + SampleReconstruct (img_enc, mb_pred, mb_rres, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8); } else // if (nonzero) => No transformed residual. Just use prediction. { for( j=block_y; j< block_y + BLOCK_SIZE_8x8; j++) { - memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(curr_mpr[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel)); + memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel)); } } @@ -1711,9 +1590,10 @@ int dct_8x8_cavlc(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, in int block_x = 8*(b8 & 0x01); int block_y = 8*(b8 >> 1); int pl_off = b8+ (pl<<2); - imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[MB_BLOCK_SIZE] = img->mpr[pl]; - int (*curr_res)[MB_BLOCK_SIZE] = img->m7[pl]; + imgpel **img_enc = enc_picture->p_curr_img; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int max_imgpel_value = img->max_imgpel_value; @@ -1729,25 +1609,25 @@ int dct_8x8_cavlc(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, in fadjust8x8 = img->AdaptiveRounding ? (pl ? &img->fadjust8x8Cr[pl-1][intra][block_y] : &img->fadjust8x8[intra][block_y]) :NULL; // Forward 8x8 transform - forward8x8(curr_res, curr_res, block_y, block_x); + forward8x8(mb_ores, mb_rres, block_y, block_x); // Quantization process - nonzero = quant_8x8cavlc_around(&curr_res[block_y], block_y, block_x, qp, img->cofAC[pl_off], fadjust8x8, + nonzero = quant_8x8cavlc(&mb_rres[block_y], block_y, block_x, qp, img->cofAC[pl_off], fadjust8x8, levelscale, invlevelscale, leveloffset, coeff_cost, pos_scan, COEFF_COST8x8[params->disthres]); if (nonzero) { // Inverse 8x8 transform - inverse8x8(curr_res, curr_res, block_y, block_x); + inverse8x8(mb_rres, mb_rres, block_y, block_x); // generate final block - SampleReconstruct (img_enc, curr_mpr, curr_res, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8); + SampleReconstruct (img_enc, mb_pred, mb_rres, block_y, block_x, img->pix_y, img->pix_x + block_x, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8); } else // if (nonzero) => No transformed residual. Just use prediction. { for( j=block_y; j< block_y + BLOCK_SIZE_8x8; j++) { - memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(curr_mpr[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel)); + memcpy(&(img_enc[img->pix_y + j][img->pix_x + block_x]),&(mb_pred[j][block_x]), BLOCK_SIZE_8x8 * sizeof(imgpel)); } } @@ -1767,8 +1647,9 @@ int dct_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int i int* ACLevel = img->cofAC[pl_off][0][0]; int* ACRun = img->cofAC[pl_off][0][1]; imgpel **img_enc = enc_picture->p_curr_img; - imgpel (*curr_mpr)[16] = img->mpr[pl]; - int (*curr_res)[16] = img->m7[pl]; + imgpel (*mb_pred)[MB_BLOCK_SIZE] = img->mb_pred[pl]; + int (*mb_ores)[MB_BLOCK_SIZE] = img->mb_ores[pl]; + int (*mb_rres)[MB_BLOCK_SIZE] = img->mb_rres[pl]; int scan_poss[4] = { 0 }, runs[4] = { -1, -1, -1, -1 }; int MCcoeff = 0; @@ -1781,9 +1662,9 @@ int dct_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int i runs[0]=runs[1]=runs[2]=runs[3]=-1; scan_poss[0] = scan_poss[1] = scan_poss[2] = scan_poss[3] = 0; - if((ipmode_DPCM<2)) + if( (ipmode_DPCM < 2)&&(intra)) { - Residual_DPCM_8x8(ipmode_DPCM, curr_res, block_y, block_x); + Residual_DPCM_8x8(ipmode_DPCM, mb_ores, mb_rres, block_y, block_x); } for (coeff_ctr=0; coeff_ctr < 64; coeff_ctr++) @@ -1799,7 +1680,7 @@ int dct_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int i runs[MCcoeff]++; } - m7 = &curr_res[block_y + j][block_x + i]; + m7 = &mb_rres[block_y + j][block_x + i]; if (img->AdaptiveRounding) { @@ -1838,17 +1719,17 @@ int dct_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int i img->cofAC[pl_off][i][0][scan_poss[i]] = 0; } - if(ipmode_DPCM<2) //For residual DPCM + if( (ipmode_DPCM < 2) && (intra)) { - Inv_Residual_DPCM_8x8(curr_res, block_y, block_x); + Inv_Residual_DPCM_8x8(mb_rres, block_y, block_x); } for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++) { for( i=block_x; i< block_x + BLOCK_SIZE_8x8; i++) { - curr_res[j][i] += curr_mpr[j][i]; - img_enc[img->pix_y + j][img->pix_x + i]= (imgpel) curr_res[j][i]; + mb_rres[j][i] += mb_pred[j][i]; + img_enc[img->pix_y + j][img->pix_x + i]= (imgpel) mb_rres[j][i]; } } @@ -1857,6 +1738,14 @@ int dct_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int i } +/*static inline void compute_diff(int *diff, imgpel *cimg, imgpel *cmpr, int width) +{ + int i; + for (i = 0; i < width; i++) + { + *(diff++) = *(cimg++) - *(cmpr++); + } +}*/ /*! ************************************************************************************* * \brief @@ -1871,12 +1760,15 @@ void compute_comp_cost8x8(imgpel **cur_img, imgpel mpr8x8[16][16], int pic_opix_ for (j=0; j<8; j++) { + // compute_diff(diff, &cur_img[j][pic_opix_x], &mpr8x8[j][0], BLOCK_SIZE_8x8); + cimg = &cur_img[j][pic_opix_x]; cmpr = &mpr8x8[j][0]; for (i=0; i<8; i++) { *diff++ = *cimg++ - *cmpr++; } + } *cost += distortion8x8 (diff64); } diff --git a/lencod/src/vlc.c b/lencod/src/vlc.c index 110bf43..02aa4ca 100644 --- a/lencod/src/vlc.c +++ b/lencod/src/vlc.c @@ -19,6 +19,7 @@ #include <math.h> #include "global.h" +#include "enc_statistics.h" #include "vlc.h" #if TRACE @@ -750,7 +751,6 @@ int symbol2vlc(SyntaxElement *sym) */ int writeSyntaxElement_VLC(SyntaxElement *se, DataPartition *dp) { - se->inf = se->value1; se->len = se->value2; symbol2vlc(se); @@ -1331,15 +1331,15 @@ int writeSyntaxElement_Level_VLCN(SyntaxElement *se, int vlc, DataPartition *dp, } +#if TRACE +int bitcounter = 0; + /*! ************************************************************************ * \brief * Write out a trace string on the trace file ************************************************************************ */ -#if TRACE -int bitcounter = 0; - void trace2out(SyntaxElement *sym) { static @@ -1415,9 +1415,9 @@ void writeVlcByteAlign(Bitstream* currStream) { if (currStream->bits_to_go < 8) { // trailing bits to process - currStream->byte_buf = (currStream->byte_buf <<currStream->bits_to_go) | (0xff >> (8 - currStream->bits_to_go)); - stats->bit_use_stuffingBits[img->type]+=currStream->bits_to_go; - currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf; + currStream->byte_buf = (currStream->byte_buf << currStream->bits_to_go) | (0xff >> (8 - currStream->bits_to_go)); + stats->bit_use_stuffingBits[img->type] += currStream->bits_to_go; + currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf; currStream->bits_to_go = 8; } } diff --git a/lencod/src/weighted_prediction.c b/lencod/src/weighted_prediction.c index 6547911..99251bb 100644 --- a/lencod/src/weighted_prediction.c +++ b/lencod/src/weighted_prediction.c @@ -4,7 +4,7 @@ * \file weighted_prediction.c * * \brief -* Estimate weights for WP +* Estimate weights for WP using DC method * * \author * Main contributors (see contributors.h for copyright, address and affiliation details) @@ -26,12 +26,21 @@ */ void InitWP(InputParameters *params) { - //if (params->WPMethod == 0) + switch ( params->WPMethod ) { - EstimateWPPSlice = estimate_weighting_factor_P_slice; - EstimateWPBSlice = estimate_weighting_factor_B_slice; - TestWPPSlice = test_wp_P_slice; - TestWPBSlice = test_wp_B_slice; + default: + case 0: + EstimateWPPSlice = EstimateWPPSliceAlg0; + EstimateWPBSlice = EstimateWPBSliceAlg0; + TestWPPSlice = TestWPPSliceAlg0; + TestWPBSlice = TestWPBSliceAlg0; + break; + case 1: + EstimateWPPSlice = EstimateWPPSliceAlg1; + EstimateWPBSlice = EstimateWPBSliceAlg1; + TestWPPSlice = TestWPPSliceAlg1; + TestWPBSlice = TestWPBSliceAlg1; + break; } } @@ -45,6 +54,7 @@ double ComputeImgSum(imgpel **CurrentImage, int height, int width) { int i, j; double sum_value = 0.0; + for (i = 0; i < height; i++) { for (j = 0; j < width; j++) @@ -62,17 +72,15 @@ double ComputeImgSum(imgpel **CurrentImage, int height, int width) ************************************************************************ */ -void estimate_weighting_factor_P_slice(int select_offset) +void EstimateWPPSliceAlg0(ImageParameters *img, InputParameters *params, int select_offset) { - int i, j, n; - - int index; - int comp; double dc_org = 0.0; + double dc_org_UV[2] = {0.0}; double dc_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double dc_ref_UV[MAX_REFERENCE_PICTURES][2] = { {0.0}}; + int i, n, k; int default_weight[3]; - int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; int weight[2][MAX_REFERENCE_PICTURES][3]; int offset[2][MAX_REFERENCE_PICTURES][3]; @@ -80,71 +88,109 @@ void estimate_weighting_factor_P_slice(int select_offset) imgpel **tmpPtr; - luma_log_weight_denom = 5; + luma_log_weight_denom = 5; chroma_log_weight_denom = 5; - wp_luma_round = 1 << (luma_log_weight_denom - 1); - wp_chroma_round = 1 << (chroma_log_weight_denom - 1); - default_weight[0] = 1 << luma_log_weight_denom; - default_weight[1] = default_weight[2] = 1 << chroma_log_weight_denom; - /* set all values to defaults */ - for (i = 0; i < 2 + list_offset; i++) + wp_luma_round = 1 << (luma_log_weight_denom - 1); + wp_chroma_round = 1 << (chroma_log_weight_denom - 1); + default_weight[0] = 1 << luma_log_weight_denom; + default_weight[1] = default_weight[2] = 1 << chroma_log_weight_denom; + + dc_org = ComputeImgSum(pCurImg, img->height, img->width); + + if (params->ChromaWeightSupport == 1) { - for (j = 0; j < listXsize[i]; j++) + for (k = 0; k < 2; k++) { - for (n = 0; n < 3; n++) - { - weight[i][j][n] = default_weight[n]; - wp_weight[i][j][n] = default_weight[n]; - wp_offset[i][j][n] = 0; - offset[i][j][n] = 0; - } - } + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } } - dc_org = ComputeImgSum(pCurImg, img->height, img->width); - for (clist = 0; clist < 2 + list_offset; clist++) { for (n = 0; n < listXsize[clist]; n++) { - // Y - tmpPtr = listX[clist][n]->p_curr_img; - dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width); - - if (select_offset == 0) + if ( wpxDetermineWP( params, img, clist, n ) ) { - if (dc_ref[n] != 0.0) - weight[clist][n][0] = (int) (default_weight[0] * dc_org / dc_ref[n] + 0.5); + /* set all values to defaults */ + for (i = 0; i < 3; i++) + { + weight[clist][n][i] = default_weight[i]; + wp_weight[clist][n][i] = default_weight[i]; + wp_offset[clist][n][i] = 0; + offset[clist][n][i] = 0; + } + + // Y + tmpPtr = listX[clist][n]->p_curr_img; + dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width); + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + // UV + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + } + } + + if (select_offset == 0) + { + if (dc_ref[n] != 0.0) + weight[clist][n][0] = (int) (default_weight[0] * dc_org / dc_ref[n] + 0.5); + else + weight[clist][n][0] = default_weight[0]; // only used when reference picture is black + weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]); + if (params->ChromaWeightSupport == 1) + { + if (dc_ref_UV[n][0] != 0) + weight[clist][n][1] = (int) (default_weight[1] * dc_org_UV[0] / dc_ref_UV[n][0] + 0.5); + else + weight[clist][n][1] = default_weight[1]; // only used when reference picture is black + weight[clist][n][1] = iClip3(-128, 127, weight[clist][n][1]); + + if (dc_ref_UV[n][1] != 0) + weight[clist][n][2] = (int) (default_weight[2] * dc_org_UV[1] / dc_ref_UV[n][1] + 0.5); + else + weight[clist][n][2] = default_weight[2]; // only used when reference picture is black + weight[clist][n][2] = iClip3(-64, 128, weight[clist][n][2]); + } + } else - weight[clist][n][0] = default_weight[0]; // only used when reference picture is black - weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]); - } - else - { - offset[clist][n][0] = (int) ((dc_org - dc_ref[n])/(img->size)+0.5); - offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); - offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); - offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); - weight[clist][n][0] = default_weight[0]; - } + { + offset[clist][n][0] = (int) ((dc_org - dc_ref[n])/(img->size)+0.5); + offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); + offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); + offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); + weight[clist][n][0] = default_weight[0]; - weight[clist][n][1] = default_weight[1]; - weight[clist][n][2] = default_weight[2]; - offset[clist][n][1] = 0; - offset[clist][n][2] = 0; - } - } + if (params->ChromaWeightSupport == 1) + { + offset[clist][n][1] = (int) ((dc_org_UV[0] - dc_ref_UV[n][0])/(img->size_cr)+0.5); + offset[clist][n][1] = (offset[clist][n][1] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][1] = iClip3( -128, 127, offset[clist][n][1]); + offset[clist][n][1] = offset[clist][n][1]<<(img->bitdepth_chroma - 8); + + weight[clist][n][1] = default_weight[1]; + + offset[clist][n][2] = (int) ((dc_org_UV[1] - dc_ref_UV[n][1])/(img->size_cr)+0.5); + offset[clist][n][2] = (offset[clist][n][2] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][2] = iClip3( -128, 127, offset[clist][n][2]); + offset[clist][n][2] = offset[clist][n][2]<<(img->bitdepth_chroma - 8); + + weight[clist][n][2] = default_weight[2]; + } + } - for (clist=0; clist<2 + list_offset; clist++) - { - for (index = 0; index < listXsize[clist]; index++) - { - for (comp=0; comp < 3; comp ++) - { - wp_weight[clist][index][comp] = weight[clist][index][comp]; - wp_offset[clist][index][comp] = offset[clist][index][comp]; - // printf("index %d component %d weight %d offset %d\n",index,comp,weight[0][index][comp],offset[0][index][comp]); + for (i=0; i < 3; i ++) + { + wp_weight[clist][n][i] = weight[clist][n][i]; + wp_offset[clist][n][i] = offset[clist][n][i]; +#if DEBUG_WP + printf("index %d component %d weight %d offset %d\n",n,i,weight[0][n][i],offset[0][n][i]); +#endif + } } } } @@ -153,41 +199,38 @@ void estimate_weighting_factor_P_slice(int select_offset) /*! ************************************************************************ * \brief -* Estimates reference picture weighting factors +* Estimates reference picture weighting factors for B slices ************************************************************************ */ -void estimate_weighting_factor_B_slice() +void EstimateWPBSliceAlg0(ImageParameters *img, InputParameters *params) { - int i, j, n; + int i, j, k, n; int tx,DistScaleFactor; int index; int comp; double dc_org = 0.0; + double dc_org_UV[2] = { 0.0 }; double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} }; - - int log_weight_denom; + double dc_ref_UV[6][MAX_REFERENCE_PICTURES][2] = { {{0.0}} }; int default_weight[3]; int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; int weight[6][MAX_REFERENCE_PICTURES][3]; int offset[6][MAX_REFERENCE_PICTURES][3]; int im_weight[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3]; - int im_offset[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3]; int clist; int wf_weight, wf_offset; imgpel **tmpPtr; - if (active_pps->weighted_bipred_idc == 2) //! implicit mode + if (active_pps->weighted_bipred_idc == 2) //! implicit mode. Values are fixed and it is important to show it here { luma_log_weight_denom = 5; chroma_log_weight_denom = 5; } - else + else //! explicit mode. Values can be changed for higher precision. { - //luma_log_weight_denom = 6; - //chroma_log_weight_denom = 6; luma_log_weight_denom = 5; chroma_log_weight_denom = 5; } @@ -198,69 +241,51 @@ void estimate_weighting_factor_B_slice() default_weight[1] = 1 << chroma_log_weight_denom; default_weight[2] = 1 << chroma_log_weight_denom; - /* set all values to defaults */ - for (i = 0; i < 2 + list_offset; i++) - { - for (j = 0; j < listXsize[i]; j++) - { - for (n = 0; n < 3; n++) - { - wp_weight[i][j][n] = default_weight[n]; - wp_offset[i][j][n] = 0; - offset [i][j][n] = 0; - weight [i][j][n] = default_weight[n]; - } - } - } - - for (i = 0; i < listXsize[LIST_0]; i++) + if (active_pps->weighted_bipred_idc == 2) //! implicit mode { - for (j = 0; j < listXsize[LIST_1]; j++) + for (i = 0; i < listXsize[LIST_0]; i++) { - int td, tb; - td = iClip3(-128, 127,(listX[LIST_1][j]->poc - listX[LIST_0][i]->poc)); - tb = iClip3(-128, 127,(enc_picture->poc - listX[LIST_0][i]->poc)); - for (comp = 0; comp < 3; comp++) + for (j = 0; j < listXsize[LIST_1]; j++) { - // implicit weights - if (td == 0) - { - im_weight[1][i][j][comp] = default_weight[comp]; - im_weight[0][i][j][comp] = default_weight[comp]; - im_offset[1][i][j][comp] = 0; - im_offset[0][i][j][comp] = 0; - } - else + int td, tb; + td = iClip3(-128, 127,(listX[LIST_1][j]->poc - listX[LIST_0][i]->poc)); + tb = iClip3(-128, 127,(enc_picture->poc - listX[LIST_0][i]->poc)); + for (comp = 0; comp < 3; comp++) { - tx = (16384 + iabs(td/2))/td; - DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6); - im_weight[1][i][j][comp] = DistScaleFactor>>2; - if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128) + // implicit weights + if (td == 0) + { + im_weight[0][i][j][comp] = default_weight[comp]; im_weight[1][i][j][comp] = default_weight[comp]; - im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp]; - im_offset[1][i][j][comp] = 0; - im_offset[0][i][j][comp] = 0; + } + else + { + tx = (16384 + iabs(td/2))/td; + DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6); + im_weight[1][i][j][comp] = DistScaleFactor>>2; + if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128) + im_weight[1][i][j][comp] = default_weight[comp]; + im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp]; + } } +#if DEBUG_WP + printf ("%d imp weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n",enc_picture->poc, i, j, im_weight[0][i][j][0], im_weight[1][i][j][0], + enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, + DistScaleFactor ,tx,td,tb); +#endif } - /* - printf ("%d imp weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n",enc_picture->poc, i, j, im_weight[0][i][j][0], im_weight[1][i][j][0], - enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, - DistScaleFactor ,tx,td,tb); - */ } - } - if (active_pps->weighted_bipred_idc == 2) //! implicit mode - { - for (i = 0; i < listXsize[LIST_0]; i++) + for (k = 0; k < 2; k++) { - for (j = 0; j < listXsize[LIST_1]; j++) + for (i = 0; i < listXsize[LIST_0]; i++) { - for (comp = 0; comp < 3; comp++) + for (j = 0; j < listXsize[LIST_1]; j++) { - log_weight_denom = (comp == 0) ? luma_log_weight_denom : chroma_log_weight_denom; - wbp_weight[1][i][j][comp] = im_weight[1][i][j][comp] ; - wbp_weight[0][i][j][comp] = im_weight[0][i][j][comp]; + for (comp = 0; comp < 3; comp++) + { + wbp_weight[k][i][j][comp] = im_weight[k][i][j][comp]; + } } } } @@ -269,12 +294,11 @@ void estimate_weighting_factor_B_slice() { for (index = 0; index < listXsize[clist]; index++) { - wp_weight[clist][index][0] = default_weight[0]; - wp_weight[clist][index][1] = default_weight[1]; - wp_weight[clist][index][2] = default_weight[2]; - wp_offset[clist][index][0] = 0; - wp_offset[clist][index][1] = 0; - wp_offset[clist][index][2] = 0; + for (comp = 0; comp < 3; comp++) + { + wp_weight[clist][index][comp] = default_weight[comp]; + wp_offset[clist][index][comp] = 0; + } } } } @@ -282,51 +306,86 @@ void estimate_weighting_factor_B_slice() { dc_org = ComputeImgSum(pCurImg, img->height, img->width); - for (clist=0; clist<2 + list_offset; clist++) + if (params->ChromaWeightSupport == 1) { - for (n = 0; n < listXsize[clist]; n++) + for (k = 0; k < 2; k++) { - // To simplify these computations we may wish to perform these after a reference is - // stored in the reference buffer and attach them to the storedimage structure!!! - // Y - tmpPtr = listX[clist][n]->p_curr_img; - dc_ref[clist][n] = ComputeImgSum(tmpPtr, img->height, img->width); - - if (dc_ref[clist][n] != 0.0) - wf_weight = (int) (default_weight[0] * dc_org / dc_ref[clist][n] + 0.5); - else - wf_weight = default_weight[0]; // only used when reference picture is black - wf_weight = iClip3(-128, 127, wf_weight); - wf_offset = 0; - - // printf("dc_org = %d, dc_ref = %d, weight[%d] = %d\n",dc_org, dc_ref[n],n,weight[n][0]); - - weight[clist][n][0] = wf_weight; - offset[clist][n][0] = wf_offset; - - weight[clist][n][1] = default_weight[1]; - weight[clist][n][2] = default_weight[2]; - offset[clist][n][1] = 0; - offset[clist][n][2] = 0; - } + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } } - if (active_pps->weighted_bipred_idc == 1) + for (clist=0; clist<2 + list_offset; clist++) { - for (clist=0; clist<2 + list_offset; clist++) + for (n = 0; n < listXsize[clist]; n++) { - for (index = 0; index < listXsize[clist]; index++) + if ( wpxDetermineWP( params, img, clist, n ) ) { - for (comp = 0; comp < 3; comp++) + /* set all values to defaults */ + for (i = 0; i < 3; i++) + { + wp_weight[clist][n][i] = default_weight[i]; + wp_offset[clist][n][i] = 0; + offset [clist][n][i] = 0; + weight [clist][n][i] = default_weight[i]; + } + // To simplify these computations we may wish to perform these after a reference is + // stored in the reference buffer and attach them to the storedimage structure!!! + // Y + tmpPtr = listX[clist][n]->p_curr_img; + dc_ref[clist][n] = ComputeImgSum(tmpPtr, img->height, img->width); + + if (dc_ref[clist][n] != 0.0) + wf_weight = (int) (default_weight[0] * dc_org / dc_ref[clist][n] + 0.5); + else + wf_weight = default_weight[0]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + + // printf("dc_org = %d, dc_ref = %d, weight[%d] = %d\n",dc_org, dc_ref[n],n,weight[n][0]); + + weight[clist][n][0] = wf_weight; + offset[clist][n][0] = wf_offset; + + // UV + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[clist][n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + + if (dc_ref_UV[clist][n][k] != 0.0) + wf_weight = (int) (default_weight[k + 1] * dc_org_UV[k] / dc_ref_UV[clist][n][k] + 0.5); + else + wf_weight = default_weight[k + 1]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + + weight[clist][n][k + 1] = wf_weight; + offset[clist][n][k + 1] = wf_offset; + } + } + else { - wp_weight[clist][index][comp] = weight[clist][index][comp]; - wp_offset[clist][index][comp] = offset[clist][index][comp]; - //printf("%d %d\n",wp_weight[clist][index][comp],wp_offset[clist][index][comp]); + weight[clist][n][1] = default_weight[1]; + weight[clist][n][2] = default_weight[2]; + offset[clist][n][1] = 0; + offset[clist][n][2] = 0; + } + + for (i = 0; i < 3; i++) + { + wp_weight[clist][n][i] = weight[clist][n][i]; + wp_offset[clist][n][i] = offset[clist][n][i]; +#if DEBUG_WP + printf("%d %d\n",wp_weight[clist][index][comp],wp_offset[clist][index][comp]); +#endif } } } } - else + + if (active_pps->weighted_bipred_idc != 1) { for (clist=0; clist<2 + list_offset; clist++) { @@ -337,21 +396,22 @@ void estimate_weighting_factor_B_slice() } } } + + for (i = 0; i < listXsize[LIST_0]; i++) { for (j = 0; j < listXsize[LIST_1]; j++) { for (comp = 0; comp < 3; comp++) { - log_weight_denom = (comp == 0) ? luma_log_weight_denom : chroma_log_weight_denom; wbp_weight[0][i][j][comp] = wp_weight[0][i][comp]; wbp_weight[1][i][j][comp] = wp_weight[1][j][comp]; } - /* +#if DEBUG_WP printf ("bpw weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n", i, j, wbp_weight[0][i][j][0], wbp_weight[1][i][j][0], - enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, - DistScaleFactor ,tx,tx,tx); - */ + enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, + DistScaleFactor ,tx,tx,tx); +#endif } } } @@ -365,14 +425,16 @@ void estimate_weighting_factor_B_slice() ************************************************************************ */ -int test_wp_P_slice(int select_offset) +int TestWPPSliceAlg0(ImageParameters *img, InputParameters *params, int select_offset) { - int i, j, n; + int i, j, k, n; int index; int comp; double dc_org = 0.0; + double dc_org_UV[2] = {0.0}; double dc_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double dc_ref_UV[MAX_REFERENCE_PICTURES][2] = { {0.0}}; int default_weight[3]; @@ -407,6 +469,14 @@ int test_wp_P_slice(int select_offset) dc_org = ComputeImgSum(pCurImg, img->height, img->width); + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } + } + for (clist = 0; clist < 2 + list_offset; clist++) { for (n = 0; n < listXsize[clist]; n++) @@ -414,6 +484,15 @@ int test_wp_P_slice(int select_offset) tmpPtr = listX[clist][n]->p_curr_img; dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width); + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + } + } + if (select_offset == 0) { if (dc_ref[n] != 0.0) @@ -421,6 +500,20 @@ int test_wp_P_slice(int select_offset) else weight[clist][n][0] = default_weight[0]; // only used when reference picture is black weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]); + if (params->ChromaWeightSupport == 1) + { + if (dc_ref_UV[n][0] != 0) + weight[clist][n][1] = (int) (default_weight[1] * dc_org_UV[0] / dc_ref_UV[n][0] + 0.5); + else + weight[clist][n][1] = default_weight[1]; // only used when reference picture is black + weight[clist][n][1] = iClip3(-128, 127, weight[clist][n][1]); + + if (dc_ref_UV[n][1] != 0) + weight[clist][n][2] = (int) (default_weight[2] * dc_org_UV[1] / dc_ref_UV[n][1] + 0.5); + else + weight[clist][n][2] = default_weight[2]; // only used when reference picture is black + weight[clist][n][2] = iClip3(-64, 128, weight[clist][n][2]); + } } else { @@ -429,6 +522,23 @@ int test_wp_P_slice(int select_offset) offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); weight[clist][n][0] = default_weight[0]; + + if (params->ChromaWeightSupport == 1) + { + offset[clist][n][1] = (int) ((dc_org_UV[0] - dc_ref_UV[n][0])/(img->size_cr)+0.5); + offset[clist][n][1] = (offset[clist][n][1] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][1] = iClip3( -128, 127, offset[clist][n][1]); + offset[clist][n][1] = offset[clist][n][1]<<(img->bitdepth_chroma - 8); + + weight[clist][n][1] = default_weight[1]; + + offset[clist][n][2] = (int) ((dc_org_UV[1] - dc_ref_UV[n][1])/(img->size_cr)+0.5); + offset[clist][n][2] = (offset[clist][n][2] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][2] = iClip3( -128, 127, offset[clist][n][2]); + offset[clist][n][2] = offset[clist][n][2]<<(img->bitdepth_chroma - 8); + + weight[clist][n][2] = default_weight[2]; + } } } } @@ -443,7 +553,7 @@ int test_wp_P_slice(int select_offset) ? iabs(offset[clist][index][comp]) > 2 : offset[clist][index][comp] != 0; - if (weight[clist][index][comp] != default_weight[0] || offset_test) + if (weight[clist][index][comp] != default_weight[0] || offset_test) { perform_wp = 1; break; @@ -460,22 +570,22 @@ int test_wp_P_slice(int select_offset) /*! ************************************************************************ * \brief -* test_wp_B_slice: +* TestWPBSliceAlg0: * Tests B slice weighting prediction ************************************************************************ */ -int test_wp_B_slice(int select_method) +int TestWPBSliceAlg0(ImageParameters *img, InputParameters *params, int select_method) { - int i, j, n; + int i, j, k, n; int tx,DistScaleFactor; int index; int comp; double dc_org = 0.0; - double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} }; - - int log_weight_denom; + double dc_org_UV[2] = { 0.0 }; + double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} }; + double dc_ref_UV[6][MAX_REFERENCE_PICTURES][2] = { {{0.0}} }; int default_weight[3]; // this needs to be fixed. @@ -483,7 +593,6 @@ int test_wp_B_slice(int select_method) int weight[6][MAX_REFERENCE_PICTURES][3]; int offset[6][MAX_REFERENCE_PICTURES][3]; int im_weight[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3]; - int im_offset[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3]; int clist; int wf_weight, wf_offset; int perform_wp = 0; @@ -533,21 +642,17 @@ int test_wp_B_slice(int select_method) // implicit weights if (td == 0) { - im_weight[1][i][j][comp] = default_weight[comp]; im_weight[0][i][j][comp] = default_weight[comp]; - im_offset[1][i][j][comp] = 0; - im_offset[0][i][j][comp] = 0; + im_weight[1][i][j][comp] = default_weight[comp]; } else { tx = (16384 + iabs(td/2))/td; DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6); - im_weight[1][i][j][comp] = DistScaleFactor>>2; + im_weight[1][i][j][comp] = DistScaleFactor >> 2; if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128) im_weight[1][i][j][comp] = default_weight[comp]; im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp]; - im_offset[1][i][j][comp] = 0; - im_offset[0][i][j][comp] = 0; } } } @@ -562,7 +667,6 @@ int test_wp_B_slice(int select_method) { for (comp = 0; comp < 3; comp++) { - log_weight_denom = (comp == 0) ? luma_log_weight_denom : chroma_log_weight_denom; wbp_weight[1][i][j][comp] = im_weight[1][i][j][comp] ; wbp_weight[0][i][j][comp] = im_weight[0][i][j][comp]; } @@ -573,12 +677,11 @@ int test_wp_B_slice(int select_method) { for (index = 0; index < listXsize[clist]; index++) { - wp_weight[clist][index][0] = default_weight[0]; - wp_weight[clist][index][1] = default_weight[1]; - wp_weight[clist][index][2] = default_weight[2]; - wp_offset[clist][index][0] = 0; - wp_offset[clist][index][1] = 0; - wp_offset[clist][index][2] = 0; + for (comp = 0; comp < 3; comp++) + { + wp_weight[clist][index][comp] = default_weight[comp]; + wp_offset[clist][index][comp] = 0; + } } } } @@ -586,6 +689,14 @@ int test_wp_B_slice(int select_method) { dc_org = ComputeImgSum(pCurImg, img->height, img->width); + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } + } + for (clist=0; clist<2 + list_offset; clist++) { for (n = 0; n < listXsize[clist]; n++) @@ -606,10 +717,32 @@ int test_wp_B_slice(int select_method) weight[clist][n][0] = wf_weight; offset[clist][n][0] = wf_offset; - weight[clist][n][1] = default_weight[1]; - weight[clist][n][2] = default_weight[2]; - offset[clist][n][1] = 0; - offset[clist][n][2] = 0; + // UV + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[clist][n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + + if (dc_ref_UV[clist][n][k] != 0.0) + wf_weight = (int) (default_weight[k + 1] * dc_org_UV[k] / dc_ref_UV[clist][n][k] + 0.5); + else + wf_weight = default_weight[k + 1]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + + weight[clist][n][k + 1] = wf_weight; + offset[clist][n][k + 1] = wf_offset; + } + } + else + { + weight[clist][n][1] = default_weight[1]; + weight[clist][n][2] = default_weight[2]; + offset[clist][n][1] = 0; + offset[clist][n][2] = 0; + } } } @@ -635,21 +768,21 @@ int test_wp_B_slice(int select_method) } } } + for (i = 0; i < listXsize[LIST_0]; i++) { for (j = 0; j < listXsize[LIST_1]; j++) { for (comp = 0; comp < 3; comp++) { - log_weight_denom = (comp == 0) ? luma_log_weight_denom : chroma_log_weight_denom; wbp_weight[0][i][j][comp] = wp_weight[0][i][comp]; wbp_weight[1][i][j][comp] = wp_weight[1][j][comp]; } - /* +#if DEBUG_WP printf ("bpw weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n", i, j, wbp_weight[0][i][j][0], wbp_weight[1][i][j][0], enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, DistScaleFactor ,tx,tx,tx); - */ +#endif } } } @@ -658,8 +791,8 @@ int test_wp_B_slice(int select_method) { int active_refs[2]; - active_refs[0] = (params->B_List0_refs == 0 ? listXsize[0] : imin(params->B_List0_refs,listXsize[0])); - active_refs[1] = (params->B_List1_refs == 0 ? listXsize[1] : imin(params->B_List0_refs,listXsize[1])); + active_refs[0] = (params->B_List0_refs == 0 ? listXsize[0] : imin(params->B_List0_refs, listXsize[0])); + active_refs[1] = (params->B_List1_refs == 0 ? listXsize[1] : imin(params->B_List1_refs, listXsize[1])); for (clist=0; clist<2 + list_offset; clist++) { @@ -680,5 +813,3 @@ int test_wp_B_slice(int select_method) } return perform_wp; } - - diff --git a/lencod/src/wp_lms.c b/lencod/src/wp_lms.c new file mode 100644 index 0000000..e05d745 --- /dev/null +++ b/lencod/src/wp_lms.c @@ -0,0 +1,877 @@ + +/*! +************************************************************************************* +* \file wp_lms.c +* +* \brief +* Estimate weights for WP using LMS method +* +* \author +* Main contributors (see contributors.h for copyright, address and affiliation details) +* - Alexis Michael Tourapis <alexismt@ieee.org> +* - Athanasios Leontaris <aleon@dolby.com> +************************************************************************************* +*/ +#include "contributors.h" + +#include "global.h" +#include "image.h" +#include "wp.h" + +static inline double ComputeNormMean(imgpel **CurrentImage, double mean_value, int height, int width) +{ + int i, j; + double sum_value = 0.0; + + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + sum_value += dabs((double) CurrentImage[i][j] - mean_value); + } + } + return sum_value; +} + +/*! +************************************************************************ +* \brief +* Estimates reference picture weighting factors for P slices +************************************************************************ +*/ + +void EstimateWPPSliceAlg1(ImageParameters *img, InputParameters *params, int select_offset) +{ + double dc_org = 0.0; + double dc_org_UV[2] = {0.0}; + double dc_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double dc_ref_UV[MAX_REFERENCE_PICTURES][2] = { {0.0}}; + double norm_org = 0.0; + double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double numer = {0.0}; + double denom[MAX_REFERENCE_PICTURES] = {0.0}; + + int i, n, k; + int default_weight[3]; + int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; + int weight[2][MAX_REFERENCE_PICTURES][3]; + int offset[2][MAX_REFERENCE_PICTURES][3]; + int clist; + + imgpel **tmpPtr; + + luma_log_weight_denom = 5; + chroma_log_weight_denom = 5; + + wp_luma_round = 1 << (luma_log_weight_denom - 1); + wp_chroma_round = 1 << (chroma_log_weight_denom - 1); + default_weight[0] = 1 << luma_log_weight_denom; + default_weight[1] = default_weight[2] = 1 << chroma_log_weight_denom; + + dc_org = ComputeImgSum(pCurImg, img->height, img->width); + + norm_org = dc_org / ((double) img->size); + numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width); + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } + } + + for (clist = 0; clist < 2 + list_offset; clist++) + { + for (n = 0; n < listXsize[clist]; n++) + { + if ( wpxDetermineWP( params, img, clist, n ) ) + { + /* set all values to defaults */ + for (i = 0; i < 3; i++) + { + weight[clist][n][i] = default_weight[i]; + wp_weight[clist][n][i] = default_weight[i]; + wp_offset[clist][n][i] = 0; + offset[clist][n][i] = 0; + } + + // Y + tmpPtr = listX[clist][n]->p_curr_img; + dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width); + + norm_ref[n] = dc_ref[n] / ((double) img->size); + denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width); + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + // UV + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + } + } + + if (select_offset == 0) + { + if (denom[n] != 0) + weight[clist][n][0] = (int) (default_weight[0] * numer / denom[n] + 0.5); + else + weight[clist][n][0] = default_weight[0]; // only used when reference picture is black + weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]); + + offset[clist][n][0] = (int) (norm_org - ((double) weight[clist][n][0] * norm_ref[n] / (double) default_weight[0]) + 0.5); + offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); + offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); + offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); + + if (params->ChromaWeightSupport == 1) + { + if (dc_ref_UV[n][0] != 0) + weight[clist][n][1] = (int) (default_weight[1] * dc_org_UV[0] / dc_ref_UV[n][0] + 0.5); + else + weight[clist][n][1] = default_weight[1]; // only used when reference picture is black + weight[clist][n][1] = iClip3(-128, 127, weight[clist][n][1]); + + if (dc_ref_UV[n][1] != 0) + weight[clist][n][2] = (int) (default_weight[2] * dc_org_UV[1] / dc_ref_UV[n][1] + 0.5); + else + weight[clist][n][2] = default_weight[2]; // only used when reference picture is black + weight[clist][n][2] = iClip3(-64, 128, weight[clist][n][2]); + } + } + else + { + offset[clist][n][0] = (int) ((dc_org - dc_ref[n])/(img->size)+0.5); + offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); + offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); + offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); + weight[clist][n][0] = default_weight[0]; + + if (params->ChromaWeightSupport == 1) + { + offset[clist][n][1] = (int) ((dc_org_UV[0] - dc_ref_UV[n][0])/(img->size_cr)+0.5); + offset[clist][n][1] = (offset[clist][n][1] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][1] = iClip3( -128, 127, offset[clist][n][1]); + offset[clist][n][1] = offset[clist][n][1]<<(img->bitdepth_chroma - 8); + + weight[clist][n][1] = default_weight[1]; + + offset[clist][n][2] = (int) ((dc_org_UV[1] - dc_ref_UV[n][1])/(img->size_cr)+0.5); + offset[clist][n][2] = (offset[clist][n][2] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][2] = iClip3( -128, 127, offset[clist][n][2]); + offset[clist][n][2] = offset[clist][n][2]<<(img->bitdepth_chroma - 8); + + weight[clist][n][2] = default_weight[2]; + } + } + + for (i=0; i < 3; i ++) + { + wp_weight[clist][n][i] = weight[clist][n][i]; + wp_offset[clist][n][i] = offset[clist][n][i]; +#if DEBUG_WP + printf("index %d component %d weight %d offset %d\n",n,i,weight[0][n][i],offset[0][n][i]); +#endif + } + } + } + } +} + +/*! +************************************************************************ +* \brief +* Estimates reference picture weighting factors for B slices +************************************************************************ +*/ +void EstimateWPBSliceAlg1(ImageParameters *img, InputParameters *params) +{ + int i, j, n; + + int tx,DistScaleFactor; + + int index; + int comp; + double dc_org = 0.0; + double dc_org_UV[2] = { 0.0 }; + double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} }; + double dc_ref_UV[6][MAX_REFERENCE_PICTURES][2] = { {{0.0}} }; + double norm_org = 0.0; + double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double numer = {0.0}; + double denom[MAX_REFERENCE_PICTURES] = {0.0}; + int k; + + int default_weight[3]; + int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; + int weight[6][MAX_REFERENCE_PICTURES][3]; + int offset[6][MAX_REFERENCE_PICTURES][3]; + int im_weight[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3]; + int clist; + int wf_weight, wf_offset; + imgpel **tmpPtr; + + if (active_pps->weighted_bipred_idc == 2) //! implicit mode. Values are fixed and it is important to show it here + { + luma_log_weight_denom = 5; + chroma_log_weight_denom = 5; + } + else //! explicit mode. Values can be changed for higher precision. + { + luma_log_weight_denom = 5; + chroma_log_weight_denom = 5; + } + + wp_luma_round = 1 << (luma_log_weight_denom - 1); + wp_chroma_round = 1 << (chroma_log_weight_denom - 1); + default_weight[0] = 1 << luma_log_weight_denom; + default_weight[1] = 1 << chroma_log_weight_denom; + default_weight[2] = 1 << chroma_log_weight_denom; + + if (active_pps->weighted_bipred_idc == 2) //! implicit mode + { + for (i = 0; i < listXsize[LIST_0]; i++) + { + for (j = 0; j < listXsize[LIST_1]; j++) + { + int td, tb; + td = iClip3(-128, 127,(listX[LIST_1][j]->poc - listX[LIST_0][i]->poc)); + tb = iClip3(-128, 127,(enc_picture->poc - listX[LIST_0][i]->poc)); + for (comp = 0; comp < 3; comp++) + { + // implicit weights + if (td == 0) + { + im_weight[0][i][j][comp] = default_weight[comp]; + im_weight[1][i][j][comp] = default_weight[comp]; + } + else + { + tx = (16384 + iabs(td/2))/td; + DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6); + im_weight[1][i][j][comp] = DistScaleFactor>>2; + if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128) + im_weight[1][i][j][comp] = default_weight[comp]; + im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp]; + } + } +#if DEBUG_WP + printf ("%d imp weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n",enc_picture->poc, i, j, im_weight[0][i][j][0], im_weight[1][i][j][0], + enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, + DistScaleFactor ,tx,td,tb); +#endif + } + } + + for (k = 0; k < 2; k++) + { + for (i = 0; i < listXsize[LIST_0]; i++) + { + for (j = 0; j < listXsize[LIST_1]; j++) + { + for (comp = 0; comp < 3; comp++) + { + wbp_weight[k][i][j][comp] = im_weight[k][i][j][comp]; + } + } + } + } + + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < listXsize[clist]; index++) + { + for (comp = 0; comp < 3; comp++) + { + wp_weight[clist][index][comp] = default_weight[comp]; + wp_offset[clist][index][comp] = 0; + } + } + } + } + else // explicit WP mode (or no WP at all) + { + dc_org = ComputeImgSum(pCurImg, img->height, img->width); + + if (params->EnhancedBWeightSupport) + { + norm_org = dc_org / ((double) img->size); + numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width); + } + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } + } + + for (clist=0; clist<2 + list_offset; clist++) + { + for (n = 0; n < listXsize[clist]; n++) + { + if ( wpxDetermineWP( params, img, clist, n ) ) + { + /* set all values to defaults */ + for (i = 0; i < 3; i++) + { + wp_weight[clist][n][i] = default_weight[i]; + wp_offset[clist][n][i] = 0; + offset [clist][n][i] = 0; + weight [clist][n][i] = default_weight[i]; + } + // To simplify these computations we may wish to perform these after a reference is + // stored in the reference buffer and attach them to the storedimage structure!!! + // Y + tmpPtr = listX[clist][n]->p_curr_img; + dc_ref[clist][n] = ComputeImgSum(tmpPtr, img->height, img->width); + + if (params->EnhancedBWeightSupport) + { + norm_ref[n] = dc_ref[clist][n] / ((double) img->size); + denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width); + } + if (params->EnhancedBWeightSupport) + { + if (denom[n] != 0) + wf_weight = (int) (default_weight[0] * numer / denom[n] + 0.5); + else + wf_weight = default_weight[0]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + + wf_offset = (int) (norm_org - ((double) wf_weight * norm_ref[n] / (double) default_weight[0]) + 0.5); + wf_offset = (wf_offset + ((img->bitdepth_luma - 8)>>1))>>(img->bitdepth_luma-8); + wf_offset = iClip3( -128, 127, wf_offset); + wf_offset = wf_offset <<(img->bitdepth_luma - 8); + } + else + { + if (dc_ref[clist][n] != 0.0) + wf_weight = (int) (default_weight[0] * dc_org / dc_ref[clist][n] + 0.5); + else + wf_weight = default_weight[0]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + } + + // printf("dc_org = %d, dc_ref = %d, weight[%d] = %d\n",dc_org, dc_ref[n],n,weight[n][0]); + + weight[clist][n][0] = wf_weight; + offset[clist][n][0] = wf_offset; + + // UV + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[clist][n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + + if (dc_ref_UV[clist][n][k] != 0.0) + wf_weight = (int) (default_weight[k + 1] * dc_org_UV[k] / dc_ref_UV[clist][n][k] + 0.5); + else + wf_weight = default_weight[k + 1]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + + weight[clist][n][k + 1] = wf_weight; + offset[clist][n][k + 1] = wf_offset; + } + } + else + { + weight[clist][n][1] = default_weight[1]; + weight[clist][n][2] = default_weight[2]; + offset[clist][n][1] = 0; + offset[clist][n][2] = 0; + } + + for (i = 0; i < 3; i++) + { + wp_weight[clist][n][i] = weight[clist][n][i]; + wp_offset[clist][n][i] = offset[clist][n][i]; +#if DEBUG_WP + printf("%d %d\n",wp_weight[clist][index][comp],wp_offset[clist][index][comp]); +#endif + } + } + } + } + + if (active_pps->weighted_bipred_idc != 1) + { + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < listXsize[clist]; index++) + { + memcpy(wp_weight[clist][index], default_weight, 3 * sizeof(int)); + memset(wp_offset[clist][index], 0, 3 * sizeof(int)); + } + } + } + + for (i = 0; i < listXsize[LIST_0]; i++) + { + for (j = 0; j < listXsize[LIST_1]; j++) + { + for (comp = 0; comp < 3; comp++) + { + wbp_weight[0][i][j][comp] = wp_weight[0][i][comp]; + wbp_weight[1][i][j][comp] = wp_weight[1][j][comp]; + } +#if DEBUG_WP + printf ("bpw weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n", i, j, wbp_weight[0][i][j][0], wbp_weight[1][i][j][0], + enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, + DistScaleFactor ,tx,tx,tx); +#endif + } + } + } +} + + +/*! +************************************************************************ +* \brief +* Tests P slice weighting factors to perform or not WP RD decision +************************************************************************ +*/ + +int TestWPPSliceAlg1(ImageParameters *img, InputParameters *params, int select_offset) +{ + int i, j, k, n; + + int index; + int comp; + double dc_org = 0.0; + double dc_org_UV[2] = {0.0}; + double dc_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double dc_ref_UV[MAX_REFERENCE_PICTURES][2] = { {0.0}}; + double norm_org = 0.0; + double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double numer = {0.0}; + double denom[MAX_REFERENCE_PICTURES] = {0.0}; + + int default_weight[3]; + + int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; + int weight[2][MAX_REFERENCE_PICTURES][3]; + int offset[2][MAX_REFERENCE_PICTURES][3]; + int clist; + int perform_wp = 0; + imgpel **tmpPtr; + + luma_log_weight_denom = 5; + chroma_log_weight_denom = 5; + wp_luma_round = 1 << (luma_log_weight_denom - 1); + wp_chroma_round = 1 << (chroma_log_weight_denom - 1); + default_weight[0] = 1 << luma_log_weight_denom; + default_weight[1] = default_weight[2] = 1 << chroma_log_weight_denom; + + /* set all values to defaults */ + for (i = 0; i < 2 + list_offset; i++) + { + for (j = 0; j < listXsize[i]; j++) + { + for (n = 0; n < 3; n++) + { + weight[i][j][n] = default_weight[n]; + wp_weight[i][j][n] = default_weight[n]; + wp_offset[i][j][n] = 0; + offset[i][j][n] = 0; + } + } + } + + dc_org = ComputeImgSum(pCurImg, img->height, img->width); + + norm_org = dc_org / ((double) img->size); + numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width); + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } + } + + for (clist = 0; clist < 2 + list_offset; clist++) + { + for (n = 0; n < listXsize[clist]; n++) + { + tmpPtr = listX[clist][n]->p_curr_img; + dc_ref[n] = ComputeImgSum(tmpPtr, img->height, img->width); + + norm_ref[n] = dc_ref[n] / ((double) img->size); + denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width); + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + } + } + + if (select_offset == 0) + { + if (denom[n] != 0) + weight[clist][n][0] = (int) (default_weight[0] * numer / denom[n] + 0.5); + else + weight[clist][n][0] = default_weight[0]; // only used when reference picture is black + weight[clist][n][0] = iClip3(-128, 127, weight[clist][n][0]); + + offset[clist][n][0] = (int) (norm_org - ((double) weight[clist][n][0] * norm_ref[n] / (double) default_weight[0]) + 0.5); + offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); + offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); + offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); + + if (params->ChromaWeightSupport == 1) + { + if (dc_ref_UV[n][0] != 0) + weight[clist][n][1] = (int) (default_weight[1] * dc_org_UV[0] / dc_ref_UV[n][0] + 0.5); + else + weight[clist][n][1] = default_weight[1]; // only used when reference picture is black + weight[clist][n][1] = iClip3(-128, 127, weight[clist][n][1]); + + if (dc_ref_UV[n][1] != 0) + weight[clist][n][2] = (int) (default_weight[2] * dc_org_UV[1] / dc_ref_UV[n][1] + 0.5); + else + weight[clist][n][2] = default_weight[2]; // only used when reference picture is black + weight[clist][n][2] = iClip3(-64, 128, weight[clist][n][2]); + } + } + else + { + offset[clist][n][0] = (int) ((dc_org - dc_ref[n])/(img->size)+0.5); + offset[clist][n][0] = (offset[clist][n][0]+((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); + offset[clist][n][0] = iClip3( -128, 127, offset[clist][n][0]); + offset[clist][n][0] = offset[clist][n][0]<<(img->bitdepth_luma-8); + weight[clist][n][0] = default_weight[0]; + + if (params->ChromaWeightSupport == 1) + { + offset[clist][n][1] = (int) ((dc_org_UV[0] - dc_ref_UV[n][0])/(img->size_cr)+0.5); + offset[clist][n][1] = (offset[clist][n][1] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][1] = iClip3( -128, 127, offset[clist][n][1]); + offset[clist][n][1] = offset[clist][n][1]<<(img->bitdepth_chroma - 8); + + weight[clist][n][1] = default_weight[1]; + + offset[clist][n][2] = (int) ((dc_org_UV[1] - dc_ref_UV[n][1])/(img->size_cr)+0.5); + offset[clist][n][2] = (offset[clist][n][2] + ((img->bitdepth_chroma - 8)>>1))>>(img->bitdepth_chroma-8); + offset[clist][n][2] = iClip3( -128, 127, offset[clist][n][2]); + offset[clist][n][2] = offset[clist][n][2]<<(img->bitdepth_chroma - 8); + + weight[clist][n][2] = default_weight[2]; + } + } + } + } + + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < listXsize[clist]; index++) + { + for (comp=0; comp < 3; comp ++) + { + int offset_test = params->RDPSliceBTest && active_sps->profile_idc != 66 + ? iabs(offset[clist][index][comp]) > 2 + : offset[clist][index][comp] != 0; + + if (weight[clist][index][comp] != default_weight[0] || offset_test) + { + perform_wp = 1; + break; + } + } + if (perform_wp == 1) break; + } + if (perform_wp == 1) break; + } + + return perform_wp; +} + +/*! +************************************************************************ +* \brief +* TestWPBSliceAlg1: +* Tests B slice weighting prediction +************************************************************************ +*/ +int TestWPBSliceAlg1(ImageParameters *img, InputParameters *params, int select_method) +{ + int i, j, k, n; + + int tx,DistScaleFactor; + + int index; + int comp; + double dc_org = 0.0; + double dc_org_UV[2] = { 0.0 }; + double dc_ref[6][MAX_REFERENCE_PICTURES] = { {0.0} }; + double dc_ref_UV[6][MAX_REFERENCE_PICTURES][2] = { {{0.0}} }; + double norm_org = 0.0; + double norm_ref[MAX_REFERENCE_PICTURES] = { 0.0 }; + double numer = {0.0}; + double denom[MAX_REFERENCE_PICTURES] = {0.0}; + + int default_weight[3]; + // this needs to be fixed. + int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0; + int weight[6][MAX_REFERENCE_PICTURES][3]; + int offset[6][MAX_REFERENCE_PICTURES][3]; + int im_weight[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES][3]; + int clist; + int wf_weight, wf_offset; + int perform_wp = 0; + imgpel **tmpPtr; + + if (select_method == 1) //! implicit mode + { + luma_log_weight_denom = 5; + chroma_log_weight_denom = 5; + } + else + { + luma_log_weight_denom = 5; + chroma_log_weight_denom = 5; + } + + wp_luma_round = 1 << (luma_log_weight_denom - 1); + wp_chroma_round = 1 << (chroma_log_weight_denom - 1); + default_weight[0] = 1 << luma_log_weight_denom; + default_weight[1] = 1 << chroma_log_weight_denom; + default_weight[2] = 1 << chroma_log_weight_denom; + + /* set all values to defaults */ + for (i = 0; i < 2 + list_offset; i++) + { + for (j = 0; j < listXsize[i]; j++) + { + for (n = 0; n < 3; n++) + { + wp_weight[i][j][n] = default_weight[n]; + wp_offset[i][j][n] = 0; + offset [i][j][n] = 0; + weight [i][j][n] = default_weight[n]; + } + } + } + + for (i = 0; i < listXsize[LIST_0]; i++) + { + for (j = 0; j < listXsize[LIST_1]; j++) + { + int td, tb; + td = iClip3(-128, 127,(listX[LIST_1][j]->poc - listX[LIST_0][i]->poc)); + tb = iClip3(-128, 127,(enc_picture->poc - listX[LIST_0][i]->poc)); + for (comp = 0; comp < 3; comp++) + { + // implicit weights + if (td == 0) + { + im_weight[0][i][j][comp] = default_weight[comp]; + im_weight[1][i][j][comp] = default_weight[comp]; + } + else + { + tx = (16384 + iabs(td/2))/td; + DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6); + im_weight[1][i][j][comp] = DistScaleFactor >> 2; + if (im_weight[1][i][j][comp] < -64 || im_weight[1][i][j][comp] >128) + im_weight[1][i][j][comp] = default_weight[comp]; + im_weight[0][i][j][comp] = 64 - im_weight[1][i][j][comp]; + } + } + } + } + + + if (select_method == 1) //! implicit mode + { + for (i = 0; i < listXsize[LIST_0]; i++) + { + for (j = 0; j < listXsize[LIST_1]; j++) + { + for (comp = 0; comp < 3; comp++) + { + wbp_weight[1][i][j][comp] = im_weight[1][i][j][comp] ; + wbp_weight[0][i][j][comp] = im_weight[0][i][j][comp]; + } + } + } + + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < listXsize[clist]; index++) + { + for (comp = 0; comp < 3; comp++) + { + wp_weight[clist][index][comp] = default_weight[comp]; + wp_offset[clist][index][comp] = 0; + } + } + } + } + else + { + dc_org = ComputeImgSum(pCurImg, img->height, img->width); + + if (params->EnhancedBWeightSupport) + { + norm_org = dc_org / ((double) img->size); + numer = ComputeNormMean(pCurImg, norm_org, img->height, img->width); + } + + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + dc_org_UV[k] = ComputeImgSum(pImgOrg[k + 1], img->height_cr, img->width_cr); + } + } + + for (clist=0; clist<2 + list_offset; clist++) + { + for (n = 0; n < listXsize[clist]; n++) + { + // To simplify these computations we may wish to perform these after a reference is + // stored in the reference buffer and attach them to the storedimage structure!!! + // Y + tmpPtr = listX[clist][n]->p_curr_img; + dc_ref[clist][n] = ComputeImgSum(tmpPtr, img->height, img->width); + + if (params->EnhancedBWeightSupport) + { + norm_ref[n] = dc_ref[clist][n] / ((double) img->size); + denom[n] = ComputeNormMean(tmpPtr, norm_ref[n], img->height, img->width); + + if (denom[n] != 0) + wf_weight = (int) (default_weight[0] * numer / denom[n] + 0.5); + else + wf_weight = default_weight[0]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + + wf_offset = (int) (norm_org - ((double) wf_weight * norm_ref[n] / (double) default_weight[0]) + 0.5); + wf_offset = (wf_offset + ((img->bitdepth_luma-8)>>1))>>(img->bitdepth_luma-8); + wf_offset = iClip3( -128, 127, wf_offset); + wf_offset = wf_offset <<(img->bitdepth_luma - 8); + } + else + { + if (dc_ref[clist][n] != 0.0) + wf_weight = (int) (default_weight[0] * dc_org / dc_ref[clist][n] + 0.5); + else + wf_weight = default_weight[0]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + } + + weight[clist][n][0] = wf_weight; + offset[clist][n][0] = wf_offset; + + // UV + if (params->ChromaWeightSupport == 1) + { + for (k = 0; k < 2; k++) + { + tmpPtr = listX[clist][n]->imgUV[k]; + dc_ref_UV[clist][n][k] = ComputeImgSum(tmpPtr, img->height_cr, img->width_cr); + + if (dc_ref_UV[clist][n][k] != 0.0) + wf_weight = (int) (default_weight[k + 1] * dc_org_UV[k] / dc_ref_UV[clist][n][k] + 0.5); + else + wf_weight = default_weight[k + 1]; // only used when reference picture is black + wf_weight = iClip3(-128, 127, wf_weight); + wf_offset = 0; + + weight[clist][n][k + 1] = wf_weight; + offset[clist][n][k + 1] = wf_offset; + } + } + else + { + weight[clist][n][1] = default_weight[1]; + weight[clist][n][2] = default_weight[2]; + offset[clist][n][1] = 0; + offset[clist][n][2] = 0; + } + } + } + + if (select_method == 0) //! explicit mode + { + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < listXsize[clist]; index++) + { + memcpy(wp_weight[clist][index], weight[clist][index], 3 * sizeof(int)); + memcpy(wp_offset[clist][index], offset[clist][index], 3 * sizeof(int)); + } + } + } + else + { + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < listXsize[clist]; index++) + { + memcpy(wp_weight[clist][index], default_weight, 3 * sizeof(int)); + memset(wp_offset[clist][index], 0, 3 * sizeof(int)); + } + } + } + + for (i = 0; i < listXsize[LIST_0]; i++) + { + for (j = 0; j < listXsize[LIST_1]; j++) + { + for (comp = 0; comp < 3; comp++) + { + wbp_weight[0][i][j][comp] = wp_weight[0][i][comp]; + wbp_weight[1][i][j][comp] = wp_weight[1][j][comp]; + } +#if DEBUG_WP + printf ("bpw weight[%d][%d] = %d , %d (%d %d %d) (%d %d) (%d %d)\n", i, j, wbp_weight[0][i][j][0], wbp_weight[1][i][j][0], + enc_picture->poc,listX[LIST_0][i]->poc, listX[LIST_1][j]->poc, + DistScaleFactor ,tx,tx,tx); +#endif + } + } + } + + if (select_method == 0) //! implicit mode + { + int active_refs[2]; + + active_refs[0] = (params->B_List0_refs == 0 ? listXsize[0] : imin(params->B_List0_refs, listXsize[0])); + active_refs[1] = (params->B_List1_refs == 0 ? listXsize[1] : imin(params->B_List1_refs, listXsize[1])); + + for (clist=0; clist<2 + list_offset; clist++) + { + for (index = 0; index < active_refs[clist]; index++) + { + for (comp=0; comp < 3; comp ++) + { + if (wp_weight[clist][index][comp] != default_weight[comp]) + { + perform_wp = 1; + break; + } + } + if (perform_wp == 1) break; + } + if (perform_wp == 1) break; + } + } + return perform_wp; +} + + diff --git a/lencod/src/wp_mcprec.c b/lencod/src/wp_mcprec.c new file mode 100644 index 0000000..59c1ef8 --- /dev/null +++ b/lencod/src/wp_mcprec.c @@ -0,0 +1,430 @@ + +/*! +************************************************************************************* +* \file wp_mcprec.c +* +* \brief +* Improved Motion Compensation Precision Scheme using Weighted Prediction +* +* \author +* Main contributors (see contributors.h for copyright, address and affiliation details) +* - Athanasios Leontaris <aleon@dolby.com> +* - Alexis Michael Tourapis <alexismt@ieee.org> +************************************************************************************* +*/ +#include "contributors.h" + +#include "global.h" +#include "image.h" +#include "slice.h" +#include "wp_mcprec.h" + +/*! +************************************************************************ +* \brief +* Initialize WPR object structure +* \para +************************************************************************ +*/ + +void wpxInitWPXObject( void ) +{ + pWPX = (WPXObject *)malloc( sizeof( WPXObject ) ); + if ( pWPX == NULL ) + { + fprintf( stderr, "\n Error initializing memory for WPXObject. Exiting...\n" ); + exit(1); + } + + // wp_ref_l0 + if ((pWPX->wp_ref_list[LIST_0] = (WeightedPredRefX *) calloc(MAX_REFERENCE_PICTURES, sizeof(WeightedPredRefX))) == NULL) + no_mem_exit("wpxInitWPXObject: pWPX->wp_ref_list[0]"); + // wp_ref_l1 + if ((pWPX->wp_ref_list[LIST_1] = (WeightedPredRefX *) calloc(MAX_REFERENCE_PICTURES, sizeof(WeightedPredRefX))) == NULL) + no_mem_exit("wpxInitWPXObject: pWPX->wp_ref_list[1]"); +} + +/*! +************************************************************************ +* \brief +* Free WPR object structure +* \para +************************************************************************ +*/ + +void wpxFreeWPXObject( void ) +{ + if ( pWPX != NULL ) + { + free( pWPX ); + } + + // wp_ref_l0 + if (pWPX->wp_ref_list[LIST_0]) + free(pWPX->wp_ref_list[LIST_0]); + pWPX->wp_ref_list[LIST_0] = NULL; + // wp_ref_l1 + if (pWPX->wp_ref_list[LIST_1]) + free(pWPX->wp_ref_list[LIST_1]); + pWPX->wp_ref_list[LIST_1] = NULL; +} + +/*! +************************************************************************ +* \brief +* Initialize WPR coding passes +* \para +************************************************************************ +*/ + +void wpxInitWPXPasses( InputParameters *params ) +{ + // initialize number of wp reference frames in each list + pWPX->num_wp_ref_list[LIST_0] = 0; + pWPX->num_wp_ref_list[LIST_1] = 0; + + switch( params->WPMCPrecision ) + { + default: + case 0: + break; + case 1: + pWPX->wp_rd_passes[0].algorithm = WP_REGULAR; + pWPX->wp_rd_passes[1].algorithm = WP_MCPREC_MINUS0; + break; + case 2: + pWPX->wp_rd_passes[0].algorithm = WP_REGULAR; + pWPX->wp_rd_passes[1].algorithm = WP_MCPREC_MINUS0; + pWPX->wp_rd_passes[2].algorithm = WP_MCPREC_MINUS1; + break; + } +} + +/*! +************************************************************************ +* \brief +* Modifies ref_pic_list for all lists +************************************************************************ +*/ + +void wpxModifyRefPicList( ImageParameters *img ) +{ + unsigned int i, j, cloned_refs; + static int default_order_list0[32]; + static int default_order_list1[32]; + static int re_order[32], *list_order; + int pred_list; + + StorablePicture **list; + + // set memory + memset( (void *)default_order_list0, 1<<20, 32 * sizeof( int ) ); + memset( (void *)default_order_list1, 1<<20, 32 * sizeof( int ) ); + memset( (void *)re_order, 1<<20, 32 * sizeof( int ) ); + + // First assign default list orders + list = listX[LIST_0]; + for (i=0; i<(unsigned int)(img->num_ref_idx_l0_active); i++) + { + default_order_list0[i] = list[i]->pic_num; + } + if ( img->type == B_SLICE ) + { + list = listX[LIST_1]; + for (i=0; i<(unsigned int)(img->num_ref_idx_l1_active); i++) + { + default_order_list1[i] = list[i]->pic_num; + } + } + + // obtain the ref_pic_list using POC-based reordering if img->type != B_SLICE + if ( img->type == P_SLICE ) + { + int list_sign[32]; + int poc_diff[32]; + int tmp_value; + int abs_poc_dist; + + for (i=0; i<dpb.ref_frames_in_buffer; i++) + { + re_order[i] = dpb.fs_ref[i]->frame->pic_num; + if (dpb.fs_ref[i]->is_used==3 && (dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term)) + { + abs_poc_dist = iabs(dpb.fs_ref[i]->frame->poc - enc_picture->poc) ; + poc_diff[i] = abs_poc_dist; + list_sign[i] = (enc_picture->poc < dpb.fs_ref[i]->frame->poc) ? +1 : -1; + } + } + + // sort these references based on poc (temporal) distance + for (i=0; i< dpb.ref_frames_in_buffer-1; i++) + { + for (j=i+1; j< dpb.ref_frames_in_buffer; j++) + { + if (poc_diff[i]>poc_diff[j] || (poc_diff[i] == poc_diff[j] && list_sign[j] > list_sign[i])) + { + tmp_value = poc_diff[i]; + poc_diff[i] = poc_diff[j]; + poc_diff[j] = tmp_value; + tmp_value = re_order[i]; + re_order[i] = re_order[j]; + re_order[j] = tmp_value ; + tmp_value = list_sign[i]; + list_sign[i] = list_sign[j]; + list_sign[j] = tmp_value ; + } + } + } + } + // end of POC-based reordering of P_SLICE + + // loop over two lists + for ( pred_list = 0; pred_list < (1 + ( img->type == B_SLICE ? 1 : 0 )); pred_list++ ) + { + if ( pred_list == LIST_0 ) + { + list_order = (img->type == P_SLICE) ? re_order : default_order_list0; + } + else + { + list_order = default_order_list1; + } + + // check algorithms (more flexibility for the future...) + switch( pWPX->curr_wp_rd_pass->algorithm ) + { + default: + case WP_MCPREC_PLUS0: + case WP_MCPREC_PLUS1: + case WP_MCPREC_MINUS0: + case WP_MCPREC_MINUS1: + // ref 0 and 1 point to to the same reference + cloned_refs = pWPX->num_wp_ref_list[pred_list] = 2; + for ( j = 0; j < cloned_refs; j++ ) + { + pWPX->wp_ref_list[pred_list][j].PicNum = list_order[0]; + } + // shift the rest + for ( j = cloned_refs; j < dpb.ref_frames_in_buffer; j++ ) + { + pWPX->wp_ref_list[pred_list][j].PicNum = list_order[j - (cloned_refs - 1)]; + pWPX->num_wp_ref_list[pred_list]++; + } + break; + case WP_MCPREC_MINUS_PLUS0: + // ref 0 and 1 point to to the same reference + cloned_refs = pWPX->num_wp_ref_list[pred_list] = 3; + for ( j = 0; j < cloned_refs; j++ ) + { + pWPX->wp_ref_list[pred_list][j].PicNum = list_order[0]; + } + // shift the rest + for ( j = cloned_refs; j < dpb.ref_frames_in_buffer; j++ ) + { + pWPX->wp_ref_list[pred_list][j].PicNum = list_order[j - (cloned_refs - 1)]; + pWPX->num_wp_ref_list[pred_list]++; + } + break; + } + // constrain list length + pWPX->num_wp_ref_list[pred_list] = imin( pWPX->num_wp_ref_list[pred_list], + ( pred_list == LIST_0 ) ? img->num_ref_idx_l0_active : img->num_ref_idx_l1_active ); + } +} + +/*! +************************************************************************ +* \brief +* Determine whether it is fine to determine WP parameters +************************************************************************ +*/ + +int wpxDetermineWP( InputParameters *params, ImageParameters *img, int clist, int n ) +{ + int i, j, determine_wp = 0; + int default_weight[3]; + // we assume it's the same as in the WP functions + int luma_log_weight_denom = 5; + int chroma_log_weight_denom = 5; + int cur_list = LIST_0; + + default_weight[0] = 1 << luma_log_weight_denom; + default_weight[1] = 1 << chroma_log_weight_denom; + default_weight[2] = 1 << chroma_log_weight_denom; + + if ( !params->WPMCPrecision ) + { + determine_wp = 1; + } + else + { + determine_wp = 0; + // check slice type + if ( img->type == P_SLICE ) + { + for (i = 0; i < 3; i++) + { + wp_weight[clist][n][i] = default_weight[i]; + } + } + else if ( img->type == B_SLICE ) + { + cur_list = ((clist % 2) == LIST_1) ? LIST_0 : LIST_1; + + // single-list prediction + for (i = 0; i < 3; i++) + { + wp_weight[clist][n][i] = default_weight[i]; + } + // bi-pred + for (j = 0; j < listXsize[cur_list]; j++) + { + for (i = 0; i < 3; i++) + wbp_weight[clist][n][j][i] = default_weight[i]; + } + } + // algorithm consideration + switch( pWPX->curr_wp_rd_pass->algorithm ) + { + case WP_MCPREC_PLUS0: + for (i = 0; i < 3; i++) + wp_offset[clist][n][i] = (n == 1) ? 1 : 0; + break; + case WP_MCPREC_MINUS0: + for (i = 0; i < 3; i++) + wp_offset[clist][n][i] = (n == 1) ? -1 : 0; + break; + case WP_MCPREC_PLUS1: + for (i = 0; i < 3; i++) + wp_offset[clist][n][i] = (n == 0) ? 1 : 0; + break; + case WP_MCPREC_MINUS1: + for (i = 0; i < 3; i++) + wp_offset[clist][n][i] = (n == 0) ? -1 : 0; + break; + case WP_MCPREC_MINUS_PLUS0: + for (i = 0; i < 3; i++) + wp_offset[clist][n][i] = (n == 1) ? -1 : ((n == 2) ? 1 : 0); + break; + default: + case WP_REGULAR: + determine_wp = 1; + break; + } + // check list (play with the WP factors) + if ( img->type == B_SLICE && cur_list == LIST_0 ) + { + for (i = 0; i < 3; i++) + wp_offset[clist][n][i] *= 2; + } + // zero out chroma offsets + for (i = 1; i < 3; i++) + { + wp_offset[clist][n][i] = 0; + } + } + + return determine_wp; +} + +/*! +************************************************************************ +* \brief +* Modify number of references +************************************************************************ +*/ + +void wpxAdaptRefNum( ImageParameters *img ) +{ + if ( pWPX->curr_wp_rd_pass->algorithm == WP_REGULAR ) + { + switch( img->type ) + { + default: + case I_SLICE: + break; + case P_SLICE: + if ( img->num_ref_idx_l0_active == ( params->P_List0_refs * ((img->structure !=0) + 1) ) ) + { + listXsize[LIST_0] = img->num_ref_idx_l0_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l0_active - ((img->structure !=0) + 1) ); + } + break; + case B_SLICE: + if ( img->num_ref_idx_l0_active == ( params->B_List0_refs * ((img->structure !=0) + 1) ) ) + { + listXsize[LIST_0] = img->num_ref_idx_l0_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l0_active - ((img->structure !=0) + 1) ); + } + if ( img->num_ref_idx_l1_active == ( params->B_List1_refs * ((img->structure !=0) + 1) ) ) + { + listXsize[LIST_1] = img->num_ref_idx_l1_active = imax( ((img->structure !=0) + 1), img->num_ref_idx_l1_active - ((img->structure !=0) + 1) ); + } + break; + } + } +} + +/*! +************************************************************************ +* \brief +* Reorder lists +************************************************************************ +*/ + +void wpxReorderLists( ImageParameters *img, Slice *currSlice ) +{ + int i, num_ref; + + wpxModifyRefPicList( img ); + + alloc_ref_pic_list_reordering_buffer(currSlice); + + for (i = 0; i < img->num_ref_idx_l0_active + 1; i++) + { + currSlice->reordering_of_pic_nums_idc_l0[i] = 3; + currSlice->abs_diff_pic_num_minus1_l0[i] = 0; + currSlice->long_term_pic_idx_l0[i] = 0; + } + + if (img->type == B_SLICE) // type should be part of currSlice not img + { + for (i = 0; i < img->num_ref_idx_l1_active + 1; i++) + { + currSlice->reordering_of_pic_nums_idc_l1[i] = 3; + currSlice->abs_diff_pic_num_minus1_l1[i] = 0; + currSlice->long_term_pic_idx_l1[i] = 0; + } + } + + // LIST_0 + num_ref = img->num_ref_idx_l0_active; + + poc_ref_pic_reorder_frame(listX[LIST_0], num_ref, + currSlice->reordering_of_pic_nums_idc_l0, + currSlice->abs_diff_pic_num_minus1_l0, + currSlice->long_term_pic_idx_l0, LIST_0); + // reference picture reordering + reorder_ref_pic_list(listX[LIST_0], &listXsize[LIST_0], + img->num_ref_idx_l0_active - 1, + currSlice->reordering_of_pic_nums_idc_l0, + currSlice->abs_diff_pic_num_minus1_l0, + currSlice->long_term_pic_idx_l0); + + if ( img->type == B_SLICE ) + { + // LIST_1 + num_ref = img->num_ref_idx_l1_active; + + poc_ref_pic_reorder_frame(listX[LIST_1], num_ref, + currSlice->reordering_of_pic_nums_idc_l1, + currSlice->abs_diff_pic_num_minus1_l1, + currSlice->long_term_pic_idx_l1, LIST_1); + // reference picture reordering + reorder_ref_pic_list(listX[LIST_1], &listXsize[LIST_1], + img->num_ref_idx_l1_active - 1, + currSlice->reordering_of_pic_nums_idc_l1, + currSlice->abs_diff_pic_num_minus1_l1, + currSlice->long_term_pic_idx_l1); + } +} + + diff --git a/lencod_vc7.vcproj b/lencod_vc7.vcproj index 7ffb13b..4f628cd 100644 --- a/lencod_vc7.vcproj +++ b/lencod_vc7.vcproj @@ -13,7 +13,7 @@ <Configurations> <Configuration Name="Debug|Win32" - OutputDirectory=".\lencod/Debug_vc7" + OutputDirectory=".\..\bin" IntermediateDirectory=".\lencod/Debug_vc7" ConfigurationType="1" UseOfMFC="0" @@ -75,7 +75,7 @@ </Configuration> <Configuration Name="Release|Win32" - OutputDirectory=".\lencod\Release_vc7" + OutputDirectory=".\..\bin" IntermediateDirectory=".\lencod\Release_vc7" ConfigurationType="1" UseOfMFC="0" @@ -157,6 +157,9 @@ <File RelativePath=".\lencod\src\cabac.c"> </File> + <File + RelativePath=".\lencod\src\cconv_yuv2rgb.c"> + </File> <File RelativePath=".\lencod\src\configfile.c"> </File> @@ -167,7 +170,10 @@ RelativePath=".\lencod\src\context_ini.c"> </File> <File - RelativePath=".\lencod\src\decoder.c"> + RelativePath=".\lencod\src\errdo.c"> + </File> + <File + RelativePath=".\lencod\src\errdo_mc_prediction.c"> </File> <File RelativePath=".\lencod\src\explicit_gop.c"> @@ -187,6 +193,18 @@ <File RelativePath=".\lencod\src\img_chroma.c"> </File> + <File + RelativePath=".\lencod\src\img_dist_ms_ssim.c"> + </File> + <File + RelativePath=".\lencod\src\img_dist_snr.c"> + </File> + <File + RelativePath=".\lencod\src\img_dist_ssim.c"> + </File> + <File + RelativePath=".\lencod\src\img_distortion.c"> + </File> <File RelativePath=".\lencod\src\img_luma.c"> </File> @@ -277,6 +295,9 @@ <File RelativePath=".\lencod\src\parsetcommon.c"> </File> + <File + RelativePath=".\lencod\src\q_around.c"> + </File> <File RelativePath=".\lencod\src\q_matrix.c"> </File> @@ -307,6 +328,18 @@ <File RelativePath=".\lencod\src\quant8x8_trellis.c"> </File> + <File + RelativePath=".\lencod\src\quantChroma.c"> + </File> + <File + RelativePath=".\lencod\src\quantChroma_around.c"> + </File> + <File + RelativePath=".\lencod\src\quantChroma_normal.c"> + </File> + <File + RelativePath=".\lencod\src\quantChroma_trellis.c"> + </File> <File RelativePath=".\lencod\src\ratectl.c"> </File> @@ -331,6 +364,9 @@ <File RelativePath=".\lencod\src\refbuf.c"> </File> + <File + RelativePath=".\lencod\src\report.c"> + </File> <File RelativePath=".\lencod\src\rtp.c"> </File> @@ -355,6 +391,12 @@ <File RelativePath=".\lencod\src\weighted_prediction.c"> </File> + <File + RelativePath=".\lencod\src\wp_lms.c"> + </File> + <File + RelativePath=".\lencod\src\wp_mcprec.c"> + </File> </Filter> <Filter Name="Header Files" @@ -371,6 +413,9 @@ <File RelativePath=".\lencod\inc\cabac.h"> </File> + <File + RelativePath=".\lencod\inc\cconv_yuv2rgb.h"> + </File> <File RelativePath=".\lencod\inc\configfile.h"> </File> @@ -392,9 +437,21 @@ <File RelativePath=".\lencod\inc\elements.h"> </File> + <File + RelativePath=".\lencod\inc\enc_statistics.h"> + </File> + <File + RelativePath=".\lencod\inc\errdo.h"> + </File> + <File + RelativePath=".\lencod\inc\errdo_mc_prediction.h"> + </File> <File RelativePath=".\lencod\inc\explicit_gop.h"> </File> + <File + RelativePath=".\lencod\inc\filehandle.h"> + </File> <File RelativePath=".\lencod\inc\fmo.h"> </File> @@ -416,6 +473,21 @@ <File RelativePath=".\lencod\inc\img_chroma.h"> </File> + <File + RelativePath=".\lencod\inc\img_dist_ms_ssim.h"> + </File> + <File + RelativePath=".\lencod\inc\img_dist_snr.h"> + </File> + <File + RelativePath=".\lencod\inc\img_dist_ssim.h"> + </File> + <File + RelativePath=".\lencod\inc\img_dist_wpsnr.h"> + </File> + <File + RelativePath=".\lencod\inc\img_distortion.h"> + </File> <File RelativePath=".\lencod\inc\img_luma.h"> </File> @@ -482,6 +554,9 @@ <File RelativePath=".\lencod\inc\parsetcommon.h"> </File> + <File + RelativePath=".\lencod\inc\q_around.h"> + </File> <File RelativePath=".\lencod\inc\q_matrix.h"> </File> @@ -494,6 +569,9 @@ <File RelativePath=".\lencod\inc\quant8x8.h"> </File> + <File + RelativePath=".\lencod\inc\quantChroma.h"> + </File> <File RelativePath=".\lencod\inc\ratectl.h"> </File> @@ -515,12 +593,18 @@ <File RelativePath=".\lencod\inc\refbuf.h"> </File> + <File + RelativePath=".\lencod\inc\report.h"> + </File> <File RelativePath=".\lencod\inc\rtp.h"> </File> <File RelativePath=".\lencod\inc\sei.h"> </File> + <File + RelativePath=".\lencod\inc\slice.h"> + </File> <File RelativePath=".\lencod\inc\symbol.h"> </File> @@ -530,6 +614,9 @@ <File RelativePath=".\lencod\inc\transform8x8.h"> </File> + <File + RelativePath=".\lencod\inc\transform_wavelet.h"> + </File> <File RelativePath=".\lencod\inc\vlc.h"> </File> @@ -539,6 +626,12 @@ <File RelativePath=".\lencod\inc\wp.h"> </File> + <File + RelativePath=".\lencod\inc\wp_lms.h"> + </File> + <File + RelativePath=".\lencod\inc\wp_mcprec.h"> + </File> </Filter> <File RelativePath="bin\encoder.cfg"> diff --git a/lencod_vc8.vcproj b/lencod_vc8.vcproj index ad73ab8..f0bccd3 100644 --- a/lencod_vc8.vcproj +++ b/lencod_vc8.vcproj @@ -1,9 +1,10 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8.00" + Version="8,00" Name="lencod" ProjectGUID="{9A39F1B7-3DFE-4263-8C02-8070F7D99AFA}" + RootNamespace="lencod" > <Platforms> <Platform @@ -224,6 +225,10 @@ RelativePath=".\lencod\src\cabac.c" > </File> + <File + RelativePath=".\lencod\src\cconv_yuv2rgb.c" + > + </File> <File RelativePath=".\lencod\src\configfile.c" > @@ -237,7 +242,11 @@ > </File> <File - RelativePath=".\lencod\src\decoder.c" + RelativePath=".\lencod\src\errdo.c" + > + </File> + <File + RelativePath=".\lencod\src\errdo_mc_prediction.c" > </File> <File @@ -264,6 +273,22 @@ RelativePath=".\lencod\src\img_chroma.c" > </File> + <File + RelativePath=".\lencod\src\img_dist_ms_ssim.c" + > + </File> + <File + RelativePath=".\lencod\src\img_dist_snr.c" + > + </File> + <File + RelativePath=".\lencod\src\img_dist_ssim.c" + > + </File> + <File + RelativePath=".\lencod\src\img_distortion.c" + > + </File> <File RelativePath=".\lencod\src\img_luma.c" > @@ -384,6 +409,10 @@ RelativePath=".\lencod\src\parsetcommon.c" > </File> + <File + RelativePath=".\lencod\src\q_around.c" + > + </File> <File RelativePath=".\lencod\src\q_matrix.c" > @@ -424,6 +453,22 @@ RelativePath=".\lencod\src\quant8x8_trellis.c" > </File> + <File + RelativePath=".\lencod\src\quantChroma.c" + > + </File> + <File + RelativePath=".\lencod\src\quantChroma_around.c" + > + </File> + <File + RelativePath=".\lencod\src\quantChroma_normal.c" + > + </File> + <File + RelativePath=".\lencod\src\quantChroma_trellis.c" + > + </File> <File RelativePath=".\lencod\src\ratectl.c" > @@ -456,6 +501,10 @@ RelativePath=".\lencod\src\refbuf.c" > </File> + <File + RelativePath=".\lencod\src\report.c" + > + </File> <File RelativePath=".\lencod\src\rtp.c" > @@ -488,6 +537,14 @@ RelativePath=".\lencod\src\weighted_prediction.c" > </File> + <File + RelativePath=".\lencod\src\wp_lms.c" + > + </File> + <File + RelativePath=".\lencod\src\wp_mcprec.c" + > + </File> </Filter> <Filter Name="Header Files" @@ -509,6 +566,10 @@ RelativePath=".\lencod\inc\cabac.h" > </File> + <File + RelativePath=".\lencod\inc\cconv_yuv2rgb.h" + > + </File> <File RelativePath=".\lencod\inc\configfile.h" > @@ -537,10 +598,26 @@ RelativePath=".\lencod\inc\elements.h" > </File> + <File + RelativePath=".\lencod\inc\enc_statistics.h" + > + </File> + <File + RelativePath=".\lencod\inc\errdo.h" + > + </File> + <File + RelativePath=".\lencod\inc\errdo_mc_prediction.h" + > + </File> <File RelativePath=".\lencod\inc\explicit_gop.h" > </File> + <File + RelativePath=".\lencod\inc\filehandle.h" + > + </File> <File RelativePath=".\lencod\inc\fmo.h" > @@ -570,11 +647,27 @@ > </File> <File - RelativePath=".\lencod\inc\img_luma.h" + RelativePath=".\lencod\inc\img_dist_ms_ssim.h" + > + </File> + <File + RelativePath=".\lencod\inc\img_dist_snr.h" + > + </File> + <File + RelativePath=".\lencod\inc\img_dist_ssim.h" + > + </File> + <File + RelativePath=".\lencod\inc\img_dist_wpsnr.h" + > + </File> + <File + RelativePath=".\lencod\inc\img_distortion.h" > </File> <File - RelativePath=".\lencod\inc\img_predblk.h" + RelativePath=".\lencod\inc\img_luma.h" > </File> <File @@ -661,6 +754,10 @@ RelativePath=".\lencod\inc\parsetcommon.h" > </File> + <File + RelativePath=".\lencod\inc\q_around.h" + > + </File> <File RelativePath=".\lencod\inc\q_matrix.h" > @@ -677,6 +774,10 @@ RelativePath=".\lencod\inc\quant8x8.h" > </File> + <File + RelativePath=".\lencod\inc\quantChroma.h" + > + </File> <File RelativePath=".\lencod\inc\ratectl.h" > @@ -705,6 +806,10 @@ RelativePath=".\lencod\inc\refbuf.h" > </File> + <File + RelativePath=".\lencod\inc\report.h" + > + </File> <File RelativePath=".\lencod\inc\rtp.h" > @@ -713,6 +818,10 @@ RelativePath=".\lencod\inc\sei.h" > </File> + <File + RelativePath=".\lencod\inc\slice.h" + > + </File> <File RelativePath=".\lencod\inc\symbol.h" > @@ -725,6 +834,10 @@ RelativePath=".\lencod\inc\transform8x8.h" > </File> + <File + RelativePath=".\lencod\inc\transform_wavelet.h" + > + </File> <File RelativePath=".\lencod\inc\vlc.h" > @@ -737,6 +850,14 @@ RelativePath=".\lencod\inc\wp.h" > </File> + <File + RelativePath=".\lencod\inc\wp_lms.h" + > + </File> + <File + RelativePath=".\lencod\inc\wp_mcprec.h" + > + </File> </Filter> <File RelativePath="bin\encoder.cfg" -- GitLab