diff options
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src')
54 files changed, 9187 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c new file mode 100644 index 0000000..f4e36ad --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CAVLCTables.c @@ -0,0 +1,703 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_CAVLCTables.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * CAVLC tables for H.264 + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM_Bitstream.h" +#include "armVC.h" +#include "armVCM4P10_CAVLCTables.h" + +/* Tables mapping a code to TrailingOnes and TotalCoeff */ + +const OMX_U8 armVCM4P10_CAVLCTrailingOnes[62] = { + 0, + 0, 1, + 0, 1, 2, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3, + 0, 1, 2, 3 +}; + +const OMX_U8 armVCM4P10_CAVLCTotalCoeff[62] = { + 0, + 1, 1, + 2, 2, 2, + 3, 3, 3, 3, + 4, 4, 4, 4, + 5, 5, 5, 5, + 6, 6, 6, 6, + 7, 7, 7, 7, + 8, 8, 8, 8, + 9, 9, 9, 9, + 10, 10, 10, 10, + 11, 11, 11, 11, + 12, 12, 12, 12, + 13, 13, 13, 13, + 14, 14, 14, 14, + 15, 15, 15, 15, + 16, 16, 16, 16 +}; + +static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken0[63] = { + { 1, 0x0001 }, + { 6, 0x0005 }, + { 2, 0x0001 }, + { 8, 0x0007 }, + { 6, 0x0004 }, + { 3, 0x0001 }, + { 9, 0x0007 }, + { 8, 0x0006 }, + { 7, 0x0005 }, + { 5, 0x0003 }, + { 10, 0x0007 }, + { 9, 0x0006 }, + { 8, 0x0005 }, + { 6, 0x0003 }, + { 11, 0x0007 }, + { 10, 0x0006 }, + { 9, 0x0005 }, + { 7, 0x0004 }, + { 13, 0x000f }, + { 11, 0x0006 }, + { 10, 0x0005 }, + { 8, 0x0004 }, + { 13, 0x000b }, + { 13, 0x000e }, + { 11, 0x0005 }, + { 9, 0x0004 }, + { 13, 0x0008 }, + { 13, 0x000a }, + { 13, 0x000d }, + { 10, 0x0004 }, + { 14, 0x000f }, + { 14, 0x000e }, + { 13, 0x0009 }, + { 11, 0x0004 }, + { 14, 0x000b }, + { 14, 0x000a }, + { 14, 0x000d }, + { 13, 0x000c }, + { 15, 0x000f }, + { 15, 0x000e }, + { 14, 0x0009 }, + { 14, 0x000c }, + { 15, 0x000b }, + { 15, 0x000a }, + { 15, 0x000d }, + { 14, 0x0008 }, + { 16, 0x000f }, + { 15, 0x0001 }, + { 15, 0x0009 }, + { 15, 0x000c }, + { 16, 0x000b }, + { 16, 0x000e }, + { 16, 0x000d }, + { 15, 0x0008 }, + { 16, 0x0007 }, + { 16, 0x000a }, + { 16, 0x0009 }, + { 16, 0x000c }, + { 16, 0x0004 }, + { 16, 0x0006 }, + { 16, 0x0005 }, + { 16, 0x0008 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken1[63] = { + { 2, 0x0003 }, + { 6, 0x000b }, + { 2, 0x0002 }, + { 6, 0x0007 }, + { 5, 0x0007 }, + { 3, 0x0003 }, + { 7, 0x0007 }, + { 6, 0x000a }, + { 6, 0x0009 }, + { 4, 0x0005 }, + { 8, 0x0007 }, + { 6, 0x0006 }, + { 6, 0x0005 }, + { 4, 0x0004 }, + { 8, 0x0004 }, + { 7, 0x0006 }, + { 7, 0x0005 }, + { 5, 0x0006 }, + { 9, 0x0007 }, + { 8, 0x0006 }, + { 8, 0x0005 }, + { 6, 0x0008 }, + { 11, 0x000f }, + { 9, 0x0006 }, + { 9, 0x0005 }, + { 6, 0x0004 }, + { 11, 0x000b }, + { 11, 0x000e }, + { 11, 0x000d }, + { 7, 0x0004 }, + { 12, 0x000f }, + { 11, 0x000a }, + { 11, 0x0009 }, + { 9, 0x0004 }, + { 12, 0x000b }, + { 12, 0x000e }, + { 12, 0x000d }, + { 11, 0x000c }, + { 12, 0x0008 }, + { 12, 0x000a }, + { 12, 0x0009 }, + { 11, 0x0008 }, + { 13, 0x000f }, + { 13, 0x000e }, + { 13, 0x000d }, + { 12, 0x000c }, + { 13, 0x000b }, + { 13, 0x000a }, + { 13, 0x0009 }, + { 13, 0x000c }, + { 13, 0x0007 }, + { 14, 0x000b }, + { 13, 0x0006 }, + { 13, 0x0008 }, + { 14, 0x0009 }, + { 14, 0x0008 }, + { 14, 0x000a }, + { 13, 0x0001 }, + { 14, 0x0007 }, + { 14, 0x0006 }, + { 14, 0x0005 }, + { 14, 0x0004 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken2[63] = { + { 4, 0x000f }, + { 6, 0x000f }, + { 4, 0x000e }, + { 6, 0x000b }, + { 5, 0x000f }, + { 4, 0x000d }, + { 6, 0x0008 }, + { 5, 0x000c }, + { 5, 0x000e }, + { 4, 0x000c }, + { 7, 0x000f }, + { 5, 0x000a }, + { 5, 0x000b }, + { 4, 0x000b }, + { 7, 0x000b }, + { 5, 0x0008 }, + { 5, 0x0009 }, + { 4, 0x000a }, + { 7, 0x0009 }, + { 6, 0x000e }, + { 6, 0x000d }, + { 4, 0x0009 }, + { 7, 0x0008 }, + { 6, 0x000a }, + { 6, 0x0009 }, + { 4, 0x0008 }, + { 8, 0x000f }, + { 7, 0x000e }, + { 7, 0x000d }, + { 5, 0x000d }, + { 8, 0x000b }, + { 8, 0x000e }, + { 7, 0x000a }, + { 6, 0x000c }, + { 9, 0x000f }, + { 8, 0x000a }, + { 8, 0x000d }, + { 7, 0x000c }, + { 9, 0x000b }, + { 9, 0x000e }, + { 8, 0x0009 }, + { 8, 0x000c }, + { 9, 0x0008 }, + { 9, 0x000a }, + { 9, 0x000d }, + { 8, 0x0008 }, + { 10, 0x000d }, + { 9, 0x0007 }, + { 9, 0x0009 }, + { 9, 0x000c }, + { 10, 0x0009 }, + { 10, 0x000c }, + { 10, 0x000b }, + { 10, 0x000a }, + { 10, 0x0005 }, + { 10, 0x0008 }, + { 10, 0x0007 }, + { 10, 0x0006 }, + { 10, 0x0001 }, + { 10, 0x0004 }, + { 10, 0x0003 }, + { 10, 0x0002 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken3[63] = { + { 6, 0x0003 }, + { 6, 0x0000 }, + { 6, 0x0001 }, + { 6, 0x0004 }, + { 6, 0x0005 }, + { 6, 0x0006 }, + { 6, 0x0008 }, + { 6, 0x0009 }, + { 6, 0x000a }, + { 6, 0x000b }, + { 6, 0x000c }, + { 6, 0x000d }, + { 6, 0x000e }, + { 6, 0x000f }, + { 6, 0x0010 }, + { 6, 0x0011 }, + { 6, 0x0012 }, + { 6, 0x0013 }, + { 6, 0x0014 }, + { 6, 0x0015 }, + { 6, 0x0016 }, + { 6, 0x0017 }, + { 6, 0x0018 }, + { 6, 0x0019 }, + { 6, 0x001a }, + { 6, 0x001b }, + { 6, 0x001c }, + { 6, 0x001d }, + { 6, 0x001e }, + { 6, 0x001f }, + { 6, 0x0020 }, + { 6, 0x0021 }, + { 6, 0x0022 }, + { 6, 0x0023 }, + { 6, 0x0024 }, + { 6, 0x0025 }, + { 6, 0x0026 }, + { 6, 0x0027 }, + { 6, 0x0028 }, + { 6, 0x0029 }, + { 6, 0x002a }, + { 6, 0x002b }, + { 6, 0x002c }, + { 6, 0x002d }, + { 6, 0x002e }, + { 6, 0x002f }, + { 6, 0x0030 }, + { 6, 0x0031 }, + { 6, 0x0032 }, + { 6, 0x0033 }, + { 6, 0x0034 }, + { 6, 0x0035 }, + { 6, 0x0036 }, + { 6, 0x0037 }, + { 6, 0x0038 }, + { 6, 0x0039 }, + { 6, 0x003a }, + { 6, 0x003b }, + { 6, 0x003c }, + { 6, 0x003d }, + { 6, 0x003e }, + { 6, 0x003f }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCCoeffToken4[15] = { + { 2, 0x0001 }, + { 6, 0x0007 }, + { 1, 0x0001 }, + { 6, 0x0004 }, + { 6, 0x0006 }, + { 3, 0x0001 }, + { 6, 0x0003 }, + { 7, 0x0003 }, + { 7, 0x0002 }, + { 6, 0x0005 }, + { 6, 0x0002 }, + { 8, 0x0003 }, + { 8, 0x0002 }, + { 7, 0x0000 }, + { 0, 0x0000 } +}; + + +const ARM_VLC32 *armVCM4P10_CAVLCCoeffTokenTables[5] = { + armVCM4P10_CAVLCCoeffToken0, + armVCM4P10_CAVLCCoeffToken1, + armVCM4P10_CAVLCCoeffToken2, + armVCM4P10_CAVLCCoeffToken3, + armVCM4P10_CAVLCCoeffToken4 +}; + +/* Table for level_prefix */ + +const ARM_VLC32 armVCM4P10_CAVLCLevelPrefix[17] = { + { 1, 1}, + { 2, 1}, + { 3, 1}, + { 4, 1}, + { 5, 1}, + { 6, 1}, + { 7, 1}, + { 8, 1}, + { 9, 1}, + { 10, 1}, + { 11, 1}, + { 12, 1}, + { 13, 1}, + { 14, 1}, + { 15, 1}, + { 16, 1}, + { 0, 0} +}; + +/* Tables for total_zeros */ + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros1[17] = { + { 1, 0x0001 }, + { 3, 0x0003 }, + { 3, 0x0002 }, + { 4, 0x0003 }, + { 4, 0x0002 }, + { 5, 0x0003 }, + { 5, 0x0002 }, + { 6, 0x0003 }, + { 6, 0x0002 }, + { 7, 0x0003 }, + { 7, 0x0002 }, + { 8, 0x0003 }, + { 8, 0x0002 }, + { 9, 0x0003 }, + { 9, 0x0002 }, + { 9, 0x0001 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2[16] = { + { 3, 0x0007 }, + { 3, 0x0006 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 3, 0x0003 }, + { 4, 0x0005 }, + { 4, 0x0004 }, + { 4, 0x0003 }, + { 4, 0x0002 }, + { 5, 0x0003 }, + { 5, 0x0002 }, + { 6, 0x0003 }, + { 6, 0x0002 }, + { 6, 0x0001 }, + { 6, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros3[15] = { + { 4, 0x0005 }, + { 3, 0x0007 }, + { 3, 0x0006 }, + { 3, 0x0005 }, + { 4, 0x0004 }, + { 4, 0x0003 }, + { 3, 0x0004 }, + { 3, 0x0003 }, + { 4, 0x0002 }, + { 5, 0x0003 }, + { 5, 0x0002 }, + { 6, 0x0001 }, + { 5, 0x0001 }, + { 6, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros4[14] = { + { 5, 0x0003 }, + { 3, 0x0007 }, + { 4, 0x0005 }, + { 4, 0x0004 }, + { 3, 0x0006 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 4, 0x0003 }, + { 3, 0x0003 }, + { 4, 0x0002 }, + { 5, 0x0002 }, + { 5, 0x0001 }, + { 5, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros5[13] = { + { 4, 0x0005 }, + { 4, 0x0004 }, + { 4, 0x0003 }, + { 3, 0x0007 }, + { 3, 0x0006 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 3, 0x0003 }, + { 4, 0x0002 }, + { 5, 0x0001 }, + { 4, 0x0001 }, + { 5, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros6[12] = { + { 6, 0x0001 }, + { 5, 0x0001 }, + { 3, 0x0007 }, + { 3, 0x0006 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 3, 0x0003 }, + { 3, 0x0002 }, + { 4, 0x0001 }, + { 3, 0x0001 }, + { 6, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros7[11] = { + { 6, 0x0001 }, + { 5, 0x0001 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 3, 0x0003 }, + { 2, 0x0003 }, + { 3, 0x0002 }, + { 4, 0x0001 }, + { 3, 0x0001 }, + { 6, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros8[10] = { + { 6, 0x0001 }, + { 4, 0x0001 }, + { 5, 0x0001 }, + { 3, 0x0003 }, + { 2, 0x0003 }, + { 2, 0x0002 }, + { 3, 0x0002 }, + { 3, 0x0001 }, + { 6, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros9[9] = { + { 6, 0x0001 }, + { 6, 0x0000 }, + { 4, 0x0001 }, + { 2, 0x0003 }, + { 2, 0x0002 }, + { 3, 0x0001 }, + { 2, 0x0001 }, + { 5, 0x0001 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros10[8] = { + { 5, 0x0001 }, + { 5, 0x0000 }, + { 3, 0x0001 }, + { 2, 0x0003 }, + { 2, 0x0002 }, + { 2, 0x0001 }, + { 4, 0x0001 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros11[7] = { + { 4, 0x0000 }, + { 4, 0x0001 }, + { 3, 0x0001 }, + { 3, 0x0002 }, + { 1, 0x0001 }, + { 3, 0x0003 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros12[6] = { + { 4, 0x0000 }, + { 4, 0x0001 }, + { 2, 0x0001 }, + { 1, 0x0001 }, + { 3, 0x0001 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros13[5] = { + { 3, 0x0000 }, + { 3, 0x0001 }, + { 1, 0x0001 }, + { 2, 0x0001 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros14[4] = { + { 2, 0x0000 }, + { 2, 0x0001 }, + { 1, 0x0001 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros15[3] = { + { 1, 0x0000 }, + { 1, 0x0001 }, + { 0, 0x0000 } +}; + +const ARM_VLC32 *armVCM4P10_CAVLCTotalZeroTables[15] = { + armVCM4P10_CAVLCTotalZeros1, + armVCM4P10_CAVLCTotalZeros2, + armVCM4P10_CAVLCTotalZeros3, + armVCM4P10_CAVLCTotalZeros4, + armVCM4P10_CAVLCTotalZeros5, + armVCM4P10_CAVLCTotalZeros6, + armVCM4P10_CAVLCTotalZeros7, + armVCM4P10_CAVLCTotalZeros8, + armVCM4P10_CAVLCTotalZeros9, + armVCM4P10_CAVLCTotalZeros10, + armVCM4P10_CAVLCTotalZeros11, + armVCM4P10_CAVLCTotalZeros12, + armVCM4P10_CAVLCTotalZeros13, + armVCM4P10_CAVLCTotalZeros14, + armVCM4P10_CAVLCTotalZeros15 +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2x2_1[5] = { + { 1, 1 }, + { 2, 1 }, + { 3, 1 }, + { 3, 0 }, + { 0, 0 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2x2_2[4] = { + { 1, 1 }, + { 2, 1 }, + { 2, 0 }, + { 0, 0 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCTotalZeros2x2_3[3] = { + { 1, 1 }, + { 1, 0 }, + { 0, 0 } +}; + +const ARM_VLC32 *armVCM4P10_CAVLCTotalZeros2x2Tables[3] = { + armVCM4P10_CAVLCTotalZeros2x2_1, + armVCM4P10_CAVLCTotalZeros2x2_2, + armVCM4P10_CAVLCTotalZeros2x2_3 +}; + + +/* Tables for run_before */ + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore1[3] = { + { 1, 0x0001 }, + { 1, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore2[4] = { + { 1, 0x0001 }, + { 2, 0x0001 }, + { 2, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore3[5] = { + { 2, 0x0003 }, + { 2, 0x0002 }, + { 2, 0x0001 }, + { 2, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore4[6] = { + { 2, 0x0003 }, + { 2, 0x0002 }, + { 2, 0x0001 }, + { 3, 0x0001 }, + { 3, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore5[7] = { + { 2, 0x0003 }, + { 2, 0x0002 }, + { 3, 0x0003 }, + { 3, 0x0002 }, + { 3, 0x0001 }, + { 3, 0x0000 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore6[8] = { + { 2, 0x0003 }, + { 3, 0x0000 }, + { 3, 0x0001 }, + { 3, 0x0003 }, + { 3, 0x0002 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 0, 0x0000 } +}; + +static const ARM_VLC32 armVCM4P10_CAVLCRunBefore7[16] = { + { 3, 0x0007 }, + { 3, 0x0006 }, + { 3, 0x0005 }, + { 3, 0x0004 }, + { 3, 0x0003 }, + { 3, 0x0002 }, + { 3, 0x0001 }, + { 4, 0x0001 }, + { 5, 0x0001 }, + { 6, 0x0001 }, + { 7, 0x0001 }, + { 8, 0x0001 }, + { 9, 0x0001 }, + { 10, 0x0001 }, + { 11, 0x0001 }, + { 0, 0x0000 } +}; + +const ARM_VLC32 *armVCM4P10_CAVLCRunBeforeTables[7] = { + armVCM4P10_CAVLCRunBefore1, + armVCM4P10_CAVLCRunBefore2, + armVCM4P10_CAVLCRunBefore3, + armVCM4P10_CAVLCRunBefore4, + armVCM4P10_CAVLCRunBefore5, + armVCM4P10_CAVLCRunBefore6, + armVCM4P10_CAVLCRunBefore7 +}; diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c new file mode 100644 index 0000000..e4bedc2 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_CompareMotionCostToMV.c @@ -0,0 +1,133 @@ +/** + * + * File Name: armVCM4P10_CompareMotionCostToMV.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * Description: + * Contains module for comparing motion vectors and SAD's to decide + * the best MV and SAD + * + */ + +#include "omxtypes.h" +#include "armOMX.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: armVCM4P10_ExpGolBitsUsed + * + * Description: + * Performs calculating Exp-Golomb code length for a given values + * + * Remarks: + * + * Parameters: + * [in] val Signed number for which Exp-Golomb code length has + * to be calculated + * + * Return Value: + * Returns the length of the Exp-Golomb code for val + */ + +static OMX_U16 armVCM4P10_ExpGolBitsUsed (OMX_S16 val) +{ + OMX_U16 sizeCodeNum, codeNum; + + /* Mapping val to codeNum */ + codeNum = armAbs (val); + if (val > 0) + { + codeNum = (2 * codeNum) - 1; + } + else + { + codeNum = 2 * codeNum; + } + + /* Size of the exp-golomb code */ + sizeCodeNum = (2 * armLogSize (codeNum + 1)) - 1; + + return sizeCodeNum; +} + + +/** + * Function: armVCM4P10_CompareMotionCostToMV + * + * Description: + * Performs comparision of motion vectors and Motion cost to decide the + * best MV and best MC + * + * Remarks: + * + * Parameters: + * [in] mvX x coordinate of the candidate motion vector in 1/4 pel units + * [in] mvY y coordinate of the candidate motion vector in 1/4 pel units + * [in] diffMV differential MV + * [in] candSAD Candidate SAD + * [in] bestMV Best MV, contains best MV till the previous interation. + * [in] nLamda Lamda factor; used to compute motion cost + * [in] *pBestCost Contains the current best motion cost. + * [out] *pBestCost pBestCost Motion cost will be associated with the best MV + * after judgement; + * computed as SAD+Lamda*BitsUsedByMV, if the candCost is less + * than the best cost passed then the *pBestCost will be equal to candCost + * [out] bestMV Finally will have the best MV after the judgement. + * + * Return Value: + * OMX_INT -- 1 to indicate that the current motion cost is the best + * 0 to indicate that it is NOT the best motion cost + */ + +OMX_INT armVCM4P10_CompareMotionCostToMV ( + OMX_S16 mvX, + OMX_S16 mvY, + OMXVCMotionVector diffMV, + OMX_INT candSAD, + OMXVCMotionVector *bestMV, + OMX_U32 nLamda, + OMX_S32 *pBestCost +) +{ + OMX_S32 candCost; + OMX_U16 sizeCodeNum; + + sizeCodeNum = armVCM4P10_ExpGolBitsUsed (diffMV.dx); + sizeCodeNum += armVCM4P10_ExpGolBitsUsed (diffMV.dy); + + /* Motion cost = SAD + lamda * ((bitsused(diffMVx) + (bitsused(diffMVy))*/ + candCost = candSAD + (nLamda * sizeCodeNum); + + /* Calculate candCost */ + if (candCost < *pBestCost) + { + *pBestCost = candCost; + bestMV->dx = mvX; + bestMV->dy = mvY; + return 1; + } + if (candCost > *pBestCost) + { + return 0; + } + /* shorter motion vector */ + if ( (mvX * mvX + mvY * mvY) < ((bestMV->dx * bestMV->dx) + (bestMV->dy * bestMV->dy)) ) + { + *pBestCost = candCost; + bestMV->dx = mvX; + bestMV->dy = mvY; + return 1; + } + + return 0; +} + +/*End of File*/ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c new file mode 100644 index 0000000..f4fb1d9 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DeBlockPixel.c @@ -0,0 +1,151 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_DeBlockPixel.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 luma deblock module + * + */ + +#ifdef DEBUG_ARMVCM4P10_DEBLOCKPIXEL +#undef DEBUG_ON +#define DEBUG_ON +#endif /* DEBUG_ARMVCM4P10_DEBLOCKPIXEL */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description + * Deblock one boundary pixel + * + * Parameters: + * [in] pQ0 Pointer to pixel q0 + * [in] Step Step between pixels q0 and q1 + * [in] tC0 Edge threshold value + * [in] alpha alpha threshold value + * [in] beta beta threshold value + * [in] bS deblocking strength + * [in] ChromaFlag True for chroma blocks + * [out] pQ0 Deblocked pixels + * + */ + +void armVCM4P10_DeBlockPixel( + OMX_U8 *pQ0, /* pointer to the pixel q0 */ + int Step, /* step between pixels q0 and q1 */ + int tC0, /* edge threshold value */ + int alpha, /* alpha */ + int beta, /* beta */ + int bS, /* deblocking strength */ + int ChromaFlag +) +{ + int p3, p2, p1, p0, q0, q1, q2, q3; + int ap, aq, delta; + + if (bS==0) + { + return; + } + + p3 = pQ0[-4*Step]; + p2 = pQ0[-3*Step]; + p1 = pQ0[-2*Step]; + p0 = pQ0[-1*Step]; + q0 = pQ0[ 0*Step]; + q1 = pQ0[ 1*Step]; + q2 = pQ0[ 2*Step]; + q3 = pQ0[ 3*Step]; + + if (armAbs(p0-q0)>=alpha || armAbs(p1-p0)>=beta || armAbs(q1-q0)>=beta) + { + DEBUG_PRINTF_10("DeBlockPixel: %02x %02x %02x %02x | %02x %02x %02x %02x alpha=%d beta=%d\n", + p3, p2, p1, p0, q0, q1, q2, q3, alpha, beta); + return; + } + + ap = armAbs(p2 - p0); + aq = armAbs(q2 - q0); + + if (bS < 4) + { + int tC = tC0; + + if (ChromaFlag) + { + tC++; + } + else + { + if (ap < beta) + { + tC++; + } + if (aq < beta) + { + tC++; + } + } + + delta = (((q0-p0)<<2) + (p1-q1) + 4) >> 3; + delta = armClip(-tC, tC, delta); + + pQ0[-1*Step] = (OMX_U8)armClip(0, 255, p0 + delta); + pQ0[ 0*Step] = (OMX_U8)armClip(0, 255, q0 - delta); + + if (ChromaFlag==0 && ap<beta) + { + delta = (p2 + ((p0+q0+1)>>1) - (p1<<1))>>1; + delta = armClip(-tC0, tC0, delta); + pQ0[-2*Step] = (OMX_U8)(p1 + delta); + } + + if (ChromaFlag==0 && aq<beta) + { + delta = (q2 + ((p0+q0+1)>>1) - (q1<<1))>>1; + delta = armClip(-tC0, tC0, delta); + pQ0[ 1*Step] = (OMX_U8)(q1 + delta); + } + } + else /* bS==4 */ + { + if (ChromaFlag==0 && ap<beta && armAbs(p0-q0)<((alpha>>2)+2)) + { + pQ0[-1*Step] = (OMX_U8)((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3); + pQ0[-2*Step] = (OMX_U8)((p2 + p1 + p0 + q0 + 2)>>2); + pQ0[-3*Step] = (OMX_U8)((2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3); + } + else + { + pQ0[-1*Step] = (OMX_U8)((2*p1 + p0 + q1 + 2)>>2); + } + + if (ChromaFlag==0 && aq<beta && armAbs(p0-q0)<((alpha>>2)+2)) + { + pQ0[ 0*Step] = (OMX_U8)((q2 + 2*q1 + 2*q0 + 2*p0 + p1 + 4)>>3); + pQ0[ 1*Step] = (OMX_U8)((q2 + q1 + p0 + q0 + 2)>>2); + pQ0[ 2*Step] = (OMX_U8)((2*q3 + 3*q2 + q1 + q0 + p0 + 4)>>3); + } + else + { + pQ0[ 0*Step] = (OMX_U8)((2*q1 + q0 + p1 + 2)>>2); + } + } + + DEBUG_PRINTF_13("DeBlockPixel: %02x %02x %02x %02x | %02x %02x %02x %02x bS=%d -> %02x %02x %02x %02x\n", + p3, p2, p1, p0, q0, q1, q2, q3, bS, + pQ0[-2*Step], pQ0[-1*Step],pQ0[0*Step],pQ0[1*Step]); + +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c new file mode 100644 index 0000000..7616add --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c @@ -0,0 +1,267 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_DecodeCoeffsToPair.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 decode coefficients module + * + */ + +#ifdef DEBUG_ARMVCM4P10_DECODECOEFFSTOPAIR +#undef DEBUG_ON +#define DEBUG_ON +#endif + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armCOMM_Bitstream.h" +#include "armVCM4P10_CAVLCTables.h" + +/* 4x4 DeZigZag table */ + +static const OMX_U8 armVCM4P10_ZigZag[16] = +{ + 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 +}; + +/* + * Description: + * This function perform the work required by the OpenMAX + * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair. + * Since most of the code is common we share it here. + * + * Parameters: + * [in] ppBitStream Double pointer to current byte in bit stream buffer + * [in] pOffset Pointer to current bit position in the byte pointed + * to by *ppBitStream + * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current + * block (4,15 or 16) + * [in] nTable Table number (0 to 4) according to the five columns + * of Table 9-5 in the H.264 spec + * [out] ppBitStream *ppBitStream is updated after each block is decoded + * [out] pOffset *pOffset is updated after each block is decoded + * [out] pNumCoeff Pointer to the number of nonzero coefficients in + * this block + * [out] ppPosCoefbuf Double pointer to destination residual + * coefficient-position pair buffer + * Return Value: + * Standard omxError result. See enumeration for possible result codes. + + */ + +OMXResult armVCM4P10_DecodeCoeffsToPair( + const OMX_U8** ppBitStream, + OMX_S32* pOffset, + OMX_U8* pNumCoeff, + OMX_U8 **ppPosCoefbuf, + OMX_INT nTable, + OMX_INT sMaxNumCoeff + ) +{ + int CoeffToken, TotalCoeff, TrailingOnes; + int Level, LevelCode, LevelPrefix, LevelSuffix, LevelSuffixSize; + int SuffixLength, Run, ZerosLeft,CoeffNum; + int i, Flags; + OMX_U8 *pPosCoefbuf = *ppPosCoefbuf; + OMX_S16 pLevel[16]; + OMX_U8 pRun[16]; + + CoeffToken = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCCoeffTokenTables[nTable]); + armRetDataErrIf(CoeffToken == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); + + TrailingOnes = armVCM4P10_CAVLCTrailingOnes[CoeffToken]; + TotalCoeff = armVCM4P10_CAVLCTotalCoeff[CoeffToken]; + *pNumCoeff = (OMX_U8)TotalCoeff; + + DEBUG_PRINTF_2("TotalCoeff = %d, TrailingOnes = %d\n", TotalCoeff, TrailingOnes); + + if (TotalCoeff == 0) + { + /* Nothing to do */ + return OMX_Sts_NoErr; + } + + /* Decode trailing ones */ + for (i=TotalCoeff-1; i>=TotalCoeff-TrailingOnes; i--) + { + if (armGetBits(ppBitStream, pOffset, 1)) + { + Level = -1; + } + else + { + Level = +1; + } + pLevel[i] = (OMX_S16)Level; + + DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]); + } + + /* Decode (non zero) level values */ + SuffixLength = 0; + if (TotalCoeff>10 && TrailingOnes<3) + { + SuffixLength=1; + } + for ( ; i>=0; i--) + { + LevelPrefix = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCLevelPrefix); + armRetDataErrIf(LevelPrefix == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); + + LevelSuffixSize = SuffixLength; + if (LevelPrefix==14 && SuffixLength==0) + { + LevelSuffixSize = 4; + } + if (LevelPrefix==15) + { + LevelSuffixSize = 12; + } + + LevelSuffix = 0; + if (LevelSuffixSize > 0) + { + LevelSuffix = armGetBits(ppBitStream, pOffset, LevelSuffixSize); + } + + LevelCode = (LevelPrefix << SuffixLength) + LevelSuffix; + + + if (LevelPrefix==15 && SuffixLength==0) + { + LevelCode += 15; + } + + /* LevelCode = 2*(magnitude-1) + sign */ + + if (i==TotalCoeff-1-TrailingOnes && TrailingOnes<3) + { + /* Level magnitude can't be 1 */ + LevelCode += 2; + } + if (LevelCode & 1) + { + /* 2a+1 maps to -a-1 */ + Level = (-LevelCode-1)>>1; + } + else + { + /* 2a+0 maps to +a+1 */ + Level = (LevelCode+2)>>1; + } + pLevel[i] = (OMX_S16)Level; + + DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]); + + if (SuffixLength==0) + { + SuffixLength=1; + } + if ( ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6 ) + { + SuffixLength++; + } + } + + /* Decode run values */ + ZerosLeft = 0; + if (TotalCoeff < sMaxNumCoeff) + { + /* Decode TotalZeros VLC */ + if (sMaxNumCoeff==4) + { + ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeros2x2Tables[TotalCoeff-1]); + armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err); + } + else + { + ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeroTables[TotalCoeff-1]); + armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err); + } + } + + DEBUG_PRINTF_1("TotalZeros = %d\n", ZerosLeft); + + CoeffNum=ZerosLeft+TotalCoeff-1; + + for (i=TotalCoeff-1; i>0; i--) + { + Run = 0; + if (ZerosLeft > 0) + { + int Table = ZerosLeft; + if (Table > 6) + { + Table = 7; + } + Run = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCRunBeforeTables[Table-1]); + armRetDataErrIf(Run == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); + } + pRun[i] = (OMX_U8)Run; + + DEBUG_PRINTF_2("Run[%d] = %d\n", i, pRun[i]); + + ZerosLeft -= Run; + } + pRun[0] = (OMX_U8)ZerosLeft; + + DEBUG_PRINTF_1("Run[0] = %d\n", pRun[i]); + + + /* Fill in coefficients */ + + if (sMaxNumCoeff==15) + { + CoeffNum++; /* Skip the DC position */ + } + + /*for (i=0;i<TotalCoeff;i++) + CoeffNum += pRun[i]+1;*/ + + for (i=(TotalCoeff-1); i>=0; i--) + { + /*CoeffNum += pRun[i]+1;*/ + Level = pLevel[i]; + + DEBUG_PRINTF_2("Coef[%d] = %d\n", CoeffNum, Level); + + Flags = CoeffNum; + CoeffNum -= (pRun[i]+1); + if (sMaxNumCoeff>4) + { + /* Perform 4x4 DeZigZag */ + Flags = armVCM4P10_ZigZag[Flags]; + } + if (i==0) + { + /* End of block flag */ + Flags += 0x20; + } + if (Level<-128 || Level>127) + { + /* Overflow flag */ + Flags += 0x10; + } + + *pPosCoefbuf++ = (OMX_U8)(Flags); + *pPosCoefbuf++ = (OMX_U8)(Level & 0xFF); + if (Flags & 0x10) + { + *pPosCoefbuf++ = (OMX_U8)(Level>>8); + } + } + + *ppPosCoefbuf = pPosCoefbuf; + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c new file mode 100644 index 0000000..d9c2541 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DequantTables.c @@ -0,0 +1,45 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_DequantTables.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize tables + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" +#include "armVC.h" + + +const OMX_U8 armVCM4P10_PosToVCol4x4[16] = +{ + 0, 2, 0, 2, + 2, 1, 2, 1, + 0, 2, 0, 2, + 2, 1, 2, 1 +}; + +const OMX_U8 armVCM4P10_PosToVCol2x2[4] = +{ + 0, 2, + 2, 1 +}; + +const OMX_U8 armVCM4P10_VMatrix[6][3] = +{ + { 10, 16, 13 }, + { 11, 18, 14 }, + { 13, 20, 16 }, + { 14, 23, 18 }, + { 16, 25, 20 }, + { 18, 29, 23 } +}; diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c new file mode 100644 index 0000000..93d54c3 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_FwdTransformResidual4x4.c @@ -0,0 +1,78 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_FwdTransformResidual4x4.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 transform module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Forward Transform Residual 4x4 Coefficients + * + * Parameters: + * [in] pSrc Source 4x4 block + * [out] pDst Destination 4x4 block + * + */ +void armVCM4P10_FwdTransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc) +{ + int i; + + /* Transform rows */ + for (i=0; i<16; i+=4) + { + int d0 = pSrc[i+0]; + int d1 = pSrc[i+1]; + int d2 = pSrc[i+2]; + int d3 = pSrc[i+3]; + int e0 = d0 + d3; + int e1 = d0 - d3; + int e2 = d1 + d2; + int e3 = d1 - d2; + int f0 = e0 + e2; + int f1 = (e1 << 1) + e3; + int f2 = e0 - e2; + int f3 = e1 - (e3 << 1); + pDst[i+0] = (OMX_S16)f0; + pDst[i+1] = (OMX_S16)f1; + pDst[i+2] = (OMX_S16)f2; + pDst[i+3] = (OMX_S16)f3; + } + + /* Transform columns */ + for (i=0; i<4; i++) + { + int f0 = pDst[i+0]; + int f1 = pDst[i+4]; + int f2 = pDst[i+8]; + int f3 = pDst[i+12]; + int g0 = f0 + f3; + int g1 = f0 - f3; + int g2 = f1 + f2; + int g3 = f1 - f2; + int h0 = g0 + g2; + int h1 = (g1 << 1) + g3; + int h2 = g0 - g2; + int h3 = g1 - (g3 << 1); + pDst[i+0] = (OMX_S16) h0; + pDst[i+4] = (OMX_S16) h1; + pDst[i+8] = (OMX_S16) h2; + pDst[i+12] = (OMX_S16) h3; + } +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c new file mode 100644 index 0000000..8732f4f --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfDiag_Luma.c @@ -0,0 +1,106 @@ +/** + * + * File Name: armVCM4P10_InterpolateHalfDiag_Luma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This functions will help to calculate Half Pel luma interpolation + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + + +/** + * Function: armVCM4P10_InterpolateHalfDiag_Luma + * + * Description: + * This function performs interpolation for (1/2, 1/2) positions + * around a full-pel position. + * + * Remarks: + * + * [in] pSrc Pointer to top-left corner of block used to interpolate + * in the reconstructed frame plane + * [in] iSrcStep Step of the source buffer. + * [in] iDstStep Step of the destination(interpolation) buffer. + * [in] iWidth Width of the current block + * [in] iHeight Height of the current block + * [out] pDst Pointer to the interpolation buffer of the (1/2,1/2)-pel + * + * Return Value: + * Standard OMXResult value. + * + */ + +OMXResult armVCM4P10_InterpolateHalfDiag_Luma( + const OMX_U8* pSrc, + OMX_U32 iSrcStep, + OMX_U8* pDst, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight +) +{ + OMX_S32 HalfCoeff, pos; + OMX_S16 Buf [21 * 16]; /* 21 rows by 16 pixels per row */ + OMX_U32 y, x; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + + /* + * Intermediate values will be 1/2 pel at Horizontal direction + * Starting at (0.5, -2) at top extending to (0.5, height + 3) at bottom + * Buf contains a 2D array of size (iWidth)X(iHeight + 5) + */ + for (y = 0; y < iHeight + 5; y++) + { + for (x = 0; x < iWidth; x++) + { + pos = (y-2) * iSrcStep + x; + HalfCoeff = + pSrc [pos - 2] - + 5 * pSrc [pos - 1] + + 20 * pSrc [pos] + + 20 * pSrc [pos + 1] - + 5 * pSrc [pos + 2] + + pSrc [pos + 3]; + Buf [y * iWidth + x] = (OMX_S16)HalfCoeff; + } /* x */ + } /* y */ + + /* Vertical interpolate */ + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + pos = y * iWidth + x; + HalfCoeff = + Buf [pos] - + 5 * Buf [pos + 1 * iWidth] + + 20 * Buf [pos + 2 * iWidth] + + 20 * Buf [pos + 3 * iWidth] - + 5 * Buf [pos + 4 * iWidth] + + Buf [pos + 5 * iWidth]; + + HalfCoeff = (HalfCoeff + 512) >> 10; + HalfCoeff = armClip(0, 255, HalfCoeff); + + pDst [y * iDstStep + x] = (OMX_U8) HalfCoeff; + } + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c new file mode 100644 index 0000000..89c0079 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfHor_Luma.c @@ -0,0 +1,82 @@ +/** + * + * File Name: armVCM4P10_InterpolateHalfHor_Luma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This functions will help to calculate Half Pel luma interpolation + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: armVCM4P10_InterpolateHalfHor_Luma + * + * Description: + * This function performs interpolation for horizontal 1/2-pel positions + * + * Remarks: + * + * [in] pSrc Pointer to top-left corner of block used to interpolate + * in the reconstructed frame plane + * [in] iSrcStep Step of the source buffer. + * [in] iDstStep Step of the destination(interpolation) buffer. + * [in] iWidth Width of the current block + * [in] iHeight Height of the current block + * [out] pDst Pointer to the interpolation buffer of the 1/2-pel + * + * Return Value: + * Standard OMXResult value. + * + */ + +OMXResult armVCM4P10_InterpolateHalfHor_Luma( + const OMX_U8* pSrc, + OMX_U32 iSrcStep, + OMX_U8* pDst, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight +) +{ + OMX_INT x, y; + OMX_S32 HalfCoeff, pos; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + pos = y * iSrcStep + x; + HalfCoeff = + pSrc [pos - 2] - + 5 * pSrc [pos - 1] + + 20 * pSrc [pos] + + 20 * pSrc [pos + 1] - + 5 * pSrc [pos + 2] + + pSrc [pos + 3]; + + HalfCoeff = (HalfCoeff + 16) >> 5; + HalfCoeff = armClip(0, 255, HalfCoeff); + + pDst [y * iDstStep + x] = HalfCoeff; + } /* x */ + } /* y */ + + return OMX_Sts_NoErr; +} + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c new file mode 100644 index 0000000..f7ecfc5 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_InterpolateHalfVer_Luma.c @@ -0,0 +1,84 @@ +/** + * + * File Name: armVCM4P10_InterpolateHalfVer_Luma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This functions will help to calculate Half Pel luma interpolation + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: armVCM4P10_InterpolateHalfVer_Luma + * + * Description: + * This function performs interpolation for vertical 1/2-pel positions + * around a full-pel position. + * + * Remarks: + * + * [in] pSrc Pointer to top-left corner of block used to interpolate + * in the reconstructed frame plane + * [in] iSrcStep Step of the source buffer. + * [in] iDstStep Step of the destination(interpolation) buffer. + * [in] iWidth Width of the current block + * [in] iHeight Height of the current block + * [out] pDst Pointer to the interpolation buffer of the 1/2-pel + * + * Return Value: + * Standard OMXResult value. + * + */ + +OMXResult armVCM4P10_InterpolateHalfVer_Luma( + const OMX_U8* pSrc, + OMX_U32 iSrcStep, + OMX_U8* pDst, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight +) +{ + OMX_S32 HalfCoeff, pos; + OMX_INT y, x; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + + + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + pos = y * iSrcStep + x; + HalfCoeff = + pSrc [pos - 2 * iSrcStep] - + 5 * pSrc [pos - 1 * iSrcStep] + + 20 * pSrc [pos] + + 20 * pSrc [pos + 1 * iSrcStep] - + 5 * pSrc [pos + 2 * iSrcStep] + + pSrc [pos + 3 * iSrcStep]; + + HalfCoeff = (HalfCoeff + 16) >> 5; + HalfCoeff = armClip(0, 255, HalfCoeff); + + pDst [y * iDstStep + x] = (OMX_U8) HalfCoeff; + } + } + + return OMX_Sts_NoErr; +} + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c new file mode 100644 index 0000000..1507d23 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Chroma.c @@ -0,0 +1,109 @@ +/** + * + * File Name: armVCM4P10_Interpolate_Chroma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate interpolation for chroma components + * + */ + +#include "omxtypes.h" +#include "armOMX.h" + +#include "armCOMM.h" + +/** + * Function: armVCM4P10_Interpolate_Chroma + * + * Description: + * This function performs interpolation for chroma components. + * + * Remarks: + * + * [in] pSrc Pointer to top-left corner of block used to + * interpolate in the reconstructed frame plane + * [in] iSrcStep Step of the source buffer. + * [in] iDstStep Step of the destination(interpolation) buffer. + * [in] iWidth Width of the current block + * [in] iHeight Height of the current block + * [in] dx Fractional part of horizontal motion vector + * component in 1/8 pixel unit (0~7) + * [in] dy Fractional part of vertical motion vector + * component in 1/8 pixel unit (0~7) + * [out] pDst Pointer to the interpolation buffer + * + * Return Value: + * Standard OMXResult value. + * + */ + OMXResult armVCM4P10_Interpolate_Chroma( + OMX_U8 *pSrc, + OMX_U32 iSrcStep, + OMX_U8 *pDst, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight, + OMX_U32 dx, + OMX_U32 dy +) +{ + OMX_U32 EightMinusdx = 8 - dx; + OMX_U32 EightMinusdy = 8 - dy; + OMX_U32 ACoeff, BCoeff, CCoeff, DCoeff; + OMX_U32 x, y; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(dx > 7, OMX_Sts_BadArgErr) + armRetArgErrIf(dy > 7, OMX_Sts_BadArgErr) + armRetArgErrIf(iSrcStep == 0, OMX_Sts_BadArgErr) + armRetArgErrIf(iDstStep == 0, OMX_Sts_BadArgErr) + armRetArgErrIf(iWidth == 0, OMX_Sts_BadArgErr) + armRetArgErrIf(iHeight == 0, OMX_Sts_BadArgErr) + + /* if fractionl mv is not (0, 0) */ + if (dx != 0 || dy != 0) + { + ACoeff = EightMinusdx * EightMinusdy; + BCoeff = dx * EightMinusdy; + CCoeff = EightMinusdx * dy; + DCoeff = dx * dy; + + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + pDst [y * iDstStep + x] = ( + ACoeff * pSrc [y * iSrcStep + x] + + BCoeff * pSrc [y * iSrcStep + x + 1] + + CCoeff * pSrc [(y + 1) * iSrcStep + x] + + DCoeff * pSrc [(y + 1) * iSrcStep + x + 1] + + 32) >> 6; + } + } + } + else + { + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + pDst [y * iDstStep + x] = pSrc [y * iSrcStep + x]; + } + } + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c new file mode 100644 index 0000000..89978dd --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_Interpolate_Luma.c @@ -0,0 +1,195 @@ +/** + * + * File Name: armVCM4P10_Interpolate_Luma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate interpolation for luma components + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: armM4P10_Copy + * + * Description: + * This function performs copy a block of data from source to destination + * + * Remarks: + * + * [in] pSrc Pointer to top-left corner of block + * [in] iSrcStep Step of the source buffer. + * [in] iDstStep Step of the destination buffer. + * [in] iWidth Width of the current block + * [in] iHeight Height of the current block + * [out] pDst Pointer to the interpolation buffer + * + * Return Value: + * Standard OMXResult value. + * + */ +static OMXResult armM4P10_Copy( + const OMX_U8* pSrc, + OMX_U32 iSrcStep, + OMX_U8* pDst, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight +) +{ + OMX_U32 x, y; + + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + pDst [y * iDstStep + x] = pSrc [y * iSrcStep + x]; + } + } + + return OMX_Sts_NoErr; +} + +/** + * Function: armVCM4P10_Interpolate_Luma + * + * Description: + * This function performs interpolation for luma components. + * + * Remarks: + * + * [in] pSrc Pointer to top-left corner of block used to + * interpolate in the reconstructed frame plane + * [in] iSrcStep Step of the source buffer. + * [in] iDstStep Step of the destination(interpolation) buffer. + * [in] iWidth Width of the current block + * [in] iHeight Height of the current block + * [in] dx Fractional part of horizontal motion vector + * component in 1/4 pixel unit (0~3) + * [in] dy Fractional part of vertical motion vector + * component in 1/4 pixel unit (0~3) + * [out] pDst Pointer to the interpolation buffer + * + * Return Value: + * Standard OMXResult value. + * + */ + + OMXResult armVCM4P10_Interpolate_Luma( + const OMX_U8 *pSrc, + OMX_U32 iSrcStep, + OMX_U8 *pDst, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight, + OMX_U32 dx, + OMX_U32 dy +) +{ + OMX_U8 pBuf1 [16*16]; + const OMX_U8 *pSrcHalfHor = pSrc; + const OMX_U8 *pSrcHalfVer = pSrc; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(dx > 3, OMX_Sts_BadArgErr) + armRetArgErrIf(dy > 3, OMX_Sts_BadArgErr) + + /* Work out positions for half pixel interpolation */ + if (dx == 3) + { + pSrcHalfVer += 1; + } + if (dy == 3) + { + pSrcHalfHor += iSrcStep; + } + + /* Switch on type of pixel + * Pixels are named 'a' to 's' as in the H.264 standard + */ + if (dx == 0 && dy == 0) + { + /* G */ + armM4P10_Copy(pSrc, iSrcStep, pDst, iDstStep, iWidth, iHeight); + } + else if (dy == 0) + { + /* a, b, c */ + armVCM4P10_InterpolateHalfHor_Luma + (pSrcHalfHor, iSrcStep, pDst, iDstStep, iWidth, iHeight); + + if (dx == 1 || dx == 3) + { + armVCCOMM_Average + (pDst, pSrcHalfVer, iDstStep, iSrcStep, pDst, iDstStep, iWidth, iHeight); + } + } + else if (dx == 0) + { + /* d, h, n */ + armVCM4P10_InterpolateHalfVer_Luma + (pSrcHalfVer, iSrcStep, pDst, iDstStep, iWidth, iHeight); + + if (dy == 1 || dy == 3) + { + armVCCOMM_Average + (pDst, pSrcHalfHor, iDstStep, iSrcStep, pDst, iDstStep, iWidth, iHeight); + } + } + else if (dx == 2 || dy == 2) + { + /* j */ + armVCM4P10_InterpolateHalfDiag_Luma + (pSrc, iSrcStep, pDst, iDstStep, iWidth, iHeight); + + if (dx == 1 || dx == 3) + { + /* i, k */ + armVCM4P10_InterpolateHalfVer_Luma + (pSrcHalfVer, iSrcStep, pBuf1, iWidth, iWidth, iHeight); + + armVCCOMM_Average + (pDst, pBuf1, iDstStep, iWidth, pDst, iDstStep, iWidth, iHeight); + } + if (dy == 1 || dy == 3) + { + /* f,q */ + armVCM4P10_InterpolateHalfHor_Luma + (pSrcHalfHor, iSrcStep, pBuf1, iWidth, iWidth, iHeight); + + armVCCOMM_Average + (pDst, pBuf1, iDstStep, iWidth, pDst, iDstStep, iWidth, iHeight); + } + } + else /* dx=1,3 and dy=1,3 */ + { + /* e, g, p, r */ + armVCM4P10_InterpolateHalfHor_Luma + (pSrcHalfHor, iSrcStep, pBuf1, iWidth, iWidth, iHeight); + + armVCM4P10_InterpolateHalfVer_Luma + (pSrcHalfVer, iSrcStep, pDst, iDstStep, iWidth, iHeight); + + armVCCOMM_Average + (pBuf1, pDst, iWidth, iDstStep, pDst, iDstStep, iWidth, iHeight); + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c new file mode 100644 index 0000000..b713073 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_PredictIntraDC4x4.c @@ -0,0 +1,88 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_PredictIntraDC4x4.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 4x4 intra prediction module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Perform DC style intra prediction, averaging upper and left block + * + * Parameters: + * [in] pSrcLeft Pointer to the buffer of 16 left coefficients: + * p[x, y] (x = -1, y = 0..3) + * [in] pSrcAbove Pointer to the buffer of 16 above coefficients: + * p[x,y] (x = 0..3, y = -1) + * [in] leftStep Step of left coefficient buffer + * [in] dstStep Step of the destination buffer + * [in] availability Neighboring 16x16 MB availability flag + * [out] pDst Pointer to the destination buffer + * + * Return Value: + * None + */ + +void armVCM4P10_PredictIntraDC4x4( + const OMX_U8* pSrcLeft, + const OMX_U8 *pSrcAbove, + OMX_U8* pDst, + OMX_INT leftStep, + OMX_INT dstStep, + OMX_S32 availability +) +{ + int x, y, Sum=0, Count = 0; + + if (availability & OMX_VC_LEFT) + { + for (y=0; y<4; y++) + { + Sum += pSrcLeft[y*leftStep]; + } + Count++; + } + if (availability & OMX_VC_UPPER) + { + for (x=0; x<4; x++) + { + Sum += pSrcAbove[x]; + } + Count++; + } + if (Count==0) + { + Sum = 128; + } + else if (Count==1) + { + Sum = (Sum + 2) >> 2; + } + else /* Count = 2 */ + { + Sum = (Sum + 4) >> 3; + } + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = (OMX_U8)Sum; + } + } +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c new file mode 100644 index 0000000..f0b5bb0 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_QuantTables.c @@ -0,0 +1,31 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_QuantTables.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize tables + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" + +const OMX_U32 armVCM4P10_MFMatrix[6][3] = +{ + {13107, 5243, 8066}, + {11916, 4660, 7490}, + {10082, 4194, 6554}, + { 9362, 3647, 5825}, + { 8192, 3355, 5243}, + { 7282, 2893, 4559} +}; diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c new file mode 100644 index 0000000..a41e04b --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_SADQuar.c @@ -0,0 +1,84 @@ +/** + * + * File Name: armVCM4P10_SADQuar.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD of pSrc with average of two Ref blocks + * + */ + +#include "omxtypes.h" +#include "armOMX.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: armVCM4P10_SADQuar + * + * Description: + * This function calculates the SAD between one block (pSrc) and the + * average of the other two (pSrcRef0 and pSrcRef1) + * + * Remarks: + * + * [in] pSrc Pointer to the original block + * [in] pSrcRef0 Pointer to reference block 0 + * [in] pSrcRef1 Pointer to reference block 1 + * [in] iSrcStep Step of the original block buffer + * [in] iRefStep0 Step of reference block 0 + * [in] iRefStep1 Step of reference block 1 + * [in] iHeight Height of the block + * [in] iWidth Width of the block + * [out] pDstSAD Pointer of result SAD + * + * Return Value: + * Standard OMXResult value. + * + */ +OMXResult armVCM4P10_SADQuar( + const OMX_U8* pSrc, + const OMX_U8* pSrcRef0, + const OMX_U8* pSrcRef1, + OMX_U32 iSrcStep, + OMX_U32 iRefStep0, + OMX_U32 iRefStep1, + OMX_U32* pDstSAD, + OMX_U32 iHeight, + OMX_U32 iWidth +) +{ + OMX_INT x, y; + OMX_S32 SAD = 0; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr) + + for (y = 0; y < iHeight; y++) + { + for (x = 0; x < iWidth; x++) + { + SAD += armAbs(pSrc [y * iSrcStep + x] - (( + pSrcRef0 [y * iRefStep0 + x] + + pSrcRef1 [y * iRefStep1 + x] + 1) >> 1)); + } + } + + *pDstSAD = SAD; + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c new file mode 100644 index 0000000..f9f756a --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_TransformResidual4x4.c @@ -0,0 +1,80 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_TransformResidual4x4.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 transform module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Transform Residual 4x4 Coefficients + * + * Parameters: + * [in] pSrc Source 4x4 block + * [out] pDst Destination 4x4 block + * + */ + +void armVCM4P10_TransformResidual4x4(OMX_S16* pDst, OMX_S16 *pSrc) +{ + int i; + + /* Transform rows */ + for (i=0; i<16; i+=4) + { + int d0 = pSrc[i+0]; + int d1 = pSrc[i+1]; + int d2 = pSrc[i+2]; + int d3 = pSrc[i+3]; + int e0 = d0 + d2; + int e1 = d0 - d2; + int e2 = (d1>>1) - d3; + int e3 = d1 + (d3>>1); + int f0 = e0 + e3; + int f1 = e1 + e2; + int f2 = e1 - e2; + int f3 = e0 - e3; + pDst[i+0] = (OMX_S16)f0; + pDst[i+1] = (OMX_S16)f1; + pDst[i+2] = (OMX_S16)f2; + pDst[i+3] = (OMX_S16)f3; + } + + /* Transform columns */ + for (i=0; i<4; i++) + { + int f0 = pDst[i+0]; + int f1 = pDst[i+4]; + int f2 = pDst[i+8]; + int f3 = pDst[i+12]; + int g0 = f0 + f2; + int g1 = f0 - f2; + int g2 = (f1>>1) - f3; + int g3 = f1 + (f3>>1); + int h0 = g0 + g3; + int h1 = g1 + g2; + int h2 = g1 - g2; + int h3 = g0 - g3; + pDst[i+0] = (OMX_S16)((h0+32)>>6); + pDst[i+4] = (OMX_S16)((h1+32)>>6); + pDst[i+8] = (OMX_S16)((h2+32)>>6); + pDst[i+12] = (OMX_S16)((h3+32)>>6); + } +} + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c new file mode 100644 index 0000000..dda49f6 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock2x2.c @@ -0,0 +1,78 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_UnpackBlock2x2.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize and transform helper module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" + +/* + * Description + * Unpack a 2x2 block of coefficient-residual pair values + * + * Parameters: + * [in] ppSrc Double pointer to residual coefficient-position pair + * buffer output by CALVC decoding + * [out] ppSrc *ppSrc is updated to the start of next non empty block + * [out] pDst Pointer to unpacked 4x4 block + */ + +void armVCM4P10_UnpackBlock2x2( + const OMX_U8 **ppSrc, + OMX_S16* pDst +) +{ + const OMX_U8 *pSrc = *ppSrc; + int i; + int Flag, Value; + + for (i=0; i<4; i++) + { + pDst[i] = 0; + } + + do + { + Flag = *pSrc++; + if (Flag & 0x10) + { + /* 16 bit */ + Value = *pSrc++; + Value = Value | ((*pSrc++)<<8); + if (Value & 0x8000) + { + Value -= 0x10000; + } + } + else + { + /* 8 bit */ + Value = *pSrc++; + if (Value & 0x80) + { + Value -= 0x100; + } + } + i = Flag & 15; + pDst[i] = (OMX_S16)Value; + } + while ((Flag & 0x20)==0); + + *ppSrc = pSrc; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c new file mode 100644 index 0000000..3c0dcbd --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_UnpackBlock4x4.c @@ -0,0 +1,78 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_UnpackBlock4x4.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize and transform helper module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" + +/* + * Description + * Unpack a 4x4 block of coefficient-residual pair values + * + * Parameters: + * [in] ppSrc Double pointer to residual coefficient-position pair + * buffer output by CALVC decoding + * [out] ppSrc *ppSrc is updated to the start of next non empty block + * [out] pDst Pointer to unpacked 4x4 block + */ + +void armVCM4P10_UnpackBlock4x4( + const OMX_U8 **ppSrc, + OMX_S16* pDst +) +{ + const OMX_U8 *pSrc = *ppSrc; + int i; + int Flag, Value; + + for (i=0; i<16; i++) + { + pDst[i] = 0; + } + + do + { + Flag = *pSrc++; + if (Flag & 0x10) + { + /* 16 bit */ + Value = *pSrc++; + Value = Value | ((*pSrc++)<<8); + if (Value & 0x8000) + { + Value -= 0x10000; + } + } + else + { + /* 8 bit */ + Value = *pSrc++; + if (Value & 0x80) + { + Value -= 0x100; + } + } + i = Flag & 15; + pDst[i] = (OMX_S16)Value; + } + while ((Flag & 0x20)==0); + + *ppSrc = pSrc; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c new file mode 100644 index 0000000..ac0d523 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_Average_4x.c @@ -0,0 +1,84 @@ +/** + * + * File Name: omxVCM4P10_Average_4x.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate Average of two 4x4 or 4x8 blocks + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_Average_4x (6.3.5.5.3) + * + * Description: + * This function calculates the average of two 4x4, 4x8 blocks. The result + * is rounded according to (a+b+1)/2. + * + * Input Arguments: + * + * pPred0 - Pointer to the top-left corner of reference block 0 + * pPred1 - Pointer to the top-left corner of reference block 1 + * iPredStep0 - Step of reference block 0; must be a multiple of 4. + * iPredStep1 - Step of reference block 1; must be a multiple of 4. + * iDstStep - Step of the destination buffer; must be a multiple of 4. + * iHeight - Height of the blocks; must be either 4 or 8. + * + * Output Arguments: + * + * pDstPred - Pointer to the destination buffer. 4-byte alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pPred0, pPred1, or pDstPred + * - pDstPred is not aligned on a 4-byte boundary + * - iPredStep0 <= 0 or iPredStep0 is not a multiple of 4 + * - iPredStep1 <= 0 or iPredStep1 is not a multiple of 4 + * - iDstStep <= 0 or iDstStep is not a multiple of 4 + * - iHeight is not equal to either 4 or 8 + * + */ + OMXResult omxVCM4P10_Average_4x ( + const OMX_U8* pPred0, + const OMX_U8* pPred1, + OMX_U32 iPredStep0, + OMX_U32 iPredStep1, + OMX_U8* pDstPred, + OMX_U32 iDstStep, + OMX_U32 iHeight +) +{ + /* check for argument error */ + armRetArgErrIf(pPred0 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pPred1 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstPred == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iHeight != 4) && (iHeight != 8), OMX_Sts_BadArgErr) + armRetArgErrIf((iPredStep0 == 0) || (iPredStep0 & 3), OMX_Sts_BadArgErr) + armRetArgErrIf((iPredStep1 == 0) || (iPredStep1 & 3), OMX_Sts_BadArgErr) + armRetArgErrIf((iDstStep == 0) || (iDstStep & 3), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pDstPred), OMX_Sts_BadArgErr) + + return armVCCOMM_Average + (pPred0, pPred1, iPredStep0, iPredStep1, pDstPred, iDstStep, 4, iHeight); +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c new file mode 100644 index 0000000..c490e10 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Half.c @@ -0,0 +1,191 @@ +/** + * + * File Name: omxVCM4P10_BlockMatch_Half.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * Description: + * Contains modules for half pel Block matching, + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + + +/** + * Function: omxVCM4P10_BlockMatch_Half (6.3.5.2.2) + * + * Description: + * Performs a half-pel block match using results from a prior integer search. + * Returns the best MV and associated cost. This function estimates the + * half-pixel motion vector by interpolating the integer resolution motion + * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial + * integer MV is generated externally. The function + * omxVCM4P10_BlockMatch_Integer may be used for integer motion estimation. + * + * Input Arguments: + * + * pSrcOrgY - Pointer to the current position in original picture plane. If + * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, + * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment + * required. + * pSrcRefY - Pointer to the top-left corner of the co-located block in the + * reference picture If iBlockWidth==4, 4-byte alignment + * required. If iBlockWidth==8, 8-byte alignment required. If + * iBlockWidth==16, 16-byte alignment required. + * nSrcOrgStep - Stride of the original picture plane in terms of full + * pixels; must be a multiple of iBlockWidth. + * nSrcRefStep - Stride of the reference picture plane in terms of full + * pixels + * iBlockWidth - Width of the current block in terms of full pixels; must + * be equal to either 4, 8, or 16. + * iBlockHeight - Height of the current block in terms of full pixels; must + * be equal to either 4, 8, or 16. + * nLamda - Lamda factor, used to compute motion cost + * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to + * compute motion cost + * pSrcDstBestMV - The best MV resulting from a prior integer search, + * represented in terms of 1/4-pel units + * + * Output Arguments: + * + * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in + * terms of 1/4-pel units + * pBestCost - Motion cost associated with the best MV; computed as + * SAD+Lamda*BitsUsedByMV + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY, + * pSrcDstBestMV, pMVPred, pBestCost + * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16. + * - Any alignment restrictions are violated + * + */ + +OMXResult omxVCM4P10_BlockMatch_Half( + const OMX_U8* pSrcOrgY, + OMX_S32 nSrcOrgStep, + const OMX_U8* pSrcRefY, + OMX_S32 nSrcRefStep, + OMX_U8 iBlockWidth, + OMX_U8 iBlockHeight, + OMX_U32 nLamda, + const OMXVCMotionVector* pMVPred, + OMXVCMotionVector* pSrcDstBestMV, + OMX_S32* pBestCost +) +{ + /* Definitions and Initializations*/ + OMX_INT candSAD; + OMX_INT fromX, toX, fromY, toY; + /* Offset to the reference at the begining of the bounding box */ + const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; + OMX_S16 x, y; + OMXVCMotionVector diffMV, candMV, integerMV; + OMX_U8 interpolY[256]; + + /* Argument error checks */ + armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); + armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); + + + /* Check for valid region */ + fromX = 1; + toX = 1; + fromY = 1; + toY = 1; + + /* Initialize to max value as a start point */ + *pBestCost = 0x7fffffff; + + integerMV.dx = pSrcDstBestMV->dx; + integerMV.dy = pSrcDstBestMV->dy; + + /* Looping on y- axis */ + for (y = -fromY; y <= toY; y++) + { + /* Looping on x- axis */ + for (x = -fromX; x <= toX; x++) + { + /* Positioning the pointer */ + pTempSrcRefY = pSrcRefY + (nSrcRefStep * (integerMV.dy/4)) + (integerMV.dx/4); + if (x < 0) + { + pTempSrcRefY = pTempSrcRefY + x; + } + if (y < 0) + { + pTempSrcRefY = pTempSrcRefY + (y * nSrcRefStep); + } + pTempSrcOrgY = pSrcOrgY; + + /* Prepare cand MV */ + candMV.dx = integerMV.dx + x * 2; + candMV.dy = integerMV.dy + y * 2; + + /* Interpolate half pel for the current position*/ + armVCM4P10_Interpolate_Luma( + pTempSrcRefY, + nSrcRefStep, + interpolY, + iBlockWidth, + iBlockWidth, + iBlockHeight, + armAbs(x) * 2, + armAbs(y) * 2); + + /* Calculate the SAD */ + armVCCOMM_SAD( + pTempSrcOrgY, + nSrcOrgStep, + interpolY, + iBlockWidth, + &candSAD, + iBlockHeight, + iBlockWidth); + + diffMV.dx = candMV.dx - pMVPred->dx; + diffMV.dy = candMV.dy - pMVPred->dy; + + /* Result calculations */ + armVCM4P10_CompareMotionCostToMV ( + candMV.dx, + candMV.dy, + diffMV, + candSAD, + pSrcDstBestMV, + nLamda, + pBestCost); + + } /* End of x- axis */ + } /* End of y-axis */ + + return OMX_Sts_NoErr; + +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c new file mode 100644 index 0000000..f7764e1 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Integer.c @@ -0,0 +1,196 @@ +/** + * + * File Name: omxVCM4P10_BlockMatch_Integer.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * Description: + * Contains modules for Block matching, a full search algorithm + * is implemented + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1) + * + * Description: + * Performs integer block match. Returns best MV and associated cost. + * + * Input Arguments: + * + * pSrcOrgY - Pointer to the top-left corner of the current block. If + * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, + * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment + * required. + * pSrcRefY - Pointer to the top-left corner of the co-located block in the + * reference picture. If iBlockWidth==4, 4-byte alignment + * required. If iBlockWidth==8, 8-byte alignment required. If + * iBlockWidth==16, 16-byte alignment required. + * nSrcOrgStep - Stride of the original picture plane, expressed in terms + * of integer pixels; must be a multiple of iBlockWidth. + * nSrcRefStep - Stride of the reference picture plane, expressed in terms + * of integer pixels + * pRefRect - pointer to the valid reference rectangle inside the reference + * picture plane + * nCurrPointPos - position of the current block in the current plane + * iBlockWidth - Width of the current block, expressed in terms of integer + * pixels; must be equal to either 4, 8, or 16. + * iBlockHeight - Height of the current block, expressed in terms of + * integer pixels; must be equal to either 4, 8, or 16. + * nLamda - Lamda factor; used to compute motion cost + * pMVPred - Predicted MV; used to compute motion cost, expressed in terms + * of 1/4-pel units + * pMVCandidate - Candidate MV; used to initialize the motion search, + * expressed in terms of integer pixels + * pMESpec - pointer to the ME specification structure + * + * Output Arguments: + * + * pDstBestMV - Best MV resulting from integer search, expressed in terms + * of 1/4-pel units + * pBestCost - Motion cost associated with the best MV; computed as + * SAD+Lamda*BitsUsedByMV + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - any of the following poitners are NULL: + * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec. + * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16. + * - Any alignment restrictions are violated + * + */ + + OMXResult omxVCM4P10_BlockMatch_Integer ( + const OMX_U8 *pSrcOrgY, + OMX_S32 nSrcOrgStep, + const OMX_U8 *pSrcRefY, + OMX_S32 nSrcRefStep, + const OMXRect *pRefRect, + const OMXVCM4P2Coordinate *pCurrPointPos, + OMX_U8 iBlockWidth, + OMX_U8 iBlockHeight, + OMX_U32 nLamda, + const OMXVCMotionVector *pMVPred, + const OMXVCMotionVector *pMVCandidate, + OMXVCMotionVector *pBestMV, + OMX_S32 *pBestCost, + void *pMESpec +) +{ + /* Definitions and Initializations*/ + OMX_INT candSAD; + OMX_INT fromX, toX, fromY, toY; + /* Offset to the reference at the begining of the bounding box */ + const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; + OMX_S16 x, y; + OMXVCMotionVector diffMV; + OMX_S32 nSearchRange; + ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec; + + /* Argument error checks */ + armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pMVCandidate == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBestMV == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); + armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); + armIgnore (pMESpec); + + if(iBlockWidth == 4) + { + nSearchRange = armMESpec->MEParams.searchRange4x4; + } + else if(iBlockWidth == 8) + { + nSearchRange = armMESpec->MEParams.searchRange8x8; + } + else + { + nSearchRange = armMESpec->MEParams.searchRange16x16; + } + /* Check for valid region */ + fromX = nSearchRange; + toX = nSearchRange; + fromY = nSearchRange; + toY = nSearchRange; + + if ((pCurrPointPos->x - nSearchRange) < pRefRect->x) + { + fromX = pCurrPointPos->x - pRefRect->x; + } + + if ((pCurrPointPos->x + iBlockWidth + nSearchRange) > (pRefRect->x + pRefRect->width)) + { + toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - iBlockWidth; + } + + if ((pCurrPointPos->y - nSearchRange) < pRefRect->y) + { + fromY = pCurrPointPos->y - pRefRect->y; + } + + if ((pCurrPointPos->y + iBlockWidth + nSearchRange) > (pRefRect->y + pRefRect->height)) + { + toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - iBlockWidth; + } + + pBestMV->dx = -fromX * 4; + pBestMV->dy = -fromY * 4; + /* Initialize to max value as a start point */ + *pBestCost = 0x7fffffff; + + /* Looping on y- axis */ + for (y = -fromY; y <= toY; y++) + { + /* Looping on x- axis */ + for (x = -fromX; x <= toX; x++) + { + /* Positioning the pointer */ + pTempSrcRefY = pSrcRefY + (nSrcRefStep * y) + x; + pTempSrcOrgY = pSrcOrgY; + + /* Calculate the SAD */ + armVCCOMM_SAD( + pTempSrcOrgY, + nSrcOrgStep, + pTempSrcRefY, + nSrcRefStep, + &candSAD, + iBlockHeight, + iBlockWidth); + + diffMV.dx = (x * 4) - pMVPred->dx; + diffMV.dy = (y * 4) - pMVPred->dy; + + /* Result calculations */ + armVCM4P10_CompareMotionCostToMV ((x * 4), (y * 4), diffMV, candSAD, pBestMV, nLamda, pBestCost); + + } /* End of x- axis */ + } /* End of y-axis */ + + return OMX_Sts_NoErr; + +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c new file mode 100644 index 0000000..513ee25 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_BlockMatch_Quarter.c @@ -0,0 +1,199 @@ +/** + * + * File Name: omxVCM4P10_BlockMatch_Quarter.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * Description: + * Contains modules for quater pel Block matching, + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + + +/** + * Function: omxVCM4P10_BlockMatch_Quarter (6.3.5.2.3) + * + * Description: + * Performs a quarter-pel block match using results from a prior half-pel + * search. Returns the best MV and associated cost. This function estimates + * the quarter-pixel motion vector by interpolating the half-pel resolution + * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the + * initial half-pel MV is generated externally. The function + * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation. + * + * Input Arguments: + * + * pSrcOrgY - Pointer to the current position in original picture plane. If + * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, + * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment + * required. + * pSrcRefY - Pointer to the top-left corner of the co-located block in the + * reference picture If iBlockWidth==4, 4-byte alignment + * required. If iBlockWidth==8, 8-byte alignment required. If + * iBlockWidth==16, 16-byte alignment required. + * nSrcOrgStep - Stride of the original picture plane in terms of full + * pixels; must be a multiple of iBlockWidth. + * nSrcRefStep - Stride of the reference picture plane in terms of full + * pixels + * iBlockWidth - Width of the current block in terms of full pixels; must + * be equal to either 4, 8, or 16. + * iBlockHeight - Height of the current block in terms of full pixels; must + * be equal to either 4, 8, or 16. + * nLamda - Lamda factor, used to compute motion cost + * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to + * compute motion cost + * pSrcDstBestMV - The best MV resulting from a prior half-pel search, + * represented in terms of 1/4 pel units + * + * Output Arguments: + * + * pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed + * in terms of 1/4-pel units + * pBestCost - Motion cost associated with the best MV; computed as + * SAD+Lamda*BitsUsedByMV + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - One of more of the following pointers is NULL: + * pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost + * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16. + * - Any alignment restrictions are violated + * + */ + +OMXResult omxVCM4P10_BlockMatch_Quarter( + const OMX_U8* pSrcOrgY, + OMX_S32 nSrcOrgStep, + const OMX_U8* pSrcRefY, + OMX_S32 nSrcRefStep, + OMX_U8 iBlockWidth, + OMX_U8 iBlockHeight, + OMX_U32 nLamda, + const OMXVCMotionVector* pMVPred, + OMXVCMotionVector* pSrcDstBestMV, + OMX_S32* pBestCost +) +{ + /* Definitions and Initializations*/ + OMX_INT candSAD; + OMX_INT fromX, toX, fromY, toY; + /* Offset to the reference at the begining of the bounding box */ + const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; + OMX_S16 x, y; + OMXVCMotionVector diffMV, candMV, initialMV; + OMX_U8 interpolY[256]; + OMX_S32 pelPosX, pelPosY; + + /* Argument error checks */ + armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); + armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); + armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); + + + /* Check for valid region */ + fromX = 1; + toX = 1; + fromY = 1; + toY = 1; + + /* Initialize to max value as a start point */ + *pBestCost = 0x7fffffff; + + initialMV.dx = pSrcDstBestMV->dx; + initialMV.dy = pSrcDstBestMV->dy; + + /* Looping on y- axis */ + for (y = -fromY; y <= toY; y++) + { + /* Looping on x- axis */ + for (x = -fromX; x <= toX; x++) + { + /* Positioning the pointer */ + pTempSrcRefY = pSrcRefY + (nSrcRefStep * (initialMV.dy/4)) + (initialMV.dx/4); + + /* Calculating the fract pel position */ + pelPosX = (initialMV.dx % 4) + x; + if (pelPosX < 0) + { + pTempSrcRefY = pTempSrcRefY - 1; + pelPosX += 4; + } + pelPosY = (initialMV.dy % 4) + y; + if (pelPosY < 0) + { + pTempSrcRefY = pTempSrcRefY - (1 * nSrcRefStep); + pelPosY += 4; + } + + pTempSrcOrgY = pSrcOrgY; + + /* Prepare cand MV */ + candMV.dx = initialMV.dx + x; + candMV.dy = initialMV.dy + y; + + /* Interpolate Quater pel for the current position*/ + armVCM4P10_Interpolate_Luma( + pTempSrcRefY, + nSrcRefStep, + interpolY, + iBlockWidth, + iBlockWidth, + iBlockHeight, + pelPosX, + pelPosY); + + /* Calculate the SAD */ + armVCCOMM_SAD( + pTempSrcOrgY, + nSrcOrgStep, + interpolY, + iBlockWidth, + &candSAD, + iBlockHeight, + iBlockWidth); + + diffMV.dx = candMV.dx - pMVPred->dx; + diffMV.dy = candMV.dy - pMVPred->dy; + + /* Result calculations */ + armVCM4P10_CompareMotionCostToMV ( + candMV.dx, + candMV.dy, + diffMV, + candSAD, + pSrcDstBestMV, + nLamda, + pBestCost); + + } /* End of x- axis */ + } /* End of y-axis */ + + return OMX_Sts_NoErr; + +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c new file mode 100644 index 0000000..a07b1bb --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockChroma_I.c @@ -0,0 +1,107 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_DeblockChroma_I.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 intra chroma deblock + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_DeblockChroma_I (6.3.3.3.6) + * + * Description: + * Performs in-place deblocking filtering on all edges of the chroma + * macroblock (16x16). + * + * Input Arguments: + * + * pSrcDst - pointer to the input macroblock; must be 8-byte aligned. + * srcdstStep - step of the arrays; must be a multiple of 8. + * pAlpha - pointer to a 2x2 array of alpha thresholds, organized as + * follows: {external vertical edge, internal vertical edge, + * external horizontal edge, internal horizontal edge }. Per + * [ISO14496-10] alpha values must be in the range [0,255]. + * pBeta - pointer to a 2x2 array of Beta Thresholds, organized as follows: + * { external vertical edge, internal vertical edge, external + * horizontal edge, internal horizontal edge }. Per [ISO14496-10] + * beta values must be in the range [0,18]. + * pThresholds - array of size 8x2 of Thresholds (TC0) (values for the left + * or above edge of each 4x2 or 2x4 block, arranged in vertical + * block order and then in horizontal block order); must be aligned + * on a 4-byte boundary. Per [ISO14496-10] values must be in the + * range [0,25]. + * pBS - array of size 16x2 of BS parameters (arranged in scan block order + * for vertical edges and then horizontal edges); valid in the + * range [0,4] with the following restrictions: i) pBS[i]== 4 may + * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== + * 4. Must be 4-byte aligned. + * + * Output Arguments: + * + * pSrcDst - pointer to filtered output macroblock. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments + * - one or more of the following pointers is NULL: pSrcDst, pAlpha, + * pBeta, pThresholds, or pBS. pSrcDst is not 8-byte aligned. + * either pThresholds or pBS is not 4-byte aligned. + * - one or more entries in the table pAlpha[0..3] is outside the range + * [0,255]. + * - one or more entries in the table pBeta[0..3] is outside the range + * [0,18]. + * - one or more entries in the table pThresholds[0..15]is outside of + * the range [0,25]. + * - pBS is out of range, i.e., one of the following conditions is true: + * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or + * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3. + * - srcdstStep is not a multiple of 8. + * + */ +OMXResult omxVCM4P10_DeblockChroma_I( + OMX_U8* pSrcDst, + OMX_S32 srcdstStep, + const OMX_U8* pAlpha, + const OMX_U8* pBeta, + const OMX_U8* pThresholds, + const OMX_U8 *pBS +) +{ + OMXResult errorCode; + + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr); + armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); + armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); + + errorCode = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( + pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS); + + armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode) + + errorCode = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( + pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+8, pBS+16); + + return errorCode; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c new file mode 100644 index 0000000..1f3a646 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DeblockLuma_I.c @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_DeblockLuma_I.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 luma deblock + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + + +/** + * Function: omxVCM4P10_DeblockLuma_I (6.3.3.3.5) + * + * Description: + * This function performs in-place deblock filtering the horizontal and + * vertical edges of a luma macroblock (16x16). + * + * Input Arguments: + * + * pSrcDst - pointer to the input macroblock; must be 16-byte aligned. + * srcdstStep - image width; must be a multiple of 16. + * pAlpha - pointer to a 2x2 table of alpha thresholds, organized as + * follows: {external vertical edge, internal vertical edge, + * external horizontal edge, internal horizontal edge }. Per + * [ISO14496-10] alpha values must be in the range [0,255]. + * pBeta - pointer to a 2x2 table of beta thresholds, organized as follows: + * {external vertical edge, internal vertical edge, external + * horizontal edge, internal horizontal edge }. Per [ISO14496-10] + * beta values must be in the range [0,18]. + * pThresholds - pointer to a 16x2 table of threshold (TC0), organized as + * follows: {values for the left or above edge of each 4x4 block, + * arranged in vertical block order and then in horizontal block + * order}; must be aligned on a 4-byte boundary. Per [ISO14496-10] + * values must be in the range [0,25]. + * pBS - pointer to a 16x2 table of BS parameters arranged in scan block + * order for vertical edges and then horizontal edges; valid in the + * range [0,4] with the following restrictions: i) pBS[i]== 4 may + * occur only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== + * 4. Must be 4-byte aligned. + * + * Output Arguments: + * + * pSrcDst - pointer to filtered output macroblock. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments + * - one or more of the following pointers is NULL: pSrcDst, pAlpha, + * pBeta, pThresholds or pBS. pSrcDst is not 16-byte aligned. + * either pThresholds or pBS is not aligned on a 4-byte boundary. + * - one or more entries in the table pAlpha[0..3] is outside the range + * [0,255]. + * - one or more entries in the table pBeta[0..3] is outside the range + * [0,18]. + * - one or more entries in the table pThresholds[0..31]is outside of + * the range [0,25]. + * - pBS is out of range, i.e., one of the following conditions is true: + * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or + * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3. + * - srcdstStep is not a multiple of 16. + * + */ + +OMXResult omxVCM4P10_DeblockLuma_I( + OMX_U8* pSrcDst, + OMX_S32 srcdstStep, + const OMX_U8* pAlpha, + const OMX_U8* pBeta, + const OMX_U8* pThresholds, + const OMX_U8 *pBS +) +{ + OMXResult errorCode; + + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot16ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(srcdstStep & 15, OMX_Sts_BadArgErr); + armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); + armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); + + errorCode = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( + pSrcDst, srcdstStep, pAlpha, pBeta, pThresholds, pBS); + + armRetArgErrIf(errorCode != OMX_Sts_NoErr, errorCode) + + errorCode = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( + pSrcDst, srcdstStep, pAlpha+2, pBeta+2, pThresholds+16, pBS+16); + + return errorCode; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c new file mode 100644 index 0000000..830ddc7 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 decode coefficients module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC (6.3.4.1.1) + * + * Description: + * Performs CAVLC decoding and inverse raster scan for a 2x2 block of + * ChromaDCLevel. The decoded coefficients in the packed position-coefficient + * buffer are stored in reverse zig-zag order, i.e., the first buffer element + * contains the last non-zero postion-coefficient pair of the block. Within + * each position-coefficient pair, the position entry indicates the + * raster-scan position of the coefficient, while the coefficient entry + * contains the coefficient value. + * + * Input Arguments: + * + * ppBitStream - Double pointer to current byte in bit stream buffer + * pOffset - Pointer to current bit position in the byte pointed to by + * *ppBitStream; valid in the range [0,7]. + * + * Output Arguments: + * + * ppBitStream - *ppBitStream is updated after each block is decoded + * pOffset - *pOffset is updated after each block is decoded + * pNumCoeff - Pointer to the number of nonzero coefficients in this block + * ppPosCoefBuf - Double pointer to destination residual + * coefficient-position pair buffer. Buffer position + * (*ppPosCoefBuf) is updated upon return, unless there are only + * zero coefficients in the currently decoded block. In this case + * the caller is expected to bypass the transform/dequantization of + * the empty blocks. + * + * Return Value: + * + * OMX_Sts_NoErr, if the function runs without error. + * + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - ppBitStream or pOffset is NULL. + * - ppPosCoefBuf or pNumCoeff is NULL. + * OMX_Sts_Err - if one of the following is true: + * - an illegal code is encountered in the bitstream + * + */ + +OMXResult omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC ( + const OMX_U8** ppBitStream, + OMX_S32* pOffset, + OMX_U8* pNumCoeff, + OMX_U8** ppPosCoefbuf + ) + +{ + armRetArgErrIf(ppBitStream==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(*ppBitStream==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(pOffset==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(*pOffset<0 , OMX_Sts_BadArgErr); + armRetArgErrIf(*pOffset>7 , OMX_Sts_BadArgErr); + armRetArgErrIf(pNumCoeff==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(ppPosCoefbuf==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(*ppPosCoefbuf==NULL , OMX_Sts_BadArgErr); + + return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff, + ppPosCoefbuf, 4, 4); + +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c new file mode 100644 index 0000000..7e83d1e --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DecodeCoeffsToPairCAVLC.c @@ -0,0 +1,117 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_DecodeCoeffsToPairCAVLC.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 decode coefficients module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_DecodeCoeffsToPairCAVLC (6.3.4.1.2) + * + * Description: + * Performs CAVLC decoding and inverse zigzag scan for 4x4 block of + * Intra16x16DCLevel, Intra16x16ACLevel, LumaLevel, and ChromaACLevel. Inverse + * field scan is not supported. The decoded coefficients in the packed + * position-coefficient buffer are stored in reverse zig-zag order, i.e., the + * first buffer element contains the last non-zero postion-coefficient pair of + * the block. Within each position-coefficient pair, the position entry + * indicates the raster-scan position of the coefficient, while the + * coefficient entry contains the coefficient value. + * + * Input Arguments: + * + * ppBitStream -Double pointer to current byte in bit stream buffer + * pOffset - Pointer to current bit position in the byte pointed to by + * *ppBitStream; valid in the range [0,7]. + * sMaxNumCoeff - Maximum the number of non-zero coefficients in current + * block + * sVLCSelect - VLC table selector, obtained from the number of non-zero + * coefficients contained in the above and left 4x4 blocks. It is + * equivalent to the variable nC described in H.264 standard table + * 9 5, except its value can t be less than zero. + * + * Output Arguments: + * + * ppBitStream - *ppBitStream is updated after each block is decoded. + * Buffer position (*ppPosCoefBuf) is updated upon return, unless + * there are only zero coefficients in the currently decoded block. + * In this case the caller is expected to bypass the + * transform/dequantization of the empty blocks. + * pOffset - *pOffset is updated after each block is decoded + * pNumCoeff - Pointer to the number of nonzero coefficients in this block + * ppPosCoefBuf - Double pointer to destination residual + * coefficient-position pair buffer + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - ppBitStream or pOffset is NULL. + * - ppPosCoefBuf or pNumCoeff is NULL. + * - sMaxNumCoeff is not equal to either 15 or 16. + * - sVLCSelect is less than 0. + * + * OMX_Sts_Err - if one of the following is true: + * - an illegal code is encountered in the bitstream + * + */ + +OMXResult omxVCM4P10_DecodeCoeffsToPairCAVLC( + const OMX_U8** ppBitStream, + OMX_S32* pOffset, + OMX_U8* pNumCoeff, + OMX_U8**ppPosCoefbuf, + OMX_INT sVLCSelect, + OMX_INT sMaxNumCoeff + ) +{ + int nTable; + + armRetArgErrIf(ppBitStream==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(*ppBitStream==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(pOffset==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(*pOffset<0 , OMX_Sts_BadArgErr); + armRetArgErrIf(*pOffset>7 , OMX_Sts_BadArgErr); + armRetArgErrIf(pNumCoeff==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(ppPosCoefbuf==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(*ppPosCoefbuf==NULL , OMX_Sts_BadArgErr); + armRetArgErrIf(sVLCSelect<0 , OMX_Sts_BadArgErr); + armRetArgErrIf(sMaxNumCoeff<15 , OMX_Sts_BadArgErr); + armRetArgErrIf(sMaxNumCoeff>16 , OMX_Sts_BadArgErr); + + /* Find VLC table number */ + if (sVLCSelect<2) + { + nTable = 0; + } + else if (sVLCSelect<4) + { + nTable = 1; + } + else if (sVLCSelect<8) + { + nTable = 2; + } + else /* sVLCSelect >= 8 */ + { + nTable = 3; + } + + return armVCM4P10_DecodeCoeffsToPair(ppBitStream, pOffset, pNumCoeff, + ppPosCoefbuf, nTable, sMaxNumCoeff); +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c new file mode 100644 index 0000000..ed5a158 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_DequantTransformResidualFromPairAndAdd.c @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_DequantTransformResidualFromPairAndAdd.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize and transform module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Dequantize Luma AC block + */ + +static void DequantLumaAC4x4( + OMX_S16* pSrcDst, + OMX_INT QP +) +{ + const OMX_U8 *pVRow = &armVCM4P10_VMatrix[QP%6][0]; + int Shift = QP / 6; + int i; + OMX_S32 Value; + + for (i=0; i<16; i++) + { + + Value = (pSrcDst[i] * pVRow[armVCM4P10_PosToVCol4x4[i]]) << Shift; + pSrcDst[i] = (OMX_S16)Value; + } +} + +/** + * Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd (6.3.4.2.3) + * + * Description: + * Reconstruct the 4x4 residual block from coefficient-position pair buffer, + * perform dequantization and integer inverse transformation for 4x4 block of + * residuals with previous intra prediction or motion compensation data, and + * update the pair buffer pointer to next non-empty block. If pDC == NULL, + * there re 16 non-zero AC coefficients at most in the packed buffer starting + * from 4x4 block position 0; If pDC != NULL, there re 15 non-zero AC + * coefficients at most in the packet buffer starting from 4x4 block position + * 1. + * + * Input Arguments: + * + * ppSrc - Double pointer to residual coefficient-position pair buffer + * output by CALVC decoding + * pPred - Pointer to the predicted 4x4 block; must be aligned on a 4-byte + * boundary + * predStep - Predicted frame step size in bytes; must be a multiple of 4 + * dstStep - Destination frame step in bytes; must be a multiple of 4 + * pDC - Pointer to the DC coefficient of this block, NULL if it doesn't + * exist + * QP - QP Quantization parameter. It should be QpC in chroma 4x4 block + * decoding, otherwise it should be QpY. + * AC - Flag indicating if at least one non-zero AC coefficient exists + * + * Output Arguments: + * + * pDst - pointer to the reconstructed 4x4 block data; must be aligned on a + * 4-byte boundary + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - pPred or pDst is NULL. + * - pPred or pDst is not 4-byte aligned. + * - predStep or dstStep is not a multiple of 4. + * - AC !=0 and Qp is not in the range of [0-51] or ppSrc == NULL. + * - AC ==0 && pDC ==NULL. + * + */ + +OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd( + const OMX_U8 **ppSrc, + const OMX_U8 *pPred, + const OMX_S16 *pDC, + OMX_U8 *pDst, + OMX_INT predStep, + OMX_INT dstStep, + OMX_INT QP, + OMX_INT AC +) +{ + OMX_S16 pBuffer[16+4]; + OMX_S16 *pDelta; + int i,x,y; + + armRetArgErrIf(pPred == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pPred),OMX_Sts_BadArgErr); + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf(predStep & 3, OMX_Sts_BadArgErr); + armRetArgErrIf(dstStep & 3, OMX_Sts_BadArgErr); + armRetArgErrIf(AC!=0 && (QP<0), OMX_Sts_BadArgErr); + armRetArgErrIf(AC!=0 && (QP>51), OMX_Sts_BadArgErr); + armRetArgErrIf(AC!=0 && ppSrc==NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(AC!=0 && *ppSrc==NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(AC==0 && pDC==NULL, OMX_Sts_BadArgErr); + + pDelta = armAlignTo8Bytes(pBuffer); + + for (i=0; i<16; i++) + { + pDelta[i] = 0; + } + if (AC) + { + armVCM4P10_UnpackBlock4x4(ppSrc, pDelta); + DequantLumaAC4x4(pDelta, QP); + } + if (pDC) + { + pDelta[0] = pDC[0]; + } + armVCM4P10_TransformResidual4x4(pDelta,pDelta); + + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,pPred[y*predStep+x] + pDelta[4*y+x]); + } + } + + return OMX_Sts_NoErr; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c new file mode 100644 index 0000000..75edee2 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c @@ -0,0 +1,130 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_FilterDeblockingChroma_HorEdge_I.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 chroma deblock module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_FilterDeblockingChroma_HorEdge_I (6.3.3.3.4) + * + * Description: + * Performs in-place deblock filtering on the horizontal edges of the chroma + * macroblock (8x8). + * + * Input Arguments: + * + * pSrcDst - pointer to the input macroblock; must be 8-byte aligned. + * srcdstStep - array step; must be a multiple of 8. + * pAlpha - array of size 2 containing alpha thresholds; the first element + * contains the threshold for the external horizontal edge, and the + * second element contains the threshold for internal horizontal + * edge. Per [ISO14496-10] alpha values must be in the range + * [0,255]. + * pBeta - array of size 2 containing beta thresholds; the first element + * contains the threshold for the external horizontal edge, and the + * second element contains the threshold for the internal + * horizontal edge. Per [ISO14496-10] beta values must be in the + * range [0,18]. + * pThresholds - array of size 8 containing thresholds, TC0, for the top + * horizontal edge of each 2x4 chroma block, arranged in horizontal + * block order; must be aligned on a 4-byte boundary. Per + * [ISO14496-10] values must be in the range [0,25]. + * pBS - array of size 16 containing BS parameters for each 2x2 chroma + * block, arranged in horizontal block order; valid in the range + * [0,4] with the following restrictions: i) pBS[i]== 4 may occur + * only for 0<=i<=3, ii) pBS[i]== 4 if and only if pBS[i^3]== 4. + * Must be 4-byte aligned. + * + * Output Arguments: + * + * pSrcDst -Pointer to filtered output macroblock. + * + * Return Value: + * + * OMX_Sts_NoErr, if the function runs without error. + * + * OMX_Sts_BadArgErr, if one of the following cases occurs: + * - any of the following pointers is NULL: + * pSrcDst, pAlpha, pBeta, pThresholds, or pBS. + * - pSrcDst is not 8-byte aligned. + * - srcdstStep is not a multiple of 8. + * - pThresholds is not 4-byte aligned. + * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255]. + * - pBeta[0] and/or pBeta[1] is outside the range [0,18]. + * - One or more entries in the table pThresholds[0..7] is outside + * of the range [0,25]. + * - pBS is out of range, i.e., one of the following conditions is true: + * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or + * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3. + * - pBS is not 4-byte aligned. + * + */ + +OMXResult omxVCM4P10_FilterDeblockingChroma_HorEdge_I( + OMX_U8* pSrcDst, + OMX_S32 srcdstStep, + const OMX_U8* pAlpha, + const OMX_U8* pBeta, + const OMX_U8* pThresholds, + const OMX_U8 *pBS + ) +{ + int I, X, Y, Internal=0; + + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr); + armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); + armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); + + for (Y=0; Y<8; Y+=4, Internal=1) + { + for (X=0; X<8; X++) + { + I = (X>>1)+4*(Y>>1); + + armRetArgErrIf(pBS[I] > 4, OMX_Sts_BadArgErr) + + armRetArgErrIf( (I > 3) && (pBS[I] == 4), + OMX_Sts_BadArgErr) + + armRetArgErrIf( (I < 4) && + ( (pBS[I] == 4) && (pBS[I^1] != 4) ), + OMX_Sts_BadArgErr) + + + /* Filter horizontal edge with q0 at (X,Y) */ + armVCM4P10_DeBlockPixel( + pSrcDst + Y*srcdstStep + X, + srcdstStep, + pThresholds[(X>>1)+4*(Y>>2)], + pAlpha[Internal], + pBeta[Internal], + pBS[I], + 1); + } + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c new file mode 100644 index 0000000..10b2592 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c @@ -0,0 +1,131 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_FilterDeblockingChroma_VerEdge_I.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 deblocking module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_FilterDeblockingChroma_VerEdge_I (6.3.3.3.3) + * + * Description: + * Performs in-place deblock filtering on four vertical edges of the chroma + * macroblock (8x8). + * + * Input Arguments: + * + * pSrcDst - Pointer to the input macroblock; must be 8-byte aligned. + * srcdstStep - Step of the arrays; must be a multiple of 8. + * pAlpha - Array of size 2 of alpha thresholds (the first item is alpha + * threshold for external vertical edge, and the second item is for + * internal vertical edge); per [ISO14496-10] alpha values must be + * in the range [0,255]. + * pBeta - Array of size 2 of beta thresholds (the first item is the beta + * threshold for the external vertical edge, and the second item is + * for the internal vertical edge); per [ISO14496-10] beta values + * must be in the range [0,18]. + * pThresholds - Array of size 8 containing thresholds, TC0, for the left + * vertical edge of each 4x2 chroma block, arranged in vertical + * block order; must be aligned on a 4-byte boundary. Per + * [ISO14496-10] values must be in the range [0,25]. + * pBS - Array of size 16 of BS parameters (values for each 2x2 chroma + * block, arranged in vertical block order). This parameter is the + * same as the pBSparameter passed into FilterDeblockLuma_VerEdge; + * valid in the range [0,4] with the following restrictions: i) + * pBS[i]== 4 may occur only for 0<=i<=3, ii) pBS[i]== 4 if and + * only if pBS[i^3]== 4. Must be 4 byte aligned. + * + * Output Arguments: + * + * pSrcDst -Pointer to filtered output macroblock. + * + * Return Value: + * + * OMX_Sts_NoErr, if the function runs without error. + * + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - one or more of the following pointers is NULL: pSrcDst, pAlpha, + * pBeta, pThresholds, or pBS. + * - pSrcDst is not 8-byte aligned. + * - srcdstStep is not a multiple of 8. + * - pThresholds is not 4-byte aligned. + * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255]. + * - pBeta[0] and/or pBeta[1] is outside the range [0,18]. + * - One or more entries in the table pThresholds[0..7] is outside + * of the range [0,25]. + * - pBS is out of range, i.e., one of the following conditions is true: + * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or + * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3. + * - pBS is not 4-byte aligned. + * + */ + +OMXResult omxVCM4P10_FilterDeblockingChroma_VerEdge_I( + OMX_U8* pSrcDst, + OMX_S32 srcdstStep, + const OMX_U8* pAlpha, + const OMX_U8* pBeta, + const OMX_U8* pThresholds, + const OMX_U8 *pBS + ) +{ + int I, X, Y, Internal=0; + + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr); + armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); + armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta[0] > 18, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta[1] > 18, OMX_Sts_BadArgErr); + + for (X=0; X<8; X+=4, Internal=1) + { + for (Y=0; Y<8; Y++) + { + I = (Y>>1)+4*(X>>1); + + armRetArgErrIf(pBS[I] > 4, OMX_Sts_BadArgErr); + + armRetArgErrIf( (I > 3) && (pBS[I] == 4), + OMX_Sts_BadArgErr); + + armRetArgErrIf( ( (pBS[I] == 4) && (pBS[I^3] != 4) ), + OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds[Y] > 25, OMX_Sts_BadArgErr); + + + /* Filter vertical edge with q0 at (X,Y) */ + armVCM4P10_DeBlockPixel( + pSrcDst + Y*srcdstStep + X, + 1, + pThresholds[(Y>>1)+4*(X>>2)], + pAlpha[Internal], + pBeta[Internal], + pBS[I], + 1); + } + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c new file mode 100644 index 0000000..30a37da --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c @@ -0,0 +1,125 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_FilterDeblockingLuma_HorEdge_I.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 luma deblock module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_FilterDeblockingLuma_HorEdge_I (6.3.3.3.2) + * + * Description: + * Performs in-place deblock filtering on four horizontal edges of the luma + * macroblock (16x16). + * + * Input Arguments: + * + * pSrcDst - pointer to the input macroblock; must be 16-byte aligned. + * srcdstStep -s tep of the arrays; must be a multiple of 16. + * pAlpha - array of size 2 of alpha thresholds (the first item is the alpha + * threshold for the external vertical edge, and the second item is + * for the internal horizontal edge); per [ISO14496-10] alpha + * values must be in the range [0,255]. + * pBeta - array of size 2 of beta thresholds (the first item is the beta + * threshold for the external horizontal edge, and the second item + * is for the internal horizontal edge). Per [ISO14496-10] beta + * values must be in the range [0,18]. + * pThresholds - array of size 16 containing thresholds, TC0, for the top + * horizontal edge of each 4x4 block, arranged in horizontal block + * order; must be aligned on a 4-byte boundary. Per [ISO14496 10] + * values must be in the range [0,25]. + * pBS - array of size 16 of BS parameters (arranged in horizontal block + * order); valid in the range [0,4] with the following + * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii) + * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned. + * + * Output Arguments: + * + * pSrcDst -Pointer to filtered output macroblock. + * + * Return Value: + * + * OMX_Sts_NoErr, if the function runs without error. + * + * OMX_Sts_BadArgErr, if one of the following cases occurs: + * - one or more of the following pointers is NULL: pSrcDst, pAlpha, + * pBeta, pThresholds, or pBS. + * - either pThresholds or pBS is not aligned on a 4-byte boundary. + * - pSrcDst is not 16-byte aligned. + * - srcdstStep is not a multiple of 16. + * - pAlpha[0] and/or pAlpha[1] is outside the range [0,255]. + * - pBeta[0] and/or pBeta[1] is outside the range [0,18]. + * - One or more entries in the table pThresholds[0..15] is + * outside of the range [0,25]. + * - pBS is out of range, i.e., one of the following conditions is true: + * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or + * (pBS[i]==4 && pBS[i^3]!=4) for 0<=i<=3. + * + */ + +OMXResult omxVCM4P10_FilterDeblockingLuma_HorEdge_I( + OMX_U8* pSrcDst, + OMX_S32 srcdstStep, + const OMX_U8* pAlpha, + const OMX_U8* pBeta, + const OMX_U8* pThresholds, + const OMX_U8 *pBS + ) +{ + int I, X, Y, Internal=0; + + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(srcdstStep & 7, OMX_Sts_BadArgErr); + armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); + armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); + + for (Y=0; Y<16; Y+=4, Internal=1) + { + for (X=0; X<16; X++) + { + I = (X>>2)+4*(Y>>2); + + armRetArgErrIf(pBS[I] > 4, OMX_Sts_BadArgErr) + + armRetArgErrIf( (I > 3) && (pBS[I] == 4), + OMX_Sts_BadArgErr) + + armRetArgErrIf( (I < 4) && + ( (pBS[I] == 4) && (pBS[I^1] != 4) ), + OMX_Sts_BadArgErr) + + /* Filter horizontal edge with q0 at (X,Y) */ + armVCM4P10_DeBlockPixel( + pSrcDst + Y*srcdstStep + X, + srcdstStep, + pThresholds[I], + pAlpha[Internal], + pBeta[Internal], + pBS[I], + 0); + } + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c new file mode 100644 index 0000000..8733427 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c @@ -0,0 +1,128 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_FilterDeblockingLuma_VerEdge_I.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 luma deblock module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_FilterDeblockingLuma_VerEdge_I (6.3.3.3.1) + * + * Description: + * Performs in-place deblock filtering on four vertical edges of the luma + * macroblock (16x16). + * + * Input Arguments: + * + * pSrcDst - Pointer to the input macroblock; must be 16-byte aligned. + * srcdstStep -Step of the arrays; must be a multiple of 16. + * pAlpha -Array of size 2 of alpha thresholds (the first item is the alpha + * threshold for the external vertical edge, and the second item is + * for the internal vertical edge); per [ISO14496-10] alpha values + * must be in the range [0,255]. + * pBeta -Array of size 2 of beta thresholds (the first item is the beta + * threshold for the external vertical edge, and the second item is + * for the internal vertical edge); per [ISO14496-10] beta values + * must be in the range [0,18]. + * pThresholds -Array of size 16 of Thresholds (TC0) (values for the left + * edge of each 4x4 block, arranged in vertical block order); must + * be aligned on a 4-byte boundary.. Per [ISO14496-10] values must + * be in the range [0,25]. + * pBS -Array of size 16 of BS parameters (arranged in vertical block + * order); valid in the range [0,4] with the following + * restrictions: i) pBS[i]== 4 may occur only for 0<=i<=3, ii) + * pBS[i]== 4 if and only if pBS[i^3]== 4. Must be 4-byte aligned. + * + * Output Arguments: + * + * pSrcDst -Pointer to filtered output macroblock. + * + * Return Value: + * If the function runs without error, it returns OMX_Sts_NoErr. + * If one of the following cases occurs, the function returns + * OMX_Sts_BadArgErr: + * Either of the pointers in pSrcDst, pAlpha, pBeta, pThresholds, or pBS + * is NULL. + * Either pThresholds or pBS is not aligned on a 4-byte boundary. + * pSrcDst is not 16-byte aligned. + * srcdstStep is not a multiple of 16. + * pAlpha[0] and/or pAlpha[1] is outside the range [0,255]. + * pBeta[0] and/or pBeta[1] is outside the range [0,18]. + * One or more entries in the table pThresholds[0..15]is outside of the + * range [0,25]. + * pBS is out of range, i.e., one of the following conditions is true: + * pBS[i]<0, pBS[i]>4, pBS[i]==4 for i>=4, or (pBS[i]==4 && + * pBS[i^3]!=4) for 0<=i<=3. + * + */ + +OMXResult omxVCM4P10_FilterDeblockingLuma_VerEdge_I( + OMX_U8* pSrcDst, + OMX_S32 srcdstStep, + const OMX_U8* pAlpha, + const OMX_U8* pBeta, + const OMX_U8* pThresholds, + const OMX_U8 *pBS + ) +{ + int X, Y, I, Internal=0; + + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot16ByteAligned(pSrcDst),OMX_Sts_BadArgErr); + armRetArgErrIf(srcdstStep & 15, OMX_Sts_BadArgErr); + armRetArgErrIf(pAlpha == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pThresholds == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pThresholds), OMX_Sts_BadArgErr); + armRetArgErrIf(pBS == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pBS), OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta[0] > 18, OMX_Sts_BadArgErr); + armRetArgErrIf(pBeta[1] > 18, OMX_Sts_BadArgErr); + + + for (X=0; X<16; X+=4, Internal=1) + { + for (Y=0; Y<16; Y++) + { + I = (Y>>2)+4*(X>>2); + + armRetArgErrIf(pBS[Y] > 4, OMX_Sts_BadArgErr); + + armRetArgErrIf((pBS[Y] == 4) && (Y > 3), + OMX_Sts_BadArgErr); + + armRetArgErrIf(( (pBS[Y] == 4) && (pBS[Y^3] != 4) ), + OMX_Sts_BadArgErr); + + armRetArgErrIf(pThresholds[Y] > 25, OMX_Sts_BadArgErr); + + /* Filter vertical edge with q0 at (X,Y) */ + armVCM4P10_DeBlockPixel( + pSrcDst + Y*srcdstStep + X, + 1, + pThresholds[I], + pAlpha[Internal], + pBeta[Internal], + pBS[I], + 0); + } + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c new file mode 100644 index 0000000..81c59d6 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_GetVLCInfo.c @@ -0,0 +1,192 @@ +/** + * + * File Name: omxVCM4P10_GetVLCInfo.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * + * This function extracts run-length encoding (RLE) information + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_GetVLCInfo (6.3.5.9.1) + * + * Description: + * This function extracts run-length encoding (RLE) information from the + * coefficient matrix. The results are returned in an OMXVCM4P10VLCInfo + * structure. + * + * Input Arguments: + * + * pSrcCoeff - pointer to the transform coefficient matrix. 8-byte + * alignment required. + * pScanMatrix - pointer to the scan order definition matrix. For a luma + * block the scan matrix should follow [ISO14496-10] section 8.5.4, + * and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, + * 10, 7, 11, 14, 15. For a chroma block, the scan matrix should + * contain the values 0, 1, 2, 3. + * bAC - indicates presence of a DC coefficient; 0 = DC coefficient + * present, 1= DC coefficient absent. + * MaxNumCoef - specifies the number of coefficients contained in the + * transform coefficient matrix, pSrcCoeff. The value should be 16 + * for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The + * value should be 4 for blocks of type CHROMADC. + * + * Output Arguments: + * + * pDstVLCInfo - pointer to structure that stores information for + * run-length coding. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrcCoeff, pScanMatrix, pDstVLCInfo + * - pSrcCoeff is not aligned on an 8-byte boundary + * + */ +OMXResult omxVCM4P10_GetVLCInfo ( + const OMX_S16* pSrcCoeff, + const OMX_U8* pScanMatrix, + OMX_U8 bAC, + OMX_U32 MaxNumCoef, + OMXVCM4P10VLCInfo* pDstVLCInfo +) +{ + OMX_INT i, MinIndex; + OMX_S32 Value; + OMX_U32 Mask = 4, RunBefore; + OMX_S16 *pLevel; + OMX_U8 *pRun; + OMX_S16 Buf [16]; + + /* check for argument error */ + armRetArgErrIf(pSrcCoeff == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot8ByteAligned(pSrcCoeff), OMX_Sts_BadArgErr) + armRetArgErrIf(pScanMatrix == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstVLCInfo == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr) + armRetArgErrIf(MaxNumCoef > 16, OMX_Sts_BadArgErr) + + /* Initialize RLE Info structure */ + pDstVLCInfo->uTrailing_Ones = 0; + pDstVLCInfo->uTrailing_One_Signs = 0; + pDstVLCInfo->uNumCoeffs = 0; + pDstVLCInfo->uTotalZeros = 0; + + for (i = 0; i < 16; i++) + { + pDstVLCInfo->iLevels [i] = 0; + pDstVLCInfo->uRuns [i] = 0; + } + + MinIndex = (bAC == 0 && MaxNumCoef == 15) ? 1 : 0; + for (i = MinIndex; i < (MaxNumCoef + MinIndex); i++) + { + /* Scan */ + Buf [i - MinIndex] = pSrcCoeff [pScanMatrix [i]]; + } + + /* skip zeros at the end */ + i = MaxNumCoef - 1; + while (!Buf [i] && i >= 0) + { + i--; + } + + if (i < 0) + { + return OMX_Sts_NoErr; + } + + /* Fill RLE Info structure */ + pLevel = pDstVLCInfo->iLevels; + pRun = pDstVLCInfo->uRuns; + RunBefore = 0; + + /* Handle first non zero separate */ + pDstVLCInfo->uNumCoeffs++; + Value = Buf [i]; + if (Value == 1 || Value == -1) + { + pDstVLCInfo->uTrailing_Ones++; + + pDstVLCInfo->uTrailing_One_Signs |= + Value == -1 ? Mask : 0; + Mask >>= 1; + } + else + { + Value -= (Value > 0 ? 1 : -1); + *pLevel++ = Value; + Mask = 0; + } + + /* Remaining non zero */ + while (--i >= 0) + { + Value = Buf [i]; + if (Value) + { + pDstVLCInfo->uNumCoeffs++; + + /* Mask becomes zero after entering */ + if (Mask && + (Value == 1 || + Value == -1)) + { + pDstVLCInfo->uTrailing_Ones++; + + pDstVLCInfo->uTrailing_One_Signs |= + Value == -1 ? Mask : 0; + Mask >>= 1; + *pRun++ = RunBefore; + RunBefore = 0; + } + else + { + /* If 3 trailing ones are not completed */ + if (Mask) + { + Mask = 0; + Value -= (Value > 0 ? 1 : -1); + } + *pLevel++ = Value; + *pRun++ = RunBefore; + RunBefore = 0; + } + } + else + { + pDstVLCInfo->uTotalZeros++; + RunBefore++; + } + } + + /* Update last run */ + if (RunBefore) + { + *pRun++ = RunBefore; + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c new file mode 100644 index 0000000..8824de2 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateChroma.c @@ -0,0 +1,99 @@ +/** + * + * File Name: omxVCM4P10_InterpolateChroma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate 1/8 Pixel interpolation for Chroma Block + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + + +/** + * Function: omxVCM4P10_InterpolateChroma (6.3.3.2.2) + * + * Description: + * Performs 1/8-pixel interpolation for inter chroma MB. + * + * Input Arguments: + * + * pSrc -Pointer to the source reference frame buffer + * srcStep -Reference frame step in bytes + * dstStep -Destination frame step in bytes; must be a multiple of + * roi.width. + * dx -Fractional part of horizontal motion vector component in 1/8 pixel + * unit; valid in the range [0,7] + * dy -Fractional part of vertical motion vector component in 1/8 pixel + * unit; valid in the range [0,7] + * roi -Dimension of the interpolation region; the parameters roi.width and + * roi.height must be equal to either 2, 4, or 8. + * + * Output Arguments: + * + * pDst -Pointer to the destination frame buffer if roi.width==2, 2-byte + * alignment required if roi.width==4, 4-byte alignment required + * if roi.width==8, 8-byte alignment required + * + * Return Value: + * If the function runs without error, it returns OMX_Sts_NoErr. + * If one of the following cases occurs, the function returns + * OMX_Sts_BadArgErr: + * pSrc or pDst is NULL. + * srcStep or dstStep < 8. + * dx or dy is out of range [0-7]. + * roi.width or roi.height is out of range {2,4,8}. + * roi.width is equal to 2, but pDst is not 2-byte aligned. + * roi.width is equal to 4, but pDst is not 4-byte aligned. + * roi.width is equal to 8, but pDst is not 8 byte aligned. + * srcStep or dstStep is not a multiple of 8. + * + */ + +OMXResult omxVCM4P10_InterpolateChroma ( + const OMX_U8* pSrc, + OMX_S32 srcStep, + OMX_U8* pDst, + OMX_S32 dstStep, + OMX_S32 dx, + OMX_S32 dy, + OMXSize roi + ) +{ + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(srcStep < 8, OMX_Sts_BadArgErr) + armRetArgErrIf(dstStep < 8, OMX_Sts_BadArgErr) + armRetArgErrIf(dx < 0, OMX_Sts_BadArgErr) + armRetArgErrIf(dx > 7, OMX_Sts_BadArgErr) + armRetArgErrIf(dy < 0, OMX_Sts_BadArgErr) + armRetArgErrIf(dy > 7, OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width != 2) && (roi.width != 4) && (roi.width != 8), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.height != 2) && (roi.height != 4) && (roi.height != 8), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width == 2) && armNot2ByteAligned(pDst), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width == 4) && armNot4ByteAligned(pDst), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width == 8) && armNot8ByteAligned(pDst), OMX_Sts_BadArgErr) + armRetArgErrIf(srcStep & 7, OMX_Sts_BadArgErr) + armRetArgErrIf(dstStep & 7, OMX_Sts_BadArgErr) + + return armVCM4P10_Interpolate_Chroma + ((OMX_U8*)pSrc, srcStep, pDst, dstStep, roi.width, roi.height, dx, dy); +} + + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c new file mode 100644 index 0000000..ef0befa --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfHor_Luma.c @@ -0,0 +1,124 @@ +/** + * + * File Name: omxVCM4P10_InterpolateHalfHor_Luma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate Half horizontal luma interpolation + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_InterpolateHalfHor_Luma (6.3.5.5.1) + * + * Description: + * This function performs interpolation for two horizontal 1/2-pel positions + * (-1/2,0) and (1/2, 0) - around a full-pel position. + * + * Input Arguments: + * + * pSrc - Pointer to the top-left corner of the block used to interpolate in + * the reconstruction frame plane. + * iSrcStep - Step of the source buffer. + * iDstStep - Step of the destination(interpolation) buffer; must be a + * multiple of iWidth. + * iWidth - Width of the current block; must be equal to either 4, 8, or 16 + * iHeight - Height of the current block; must be equal to 4, 8, or 16 + * + * Output Arguments: + * + * pDstLeft -Pointer to the interpolation buffer of the left -pel position + * (-1/2, 0) + * If iWidth==4, 4-byte alignment required. + * If iWidth==8, 8-byte alignment required. + * If iWidth==16, 16-byte alignment required. + * pDstRight -Pointer to the interpolation buffer of the right -pel + * position (1/2, 0) + * If iWidth==4, 4-byte alignment required. + * If iWidth==8, 8-byte alignment required. + * If iWidth==16, 16-byte alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrc, pDstLeft, or pDstRight + * - iWidth or iHeight have values other than 4, 8, or 16 + * - iWidth==4 but pDstLeft and/or pDstRight is/are not aligned on a 4-byte boundary + * - iWidth==8 but pDstLeft and/or pDstRight is/are not aligned on a 8-byte boundary + * - iWidth==16 but pDstLeft and/or pDstRight is/are not aligned on a 16-byte boundary + * - any alignment restrictions are violated + * + */ + +OMXResult omxVCM4P10_InterpolateHalfHor_Luma( + const OMX_U8* pSrc, + OMX_U32 iSrcStep, + OMX_U8* pDstLeft, + OMX_U8* pDstRight, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight +) +{ + OMXResult RetValue; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstLeft == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstRight == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth == 4) && + armNot4ByteAligned(pDstLeft) && + armNot4ByteAligned(pDstRight), OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth == 8) && + armNot8ByteAligned(pDstLeft) && + armNot8ByteAligned(pDstRight), OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth == 16) && + armNot16ByteAligned(pDstLeft) && + armNot16ByteAligned(pDstRight), OMX_Sts_BadArgErr) + + armRetArgErrIf((iHeight != 16) && (iHeight != 8)&& (iHeight != 4), OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth != 16) && (iWidth != 8)&& (iWidth != 4), OMX_Sts_BadArgErr) + + RetValue = armVCM4P10_InterpolateHalfHor_Luma ( + pSrc - 1, + iSrcStep, + pDstLeft, + iDstStep, + iWidth, + iHeight); + + if (RetValue != OMX_Sts_NoErr) + { + return RetValue; + } + + RetValue = armVCM4P10_InterpolateHalfHor_Luma ( + pSrc, + iSrcStep, + pDstRight, + iDstStep, + iWidth, + iHeight); + + return RetValue; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c new file mode 100644 index 0000000..3560ff8 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateHalfVer_Luma.c @@ -0,0 +1,123 @@ +/** + * + * File Name: omxVCM4P10_InterpolateHalfVer_Luma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD for 4x4 blocks + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + + +/** + * Function: omxVCM4P10_InterpolateHalfVer_Luma (6.3.5.5.2) + * + * Description: + * This function performs interpolation for two vertical 1/2-pel positions - + * (0, -1/2) and (0, 1/2) - around a full-pel position. + * + * Input Arguments: + * + * pSrc - Pointer to top-left corner of block used to interpolate in the + * reconstructed frame plane + * iSrcStep - Step of the source buffer. + * iDstStep - Step of the destination (interpolation) buffer; must be a + * multiple of iWidth. + * iWidth - Width of the current block; must be equal to either 4, 8, or 16 + * iHeight - Height of the current block; must be equal to either 4, 8, or 16 + * + * Output Arguments: + * + * pDstUp -Pointer to the interpolation buffer of the -pel position above + * the current full-pel position (0, -1/2) + * If iWidth==4, 4-byte alignment required. + * If iWidth==8, 8-byte alignment required. + * If iWidth==16, 16-byte alignment required. + * pDstDown -Pointer to the interpolation buffer of the -pel position below + * the current full-pel position (0, 1/2) + * If iWidth==4, 4-byte alignment required. + * If iWidth==8, 8-byte alignment required. + * If iWidth==16, 16-byte alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrc, pDstUp, or pDstDown + * - iWidth or iHeight have values other than 4, 8, or 16 + * - iWidth==4 but pDstUp and/or pDstDown is/are not aligned on a 4-byte boundary + * - iWidth==8 but pDstUp and/or pDstDown is/are not aligned on a 8-byte boundary + * - iWidth==16 but pDstUp and/or pDstDown is/are not aligned on a 16-byte boundary + * + */ + OMXResult omxVCM4P10_InterpolateHalfVer_Luma( + const OMX_U8* pSrc, + OMX_U32 iSrcStep, + OMX_U8* pDstUp, + OMX_U8* pDstDown, + OMX_U32 iDstStep, + OMX_U32 iWidth, + OMX_U32 iHeight +) +{ + OMXResult RetValue; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstUp == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstDown == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth == 4) && + armNot4ByteAligned(pDstUp) && + armNot4ByteAligned(pDstDown), OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth == 8) && + armNot8ByteAligned(pDstUp) && + armNot8ByteAligned(pDstDown), OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth == 16) && + armNot16ByteAligned(pDstUp) && + armNot16ByteAligned(pDstDown), OMX_Sts_BadArgErr) + + armRetArgErrIf((iHeight != 16) && (iHeight != 8)&& (iHeight != 4), OMX_Sts_BadArgErr) + armRetArgErrIf((iWidth != 16) && (iWidth != 8)&& (iWidth != 4), OMX_Sts_BadArgErr) + + RetValue = armVCM4P10_InterpolateHalfVer_Luma( + pSrc - iSrcStep, + iSrcStep, + pDstUp, + iDstStep, + iWidth, + iHeight); + + if (RetValue != OMX_Sts_NoErr) + { + return RetValue; + } + + RetValue = armVCM4P10_InterpolateHalfVer_Luma( + pSrc, + iSrcStep, + pDstDown, + iDstStep, + iWidth, + iHeight); + + return RetValue; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c new file mode 100644 index 0000000..d233735 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InterpolateLuma.c @@ -0,0 +1,99 @@ +/** + * + * File Name: omxVCM4P10_InterpolateLuma.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate Performs quarter-pixel interpolation + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_InterpolateLuma (6.3.3.2.1) + * + * Description: + * Performs quarter-pixel interpolation for inter luma MB. It is assumed that + * the frame is already padded when calling this function. + * + * Input Arguments: + * + * pSrc -Pointer to the source reference frame buffer + * srcStep -reference frame step, in bytes; must be a multiple of roi.width + * dstStep -destination frame step, in bytes; must be a multiple of + * roi.width + * dx -Fractional part of horizontal motion vector component in 1/4 pixel + * unit; valid in the range [0,3] + * dy -Fractional part of vertical motion vector y component in 1/4 pixel + * unit; valid in the range [0,3] + * roi -Dimension of the interpolation region; the parameters roi.width and + * roi.height must be equal to either 4, 8, or 16. + * + * Output Arguments: + * + * pDst -Pointer to the destination frame buffer if roi.width==4, 4-byte + * alignment required if roi.width==8, 8-byte alignment required + * if roi.width==16, 16-byte alignment required + * + * Return Value: + * If the function runs without error, it returns OMX_Sts_NoErr. + * If one of the following cases occurs, the function returns + * OMX_Sts_BadArgErr: + * pSrc or pDst is NULL. + * srcStep or dstStep < roi.width. + * dx or dy is out of range [0,3]. + * roi.width or roi.height is out of range {4, 8, 16}. + * roi.width is equal to 4, but pDst is not 4 byte aligned. + * roi.width is equal to 8 or 16, but pDst is not 8 byte aligned. + * srcStep or dstStep is not a multiple of 8. + * + */ + +OMXResult omxVCM4P10_InterpolateLuma ( + const OMX_U8* pSrc, + OMX_S32 srcStep, + OMX_U8* pDst, + OMX_S32 dstStep, + OMX_S32 dx, + OMX_S32 dy, + OMXSize roi + ) +{ + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(srcStep < roi.width, OMX_Sts_BadArgErr) + armRetArgErrIf(dstStep < roi.width, OMX_Sts_BadArgErr) + armRetArgErrIf(dx < 0, OMX_Sts_BadArgErr) + armRetArgErrIf(dx > 3, OMX_Sts_BadArgErr) + armRetArgErrIf(dy < 0, OMX_Sts_BadArgErr) + armRetArgErrIf(dy > 3, OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width != 4) && (roi.width != 8) && (roi.width != 16), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.height != 4) && (roi.height != 8) && (roi.height != 16), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width == 4) && armNot4ByteAligned(pDst), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width == 8) && armNot8ByteAligned(pDst), OMX_Sts_BadArgErr) + armRetArgErrIf((roi.width == 16) && armNot16ByteAligned(pDst), OMX_Sts_BadArgErr) + armRetArgErrIf(srcStep & 7, OMX_Sts_BadArgErr) + armRetArgErrIf(dstStep & 7, OMX_Sts_BadArgErr) + + return armVCM4P10_Interpolate_Luma + (pSrc, srcStep, pDst, dstStep, roi.width, roi.height, dx, dy); + +} + + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c new file mode 100644 index 0000000..92ba031 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_ChromaDC.c @@ -0,0 +1,102 @@ +/** + * + * File Name: omxVCM4P10_InvTransformDequant_ChromaDC.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate 4x4 hadamard transform of chroma DC + * coefficients and quantization + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_InvTransformDequant_ChromaDC (6.3.5.6.4) + * + * Description: + * This function performs inverse 2x2 Hadamard transform and then dequantizes + * the coefficients. + * + * Input Arguments: + * + * pSrc - Pointer to the 2x2 array of the 2x2 Hadamard-transformed and + * quantized coefficients. 8 byte alignment required. + * iQP - Quantization parameter; must be in the range [0,51]. + * + * Output Arguments: + * + * pDst - Pointer to inverse-transformed and dequantized coefficients. + * 8-byte alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: pSrc + * - pSrc or pDst is not aligned on an 8-byte boundary + * + */ +OMXResult omxVCM4P10_InvTransformDequant_ChromaDC( + const OMX_S16* pSrc, + OMX_S16* pDst, + OMX_U32 iQP +) +{ + OMX_INT i, j; + OMX_S32 m[2][2]; + OMX_S32 QPer, V00, Value; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot8ByteAligned(pSrc), OMX_Sts_BadArgErr); + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr) + + /* Inv Hadamard Transform for 2x2 block */ + m[0][0] = pSrc[0] + pSrc[1] + pSrc[2] + pSrc[3]; + m[0][1] = pSrc[0] - pSrc[1] + pSrc[2] - pSrc[3]; + m[1][0] = pSrc[0] + pSrc[1] - pSrc[2] - pSrc[3]; + m[1][1] = pSrc[0] - pSrc[1] - pSrc[2] + pSrc[3]; + + /* Quantization */ + /* Scaling */ + QPer = iQP / 6; + V00 = armVCM4P10_VMatrix [iQP % 6][0]; + + for (j = 0; j < 2; j++) + { + for (i = 0; i < 2; i++) + { + if (QPer < 1) + { + Value = (m[j][i] * V00) >> 1; + } + else + { + Value = (m[j][i] * V00) << (QPer - 1); + } + + pDst[j * 2 + i] = (OMX_S16) Value; + } + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c new file mode 100644 index 0000000..a3b1200 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformDequant_LumaDC.c @@ -0,0 +1,128 @@ +/** + * + * File Name: omxVCM4P10_InvTransformDequant_LumaDC.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate 4x4 hadamard transform of luma DC coefficients + * and quantization + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_InvTransformDequant_LumaDC (6.3.5.6.3) + * + * Description: + * This function performs inverse 4x4 Hadamard transform and then dequantizes + * the coefficients. + * + * Input Arguments: + * + * pSrc - Pointer to the 4x4 array of the 4x4 Hadamard-transformed and + * quantized coefficients. 16 byte alignment required. + * iQP - Quantization parameter; must be in the range [0,51]. + * + * Output Arguments: + * + * pDst - Pointer to inverse-transformed and dequantized coefficients. + * 16-byte alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: pSrc + * - pSrc or pDst is not aligned on a 16-byte boundary + * + */ +OMXResult omxVCM4P10_InvTransformDequant_LumaDC( + const OMX_S16* pSrc, + OMX_S16* pDst, + OMX_U32 iQP +) +{ + OMX_INT i, j; + OMX_S32 m1[4][4], m2[4][4], Value; + OMX_S32 QPer, V; + + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot16ByteAligned(pSrc), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr) + + /* Inv Hadamard Transform for DC Luma 4x4 block */ + /* Horizontal */ + for (i = 0; i < 4; i++) + { + j = i * 4; + + m1[i][0] = pSrc[j + 0] + pSrc[j + 2]; /* a+c */ + m1[i][1] = pSrc[j + 1] + pSrc[j + 3]; /* b+d */ + m1[i][2] = pSrc[j + 0] - pSrc[j + 2]; /* a-c */ + m1[i][3] = pSrc[j + 1] - pSrc[j + 3]; /* b-d */ + + m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */ + m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */ + m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */ + m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */ + + } + + /* Vertical */ + for (i = 0; i < 4; i++) + { + m1[0][i] = m2[0][i] + m2[2][i]; + m1[1][i] = m2[1][i] + m2[3][i]; + m1[2][i] = m2[0][i] - m2[2][i]; + m1[3][i] = m2[1][i] - m2[3][i]; + + m2[0][i] = m1[0][i] + m1[1][i]; + m2[1][i] = m1[2][i] + m1[3][i]; + m2[2][i] = m1[2][i] - m1[3][i]; + m2[3][i] = m1[0][i] - m1[1][i]; + } + + + /* Scaling */ + QPer = iQP / 6; + V = armVCM4P10_VMatrix [iQP % 6][0]; + + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + if (QPer < 2) + { + Value = (m2[j][i] * V + (1 << (1 - QPer))) >> (2 - QPer); + } + else + { + Value = m2[j][i] * V * (1 << (QPer - 2)); + } + + pDst[j * 4 + i] = (OMX_S16) Value; + + } + } + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c new file mode 100644 index 0000000..3303997 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_InvTransformResidualAndAdd.c @@ -0,0 +1,124 @@ +/** + * + * File Name: omxVCM4P10_InvTransformResidualAndAdd.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will inverse integer 4x4 transform + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_InvTransformResidualAndAdd (6.3.5.7.1) + * + * Description: + * This function performs inverse an 4x4 integer transformation to produce + * the difference signal and then adds the difference to the prediction to get + * the reconstructed signal. + * + * Input Arguments: + * + * pSrcPred - Pointer to prediction signal. 4-byte alignment required. + * pDequantCoeff - Pointer to the transformed coefficients. 8-byte + * alignment required. + * iSrcPredStep - Step of the prediction buffer; must be a multiple of 4. + * iDstReconStep - Step of the destination reconstruction buffer; must be a + * multiple of 4. + * bAC - Indicate whether there is AC coefficients in the coefficients + * matrix. + * + * Output Arguments: + * + * pDstRecon -Pointer to the destination reconstruction buffer. 4-byte + * alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrcPred, pDequantCoeff, pDstRecon + * - pSrcPred is not aligned on a 4-byte boundary + * - iSrcPredStep or iDstReconStep is not a multiple of 4. + * - pDequantCoeff is not aligned on an 8-byte boundary + * + */ +OMXResult omxVCM4P10_InvTransformResidualAndAdd( + const OMX_U8* pSrcPred, + const OMX_S16* pDequantCoeff, + OMX_U8* pDstRecon, + OMX_U32 iSrcPredStep, + OMX_U32 iDstReconStep, + OMX_U8 bAC +) +{ + OMX_INT i, j; + OMX_S16 In[16], Out[16]; + OMX_S32 Value; + + /* check for argument error */ + armRetArgErrIf(pSrcPred == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pSrcPred), OMX_Sts_BadArgErr) + armRetArgErrIf(pDequantCoeff == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot8ByteAligned(pDequantCoeff), OMX_Sts_BadArgErr) + armRetArgErrIf(pDstRecon == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pDstRecon), OMX_Sts_BadArgErr) + armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr) + armRetArgErrIf(iSrcPredStep == 0 || iSrcPredStep & 3, OMX_Sts_BadArgErr) + armRetArgErrIf(iDstReconStep == 0 || iDstReconStep & 3, OMX_Sts_BadArgErr) + + if (bAC) + { + for (i = 0; i < 16; i++) + { + In[i] = pDequantCoeff [i]; + } + } + else + { + /* Copy DC */ + In[0] = pDequantCoeff [0]; + + for (i = 1; i < 16; i++) + { + In[i] = 0; + } + } + + /* Residual Transform */ + armVCM4P10_TransformResidual4x4 (Out, In); + + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + /* Add predition */ + Value = (OMX_S32) Out [j * 4 + i] + pSrcPred [j * iSrcPredStep + i]; + + /* Saturate Value to OMX_U8 */ + Value = armClip (0, 255, Value); + + pDstRecon[j * iDstReconStep + i] = (OMX_U8) Value; + } + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c new file mode 100644 index 0000000..8c3a5c3 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEGetBufSize.c @@ -0,0 +1,70 @@ +/** + * + * File Name: omxVCM4P10_MEGetBufSize.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * Description: + * Initialization modules for the vendor specific Motion Estimation structure. + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_MEGetBufSize (6.3.5.1.1) + * + * Description: + * Computes the size, in bytes, of the vendor-specific specification + * structure for the omxVCM4P10 motion estimation functions BlockMatch_Integer + * and MotionEstimationMB. + * + * Input Arguments: + * + * MEmode - motion estimation mode; available modes are defined by the + * enumerated type OMXVCM4P10MEMode + * pMEParams -motion estimation parameters + * + * Output Arguments: + * + * pSize - pointer to the number of bytes required for the motion + * estimation specification structure + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - pMEParams or pSize is NULL. + * - an invalid MEMode is specified. + * + */ + +OMXResult omxVCM4P10_MEGetBufSize( + OMXVCM4P10MEMode MEMode, + const OMXVCM4P10MEParams *pMEParams, + OMX_U32 *pSize + ) +{ + armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr); + armRetArgErrIf(!pSize, OMX_Sts_BadArgErr); + armRetArgErrIf((MEMode != OMX_VC_M4P10_FAST_SEARCH) && + (MEMode != OMX_VC_M4P10_FULL_SEARCH), OMX_Sts_BadArgErr); + armRetArgErrIf((pMEParams->searchRange16x16 <= 0) || + (pMEParams->searchRange8x8 <= 0) || + (pMEParams->searchRange4x4 <= 0), OMX_Sts_BadArgErr); + + *pSize = (OMX_INT) sizeof(ARMVCM4P10_MESpec); + + return OMX_Sts_NoErr; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c new file mode 100644 index 0000000..58ecc88 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MEInit.c @@ -0,0 +1,92 @@ +/** + * + * File Name: omxVCM4P10_MEInit.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * Description: + * Initialization modules for the vendor specific Motion Estimation structure. + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_MEInit (6.3.5.1.2) + * + * Description: + * Initializes the vendor-specific specification structure required for the + * omxVCM4P10 motion estimation functions: BlockMatch_Integer and + * MotionEstimationMB. Memory for the specification structure *pMESpec must be + * allocated prior to calling the function, and should be aligned on a 4-byte + * boundary. The number of bytes required for the specification structure can + * be determined using the function omxVCM4P10_MEGetBufSize. Following + * initialization by this function, the vendor-specific structure *pMESpec + * should contain an implementation-specific representation of all motion + * estimation parameters received via the structure pMEParams, for example + * searchRange16x16, searchRange8x8, etc. + * + * Input Arguments: + * + * MEmode - motion estimation mode; available modes are defined by the + * enumerated type OMXVCM4P10MEMode + * pMEParams - motion estimation parameters + * pMESpec - pointer to the uninitialized ME specification structure + * + * Output Arguments: + * + * pMESpec - pointer to the initialized ME specification structure + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - pMEParams or pSize is NULL. + * - an invalid value was specified for the parameter MEmode + * - a negative or zero value was specified for one of the search ranges + * (e.g., pMBParams >searchRange8x8, pMEParams->searchRange16x16, etc.) + * - either in isolation or in combination, one or more of the enables or + * search ranges in the structure *pMEParams were configured such + * that the requested behavior fails to comply with [ISO14496-10]. + * + */ + +OMXResult omxVCM4P10_MEInit( + OMXVCM4P10MEMode MEMode, + const OMXVCM4P10MEParams *pMEParams, + void *pMESpec + ) +{ + ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec; + + armRetArgErrIf(!pMEParams, OMX_Sts_BadArgErr); + armRetArgErrIf(!pMESpec, OMX_Sts_BadArgErr); + armRetArgErrIf((MEMode != OMX_VC_M4P10_FAST_SEARCH) && + (MEMode != OMX_VC_M4P10_FULL_SEARCH), OMX_Sts_BadArgErr); + armRetArgErrIf((pMEParams->searchRange16x16 <= 0) || + (pMEParams->searchRange8x8 <= 0) || + (pMEParams->searchRange4x4 <= 0), OMX_Sts_BadArgErr); + + armMESpec->MEParams.blockSplitEnable8x8 = pMEParams->blockSplitEnable8x8; + armMESpec->MEParams.blockSplitEnable4x4 = pMEParams->blockSplitEnable4x4; + armMESpec->MEParams.halfSearchEnable = pMEParams->halfSearchEnable; + armMESpec->MEParams.quarterSearchEnable = pMEParams->quarterSearchEnable; + armMESpec->MEParams.intraEnable4x4 = pMEParams->intraEnable4x4; + armMESpec->MEParams.searchRange16x16 = pMEParams->searchRange16x16; + armMESpec->MEParams.searchRange8x8 = pMEParams->searchRange8x8; + armMESpec->MEParams.searchRange4x4 = pMEParams->searchRange4x4; + armMESpec->MEMode = MEMode; + + return OMX_Sts_NoErr; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c new file mode 100644 index 0000000..33dbf3f --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_MotionEstimationMB.c @@ -0,0 +1,1892 @@ +/** x + * + * File Name: omxVCM4P10_MotionEstimationMB.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function perform MB level motion estimation + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +#define ARM_VCM4P10_MAX_FRAMES (15) +#define ARM_VCM4P10_MAX_4x4_SAD (0xffff) +#define ARM_VCM4P10_MAX_MODE_VALUE (0xffffffff) +#define ARM_VCM4P10_MAX_MODES (16) +#define ARM_VCM4P10_MB_BLOCK_SIZE (16) +#define ARM_VCM4P10_MEDIAN(a,b,c) (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b) +#define ARM_VCM4P10_SHIFT_QP (12) + +#define ARM_VCM4P10_MVPRED_MEDIAN (0) +#define ARM_VCM4P10_MVPRED_L (1) +#define ARM_VCM4P10_MVPRED_U (2) +#define ARM_VCM4P10_MVPRED_UR (3) + +#define ARM_VCM4P10_MB_BLOCK_SIZE (16) +#define ARM_VCM4P10_BLOCK_SIZE (4) +#define ARM_VCM4P10_MAX_COST (1 << 30) +#define ARM_VCM4P10_INVALID_BLOCK (-2) + + +/** + * Function: armVCM4P10_CalculateBlockSAD + * + * Description: + * Calculate SAD value for the selected MB encoding mode and update + * pDstBlockSAD parameter. These SAD values are calculated 4x4 blocks at + * a time and in the scan order. + * + * Remarks: + * + * Parameters: + * [in] pSrcMBInfo - + * [in] pSrcCurrBuf - + * [in] SrcCurrStep - + * [in] pSrcRefBufList- + * [in] SrcRefStep - + * [in] pSrcRecBuf - + * [in] SrcRecStep - + * [in] pRefRect - + * [in] pCurrPointPos - + * [in] Lambda - + * [in] pMESpec - + * [in] pMBInter - + * [in] pMBIntra - + * [out] pDstBlockSAD - pointer to 16 element array for SAD corresponding to 4x4 blocks + * Return Value: + * None + * + */ + +static OMXResult armVCM4P10_CalculateBlockSAD( + OMXVCM4P10MBInfo *pSrcMBInfo, + const OMX_U8 *pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES], + OMX_S32 SrcRefStep, + const OMX_U8 *pSrcRecBuf, + OMX_S32 SrcRecStep, + const OMXRect *pRefRect, + const OMXVCM4P2Coordinate *pCurrPointPos, + const OMXVCM4P10MBInfoPtr *pMBInter, + const OMXVCM4P10MBInfoPtr *pMBIntra, + OMX_U16 *pDstBlockSAD) +{ + OMX_INT InvalidSAD = 0; + OMX_INT i; + + OMX_U8 Buffer [16*16 + 15]; + OMX_U8 *pTempDstBuf; + OMX_S32 TempDstStep; + OMX_U8 *pTempRefBuf; + OMX_S32 TempRefStep; + + /* Temporary buffer to store the predicted mb coefficients */ + pTempDstBuf = armAlignTo16Bytes(Buffer); + TempDstStep = 16; + + /* Update pDstBlockSAD if MB is a valid type */ + if (pSrcMBInfo) + { + OMX_U32 Width=0, Height=0, MaxXPart, MaxYPart,MaxSubXPart,MaxSubYPart; + + /* Depending on type of MB, do prediction and fill temp buffer */ + switch (pSrcMBInfo->mbType) + { + case OMX_VC_P_16x16: + Width = 16; + Height = 16; + break; + case OMX_VC_P_16x8: + Width = 16; + Height = 8; + break; + case OMX_VC_P_8x16: + Width = 8; + Height = 16; + break; + case OMX_VC_P_8x8: + Width = 8; + Height = 8; + break; + case OMX_VC_INTRA_4x4: + { + /* Create predicted MB Intra4x4 mode */ + OMX_S32 PredIntra4x4Mode [5][9]; + OMX_S32 x, y, Block8x8, Block4x4, BlockX, BlockY; + OMX_U8 pSrcYBuff [(16*3)*(16*2)]; + OMX_U8 *pSrcY; + OMX_S32 StepSrcY; + OMX_S32 availability; + + for (y = 0; y < 5; y++) + { + for (x = 0; x < 9; x++) + { + /* + * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this + * 4x4 block is not available + */ + PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK; + } + } + + /* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/ + for (x = 0; x < 4; x++) + { + /* Store values of b0, b1, b2, b3 */ + if (pMBIntra[1] != NULL) + { + PredIntra4x4Mode [0][x + 1] = + pMBIntra[1]->pIntra4x4PredMode[3*4 + x]; + } + + /* Store values of d0, d1, d2, d3 */ + if (pMBIntra[3] != NULL) + { + PredIntra4x4Mode [0][x + 5] = + pMBIntra[3]->pIntra4x4PredMode[3*4 + x]; + } + } + + /* Store values of c3 */ + if (pMBIntra[2] != NULL) + { + PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15]; + } + + for (y = 0; y < 4; y++) + { + /* Store values of a0, a1, a2, a3 */ + if (pMBIntra[0] != NULL) + { + PredIntra4x4Mode [y + 1][0] = + pMBIntra[0]->pIntra4x4PredMode[y*4 + 3]; + } + } + + /* + * Update neighbouring Pred mode array which will be used for + * prediction of Intra4x4 modes. + */ + + pSrcY = pSrcYBuff; + StepSrcY = 16 * 3; + for (y = 0; y < (16 * 2); y++) + { + for (x = 0; x < (16 * 3); x++) + { + pSrcY [StepSrcY * y + x] = + pSrcRecBuf [SrcRecStep * (y - 16) + x - 16]; + } + } + + + /* for each 8x8 block */ + for (Block8x8 = 0; Block8x8 < 4; Block8x8++) + { + /* for each 4x4 block inside 8x8 block */ + for (Block4x4 = 0; Block4x4 < 4; Block4x4++) + { + /* Get block cordinates from 8x8 block index and 4x4 block index */ + BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1); + BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1); + + /* Add offset to point to start of current MB in the array pIntra4x4PredMode */ + x = BlockX + 1; + y = BlockY + 1; + + availability = 0; + + /* Check for availability of LEFT Block */ + if (PredIntra4x4Mode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK) + { + availability |= OMX_VC_LEFT; + } + + /* Check for availability of UPPER Block */ + if (PredIntra4x4Mode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK) + { + availability |= OMX_VC_UPPER; + } + + /* Check for availability of UPPER LEFT Block */ + if (PredIntra4x4Mode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK) + { + availability |= OMX_VC_UPPER_LEFT; + } + + PredIntra4x4Mode [y][x] = pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX]; + x = BlockX * 4; + y = BlockY * 4; + + pSrcY = pSrcYBuff + 16 * StepSrcY + 16 + y * StepSrcY + x; + + omxVCM4P10_PredictIntra_4x4( + pSrcY - 1, + pSrcY - StepSrcY, + pSrcY - StepSrcY - 1, + pTempDstBuf + x + y * TempDstStep, + StepSrcY, + TempDstStep, + pSrcMBInfo->pIntra4x4PredMode[BlockY*4+BlockX], + availability); + + for (BlockY=0;BlockY<4;BlockY++) + { + for(BlockX=0;BlockX<4;BlockX++) + { + pSrcY [BlockY * StepSrcY + BlockX] = + (OMX_U8)(*(pTempDstBuf + x + y * TempDstStep + BlockY * TempDstStep + BlockX)); + } + } + + } + } + break; + } + case OMX_VC_INTRA_16x16: + { + OMX_U32 MBPosX = pCurrPointPos->x >> 4; + OMX_U32 MBPosY = pCurrPointPos->y >> 4; + OMX_U32 availability = 0; + + /* Check for availability of LEFT MB */ + if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0)) + { + availability |= OMX_VC_LEFT; + } + + /* Check for availability of UP MB */ + if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0)) + { + availability |= OMX_VC_UPPER; + } + + /* Check for availability of UP-LEFT MB */ + if ((MBPosX > 0) && (MBPosY > 0) && + (pMBIntra [2] != 0 || pMBInter [2] != 0)) + { + availability |= OMX_VC_UPPER_LEFT; + } + + omxVCM4P10_PredictIntra_16x16( + pSrcRecBuf - 1, + pSrcRecBuf - SrcRecStep, + pSrcRecBuf - SrcRecStep - 1, + pTempDstBuf, + SrcRecStep, + TempDstStep, + pSrcMBInfo->Intra16x16PredMode, + availability); + + break; + } + + case OMX_VC_INTER_SKIP: + case OMX_VC_PREF0_8x8: + case OMX_VC_INTRA_PCM: + default: + /* These cases will update pDstBlockSAD with MAX value */ + InvalidSAD = 1; + break; + } + + /* INTER MB */ + if ((pSrcMBInfo->mbType == OMX_VC_P_16x16) || + (pSrcMBInfo->mbType == OMX_VC_P_8x16) || + (pSrcMBInfo->mbType == OMX_VC_P_16x8) || + (pSrcMBInfo->mbType == OMX_VC_P_8x8)) + { + const OMX_U8 *pTempSrcBuf; + OMX_S32 TempSrcStep; + OMX_S32 mvx,mvy; + OMX_U32 PartX, PartY, SubPartX, SubPartY; + + TempSrcStep = SrcRefStep; + + MaxXPart = 16/Width; + MaxYPart = 16/Height; + + + for (PartY = 0; PartY < MaxYPart; PartY++) + { + for (PartX = 0; PartX < MaxXPart; PartX++) + { + + pTempSrcBuf = pSrcRefBufList[pSrcMBInfo->pRefL0Idx[PartY * 2 + PartX]]; + + if (MaxXPart == 2 && MaxYPart == 2) + { + switch (pSrcMBInfo->subMBType[PartY*2+PartX]) + { + case OMX_VC_SUB_P_8x8: + Width = 8; + Height = 8; + break; + case OMX_VC_SUB_P_8x4: + Width = 8; + Height = 4; + break; + case OMX_VC_SUB_P_4x8: + Width = 4; + Height = 8; + break; + case OMX_VC_SUB_P_4x4: + Width = 4; + Height = 4; + break; + default: + /* Default */ + Width = 4; + Height = 4; + break; + } + + MaxSubXPart = 8/Width; + MaxSubYPart = 8/Height; + + for (SubPartY = 0; SubPartY < MaxSubYPart; SubPartY++) + { + for (SubPartX = 0; SubPartX < MaxSubXPart; SubPartX++) + { + mvx = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dx; + mvy = pSrcMBInfo->pMV0 [2*PartY + SubPartY][2*PartX + SubPartX].dy; + armVCM4P10_Interpolate_Luma( + pTempSrcBuf + (8*PartX + 4*SubPartX + (mvx/4)) + (8*PartY + 4*SubPartY + (mvy/4)) * TempSrcStep, + TempSrcStep, + pTempDstBuf + (8*PartX + 4*SubPartX) + (8*PartY + 4*SubPartY) * TempDstStep, + TempDstStep, + Width, + Height, + mvx & 3, + mvy & 3 + ); + } + } + } + else + { + + mvx = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dx; + mvy = pSrcMBInfo->pMV0 [2*PartY][2*PartX].dy; + armVCM4P10_Interpolate_Luma( + pTempSrcBuf + (8*PartX + (mvx/4)) + (8*PartY + (mvy/4)) * TempSrcStep, + TempSrcStep, + pTempDstBuf + (8*PartX) + (8*PartY) * TempDstStep, + TempDstStep, + Width, + Height, + mvx & 3, + mvy & 3 + ); + + } + } + } + } + } + else + { + InvalidSAD = 1; + } + + /* Calculate SAD from predicted buffer */ + if (!InvalidSAD) + { + OMX_U32 x8x8, y8x8, x4x4, y4x4, Block8x8, Block4x4; + OMX_S32 SAD; + + pTempRefBuf = pTempDstBuf; + TempRefStep = 16; + + /* SAD for each 4x4 block in scan order */ + for (Block8x8 = 0; Block8x8 < 4; Block8x8++) + { + x8x8 = 8*(Block8x8 & 1); + y8x8 = 8*(Block8x8 >> 1); + for (Block4x4 = 0; Block4x4 < 4; Block4x4++) + { + x4x4 = 4*(Block4x4 & 1); + y4x4 = 4*(Block4x4 >> 1); + + armVCCOMM_SAD( + pSrcCurrBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * SrcCurrStep, + SrcCurrStep, + pTempRefBuf + (x8x8 + x4x4) + (y8x8 + y4x4) * TempRefStep, + TempRefStep, + &SAD, + 4, /* Height */ + 4); /* Width */ + *(pDstBlockSAD + 4 * Block8x8 + Block4x4) = (SAD < 0x7fff) ? (OMX_U16) SAD : ARM_VCM4P10_MAX_MODE_VALUE; + } + } + } + else + { + /* Fill SADs with max values and return*/ + for (i = 0; i < 16; i++) + { + pDstBlockSAD [i] = ARM_VCM4P10_MAX_4x4_SAD; + } + } + return OMX_Sts_NoErr; +} + + + +/** + * Function: armVCM4P10_Mode4x4Decision + * + * Description: + * Intra 4x4 Mode decision by calculating cost for all possible modes and + * choosing the best mode + * + * Remarks: + * + * Parameters: + * [in] pSrcCurrBuf - Pointer to the start of current Macroblock + * [in] SrcCurrStep - Step size of the pointer pSrcCurrBuf + * [in/out] pSrcDstMBCurr - Pointer to the OMXVCM4P10MBInfo which will be updated for + * field pIntra4x4PredMode of the current block. + * [in] Block8x8 - Index 8x8 block in which current 4x4 block belongs + * [in] Block4x4 - Index of current 4x4 block + * [in/out] pPredIntra4x4SrcY - Pointer to current block location in buffer + * with reconstructed values. This will be modified by this + * function with best mode predicted values + * [in] StepPredIntra4x4SrcY - Step size of the pointer pPredIntra4x4SrcY + * [in] pIntra4x4PredMode - Array of Intra 4x4 prediction mode for the MB. + * Current MB modes starts at [1,1]. + * [in] pBestCost - Cost for the Best Intra 4x4 mode + * Return Value: + * None + * + */ +static OMXVoid armVCM4P10_Mode4x4Decision ( + const OMX_U8* pSrcCurrBuf, + OMX_S32 SrcCurrStep, + OMXVCM4P10MBInfo *pSrcDstMBCurr, + OMX_S32 Block8x8, + OMX_S32 Block4x4, + OMX_U8 *pPredIntra4x4SrcY, + OMX_S32 StepPredIntra4x4SrcY, + OMX_S32 pIntra4x4PredMode [][9], + OMX_S32 *pBestCost +) +{ + OMX_S32 i, j, x, y, BlockX, BlockY, mode; + OMX_S32 Cost, BestCost; + OMX_U8 *pSrcY; + OMX_S32 StepSrcY; + OMX_S32 availability = 0; + OMX_U8 pPredBlock [4*4]; + OMXResult Ret = OMX_Sts_Err; + + /* Get block cordinates from 8x8 block index and 4x4 block index */ + BlockX = ((Block8x8 & 1) << 1) + (Block4x4 & 1); + BlockY = ((Block8x8 >> 1) << 1) + (Block4x4 >> 1); + + /* Add offset to point to start of current MB in the array pIntra4x4PredMode */ + x = BlockX + 1; + y = BlockY + 1; + + /* Check for availability of LEFT Block */ + if (pIntra4x4PredMode [y][x - 1] != ARM_VCM4P10_INVALID_BLOCK) + { + availability |= OMX_VC_LEFT; + } + + /* Check for availability of UPPER Block */ + if (pIntra4x4PredMode [y - 1][x] != ARM_VCM4P10_INVALID_BLOCK) + { + availability |= OMX_VC_UPPER; + } + + /* Check for availability of UPPER LEFT Block */ + if (pIntra4x4PredMode [y - 1][x - 1] != ARM_VCM4P10_INVALID_BLOCK) + { + availability |= OMX_VC_UPPER_LEFT; + } + + pSrcY = pPredIntra4x4SrcY + + StepPredIntra4x4SrcY * (BlockY << 2) + + (BlockX << 2); + + StepSrcY = StepPredIntra4x4SrcY; + + x = BlockX * 4; + y = BlockY * 4; + + Cost = BestCost = ARM_VCM4P10_MAX_COST; + + /* Go through each mode for minim cost */ + for (mode = 0; mode < 9; mode++) + { + Ret = omxVCM4P10_PredictIntra_4x4( + pSrcY - 1, + pSrcY - StepSrcY, + pSrcY - StepSrcY - 1, + pPredBlock, + StepSrcY, + 4, + (OMXVCM4P10Intra4x4PredMode) mode, + availability); + + if (Ret == OMX_Sts_NoErr) + { + armVCCOMM_SAD( + pSrcCurrBuf + (y * SrcCurrStep) + x, + SrcCurrStep, + pPredBlock, + 4, + &Cost, + 4, + 4); + + if (Cost < BestCost) + { + BestCost = Cost; + + pIntra4x4PredMode [BlockY + 1][BlockX + 1] = + (OMXVCM4P10Intra4x4PredMode) mode; + pSrcDstMBCurr->pIntra4x4PredMode [BlockY * 4 + BlockX] = + (OMXVCM4P10Intra4x4PredMode) mode; + + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + pSrcY [StepSrcY * j + i] = pPredBlock [4 * j + i]; + } + } + } + } + } + + *pBestCost = BestCost; + return; +} + +/** + * Function: armVCM4P10_SetMotionVectorPredictor + * + * Description: + * This function will do the MV Prediction for Inter MBs + * + * Parameters: + * [in] BlockStartX - Start X index in integer pels in current Block + * [in] BlockStartY - Start Y index in integer pels in current Block + * [in] BlockSizeX - Width of current block + * [in] BlockSizeY - Height of current block + * [in] RefFrame - Index of the reference frame for prediction + * [in] pRefFrArr - Pointer to Ref array storing neighbouring MVs for MV prediction + * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction + * [out] pMVPred - Pointer to predicted MVs + * Remarks: + * + * Return Value: + * None + * + */ +static OMXVoid armVCM4P10_SetMotionVectorPredictor( + OMX_U32 BlockStartX, + OMX_U32 BlockStartY, + OMX_U32 BlockSizex, + OMX_U32 BlockSizey, + OMX_S32 RefFrame, + OMX_S32 pRefFrArr[][6], + OMXVCMotionVector pMVArr[][12], + OMXVCMotionVector *pMVPred +) +{ + OMX_S32 RFrameL; /* Left */ + OMX_S32 RFrameU; /* Up */ + OMX_S32 RFrameUR; /* Up-Right */ + + OMX_S32 BlockX, BlockY, BlockXFr, BlockYFr, MVPredType; + OMX_S32 BlockXPlusOff, BlockXPlusOffFr, BlockXMin1Fr, BlockYMin1Fr; + + BlockX = 4 + (BlockStartX >> 2); + BlockY = 4 + (BlockStartY >> 2); + BlockXPlusOff = BlockX + (BlockSizex >> 2); + + BlockXFr = BlockX >> 1; + BlockYFr = BlockY >> 1; + BlockXMin1Fr = (BlockX - 1) >> 1; + BlockYMin1Fr = (BlockY - 1) >> 1; + BlockXPlusOffFr = BlockXPlusOff >> 1; + + MVPredType = ARM_VCM4P10_MVPRED_MEDIAN; + + RFrameL = pRefFrArr [BlockYFr][BlockXMin1Fr]; + RFrameU = pRefFrArr [BlockYMin1Fr][BlockXFr]; + RFrameUR = pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr]; + + if (RFrameUR == ARM_VCM4P10_INVALID_BLOCK) + { + RFrameUR = pRefFrArr [BlockYMin1Fr][BlockXMin1Fr]; + } + + /* + * Prediction if only one of the neighbors uses the reference frame + * we are checking + */ + + if (RFrameL == RefFrame && RFrameU != RefFrame && RFrameUR != RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_L; + } + else if(RFrameL != RefFrame && RFrameU == RefFrame && RFrameUR != RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_U; + } + else if(RFrameL != RefFrame && RFrameU != RefFrame && RFrameUR == RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_UR; + } + + /* Directional predictions */ + else if(BlockSizex == 8 && BlockSizey == 16) + { + if(BlockStartX == 0) + { + if(RFrameL == RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_L; + } + } + else + { + if (RFrameUR == RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_UR; + } + } + } + else if(BlockSizex == 16 && BlockSizey == 8) + { + if(BlockStartY == 0) + { + if(RFrameU == RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_U; + } + } + else + { + if(RFrameL == RefFrame) + { + MVPredType = ARM_VCM4P10_MVPRED_L; + } + } + } + + switch (MVPredType) + { + case ARM_VCM4P10_MVPRED_MEDIAN: + if (!(pRefFrArr [BlockYMin1Fr][BlockXMin1Fr] == ARM_VCM4P10_INVALID_BLOCK || + pRefFrArr [BlockYMin1Fr][BlockXFr] == ARM_VCM4P10_INVALID_BLOCK || + pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr] == ARM_VCM4P10_INVALID_BLOCK)) + { + pMVPred->dx = pMVArr [BlockY][BlockX - 1].dx; + pMVPred->dy = pMVArr [BlockY][BlockX - 1].dy; + } + else + { + pMVPred->dx = + ARM_VCM4P10_MEDIAN(pMVArr [BlockY][BlockX - 1].dx, + pMVArr [BlockY - 1][BlockX].dx, + pMVArr [BlockY - 1][BlockXPlusOff].dx); + pMVPred->dy = + ARM_VCM4P10_MEDIAN(pMVArr [BlockY][BlockX - 1].dy, + pMVArr [BlockY - 1][BlockX].dy, + pMVArr [BlockY - 1][BlockXPlusOff].dy); + } + break; + + case ARM_VCM4P10_MVPRED_L: + pMVPred->dx = pMVArr [BlockY][BlockX - 1].dx; + pMVPred->dy = pMVArr [BlockY][BlockX - 1].dy; + break; + case ARM_VCM4P10_MVPRED_U: + pMVPred->dx = pMVArr [BlockY - 1][BlockX].dx; + pMVPred->dy = pMVArr [BlockY - 1][BlockX].dy; + break; + case ARM_VCM4P10_MVPRED_UR: + if (pRefFrArr [BlockYMin1Fr][BlockXPlusOffFr] != ARM_VCM4P10_INVALID_BLOCK) + { + pMVPred->dx = pMVArr [BlockY - 1][BlockXPlusOff].dx; + pMVPred->dy = pMVArr [BlockY - 1][BlockXPlusOff].dy; + } + else + { + pMVPred->dx = pMVArr [BlockY - 1][BlockX - 1].dx; + pMVPred->dy = pMVArr [BlockY - 1][BlockX - 1].dy; + } + break; + default: + break; + } + + return; +} + +/** + * Function: armVCM4P10_BlockMotionSearch + * + * Description: + * Gets best MV for the current block + * + * Parameters: + * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock + * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf + * [in] pSrcRefY - Pointer to the start of luma component of co-located reference MB + * [in] nSrcRefStep - Step size for the pointer pSrcRefY + * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin. + * [in] pCurrPointPos Position of the current macroblock in the current plane. + * [in] pMESpec - Motion estimation structure + * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four + * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right). + * [in] nLamda - For calculating the cost + * [out] pBestCost - Minimum cost for encoding current block + * [out] pBestMV - MV corresponding to best cost + * [in] BlockStartX - Block start X index in integer pels + * [in] BlockStartY - Block start Y index in integer pels + * [in] BlockSizeX - Width of current block + * [in] BlockSizeY - Height of current block + * [in] RefFrame - Index of the reference frame for prediction + * [in] pRefFrArr - Pointer to reference frame array storing neighbouring MVs for prediction + * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction + * [in] pMVPred - Pointer to MV predicted from neighbour MVs + * Remarks: + * + * Return Value: + * OMXResult + * + */ +static OMXResult armVCM4P10_BlockMotionSearch( + const OMX_U8* pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8* pSrcRefY, + OMX_S32 nSrcRefStep, + const OMXRect *pRefRect, + const OMXVCM4P2Coordinate *pCurrPointPos, + void* pMESpec, + + OMX_S32 nLamda, + OMX_S32* pBestCost, + OMXVCMotionVector *pBestMV, + + OMX_U32 BlockStartX, + OMX_U32 BlockStartY, + OMX_U32 BlockSizeX, + OMX_U32 BlockSizeY, + OMX_S32 RefFrame, + OMX_S32 pRefFrArr [][6], + OMXVCMotionVector pMVArr [][12], + OMXVCMotionVector *pMVPred + ) +{ + + OMXVCMotionVector MVCalculated, MVCandidate; + OMX_S32 Cost; + OMXResult RetValue; + OMXVCM4P10MEParams *pMEParams; + OMXVCM4P2Coordinate CurrBlockPos; + + /* Get Predicted Motion Vectors */ + armVCM4P10_SetMotionVectorPredictor ( + BlockStartX, + BlockStartY, + BlockSizeX, + BlockSizeY, + RefFrame, + pRefFrArr, + pMVArr, + pMVPred); + + /* Initialize candidate MV */ + MVCandidate.dx = 0; + MVCandidate.dy = 0; + + CurrBlockPos.x = pCurrPointPos->x + BlockStartX; + CurrBlockPos.y = pCurrPointPos->y + BlockStartY; + + /* Block Match Integer */ + RetValue = omxVCM4P10_BlockMatch_Integer ( + pSrcCurrBuf, + SrcCurrStep, + pSrcRefY, + nSrcRefStep, + pRefRect, + &CurrBlockPos, + BlockSizeX, + BlockSizeY, + nLamda, + pMVPred, + &MVCandidate, + &MVCalculated, + &Cost, + pMESpec); + + /* updated BestMV*/ + /**pBestCost = Cost; + pBestMV->dx = MVCalculated.dx; + pBestMV->dy = MVCalculated.dy;*/ + + pMEParams = (OMXVCM4P10MEParams *) pMESpec; + + /* Block Match Half pel */ + if (pMEParams->halfSearchEnable) + { + RetValue = omxVCM4P10_BlockMatch_Half( + pSrcCurrBuf, + SrcCurrStep, + pSrcRefY, + nSrcRefStep, + BlockSizeX, + BlockSizeY, + nLamda, + pMVPred, + &MVCalculated, /* input/output*/ + &Cost); + } + + /* Block Match Quarter pel */ + if (pMEParams->quarterSearchEnable) + { + RetValue = omxVCM4P10_BlockMatch_Quarter( + pSrcCurrBuf, + SrcCurrStep, + pSrcRefY, + nSrcRefStep, + BlockSizeX, + BlockSizeY, + nLamda, + pMVPred, + &MVCalculated, + &Cost); + } + + /* updated Best Cost and Best MV */ + *pBestCost = Cost; + pBestMV->dx = MVCalculated.dx; + pBestMV->dy = MVCalculated.dy; + + /* + * Skip MB cost calculations of 16x16 inter mode + */ + return RetValue; +} + +/** + * Function: armVCM4P10_PartitionME + * + * Description: + * Gets best cost for the current partition + * + * Parameters: + * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock + * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf + * [in] pSrcRefBufList - Pointer to List of ref buffer of co-located reference MB + * [in] nSrcRefStep - Step size for the pointer pSrcRefY + * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin. + * [in] pCurrPointPos Position of the current macroblock in the current plane. + * [in] pMESpec - Motion estimation structure + * [in] PartWidth - Width of current partition + * [in] PartHeight - Height of current partition + * [in] BlockWidth - Width of current block + * [in] BlockHeight - Height of current block + * [in] PartStartX - Partition start X index in integer pels + * [in] PartStartY - Partition start Y index in integer pels + * [in] pMVArr - Pointer to MV array storing neighbouring MVs for MV prediction + * [in] pRefFrArr - Pointer to reference frame array storing neighbouring MVs for prediction + * [in] Lambda - For calculating the cost + * [out] pCost - Pointer to cost for Inter MB + * + * Return Value: + * OMXResult + * + */ +static OMXResult armVCM4P10_PartitionME ( + const OMX_U8* pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES], + OMX_S32 SrcRefStep, + const OMXRect *pRefRect, + const OMXVCM4P2Coordinate *pCurrPointPos, + void* pMESpec, + + OMX_S32 PartWidth, + OMX_S32 PartHeight, + OMX_S32 BlockWidth, + OMX_S32 BlockHeight, + OMX_S32 PartStartX, + OMX_S32 PartStartY, + + OMXVCMotionVector pMVArr [][12], + OMX_S32 pRefFrArr [][6], + OMXVCMotionVector pMVPredArr [][4], + + OMX_S32 Lambda, + OMX_S32 *pCost +) +{ + OMX_U32 x, y, i, j, ref, OffX, OffY, OffSrc, OffRef; + OMX_S32 BlockCost, PartitionCost, BestCost; + OMX_S32 BestRefFrame=0; + OMXVCMotionVector BestMV [4][4]; + OMXVCMotionVector BestMVPred [4][4]; + OMXVCMotionVector MVPred; + OMXVCMotionVector DstMV; + + BestCost = ARM_VCM4P10_MAX_COST; + + for (ref = 0; ref < ARM_VCM4P10_MAX_FRAMES; ref++) + { + if (pSrcRefBufList [ref] == NULL) + { + /* No reference frame, continue */ + continue; + } + + PartitionCost = 0; + + for (y = 0; y < PartHeight; y += BlockHeight) + { + for (x = 0; x < PartWidth; x += BlockWidth) + { + OffSrc = SrcCurrStep * (PartStartY + y) + PartStartX + x; + OffRef = SrcRefStep * (PartStartY + y) + PartStartX + x; + armVCM4P10_BlockMotionSearch ( + pSrcCurrBuf + OffSrc, + SrcCurrStep, + pSrcRefBufList [ref] + OffRef, + SrcRefStep, + pRefRect, + pCurrPointPos, + pMESpec, + + Lambda, + &BlockCost, + &DstMV, + + x + PartStartX, + y + PartStartY, + BlockWidth, + BlockHeight, + ref, + pRefFrArr, + pMVArr, + &MVPred); + + PartitionCost += BlockCost; + + OffX = (PartStartX + x) >> 2; + OffY = (PartStartY + y) >> 2; + + for (j = 0; j < (BlockHeight >> 2); j++) + { + for (i = 0; i < (BlockWidth >> 2); i++) + { + pMVArr [4 + OffY + j][4 + OffX + i].dx = DstMV.dx; + pMVArr [4 + OffY + j][4 + OffX + i].dy = DstMV.dy; + pMVPredArr [OffY + j][OffX + i].dx = MVPred.dx; + pMVPredArr [OffY + j][OffX + i].dy = MVPred.dy; + } + } + + pRefFrArr [2 + (OffY >> 1)][2 + (OffX >> 1)] = ref; + for (j = 0; j < (BlockHeight >> 3); j++) + { + for (i = 0; i < (BlockWidth >> 3); i++) + { + pRefFrArr [2 + (OffY >> 1) + j][2 + (OffX >> 1) + i] = ref; + } + } + + } + } + + /* + * If PartitionCost is less for this reference frame, motion vectors needs to be backedup + */ + if (PartitionCost <= BestCost) + { + BestCost = PartitionCost; + BestRefFrame = ref; + + for (y = 0; y < (PartHeight/BlockHeight); y++) + { + for (x = 0; x < (PartWidth/BlockWidth); x++) + { + OffX = (PartStartX + x * BlockWidth) >> 2; + OffY = (PartStartY + y * BlockHeight) >> 2; + + BestMV[y][x].dx = pMVArr [4 + OffY][4 + OffX].dx; + BestMV[y][x].dy = pMVArr [4 + OffY][4 + OffX].dy; + BestMVPred[y][x].dx = pMVPredArr [OffY][OffX].dx; + BestMVPred[y][x].dy = pMVPredArr [OffY][OffX].dy; + } + } + } + + } + + /* + * Copy back best reference frame, motion vectors and cost. + */ + for (y = 0; y < (PartHeight/BlockHeight); y++) + { + for (x = 0; x < (PartWidth/BlockWidth); x++) + { + OffX = (PartStartX + x * BlockWidth) >> 2; + OffY = (PartStartY + y * BlockHeight) >> 2; + + for (j = 0; j < (BlockHeight >> 2); j++) + { + for (i = 0; i < (BlockWidth >> 2); i++) + { + pMVArr [4 + OffY + j][4 + OffX + i].dx = BestMV[y][x].dx; + pMVArr [4 + OffY + j][4 + OffX + i].dy = BestMV[y][x].dy; + pMVPredArr [OffY + j][OffX + i].dx = BestMVPred[y][x].dx; + pMVPredArr [OffY + j][OffX + i].dy = BestMVPred[y][x].dy; + } + } + + for (j = 0; j < (BlockHeight >> 3); j++) + { + for (i = 0; i < (BlockWidth >> 3); i++) + { + pRefFrArr [2 + (OffY >> 1) + j][2 + (OffX >> 1) + i] = BestRefFrame; + } + } + } + } + + *pCost = BestCost; + return OMX_Sts_NoErr; + +} + +/** + * Function: armVCM4P10_Intra16x16Estimation + * + * Description: + * Performs MB-level motion estimation for INTER MB type and selects best motion estimation strategy from + * the set of modes supported in baseline profile ISO/IEC 14496-10. + * + * Remarks: + * + * Parameters: + * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock + * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf + * [in] pSrcRecBuf - Pointer to the start of luma component of co-located reconstructed MB + * [in] SrcRecStep - Step size for the pointer pSrcRecBuf + * [in] nMBPosX - Position of MB in the frame w.r.t X axis + * [in] nMBPosY - Position of MB in the frame w.r.t Y axis + * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four + * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right). + * [in] pMBIntra - Array, of dimension four, containing pointers to information associated with four + * adjacent type INTRA MBs (Left, Top, Top-Left, Top-Right). + * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set + * before calling this function + * [in] Lambda - For calculating the cost + * [out] pCost - Pointer to cost for Intra16x16 + * Return Value: + * OMX_Sts_NoErr - No Error + * OMX_Sts_BadArgErr - Bad arguments: + * + */ + +static OMXResult armVCM4P10_Intra16x16Estimation( + const OMX_U8* pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8* pSrcRecBuf, + OMX_S32 SrcRecStep, + const OMXVCM4P2Coordinate *pCurrPointPos, + const OMXVCM4P10MBInfoPtr *pMBInter, + const OMXVCM4P10MBInfoPtr *pMBIntra, + OMXVCM4P10MBInfo *pSrcDstMBCurr, + OMX_U32 *pCost) +{ + OMX_U8 PredBuf [16*16 + 16]; + OMX_U8 *pPred; + OMX_S32 mode; + OMX_S32 Cost; + OMX_S32 availability = 0; + OMXResult Ret; + OMXVCM4P10Intra16x16PredMode IntraMode16x16 [4] = + {OMX_VC_16X16_VERT, OMX_VC_16X16_HOR, + OMX_VC_16X16_DC, OMX_VC_16X16_PLANE}; + OMX_U32 MBPosX = pCurrPointPos->x >> 4; + OMX_U32 MBPosY = pCurrPointPos->y >> 4; + + pPred = armAlignTo16Bytes(PredBuf); + + /* Check for availability of LEFT MB */ + if ((MBPosX != 0) && (pMBIntra [0] != 0 || pMBInter [0] != 0)) + { + availability |= OMX_VC_LEFT; + } + + /* Check for availability of UP MB */ + if ((MBPosY != 0) && (pMBIntra [1] != 0 || pMBInter [1] != 0)) + { + availability |= OMX_VC_UPPER; + } + + /* Check for availability of UP-LEFT MB */ + if ((MBPosX > 0) && (MBPosY > 0) && + (pMBIntra [2] != 0 || pMBInter [2] != 0)) + { + availability |= OMX_VC_UPPER_LEFT; + } + + *pCost = ARM_VCM4P10_MAX_COST; + for (mode = 0; mode < 4; mode++) + { + Ret = omxVCM4P10_PredictIntra_16x16( + pSrcRecBuf - 1, + pSrcRecBuf - SrcRecStep, + pSrcRecBuf - SrcRecStep - 1, + pPred, + SrcRecStep, + 16, + IntraMode16x16 [mode], + availability); + if (Ret == OMX_Sts_NoErr) + { + armVCCOMM_SAD( + pSrcCurrBuf, + SrcCurrStep, + pPred, + 16, + &Cost, + 16, + 16); + if (Cost < *pCost) + { + *pCost = Cost; + pSrcDstMBCurr->Intra16x16PredMode = IntraMode16x16 [mode]; + } + + } + + } + + return OMX_Sts_NoErr; +} + +/** + * Function: armVCM4P10_Intra4x4Estimation + * + * Description: + * Performs MB-level motion estimation for Intra 4x4 MB type and selects + * the best set of modes supported in baseline profile. + * + * Parameters: + * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock + * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf + * [in] pSrcRecBuf - Pointer to the start of luma component of co-located reconstructed MB + * [in] SrcRecStep - Step size for the pointer pSrcRecBuf + * [in] nMBPosX - Position of MB in the frame w.r.t X axis + * [in] nMBPosY - Position of MB in the frame w.r.t Y axis + * [in] pMBIntra - Array, of dimension four, containing pointers to information associated with four + * adjacent type INTRA MBs (Left, Top, Top-Left, Top-Right). + * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set + * before calling this function + * [in] Lambda - For calculating the cost + * [out] pCost - Pointer to cost for Intra4x4 + * Return Value: + * OMX_Sts_NoErr - No Error + * OMX_Sts_BadArgErr - Bad arguments: + * + */ + +static OMXResult armVCM4P10_Intra4x4Estimation( + const OMX_U8* pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8* pSrcRecBuf, + OMX_S32 SrcRecStep, + const OMXVCM4P10MBInfoPtr *pMBIntra, + OMXVCM4P10MBInfo *pSrcDstMBCurr, + OMX_U32 *pCost) +{ + OMX_S32 x, y, Block4x4, Block8x8; + OMX_S32 Cost; + + /* + * PredIntra4x4Mode will store prediction modes of 4x4 blocks. + * Modes for current MB starts at index [1][1]. + * Modes of nighbouring MB's will be as shown below + * A value of ARM_VCM4P10_INVALID_BLOCK for any block in this array means + * that block is not available for prediction. + * + * c3 b0 b1 b2 b3 d0 d1 d2 d3 + * a0 xx xx xx xx - - - - + * a1 xx xx xx xx - - - - + * a2 xx xx xx xx - - - - + * a3 xx xx xx xx - - - - + * + */ + OMX_S32 PredIntra4x4Mode [5][9]; + + /* + * pSrcY stores re-construsted source array of size 3MB X 2MB as below + * + * MB11 MB12 MB13 + * MB21 MB22 MB23 + * + * This array will be used for local reconstruction of 4x4 blocks + * with best prediction mode within an MB + */ + OMX_U8 pSrcY [(16*3)*(16*2)]; + OMX_S32 StepSrcY; + + /* init */ + *pCost = 0; + + for (y = 0; y < 5; y++) + { + for (x = 0; x < 9; x++) + { + /* + * Initialize with value of ARM_VCM4P10_INVALID_BLOCK, to mean this + * 4x4 block is not available + */ + PredIntra4x4Mode [y][x] = ARM_VCM4P10_INVALID_BLOCK; + } + } + + /* Replace ARM_VCM4P10_INVALID_BLOCK value with available MBs values*/ + for (x = 0; x < 4; x++) + { + /* Store values of b0, b1, b2, b3 */ + if (pMBIntra[1] != NULL) + { + PredIntra4x4Mode [0][x + 1] = + pMBIntra[1]->pIntra4x4PredMode[3*4 + x]; + } + + /* Store values of d0, d1, d2, d3 */ + if (pMBIntra[3] != NULL) + { + PredIntra4x4Mode [0][x + 5] = + pMBIntra[3]->pIntra4x4PredMode[3*4 + x]; + } + } + + /* Store values of c3 */ + if (pMBIntra[2] != NULL) + { + PredIntra4x4Mode [0][0] = pMBIntra[2]->pIntra4x4PredMode[15]; + } + + for (y = 0; y < 4; y++) + { + /* Store values of a0, a1, a2, a3 */ + if (pMBIntra[0] != NULL) + { + PredIntra4x4Mode [y + 1][0] = + pMBIntra[0]->pIntra4x4PredMode[y*4 + 3]; + } + } + + /* + * Update neighbouring Pred mode array which will be used for + * prediction of Intra4x4 modes. + */ + + StepSrcY = 16 * 3; + for (y = 0; y < (16 * 2); y++) + { + for (x = 0; x < (16 * 3); x++) + { + pSrcY [StepSrcY * y + x] = + pSrcRecBuf [SrcRecStep * (y - 16) + x - 16]; + } + } + + /* for each 8x8 block */ + for (Block8x8 = 0; Block8x8 < 4; Block8x8++) + { + /* for each 4x4 block inside 8x8 block */ + for (Block4x4 = 0; Block4x4 < 4; Block4x4++) + { + armVCM4P10_Mode4x4Decision ( + pSrcCurrBuf, + SrcCurrStep, + pSrcDstMBCurr, + Block8x8, + Block4x4, + pSrcY + 16 * StepSrcY + 16, + StepSrcY, + PredIntra4x4Mode, + &Cost); + + *pCost += Cost; + } + } + return OMX_Sts_NoErr; +} + +/** + * Function: armVCM4P10_InterMEMB + * + * Description: + * Performs MB-level motion estimation for INTER MB type and selects best motion estimation strategy from + * the set of modes supported in baseline profile ISO/IEC 14496-10. + * + * Remarks: + * + * Parameters: + * [in] pSrcCurrBuf - Pointer to the start of luma component of current Macroblock + * [in] SrcCurrStep - Step size for the pointer pSrcCurrBuf + * [in] pSrcRefBufList - Pointer to the start of luma component of co-located reference MB + * [in] SrcRefStep - Step size for the pointer pSrcRefY + * [in] pRefRect Pointer to the valid reference rectangle; relative to the image origin. + * [in] pCurrPointPos Position of the current macroblock in the current plane. + * [in] pMESpec - Motion estimation structure + * [in] pMBInter - Array, of dimension four, containing pointers to information associated with four + * adjacent type INTER MBs (Left, Top, Top-Left, Top-Right). + * [in/out] pSrcDstMBCurr - Pointer to information structure for the current MB. Following member should be set + * before calling this function + * [in] Lambda - For calculating the cost + * [out] pDstCost - Pointer to cost for Inter MB + * Return Value: + * OMX_Sts_NoErr - No Error + * OMX_Sts_BadArgErr - Bad arguments: + * + */ + +static OMXResult armVCM4P10_InterMEMB( + const OMX_U8 *pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES], + OMX_S32 SrcRefStep, + const OMXRect *pRefRect, + const OMXVCM4P2Coordinate *pCurrPointPos, + OMX_U32 Lambda, + void *pMESpec, + const OMXVCM4P10MBInfoPtr *pMBInter, + OMXVCM4P10MBInfoPtr pSrcDstMBCurr, + OMX_U32 *pDstCost) +{ + OMX_S32 i, j, x, y, mode; + OMX_U32 Block8x8, XPerMB, YPerMB, Block2x, Block2y; + OMX_S32 PartStartX = 0, PartStartY = 0; + OMX_S32 PartWidth = 8, PartHeight = 8, BlockWidth = 4, BlockHeight = 4; + const OMX_U32 BlkSz [4][2] = {{4,4}, {4,8}, {8,4}}; + const OMX_U32 PartSz [4][2] = {{8,8}, {8,16}, {16,8}, {16,16}}; + const OMXVCM4P10SubMacroblockType + ModeSubMBType4x4 [] = {OMX_VC_SUB_P_4x4, OMX_VC_SUB_P_4x8, + OMX_VC_SUB_P_8x4, OMX_VC_SUB_P_8x8}; + const OMXVCM4P10MacroblockType + ModeMBType [] = {OMX_VC_P_8x8, OMX_VC_P_8x16, OMX_VC_P_16x8, OMX_VC_P_16x16}; + + OMXVCM4P10MEParams *pMBOptions; + /* + * RefFrArr and MVArr will be used for temporary storage of Reference frame index and MVs + * It will store RefIndex and MVs of 6 MBs as shown below + * + * |------|------|------| + * |Tp-Lt |Top |Tp-R | + * | MB | MB | MB | + * |------|------|------| + * |Left | Curr | | + * | MB | MB | | + * |------|------|------| + */ + OMX_S32 RefFrArr [4][6]; + OMXVCMotionVector MVArr [8][12]; + OMXVCMotionVector MVPredArr [4][4]; + + /* + * IndexToLoc will translate pMBInter index into spacial arrangement of MBs + */ + OMX_S32 IndexToLoc [] = {2,1,3,0}; + OMX_U32 part, MaxPart; + OMX_S32 Cost, MotionCost8x8 [4], MBCost, BestCost; + + /* + * Update neighbouring MV array and Ref frame array which will be used for + * prediction of MVs and Ref frames. + */ + + /* Set cost to a high value */ + Cost = BestCost = ARM_VCM4P10_MAX_COST; + + for (y = 0; y < 8; y++) + { + for (x = 0; x < 12; x++) + { + i = 3 * (y >> 2) + (x >> 2); + if ((y < 4 || x < 4) && (pMBInter[IndexToLoc[i]] != NULL)) + { + MVArr [y][x].dx = + pMBInter[IndexToLoc[i]]->pMV0[y % 4][x % 4].dx; + MVArr [y][x].dy = + pMBInter[IndexToLoc[i]]->pMV0[y % 4][x % 4].dy; + } + else + { + MVArr [y][x].dx = 0; + MVArr [y][x].dy = 0; + } + } + } + + for (y = 0; y < 4; y++) + { + for (x = 0; x < 6; x++) + { + i = 3 * (y >> 1) + (x >> 1); + if ((y < 2 || x < 2) && (pMBInter[IndexToLoc[i]] != NULL)) + { + RefFrArr [y][x] = + pMBInter[IndexToLoc[i]]->pRefL0Idx [(y % 2) * 2 + (x % 2)]; + } + else + { + RefFrArr [y][x] = ARM_VCM4P10_INVALID_BLOCK; + } + } + } + + for (y = 0; y < 4; y++) + { + for (x = 0; x < 4; x++) + { + MVPredArr [y][x].dx = 0; + MVPredArr [y][x].dy = 0; + } + } + /* + * Motion Estimation for 8x8 MB Partition + */ + + for (i = 0; i < 4; i++) + { + MotionCost8x8 [i] = 0; + } + + pMBOptions = (OMXVCM4P10MEParams *) pMESpec; + + if (pMBOptions->blockSplitEnable8x8 == 1 && + pMBOptions->blockSplitEnable4x4 == 1) + { + pSrcDstMBCurr->mbType = OMX_VC_P_8x8; + + PartWidth = PartSz [0][0]; + PartHeight = PartSz [0][1]; + + /* For each 8x8 partitions */ + for (Block8x8 = 0; Block8x8 < 4; Block8x8++) + { + PartStartX = (Block8x8 % 2) << 3; + PartStartY = (Block8x8 / 2) << 3; + + Block2x = (Block8x8 & 1) << 1; + Block2y = (Block8x8 >> 1) << 1; + + BestCost = ARM_VCM4P10_MAX_COST; + for (mode = 0; mode < 3; mode++) + { + BlockWidth = BlkSz [mode][0]; + BlockHeight = BlkSz [mode][1]; + + armVCM4P10_PartitionME ( + pSrcCurrBuf, + SrcCurrStep, + pSrcRefBufList, + SrcRefStep, + pRefRect, + pCurrPointPos, + pMESpec, + + PartWidth, + PartHeight, + BlockWidth, + BlockHeight, + PartStartX, + PartStartY, + + MVArr, + RefFrArr, + MVPredArr, + + Lambda, + &Cost); + + if (Cost <= BestCost) + { + /* Update cost */ + BestCost = Cost; + + /* Update MBCurr struct */ + pSrcDstMBCurr->subMBType [Block8x8] = ModeSubMBType4x4 [mode]; + + pSrcDstMBCurr->pRefL0Idx [Block8x8] = RefFrArr [2 + (PartStartY >> 3)][2 + (PartStartX >> 3)]; + + /* Update pMV0 and pMVPred of MBCurr struct */ + for (j = 0; j < 2; j++) + { + for (i = 0; i < 2; i++) + { + pSrcDstMBCurr->pMV0 [Block2y + j][Block2x + i].dx = + MVArr [4 + Block2y + j][4 + Block2x + i].dx; + pSrcDstMBCurr->pMV0 [Block2y + j][Block2x + i].dy = + MVArr [4 + Block2y + j][4 + Block2x + i].dy; + + pSrcDstMBCurr->pMVPred [Block2y + j][Block2x + i].dx = + MVPredArr [Block2y + j][Block2x + i].dx; + pSrcDstMBCurr->pMVPred [Block2y + j][Block2x + i].dy = + MVPredArr [Block2y + j][Block2x + i].dy; + } + } + } + } + + /* Update cost */ + MotionCost8x8 [Block8x8] = BestCost; + } + + /* Cost for mbType OMX_VC_P_8x8 */ + BestCost = 0; + for (i = 0; i < 4; i++) + { + BestCost += MotionCost8x8 [i]; + } + } + else + { + /* Set sub MB type to 8x8 */ + for (i = 0; i < 4; i++) + { + pSrcDstMBCurr->subMBType [i] = OMX_VC_SUB_P_8x8; + } + } + + /* + * Motion Estimation for 8x8, 8x16, 16x8 and 16x16 MB Partition + * If pMBOptions->b8x8BlockSplitEnable is 0, do only 16x16 ME (mode 3) + */ + for (mode = (pMBOptions->blockSplitEnable8x8 == 1 ? 0 : 3); mode < 4; mode++) + { + BlockWidth = PartWidth = PartSz [mode][0]; + BlockHeight = PartHeight = PartSz [mode][1]; + + XPerMB = 16 / PartWidth; + YPerMB = 16 / PartHeight; + MaxPart = XPerMB * YPerMB; + + MBCost = 0; + + /* part size 4, 2, 2 and 1 corresponding to 8x8, 8x16, 16x8 and 16x16 MB */ + for (part = 0; part < MaxPart; part++) + { + PartStartX = (part % XPerMB) * PartWidth; + PartStartY = (part / XPerMB) * PartHeight; + + armVCM4P10_PartitionME ( + pSrcCurrBuf, + SrcCurrStep, + pSrcRefBufList, + SrcRefStep, + pRefRect, + pCurrPointPos, + pMESpec, + + PartWidth, + PartHeight, + BlockWidth, + BlockHeight, + PartStartX, + PartStartY, + + MVArr, + RefFrArr, + MVPredArr, + + Lambda, + &Cost); + + MBCost += Cost; + } + + if (MBCost <= BestCost) + { + /* Update cost */ + BestCost = MBCost; + + /* Update mbType of MBCurr struct */ + pSrcDstMBCurr->mbType = ModeMBType [mode]; + + /* Update pMV0 and pMVPred of MBCurr struct */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + pSrcDstMBCurr->pMV0 [j][i].dx = MVArr [4+j][4+i].dx; + pSrcDstMBCurr->pMV0 [j][i].dy = MVArr [4+j][4+i].dy; + pSrcDstMBCurr->pMVPred [j][i].dx = MVPredArr [j][i].dx; + pSrcDstMBCurr->pMVPred [j][i].dy = MVPredArr [j][i].dy; + } + } + for (j = 0; j < 2; j++) + { + for (i = 0; i < 2; i++) + { + pSrcDstMBCurr->pRefL0Idx [j*2+i] = RefFrArr [2+j][2+i]; + } + } + } + + } + + /* Update Best Cost */ + *pDstCost = BestCost; + + return OMX_Sts_NoErr; +} + +/** + * Function: omxVCM4P10_MotionEstimationMB (6.3.5.3.1) + * + * Description: + * Performs MB-level motion estimation and selects best motion estimation + * strategy from the set of modes supported in baseline profile [ISO14496-10]. + * + * Input Arguments: + * + * pSrcCurrBuf - Pointer to the current position in original picture plane; + * 16-byte alignment required + * pSrcRefBufList - Pointer to an array with 16 entries. Each entry points + * to the top-left corner of the co-located MB in a reference + * picture. The array is filled from low-to-high with valid + * reference frame pointers; the unused high entries should be set + * to NULL. Ordering of the reference frames should follow + * [ISO14496-10] subclause 8.2.4 Decoding Process for Reference + * Picture Lists. The entries must be 16-byte aligned. + * pSrcRecBuf - Pointer to the top-left corner of the co-located MB in the + * reconstructed picture; must be 16-byte aligned. + * SrcCurrStep - Width of the original picture plane in terms of full + * pixels; must be a multiple of 16. + * SrcRefStep - Width of the reference picture plane in terms of full + * pixels; must be a multiple of 16. + * SrcRecStep - Width of the reconstructed picture plane in terms of full + * pixels; must be a multiple of 16. + * pRefRect - Pointer to the valid reference rectangle; relative to the + * image origin. + * pCurrPointPos - Position of the current macroblock in the current plane. + * Lambda - Lagrange factor for computing the cost function + * pMESpec - Pointer to the motion estimation specification structure; must + * have been allocated and initialized prior to calling this + * function. + * pMBInter - Array, of dimension four, containing pointers to information + * associated with four adjacent type INTER MBs (Left, Top, + * Top-Left, Top-Right). Any pointer in the array may be set equal + * to NULL if the corresponding MB doesn t exist or is not of type + * INTER. pMBInter[0] - Pointer to left MB information pMBInter[1] + * - Pointer to top MB information pMBInter[2] - Pointer to + * top-left MB information pMBInter[3] - Pointer to top-right MB + * information + * pMBIntra - Array, of dimension four, containing pointers to information + * associated with four adjacent type INTRA MBs (Left, Top, + * Top-Left, Top-Right). Any pointer in the array may be set equal + * to NULL if the corresponding MB doesn t exist or is not of type + * INTRA. pMBIntra[0] - Pointer to left MB information pMBIntra[1] + * - Pointer to top MB information pMBIntra[2] - Pointer to + * top-left MB information pMBIntra[3] - Pointer to top-right MB + * information + * pSrcDstMBCurr - Pointer to information structure for the current MB. + * The following entries should be set prior to calling the + * function: sliceID - the number of the slice the to which the + * current MB belongs. + * + * Output Arguments: + * + * pDstCost - Pointer to the minimum motion cost for the current MB. + * pDstBlockSAD - Pointer to the array of SADs for each of the sixteen luma + * 4x4 blocks in each MB. The block SADs are in scan order for + * each MB. For implementations that cannot compute the SAD values + * individually, the maximum possible value (0xffff) is returned + * for each of the 16 block SAD entries. + * pSrcDstMBCurr - Pointer to updated information structure for the current + * MB after MB-level motion estimation has been completed. The + * following fields are updated by the ME function. The following + * parameter set quantifies the MB-level ME search results: MbType + * subMBType[4] pMV0[4][4] pMVPred[4][4] pRefL0Idx[4] + * Intra16x16PredMode pIntra4x4PredMode[4][4] + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - One of more of the following pointers is NULL: pSrcCurrBuf, + * pSrcRefBufList, pSrcRecBuf, pRefRect, pCurrPointPos, pMESpec, + * pMBInter, pMBIntra,pSrcDstMBCurr, pDstCost, pSrcRefBufList[0] + * - SrcRefStep, SrcRecStep are not multiples of 16 + * - iBlockWidth or iBlockHeight are values other than 4, 8, or 16. + * - Any alignment restrictions are violated + * + */ + +OMXResult omxVCM4P10_MotionEstimationMB( + const OMX_U8 *pSrcCurrBuf, + OMX_S32 SrcCurrStep, + const OMX_U8 *pSrcRefBufList[ARM_VCM4P10_MAX_FRAMES], + OMX_S32 SrcRefStep, + const OMX_U8 *pSrcRecBuf, + OMX_S32 SrcRecStep, + const OMXRect *pRefRect, + const OMXVCM4P2Coordinate *pCurrPointPos, + OMX_U32 Lambda, + void *pMESpec, + const OMXVCM4P10MBInfoPtr *pMBInter, + const OMXVCM4P10MBInfoPtr *pMBIntra, + OMXVCM4P10MBInfo *pSrcDstMBCurr, + OMX_INT *pDstCost, + OMX_U16 *pDstBlockSAD) +{ + OMX_U32 Cost, i, IntraFlag = 1; + OMXVCM4P10MEParams *pMEParams; + + /* check for argument error */ + armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRefBufList == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRecBuf == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pMBInter == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pMBIntra == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstCost == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(SrcRefStep <= 0 || SrcRefStep & 15, OMX_Sts_BadArgErr) + armRetArgErrIf(SrcRecStep <= 0 || SrcRecStep & 15, OMX_Sts_BadArgErr) + armRetArgErrIf(SrcCurrStep <= 0 || SrcCurrStep & 15, OMX_Sts_BadArgErr) + + armRetArgErrIf(armNot16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot16ByteAligned(pSrcRecBuf), OMX_Sts_BadArgErr) + + for (i = 0; i < ARM_VCM4P10_MAX_FRAMES; i++) + { + armRetArgErrIf(pSrcRefBufList [i] != NULL && + armNot16ByteAligned(pSrcRefBufList [i]), OMX_Sts_BadArgErr) + + /* Check if current MB needs INTER cost calculations */ + if (pSrcRefBufList [i] != NULL && IntraFlag == 1) + { + IntraFlag = 0; + } + } + + *pDstCost = ARM_VCM4P10_MAX_COST; + /* + * Inter cost calculations + */ + + /* check this MB can be Inter */ + if (IntraFlag != 1) + { + armVCM4P10_InterMEMB( + pSrcCurrBuf, + SrcCurrStep, + pSrcRefBufList, + SrcRefStep, + pRefRect, + pCurrPointPos, + Lambda, + pMESpec, + pMBInter, + pSrcDstMBCurr, + &Cost + ); + + *pDstCost = Cost; + } + + pMEParams = (OMXVCM4P10MEParams *)pMESpec; + + if (pMEParams->intraEnable4x4 == 1) + { + /* + * Intra 4x4 cost calculations + */ + armVCM4P10_Intra4x4Estimation( + pSrcCurrBuf, + SrcCurrStep, + pSrcRecBuf, + SrcRecStep, + pMBIntra, + pSrcDstMBCurr, + &Cost + ); + + if (Cost <= *pDstCost) + { + *pDstCost = Cost; + pSrcDstMBCurr->mbType = OMX_VC_INTRA_4x4; + + } + + } + + /* + * Cost for Intra 16x16 mode + */ + + armVCM4P10_Intra16x16Estimation( + pSrcCurrBuf, + SrcCurrStep, + pSrcRecBuf, + SrcRecStep, + pCurrPointPos, + pMBInter, + pMBIntra, + pSrcDstMBCurr, + &Cost + ); + + if (Cost <= *pDstCost) + { + *pDstCost = Cost; + pSrcDstMBCurr->mbType = OMX_VC_INTRA_16x16; + } + + /* + * Update pDstBlockSAD to max value + */ + armVCM4P10_CalculateBlockSAD( pSrcDstMBCurr, + pSrcCurrBuf, + SrcCurrStep, + pSrcRefBufList, + SrcRefStep, + pSrcRecBuf, + SrcRecStep, + pRefRect, + pCurrPointPos, + pMBInter, + pMBIntra, + pDstBlockSAD); + + + return OMX_Sts_NoErr; +} + + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c new file mode 100644 index 0000000..d6ca783 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntraChroma_8x8.c @@ -0,0 +1,284 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_PredictIntraChroma_8x8.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 Chroma 8x8 intra prediction module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Perform DC style intra prediction, upper block has priority + * + * Parameters: + * [in] pSrcLeft Pointer to the buffer of 16 left coefficients: + * p[x, y] (x = -1, y = 0..3) + * [in] pSrcAbove Pointer to the buffer of 16 above coefficients: + * p[x,y] (x = 0..3, y = -1) + * [in] leftStep Step of left coefficient buffer + * [in] dstStep Step of the destination buffer + * [in] availability Neighboring 16x16 MB availability flag + * [out] pDst Pointer to the destination buffer + * + * Return Value: + * None + */ + +static void armVCM4P10_PredictIntraDCUp4x4( + const OMX_U8* pSrcLeft, + const OMX_U8 *pSrcAbove, + OMX_U8* pDst, + OMX_INT leftStep, + OMX_INT dstStep, + OMX_S32 availability +) +{ + int x, y, Sum=0, Count = 0; + + if (availability & OMX_VC_UPPER) + { + for (x=0; x<4; x++) + { + Sum += pSrcAbove[x]; + } + Count++; + } + else if (availability & OMX_VC_LEFT) + { + for (y=0; y<4; y++) + { + Sum += pSrcLeft[y*leftStep]; + } + Count++; + } + if (Count==0) + { + Sum = 128; + } + else + { + Sum = (Sum + 2) >> 2; + } + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = (OMX_U8)Sum; + } + } +} + +/* + * Description: + * Perform DC style intra prediction, left block has priority + * + * Parameters: + * [in] pSrcLeft Pointer to the buffer of 16 left coefficients: + * p[x, y] (x = -1, y = 0..3) + * [in] pSrcAbove Pointer to the buffer of 16 above coefficients: + * p[x,y] (x = 0..3, y = -1) + * [in] leftStep Step of left coefficient buffer + * [in] dstStep Step of the destination buffer + * [in] availability Neighboring 16x16 MB availability flag + * [out] pDst Pointer to the destination buffer + * + * Return Value: + * None + */ + +static void armVCM4P10_PredictIntraDCLeft4x4( + const OMX_U8* pSrcLeft, + const OMX_U8 *pSrcAbove, + OMX_U8* pDst, + OMX_INT leftStep, + OMX_INT dstStep, + OMX_S32 availability +) +{ + int x, y, Sum=0, Count = 0; + + if (availability & OMX_VC_LEFT) + { + for (y=0; y<4; y++) + { + Sum += pSrcLeft[y*leftStep]; + } + Count++; + } + else if (availability & OMX_VC_UPPER) + { + for (x=0; x<4; x++) + { + Sum += pSrcAbove[x]; + } + Count++; + } + if (Count==0) + { + Sum = 128; + } + else + { + Sum = (Sum + 2) >> 2; + } + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = (OMX_U8)Sum; + } + } +} + +/** + * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3) + * + * Description: + * Performs intra prediction for chroma samples. + * + * Input Arguments: + * + * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y= + * 0..7). + * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y + * = -1); must be aligned on an 8-byte boundary. + * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) + * leftStep - Step of left pixel buffer; must be a multiple of 8. + * dstStep - Step of the destination buffer; must be a multiple of 8. + * predMode - Intra chroma prediction mode, please refer to section 3.4.3. + * availability - Neighboring chroma block availability flag, please refer + * to "Neighboring Macroblock Availability". + * + * Output Arguments: + * + * pDst - Pointer to the destination buffer; must be aligned on an 8-byte + * boundary. + * + * Return Value: + * If the function runs without error, it returns OMX_Sts_NoErr. + * If any of the following cases occurs, the function returns + * OMX_Sts_BadArgErr: + * pDst is NULL. + * dstStep < 8 or dstStep is not a multiple of 8. + * leftStep is not a multiple of 8. + * predMode is not in the valid range of enumeration + * OMXVCM4P10IntraChromaPredMode. + * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set + * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available. + * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT + * indicating p[-1,y] (y = 0..7) is not available. + * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set + * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating + * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not + * available. + * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. + * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. + * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. + * either pSrcAbove or pDst is not aligned on a 8-byte boundary. Note: + * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if + * they are not used by intra prediction implied in predMode. + * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma + * prediction. + * + */ +OMXResult omxVCM4P10_PredictIntraChroma_8x8( + const OMX_U8* pSrcLeft, + const OMX_U8 *pSrcAbove, + const OMX_U8 *pSrcAboveLeft, + OMX_U8* pDst, + OMX_INT leftStep, + OMX_INT dstStep, + OMXVCM4P10IntraChromaPredMode predMode, + OMX_S32 availability + ) +{ + int x, y, Sum; + int H, V, a, b, c; + + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(dstStep < 8, OMX_Sts_BadArgErr); + armRetArgErrIf((dstStep % 8) != 0, OMX_Sts_BadArgErr); + armRetArgErrIf((leftStep % 8) != 0, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_CHROMA_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_CHROMA_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf((unsigned)predMode > OMX_VC_CHROMA_PLANE, OMX_Sts_BadArgErr); + + switch (predMode) + { + case OMX_VC_CHROMA_DC: + armVCM4P10_PredictIntraDC4x4( pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability); + armVCM4P10_PredictIntraDCUp4x4( pSrcLeft, pSrcAbove+4, pDst+4, leftStep, dstStep, availability); + armVCM4P10_PredictIntraDCLeft4x4( pSrcLeft+4*leftStep, pSrcAbove, pDst+4*dstStep, leftStep, dstStep, availability); + armVCM4P10_PredictIntraDC4x4( pSrcLeft+4*leftStep, pSrcAbove+4, pDst+4+4*dstStep, leftStep, dstStep, availability); + break; + + case OMX_VC_CHROMA_HOR: + for (y=0; y<8; y++) + { + for (x=0; x<8; x++) + { + pDst[y*dstStep+x] = pSrcLeft[y*leftStep]; + } + } + break; + + case OMX_VC_CHROMA_VERT: + for (y=0; y<8; y++) + { + for (x=0; x<8; x++) + { + pDst[y*dstStep+x] = pSrcAbove[x]; + } + } + break; + + case OMX_VC_CHROMA_PLANE: + H = 4*(pSrcAbove[7] - pSrcAboveLeft[0]); + for (x=2; x>=0; x--) + { + H += (x+1)*(pSrcAbove[4+x] - pSrcAbove[2-x]); + } + V = 4*(pSrcLeft[7*leftStep] - pSrcAboveLeft[0]); + for (y=2; y>=0; y--) + { + V += (y+1)*(pSrcLeft[(4+y)*leftStep] - pSrcLeft[(2-y)*leftStep]); + } + a = 16*(pSrcAbove[7] + pSrcLeft[7*leftStep]); + b = (17*H+16)>>5; + c = (17*V+16)>>5; + for (y=0; y<8; y++) + { + for (x=0; x<8; x++) + { + Sum = (a + b*(x-3) + c*(y-3) + 16)>>5; + pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum); + } + } + break; + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c new file mode 100644 index 0000000..c90cb4c --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_16x16.c @@ -0,0 +1,198 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_PredictIntra_16x16.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 16x16 intra prediction module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_PredictIntra_16x16 (6.3.3.1.2) + * + * Description: + * Perform Intra_16x16 prediction for luma samples. If the upper-right block + * is not available, then duplication work should be handled inside the + * function. Users need not define them outside. + * + * Input Arguments: + * + * pSrcLeft - Pointer to the buffer of 16 left pixels: p[x, y] (x = -1, y = + * 0..15) + * pSrcAbove - Pointer to the buffer of 16 above pixels: p[x,y] (x = 0..15, + * y= -1); must be aligned on a 16-byte boundary. + * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) + * leftStep - Step of left pixel buffer; must be a multiple of 16. + * dstStep - Step of the destination buffer; must be a multiple of 16. + * predMode - Intra_16x16 prediction mode, please refer to section 3.4.1. + * availability - Neighboring 16x16 MB availability flag. Refer to + * section 3.4.4. + * + * Output Arguments: + * + * pDst -Pointer to the destination buffer; must be aligned on a 16-byte + * boundary. + * + * Return Value: + * If the function runs without error, it returns OMX_Sts_NoErr. + * If one of the following cases occurs, the function returns + * OMX_Sts_BadArgErr: + * pDst is NULL. + * dstStep < 16. or dstStep is not a multiple of 16. + * leftStep is not a multiple of 16. + * predMode is not in the valid range of enumeration + * OMXVCM4P10Intra16x16PredMode + * predMode is OMX_VC_16X16_VERT, but availability doesn't set + * OMX_VC_UPPER indicating p[x,-1] (x = 0..15) is not available. + * predMode is OMX_VC_16X16_HOR, but availability doesn't set OMX_VC_LEFT + * indicating p[-1,y] (y = 0..15) is not available. + * predMode is OMX_VC_16X16_PLANE, but availability doesn't set + * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating + * p[x,-1](x = 0..15), or p[-1,y] (y = 0..15), or p[-1,-1] is not + * available. + * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. + * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. + * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. + * either pSrcAbove or pDst is not aligned on a 16-byte boundary. + * + * Note: + * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if + * they are not used by intra prediction implied in predMode. + * Note: + * OMX_VC_UPPER_RIGHT is not used in intra_16x16 luma prediction. + * + */ +OMXResult omxVCM4P10_PredictIntra_16x16( + const OMX_U8* pSrcLeft, + const OMX_U8 *pSrcAbove, + const OMX_U8 *pSrcAboveLeft, + OMX_U8* pDst, + OMX_INT leftStep, + OMX_INT dstStep, + OMXVCM4P10Intra16x16PredMode predMode, + OMX_S32 availability) +{ + int x,y,Sum,Count; + int H,V,a,b,c; + + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(dstStep < 16, OMX_Sts_BadArgErr); + armRetArgErrIf((dstStep % 16) != 0, OMX_Sts_BadArgErr); + armRetArgErrIf((leftStep % 16) != 0, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot16ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); + armRetArgErrIf(armNot16ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_16X16_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_16X16_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_16X16_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf((unsigned)predMode > OMX_VC_16X16_PLANE, OMX_Sts_BadArgErr); + + switch (predMode) + { + case OMX_VC_16X16_VERT: + for (y=0; y<16; y++) + { + for (x=0; x<16; x++) + { + pDst[y*dstStep+x] = pSrcAbove[x]; + } + } + break; + + case OMX_VC_16X16_HOR: + for (y=0; y<16; y++) + { + for (x=0; x<16; x++) + { + pDst[y*dstStep+x] = pSrcLeft[y*leftStep]; + } + } + break; + + case OMX_VC_16X16_DC: + /* This can always be used even if no blocks available */ + Sum = 0; + Count = 0; + if (availability & OMX_VC_LEFT) + { + for (y=0; y<16; y++) + { + Sum += pSrcLeft[y*leftStep]; + } + Count++; + } + if (availability & OMX_VC_UPPER) + { + for (x=0; x<16; x++) + { + Sum += pSrcAbove[x]; + } + Count++; + } + if (Count==0) + { + Sum = 128; + } + else if (Count==1) + { + Sum = (Sum + 8) >> 4; + } + else /* Count = 2 */ + { + Sum = (Sum + 16) >> 5; + } + for (y=0; y<16; y++) + { + for (x=0; x<16; x++) + { + pDst[y*dstStep+x] = (OMX_U8)Sum; + } + } + break; + + case OMX_VC_16X16_PLANE: + H = 8*(pSrcAbove[15] - pSrcAboveLeft[0]); + for (x=6; x>=0; x--) + { + H += (x+1)*(pSrcAbove[8+x] - pSrcAbove[6-x]); + } + V = 8*(pSrcLeft[15*leftStep] - pSrcAboveLeft[0]); + for (y=6; y>=0; y--) + { + V += (y+1)*(pSrcLeft[(8+y)*leftStep] - pSrcLeft[(6-y)*leftStep]); + } + a = 16*(pSrcAbove[15] + pSrcLeft[15*leftStep]); + b = (5*H+32)>>6; + c = (5*V+32)>>6; + for (y=0; y<16; y++) + { + for (x=0; x<16; x++) + { + Sum = (a + b*(x-7) + c*(y-7) + 16)>>5; + pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum); + } + } + break; + } + + return OMX_Sts_NoErr; +} + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c new file mode 100644 index 0000000..3fa8212 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_PredictIntra_4x4.c @@ -0,0 +1,338 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_PredictIntra_4x4.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 4x4 intra prediction module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_PredictIntra_4x4 (6.3.3.1.1) + * + * Description: + * Perform Intra_4x4 prediction for luma samples. If the upper-right block is + * not available, then duplication work should be handled inside the function. + * Users need not define them outside. + * + * Input Arguments: + * + * pSrcLeft - Pointer to the buffer of 4 left pixels: + * p[x, y] (x = -1, y = 0..3) + * pSrcAbove - Pointer to the buffer of 8 above pixels: + * p[x,y] (x = 0..7, y =-1); + * must be aligned on a 4-byte boundary. + * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) + * leftStep - Step of left pixel buffer; must be a multiple of 4. + * dstStep - Step of the destination buffer; must be a multiple of 4. + * predMode - Intra_4x4 prediction mode. + * availability - Neighboring 4x4 block availability flag, refer to + * "Neighboring Macroblock Availability" . + * + * Output Arguments: + * + * pDst - Pointer to the destination buffer; must be aligned on a 4-byte + * boundary. + * + * Return Value: + * If the function runs without error, it returns OMX_Sts_NoErr. + * If one of the following cases occurs, the function returns + * OMX_Sts_BadArgErr: + * pDst is NULL. + * dstStep < 4, or dstStep is not a multiple of 4. + * leftStep is not a multiple of 4. + * predMode is not in the valid range of enumeration + * OMXVCM4P10Intra4x4PredMode. + * predMode is OMX_VC_4x4_VERT, but availability doesn't set OMX_VC_UPPER + * indicating p[x,-1] (x = 0..3) is not available. + * predMode is OMX_VC_4x4_HOR, but availability doesn't set OMX_VC_LEFT + * indicating p[-1,y] (y = 0..3) is not available. + * predMode is OMX_VC_4x4_DIAG_DL, but availability doesn't set + * OMX_VC_UPPER indicating p[x, 1] (x = 0..3) is not available. + * predMode is OMX_VC_4x4_DIAG_DR, but availability doesn't set + * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating + * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not + * available. + * predMode is OMX_VC_4x4_VR, but availability doesn't set + * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating + * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not + * available. + * predMode is OMX_VC_4x4_HD, but availability doesn't set + * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating + * p[x,-1] (x = 0..3), or p[-1,y] (y = 0..3) or p[-1,-1] is not + * available. + * predMode is OMX_VC_4x4_VL, but availability doesn't set OMX_VC_UPPER + * indicating p[x,-1] (x = 0..3) is not available. + * predMode is OMX_VC_4x4_HU, but availability doesn't set OMX_VC_LEFT + * indicating p[-1,y] (y = 0..3) is not available. + * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. + * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. + * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. + * either pSrcAbove or pDst is not aligned on a 4-byte boundary. + * + * Note: + * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointers if + * they are not used by intra prediction as implied in predMode. + * + */ + +OMXResult omxVCM4P10_PredictIntra_4x4( + const OMX_U8* pSrcLeft, + const OMX_U8 *pSrcAbove, + const OMX_U8 *pSrcAboveLeft, + OMX_U8* pDst, + OMX_INT leftStep, + OMX_INT dstStep, + OMXVCM4P10Intra4x4PredMode predMode, + OMX_S32 availability + ) +{ + int x, y; + OMX_U8 pTmp[10]; + + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((leftStep % 4) != 0, OMX_Sts_BadArgErr); + armRetArgErrIf((dstStep % 4) != 0, OMX_Sts_BadArgErr); + armRetArgErrIf((dstStep < 4), OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DL && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_DIAG_DR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_VR && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_VR && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_VR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_HD && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_HD && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_HD && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_VL && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); + armRetArgErrIf(predMode==OMX_VC_4X4_HU && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); + armRetArgErrIf((unsigned)predMode > OMX_VC_4X4_HU, OMX_Sts_BadArgErr); + + /* Note: This code must not read the pSrc arrays unless the corresponding + * block is marked as available. If the block is not avaibable then pSrc + * may not be a valid pointer. + * + * Note: To make the code more readable we refer to the neighbouring pixels + * in variables named as below: + * + * UL U0 U1 U2 U3 U4 U5 U6 U7 + * L0 xx xx xx xx + * L1 xx xx xx xx + * L2 xx xx xx xx + * L3 xx xx xx xx + */ + +#define UL pSrcAboveLeft[0] +#define U0 pSrcAbove[0] +#define U1 pSrcAbove[1] +#define U2 pSrcAbove[2] +#define U3 pSrcAbove[3] +#define U4 pSrcAbove[4] +#define U5 pSrcAbove[5] +#define U6 pSrcAbove[6] +#define U7 pSrcAbove[7] +#define L0 pSrcLeft[0*leftStep] +#define L1 pSrcLeft[1*leftStep] +#define L2 pSrcLeft[2*leftStep] +#define L3 pSrcLeft[3*leftStep] + + switch (predMode) + { + case OMX_VC_4X4_VERT: + for (y=0; y<4; y++) + { + pDst[y*dstStep+0] = U0; + pDst[y*dstStep+1] = U1; + pDst[y*dstStep+2] = U2; + pDst[y*dstStep+3] = U3; + } + break; + + case OMX_VC_4X4_HOR: + for (x=0; x<4; x++) + { + pDst[0*dstStep+x] = L0; + pDst[1*dstStep+x] = L1; + pDst[2*dstStep+x] = L2; + pDst[3*dstStep+x] = L3; + } + break; + + case OMX_VC_4X4_DC: + /* This can always be used even if no blocks available */ + armVCM4P10_PredictIntraDC4x4(pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability); + break; + + case OMX_VC_4X4_DIAG_DL: + pTmp[0] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2); + pTmp[1] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2); + if (availability & OMX_VC_UPPER_RIGHT) + { + pTmp[2] = (OMX_U8)((U2 + 2*U3 + U4 + 2)>>2); + pTmp[3] = (OMX_U8)((U3 + 2*U4 + U5 + 2)>>2); + pTmp[4] = (OMX_U8)((U4 + 2*U5 + U6 + 2)>>2); + pTmp[5] = (OMX_U8)((U5 + 2*U6 + U7 + 2)>>2); + pTmp[6] = (OMX_U8)((U6 + 3*U7 + 2)>>2); + } + else + { + pTmp[2] = (OMX_U8)((U2 + 3*U3 + 2)>>2); + pTmp[3] = U3; + pTmp[4] = U3; + pTmp[5] = U3; + pTmp[6] = U3; + } + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = pTmp[x+y]; + } + } + break; + + case OMX_VC_4X4_DIAG_DR: + /* x-y = -3, -2, -1, 0, 1, 2, 3 */ + pTmp[0] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2); + pTmp[1] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2); + pTmp[2] = (OMX_U8)((UL + 2*L0 + L1 + 2)>>2); + pTmp[3] = (OMX_U8)((U0 + 2*UL + L0 + 2)>>2); + pTmp[4] = (OMX_U8)((U1 + 2*U0 + UL + 2)>>2); + pTmp[5] = (OMX_U8)((U2 + 2*U1 + U0 + 2)>>2); + pTmp[6] = (OMX_U8)((U3 + 2*U2 + U1 + 2)>>2); + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = pTmp[3+x-y]; + } + } + break; + + case OMX_VC_4X4_VR: + /* zVR=2x-y = -3, -2, -1, 0, 1, 2, 3, 4, 5, 6 + * x-(y>>1) = -1, -1, 0, 0, 1, 1, 2, 2, 3, 3 + * y = 3, 2, ?, ?, ?, ?, ?, ?, 1, 0 + */ + pTmp[0] = (OMX_U8)((L2 + 2*L1 + L0 + 2)>>2); + pTmp[1] = (OMX_U8)((L1 + 2*L0 + UL + 2)>>2); + pTmp[2] = (OMX_U8)((L0 + 2*UL + U0 + 2)>>2); + pTmp[3] = (OMX_U8)((UL + U0 + 1)>>1); + pTmp[4] = (OMX_U8)((UL + 2*U0 + U1 + 2)>>2); + pTmp[5] = (OMX_U8)((U0 + U1 + 1)>>1); + pTmp[6] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2); + pTmp[7] = (OMX_U8)((U1 + U2 + 1)>>1); + pTmp[8] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2); + pTmp[9] = (OMX_U8)((U2 + U3 + 1)>>1); + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = pTmp[3+2*x-y]; + } + } + break; + + case OMX_VC_4X4_HD: + /* zHD=2y-x = -3 -2 -1 0 1 2 3 4 5 6 + * y-(x>>1) = -1 -1 0 0 1 1 2 2 3 3 + * x = 3 2 1 0 + */ + pTmp[0] = (OMX_U8)((U2 + 2*U1 + U0 + 2)>>2); + pTmp[1] = (OMX_U8)((U1 + 2*U0 + UL + 2)>>2); + pTmp[2] = (OMX_U8)((U0 + 2*UL + L0 + 2)>>2); + pTmp[3] = (OMX_U8)((UL + L0 + 1)>>1); + pTmp[4] = (OMX_U8)((UL + 2*L0 + L1 + 2)>>2); + pTmp[5] = (OMX_U8)((L0 + L1 + 1)>>1); + pTmp[6] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2); + pTmp[7] = (OMX_U8)((L1 + L2 + 1)>>1); + pTmp[8] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2); + pTmp[9] = (OMX_U8)((L2 + L3 + 1)>>1); + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = pTmp[3+2*y-x]; + } + } + break; + + case OMX_VC_4X4_VL: + /* Note: x+(y>>1) = (2*x+y)>>1 + * 2x+y = 0 1 2 3 4 5 6 7 8 9 + */ + pTmp[0] = (OMX_U8)((U0 + U1 + 1)>>1); + pTmp[1] = (OMX_U8)((U0 + 2*U1 + U2 + 2)>>2); + pTmp[2] = (OMX_U8)((U1 + U2 + 1)>>1); + pTmp[3] = (OMX_U8)((U1 + 2*U2 + U3 + 2)>>2); + pTmp[4] = (OMX_U8)((U2 + U3 + 1)>>1); + if (availability & OMX_VC_UPPER_RIGHT) + { + pTmp[5] = (OMX_U8)((U2 + 2*U3 + U4 + 2)>>2); + pTmp[6] = (OMX_U8)((U3 + U4 + 1)>>1); + pTmp[7] = (OMX_U8)((U3 + 2*U4 + U5 + 2)>>2); + pTmp[8] = (OMX_U8)((U4 + U5 + 1)>>1); + pTmp[9] = (OMX_U8)((U4 + 2*U5 + U6 + 2)>>2); + } + else + { + pTmp[5] = (OMX_U8)((U2 + 3*U3 + 2)>>2); + pTmp[6] = U3; + pTmp[7] = U3; + pTmp[8] = U3; + pTmp[9] = U3; + } + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = pTmp[2*x+y]; + } + } + break; + + case OMX_VC_4X4_HU: + /* zHU = x+2*y */ + pTmp[0] = (OMX_U8)((L0 + L1 + 1)>>1); + pTmp[1] = (OMX_U8)((L0 + 2*L1 + L2 + 2)>>2); + pTmp[2] = (OMX_U8)((L1 + L2 + 1)>>1); + pTmp[3] = (OMX_U8)((L1 + 2*L2 + L3 + 2)>>2); + pTmp[4] = (OMX_U8)((L2 + L3 + 1)>>1); + pTmp[5] = (OMX_U8)((L2 + 3*L3 + 2)>>2); + pTmp[6] = L3; + pTmp[7] = L3; + pTmp[8] = L3; + pTmp[9] = L3; + for (y=0; y<4; y++) + { + for (x=0; x<4; x++) + { + pDst[y*dstStep+x] = pTmp[x+2*y]; + } + } + break; + } + + return OMX_Sts_NoErr; +} diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c new file mode 100644 index 0000000..c8114ee --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_16x.c @@ -0,0 +1,86 @@ +/** + * + * File Name: omxVCM4P10_SADQuar_16x.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD of pSrc with average of two Ref blocks + * of 16x16 or 16x8 + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_SADQuar_16x (6.3.5.4.4) + * + * Description: + * This function calculates the SAD between one block (pSrc) and the average + * of the other two (pSrcRef0 and pSrcRef1) for 16x16 or 16x8 blocks. + * Rounding is applied according to the convention (a+b+1)>>1. + * + * Input Arguments: + * + * pSrc - Pointer to the original block; must be aligned on a 16-byte + * boundary. + * pSrcRef0 - Pointer to reference block 0 + * pSrcRef1 - Pointer to reference block 1 + * iSrcStep - Step of the original block buffer; must be a multiple of 16 + * iRefStep0 - Step of reference block 0 + * iRefStep1 - Step of reference block 1 + * iHeight - Height of the block; must be equal to either 8 or 16 + * + * Output Arguments: + * + * pDstSAD -Pointer of result SAD + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - iHeight is not equal to either 8 or 16. + * - One of more of the following pointers is NULL: pSrc, pSrcRef0, + * pSrcRef1, pDstSAD. + * - iSrcStep is not a multiple of 16 + * - Any alignment restrictions are violated + * + */ +OMXResult omxVCM4P10_SADQuar_16x( + const OMX_U8* pSrc, + const OMX_U8* pSrcRef0, + const OMX_U8* pSrcRef1, + OMX_U32 iSrcStep, + OMX_U32 iRefStep0, + OMX_U32 iRefStep1, + OMX_U32* pDstSAD, + OMX_U32 iHeight +) +{ + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iHeight != 16) && (iHeight != 8), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot16ByteAligned(pSrc), OMX_Sts_BadArgErr) + armRetArgErrIf((iSrcStep == 0) || (iSrcStep & 15), OMX_Sts_BadArgErr) + + + return armVCM4P10_SADQuar + (pSrc, pSrcRef0, pSrcRef1, iSrcStep, + iRefStep0, iRefStep1, pDstSAD, iHeight, 16); +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c new file mode 100644 index 0000000..4b330ba --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_4x.c @@ -0,0 +1,85 @@ +/** + * + * File Name: omxVCM4P10_SADQuar_4x.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD of pSrc with average of two Ref blocks + * of 4x8 or 4x4 blocks + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_SADQuar_4x (6.3.5.4.2) + * + * Description: + * This function calculates the SAD between one block (pSrc) and the average + * of the other two (pSrcRef0 and pSrcRef1) for 4x8 or 4x4 blocks. Rounding + * is applied according to the convention (a+b+1)>>1. + * + * Input Arguments: + * + * pSrc - Pointer to the original block; must be aligned on a 4-byte + * boundary. + * pSrcRef0 - Pointer to reference block 0 + * pSrcRef1 - Pointer to reference block 1 + * iSrcStep - Step of the original block buffer; must be a multiple of 4. + * iRefStep0 - Step of reference block 0 + * iRefStep1 - Step of reference block 1 + * iHeight - Height of the block; must be equal to either 4 or 8. + * + * Output Arguments: + * + * pDstSAD - Pointer of result SAD + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - iHeight is not equal to either 4 or 8. + * - One of more of the following pointers is NULL: pSrc, pSrcRef0, + * pSrcRef1, pDstSAD. + * - iSrcStep is not a multiple of 4 + * - Any alignment restrictions are violated + * + */ +OMXResult omxVCM4P10_SADQuar_4x( + const OMX_U8* pSrc, + const OMX_U8* pSrcRef0, + const OMX_U8* pSrcRef1, + OMX_U32 iSrcStep, + OMX_U32 iRefStep0, + OMX_U32 iRefStep1, + OMX_U32* pDstSAD, + OMX_U32 iHeight +) +{ + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf((iHeight != 8) && (iHeight != 4), OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pSrc), OMX_Sts_BadArgErr); + armRetArgErrIf((iSrcStep == 0) || (iSrcStep & 3), OMX_Sts_BadArgErr); + + return armVCM4P10_SADQuar + (pSrc, pSrcRef0, pSrcRef1, iSrcStep, + iRefStep0, iRefStep1, pDstSAD, iHeight, 4); +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c new file mode 100644 index 0000000..c9e9c24 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SADQuar_8x.c @@ -0,0 +1,87 @@ +/** + * + * File Name: omxVCM4P10_SADQuar_8x.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD of pSrc with average of two Ref blocks + * of 8x16 or 8x8 or 8x4 + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_SADQuar_8x (6.3.5.4.3) + * + * Description: + * This function calculates the SAD between one block (pSrc) and the average + * of the other two (pSrcRef0 and pSrcRef1) for 8x16, 8x8, or 8x4 blocks. + * Rounding is applied according to the convention (a+b+1)>>1. + * + * Input Arguments: + * + * pSrc - Pointer to the original block; must be aligned on an 8-byte + * boundary. + * pSrcRef0 - Pointer to reference block 0 + * pSrcRef1 - Pointer to reference block 1 + * iSrcStep - Step of the original block buffer; must be a multiple of 8. + * iRefStep0 - Step of reference block 0 + * iRefStep1 - Step of reference block 1 + * iHeight - Height of the block; must be equal either 4, 8, or 16. + * + * Output Arguments: + * + * pDstSAD - Pointer of result SAD + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - iHeight is not equal to either 4, 8, or 16. + * - One of more of the following pointers is NULL: pSrc, pSrcRef0, + * pSrcRef1, pDstSAD. + * - iSrcStep is not a multiple of 8 + * - Any alignment restrictions are violated + * + */ +OMXResult omxVCM4P10_SADQuar_8x( + const OMX_U8* pSrc, + const OMX_U8* pSrcRef0, + const OMX_U8* pSrcRef1, + OMX_U32 iSrcStep, + OMX_U32 iRefStep0, + OMX_U32 iRefStep1, + OMX_U32* pDstSAD, + OMX_U32 iHeight +) +{ + /* check for argument error */ + armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef0 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef1 == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iHeight != 16) && (iHeight != 8) && + (iHeight != 4), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot8ByteAligned(pSrc), OMX_Sts_BadArgErr) + armRetArgErrIf((iSrcStep == 0) || (iSrcStep & 7), OMX_Sts_BadArgErr) + + + return armVCM4P10_SADQuar + (pSrc, pSrcRef0, pSrcRef1, iSrcStep, + iRefStep0, iRefStep1, pDstSAD, iHeight, 8); +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c new file mode 100644 index 0000000..927c454 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SAD_4x.c @@ -0,0 +1,77 @@ +/** + * + * File Name: omxVCM4P10_SAD_4x.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD for 4x8 and 4x4 blocks + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_SAD_4x (6.3.5.4.1) + * + * Description: + * This function calculates the SAD for 4x8 and 4x4 blocks. + * + * Input Arguments: + * + * pSrcOrg -Pointer to the original block; must be aligned on a 4-byte + * boundary. + * iStepOrg -Step of the original block buffer; must be a multiple of 4. + * pSrcRef -Pointer to the reference block + * iStepRef -Step of the reference block buffer + * iHeight -Height of the block; must be equal to either 4 or 8. + * + * Output Arguments: + * + * pDstSAD -Pointer of result SAD + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - One of more of the following pointers is NULL: + * pSrcOrg, pSrcRef, or pDstSAD + * - iHeight is not equal to either 4 or 8. + * - iStepOrg is not a multiple of 4 + * - Any alignment restrictions are violated + * + */ +OMXResult omxVCM4P10_SAD_4x( + const OMX_U8* pSrcOrg, + OMX_U32 iStepOrg, + const OMX_U8* pSrcRef, + OMX_U32 iStepRef, + OMX_S32* pDstSAD, + OMX_U32 iHeight +) +{ + /* check for argument error */ + armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iHeight != 8) && (iHeight != 4), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr) + armRetArgErrIf((iStepOrg == 0) || (iStepOrg & 3), OMX_Sts_BadArgErr) + armRetArgErrIf((iStepRef == 0) || (iStepRef & 3), OMX_Sts_BadArgErr) + + return armVCCOMM_SAD + (pSrcOrg, iStepOrg, pSrcRef, iStepRef, pDstSAD, iHeight, 4); +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c new file mode 100644 index 0000000..a91ae66 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SATD_4x4.c @@ -0,0 +1,132 @@ +/** + * + * File Name: omxVCM4P10_SATD_4x4.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD for 4x4 blocks + * + */ +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_SATD_4x4 (6.3.5.4.5) + * + * Description: + * This function calculates the sum of absolute transform differences (SATD) + * for a 4x4 block by applying a Hadamard transform to the difference block + * and then calculating the sum of absolute coefficient values. + * + * Input Arguments: + * + * pSrcOrg - Pointer to the original block; must be aligned on a 4-byte + * boundary + * iStepOrg - Step of the original block buffer; must be a multiple of 4 + * pSrcRef - Pointer to the reference block; must be aligned on a 4-byte + * boundary + * iStepRef - Step of the reference block buffer; must be a multiple of 4 + * + * Output Arguments: + * + * pDstSAD - pointer to the resulting SAD + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrcOrg, pSrcRef, or pDstSAD either pSrcOrg + * - pSrcRef is not aligned on a 4-byte boundary + * - iStepOrg <= 0 or iStepOrg is not a multiple of 4 + * - iStepRef <= 0 or iStepRef is not a multiple of 4 + * + */ +OMXResult omxVCM4P10_SATD_4x4( + const OMX_U8* pSrcOrg, + OMX_U32 iStepOrg, + const OMX_U8* pSrcRef, + OMX_U32 iStepRef, + OMX_U32* pDstSAD +) +{ + OMX_INT i, j; + OMX_S32 SATD = 0; + OMX_S32 d [4][4], m1[4][4], m2[4][4]; + + /* check for argument error */ + armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcRef == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf((iStepOrg == 0) || (iStepOrg & 3), OMX_Sts_BadArgErr) + armRetArgErrIf((iStepRef == 0) || (iStepRef & 3), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pSrcRef), OMX_Sts_BadArgErr) + + /* Calculate the difference */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + d [j][i] = pSrcOrg [j * iStepOrg + i] - pSrcRef [j * iStepRef + i]; + } + } + + /* Hadamard Transfor for 4x4 block */ + + /* Horizontal */ + for (i = 0; i < 4; i++) + { + m1[i][0] = d[i][0] + d[i][2]; /* a+c */ + m1[i][1] = d[i][1] + d[i][3]; /* b+d */ + m1[i][2] = d[i][0] - d[i][2]; /* a-c */ + m1[i][3] = d[i][1] - d[i][3]; /* b-d */ + + m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */ + m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */ + m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */ + m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */ + + } + + /* Vertical */ + for (i = 0; i < 4; i++) + { + m1[0][i] = m2[0][i] + m2[2][i]; + m1[1][i] = m2[1][i] + m2[3][i]; + m1[2][i] = m2[0][i] - m2[2][i]; + m1[3][i] = m2[1][i] - m2[3][i]; + + m2[0][i] = m1[0][i] + m1[1][i]; + m2[1][i] = m1[2][i] + m1[3][i]; + m2[2][i] = m1[2][i] - m1[3][i]; + m2[3][i] = m1[0][i] - m1[1][i]; + } + + /* calculate SAD for Transformed coefficients */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + SATD += armAbs(m2 [j][i]); + } + } + + *pDstSAD = (SATD + 1) / 2; + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c new file mode 100644 index 0000000..23a5662 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_SubAndTransformQDQResidual.c @@ -0,0 +1,220 @@ +/** + * + * File Name: omxVCM4P10_SubAndTransformQDQResidual.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate SAD for 4x4 blocks + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_SubAndTransformQDQResidual (6.3.5.8.1) + * + * Description: + * This function subtracts the prediction signal from the original signal to + * produce the difference signal and then performs a 4x4 integer transform and + * quantization. The quantized transformed coefficients are stored as + * pDstQuantCoeff. This function can also output dequantized coefficients or + * unquantized DC coefficients optionally by setting the pointers + * pDstDeQuantCoeff, pDCCoeff. + * + * Input Arguments: + * + * pSrcOrg - Pointer to original signal. 4-byte alignment required. + * pSrcPred - Pointer to prediction signal. 4-byte alignment required. + * iSrcOrgStep - Step of the original signal buffer; must be a multiple of + * 4. + * iSrcPredStep - Step of the prediction signal buffer; must be a multiple + * of 4. + * pNumCoeff -Number of non-zero coefficients after quantization. If this + * parameter is not required, it is set to NULL. + * nThreshSAD - Zero-block early detection threshold. If this parameter is + * not required, it is set to 0. + * iQP - Quantization parameter; must be in the range [0,51]. + * bIntra - Indicates whether this is an INTRA block, either 1-INTRA or + * 0-INTER + * + * Output Arguments: + * + * pDstQuantCoeff - Pointer to the quantized transformed coefficients. + * 8-byte alignment required. + * pDstDeQuantCoeff - Pointer to the dequantized transformed coefficients + * if this parameter is not equal to NULL. 8-byte alignment + * required. + * pDCCoeff - Pointer to the unquantized DC coefficient if this parameter + * is not equal to NULL. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrcOrg, pSrcPred, pNumCoeff, pDstQuantCoeff, + * pDstDeQuantCoeff, pDCCoeff + * - pSrcOrg is not aligned on a 4-byte boundary + * - pSrcPred is not aligned on a 4-byte boundary + * - iSrcOrgStep is not a multiple of 4 + * - iSrcPredStep is not a multiple of 4 + * - pDstQuantCoeff or pDstDeQuantCoeff is not aligned on an 8-byte boundary + * + */ + OMXResult omxVCM4P10_SubAndTransformQDQResidual ( + const OMX_U8* pSrcOrg, + const OMX_U8* pSrcPred, + OMX_U32 iSrcOrgStep, + OMX_U32 iSrcPredStep, + OMX_S16* pDstQuantCoeff, + OMX_S16* pDstDeQuantCoeff, + OMX_S16* pDCCoeff, + OMX_S8* pNumCoeff, + OMX_U32 nThreshSAD, + OMX_U32 iQP, + OMX_U8 bIntra +) +{ + OMX_INT i, j; + OMX_S8 NumCoeff = 0; + OMX_S16 Buf[16], m[16]; + OMX_U32 QBits, QPper, QPmod, f; + OMX_S32 Value, MF, ThreshDC; + + /* check for argument error */ + armRetArgErrIf(pSrcOrg == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDstDeQuantCoeff == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pNumCoeff == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(pDCCoeff == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pSrcOrg), OMX_Sts_BadArgErr) + armRetArgErrIf(pSrcPred == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot4ByteAligned(pSrcPred), OMX_Sts_BadArgErr) + armRetArgErrIf(pDstQuantCoeff == NULL, OMX_Sts_BadArgErr) + armRetArgErrIf(armNot8ByteAligned(pDstQuantCoeff), OMX_Sts_BadArgErr) + armRetArgErrIf((pDstDeQuantCoeff != NULL) && + armNot8ByteAligned(pDstDeQuantCoeff), OMX_Sts_BadArgErr) + armRetArgErrIf((bIntra != 0) && (bIntra != 1), OMX_Sts_BadArgErr) + armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr) + armRetArgErrIf(iSrcOrgStep == 0, OMX_Sts_BadArgErr) + armRetArgErrIf(iSrcPredStep == 0, OMX_Sts_BadArgErr) + armRetArgErrIf(iSrcOrgStep & 3, OMX_Sts_BadArgErr) + armRetArgErrIf(iSrcPredStep & 3, OMX_Sts_BadArgErr) + + /* + * Zero-Block Early detection using nThreshSAD param + */ + + QPper = iQP / 6; + QPmod = iQP % 6; + QBits = 15 + QPper; + + f = (1 << QBits) / (bIntra ? 3 : 6); + + /* Do Zero-Block Early detection if enabled */ + if (nThreshSAD) + { + ThreshDC = ((1 << QBits) - f) / armVCM4P10_MFMatrix[QPmod][0]; + if (nThreshSAD < ThreshDC) + { + /* Set block to zero */ + if (pDCCoeff != NULL) + { + *pDCCoeff = 0; + } + + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + pDstQuantCoeff [4 * j + i] = 0; + if (pDstDeQuantCoeff != NULL) + { + pDstDeQuantCoeff [4 * j + i] = 0; + } + } + } + + if (pNumCoeff != NULL) + { + *pNumCoeff = 0; + } + return OMX_Sts_NoErr; + } + } + + + /* Calculate difference */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + Buf [j * 4 + i] = + pSrcOrg [j * iSrcOrgStep + i] - pSrcPred [j * iSrcPredStep + i]; + } + } + + /* Residual Transform */ + armVCM4P10_FwdTransformResidual4x4 (m, Buf); + + if (pDCCoeff != NULL) + { + /* Copy unquantized DC value into pointer */ + *pDCCoeff = m[0]; + } + + /* Quantization */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + MF = armVCM4P10_MFMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]]; + Value = armAbs(m[j * 4 + i]) * MF + f; + Value >>= QBits; + Value = m[j * 4 + i] < 0 ? -Value : Value; + Buf[4 * j + i] = pDstQuantCoeff [4 * j + i] = (OMX_S16)Value; + if ((pNumCoeff != NULL) && Value) + { + NumCoeff++; + } + } + } + + /* Output number of non-zero Coeffs */ + if (pNumCoeff != NULL) + { + *pNumCoeff = NumCoeff; + } + + /* Residual Inv Transform */ + if (pDstDeQuantCoeff != NULL) + { + /* Re Scale */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + m [j * 4 + i] = Buf [j * 4 + i] * (1 << QPper) * + armVCM4P10_VMatrix[QPmod][armVCM4P10_PosToVCol4x4[j * 4 + i]]; + } + } + armVCM4P10_TransformResidual4x4 (pDstDeQuantCoeff, m); + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c new file mode 100644 index 0000000..9ad0e81 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantChromaDCFromPair.c @@ -0,0 +1,131 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_TransformDequantChromaDCFromPair.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize and transform module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Dequantize Chroma 2x2 DC block + */ + +static void DequantChromaDC2x2( + OMX_S16* pDst, + OMX_INT QP +) +{ + int Shift = (QP/6)-1 ; + int Scale = armVCM4P10_VMatrix[QP%6][0]; + int i, Value; + + if (Shift >= 0) + { + for (i=0; i<4; i++) + { + Value = (pDst[i] * Scale) << Shift; + pDst[i] = (OMX_S16)Value; + } + } + else + { + for (i=0; i<4; i++) + { + Value = (pDst[i] * Scale) >> 1; + pDst[i] = (OMX_S16)Value; + } + } +} + + +/* + * Description: + * Inverse Transform DC 2x2 Coefficients + */ + +static void InvTransformDC2x2(OMX_S16* pData) +{ + int c00 = pData[0]; + int c01 = pData[1]; + int c10 = pData[2]; + int c11 = pData[3]; + + int d00 = c00 + c01; + int d01 = c00 - c01; + int d10 = c10 + c11; + int d11 = c10 - c11; + + pData[0] = (OMX_S16)(d00 + d10); + pData[1] = (OMX_S16)(d01 + d11); + pData[2] = (OMX_S16)(d00 - d10); + pData[3] = (OMX_S16)(d01 - d11); +} + + +/** + * Function: omxVCM4P10_TransformDequantChromaDCFromPair (6.3.4.2.2) + * + * Description: + * Reconstruct the 2x2 ChromaDC block from coefficient-position pair buffer, + * perform integer inverse transformation, and dequantization for 2x2 chroma + * DC coefficients, and update the pair buffer pointer to next non-empty + * block. + * + * Input Arguments: + * + * ppSrc - Double pointer to residual coefficient-position pair buffer + * output by CALVC decoding + * QP - Quantization parameter QpC + * + * Output Arguments: + * + * ppSrc - *ppSrc is updated to the start of next non empty block + * pDst - Pointer to the reconstructed 2x2 ChromaDC coefficients buffer; + * must be aligned on a 4-byte boundary. + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - ppSrc or pDst is NULL. + * - pDst is not 4-byte aligned. + * - QP is not in the range of [0-51]. + * + */ + +OMXResult omxVCM4P10_TransformDequantChromaDCFromPair( + const OMX_U8 **ppSrc, + OMX_S16* pDst, + OMX_INT QP + ) +{ + armRetArgErrIf(ppSrc == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(*ppSrc == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf(QP<0, OMX_Sts_BadArgErr); + armRetArgErrIf(QP>51, OMX_Sts_BadArgErr); + + armVCM4P10_UnpackBlock2x2(ppSrc, pDst); + InvTransformDC2x2(pDst); + DequantChromaDC2x2(pDst, QP); + + return OMX_Sts_NoErr; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c new file mode 100644 index 0000000..16c8be1 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformDequantLumaDCFromPair.c @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: omxVCM4P10_TransformDequantLumaDCFromPair.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 inverse quantize and transform module + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/* + * Description: + * Dequantize Luma DC block + */ + +static void DequantLumaDC4x4( + OMX_S16* pDst, + OMX_INT QP +) +{ + int Shift = (QP/6)-2 ; + int Scale = armVCM4P10_VMatrix[QP%6][0]; + int i, Round, Value; + + if (Shift >= 0) + { + for (i=0; i<16; i++) + { + Value = (pDst[i] * Scale) << Shift; + pDst[i] = (OMX_S16)Value; + } + } + else + { + Shift = -Shift;; + Round = 1<<(Shift-1); + + for (i=0; i<16; i++) + { + Value = (pDst[i] * Scale + Round) >> Shift; + pDst[i] = (OMX_S16)Value; + } + } +} + + + +/* + * Description: + * Inverse Transform DC 4x4 Coefficients + */ +static void InvTransformDC4x4(OMX_S16* pData) +{ + int i; + + /* Transform rows */ + for (i=0; i<16; i+=4) + { + int c0 = pData[i+0]; + int c1 = pData[i+1]; + int c2 = pData[i+2]; + int c3 = pData[i+3]; + pData[i+0] = (OMX_S16)(c0+c1+c2+c3); + pData[i+1] = (OMX_S16)(c0+c1-c2-c3); + pData[i+2] = (OMX_S16)(c0-c1-c2+c3); + pData[i+3] = (OMX_S16)(c0-c1+c2-c3); + } + + /* Transform columns */ + for (i=0; i<4; i++) + { + int c0 = pData[i+0]; + int c1 = pData[i+4]; + int c2 = pData[i+8]; + int c3 = pData[i+12]; + pData[i+0] = (OMX_S16)(c0+c1+c2+c3); + pData[i+4] = (OMX_S16)(c0+c1-c2-c3); + pData[i+8] = (OMX_S16)(c0-c1-c2+c3); + pData[i+12] = (OMX_S16)(c0-c1+c2-c3); + } +} + + +/** + * Function: omxVCM4P10_TransformDequantLumaDCFromPair (6.3.4.2.1) + * + * Description: + * Reconstructs the 4x4 LumaDC block from the coefficient-position pair + * buffer, performs integer inverse, and dequantization for 4x4 LumaDC + * coefficients, and updates the pair buffer pointer to the next non-empty + * block. + * + * Input Arguments: + * + * ppSrc - Double pointer to residual coefficient-position pair buffer + * output by CALVC decoding + * QP - Quantization parameter QpY + * + * Output Arguments: + * + * ppSrc - *ppSrc is updated to the start of next non empty block + * pDst - Pointer to the reconstructed 4x4 LumaDC coefficients buffer; must + * be aligned on a 8-byte boundary. + * + * Return Value: + * OMX_Sts_NoErr, if the function runs without error. + * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: + * - ppSrc or pDst is NULL. + * - pDst is not 8 byte aligned. + * - QP is not in the range of [0-51]. + * + */ + +OMXResult omxVCM4P10_TransformDequantLumaDCFromPair( + const OMX_U8 **ppSrc, + OMX_S16* pDst, + OMX_INT QP + ) +{ + armRetArgErrIf(ppSrc == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(*ppSrc == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr); + armRetArgErrIf(QP<0, OMX_Sts_BadArgErr); + armRetArgErrIf(QP>51, OMX_Sts_BadArgErr); + + armVCM4P10_UnpackBlock4x4(ppSrc, pDst); + /*InvTransformDequantLumaDC4x4(pDst, QP);*/ + InvTransformDC4x4(pDst); + DequantLumaDC4x4(pDst, QP); + + return OMX_Sts_NoErr; +} + +/* End of file */ diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c new file mode 100644 index 0000000..b5544dd --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_ChromaDC.c @@ -0,0 +1,97 @@ +/** + * + * File Name: omxVCM4P10_TransformQuant_ChromaDC.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate 4x4 hadamard transform of chroma DC + * coefficients and quantization + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armVC.h" +#include "armCOMM.h" + +/** + * Function: omxVCM4P10_TransformQuant_ChromaDC (6.3.5.6.1) + * + * Description: + * This function performs 2x2 Hadamard transform of chroma DC coefficients + * and then quantizes the coefficients. + * + * Input Arguments: + * + * pSrcDst - Pointer to the 2x2 array of chroma DC coefficients. 8-byte + * alignment required. + * iQP - Quantization parameter; must be in the range [0,51]. + * bIntra - Indicate whether this is an INTRA block. 1-INTRA, 0-INTER + * + * Output Arguments: + * + * pSrcDst - Pointer to transformed and quantized coefficients. 8-byte + * alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: + * pSrcDst + * - pSrcDst is not aligned on an 8-byte boundary + * + */ +OMXResult omxVCM4P10_TransformQuant_ChromaDC( + OMX_S16* pSrcDst, + OMX_U32 iQP, + OMX_U8 bIntra +) +{ + OMX_INT i, j; + OMX_S32 m[2][2]; + OMX_S32 Value; + OMX_S32 QbitsPlusOne, Two_f, MF00; + + /* Check for argument error */ + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot8ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr); + + /* Hadamard Transform for 2x2 block */ + m[0][0] = pSrcDst[0] + pSrcDst[1] + pSrcDst[2] + pSrcDst[3]; + m[0][1] = pSrcDst[0] - pSrcDst[1] + pSrcDst[2] - pSrcDst[3]; + m[1][0] = pSrcDst[0] + pSrcDst[1] - pSrcDst[2] - pSrcDst[3]; + m[1][1] = pSrcDst[0] - pSrcDst[1] - pSrcDst[2] + pSrcDst[3]; + + /* Quantization */ + QbitsPlusOne = ARM_M4P10_Q_OFFSET + 1 + (iQP / 6); /*floor (QP/6)*/ + MF00 = armVCM4P10_MFMatrix [iQP % 6][0]; + + Two_f = (1 << QbitsPlusOne) / (bIntra ? 3 : 6); /* 3->INTRA, 6->INTER */ + + /* Scaling */ + for (j = 0; j < 2; j++) + { + for (i = 0; i < 2; i++) + { + Value = (armAbs(m[j][i]) * MF00 + Two_f) >> QbitsPlusOne; + pSrcDst[j * 2 + i] = (OMX_S16)((m[j][i] < 0) ? -Value : Value); + } + } + + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c new file mode 100644 index 0000000..2ccf7f0 --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/omxVCM4P10_TransformQuant_LumaDC.c @@ -0,0 +1,119 @@ +/** + * + * File Name: omxVCM4P10_TransformQuant_LumaDC.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * Description: + * This function will calculate 4x4 hadamard transform of luma DC coefficients + * and quantization + * + */ + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armVC.h" + +/** + * Function: omxVCM4P10_TransformQuant_LumaDC (6.3.5.6.2) + * + * Description: + * This function performs a 4x4 Hadamard transform of luma DC coefficients + * and then quantizes the coefficients. + * + * Input Arguments: + * + * pSrcDst - Pointer to the 4x4 array of luma DC coefficients. 16-byte + * alignment required. + * iQP - Quantization parameter; must be in the range [0,51]. + * + * Output Arguments: + * + * pSrcDst - Pointer to transformed and quantized coefficients. 16-byte + * alignment required. + * + * Return Value: + * + * OMX_Sts_NoErr - no error + * OMX_Sts_BadArgErr - bad arguments; returned if any of the following + * conditions are true: + * - at least one of the following pointers is NULL: pSrcDst + * - pSrcDst is not aligned on an 16-byte boundary + * + */ +OMXResult omxVCM4P10_TransformQuant_LumaDC( + OMX_S16* pSrcDst, + OMX_U32 iQP +) +{ + OMX_INT i, j; + OMX_S32 m1[4][4], m2[4][4]; + OMX_S32 Value; + OMX_U32 QbitsPlusOne, Two_f, MF; + + /* Check for argument error */ + armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); + armRetArgErrIf(armNot16ByteAligned(pSrcDst), OMX_Sts_BadArgErr); + armRetArgErrIf(iQP > 51, OMX_Sts_BadArgErr); + + /* Hadamard Transform for 4x4 block */ + /* Horizontal Hadamard */ + for (i = 0; i < 4; i++) + { + j = i * 4; + + m1[i][0] = pSrcDst[j + 0] + pSrcDst[j + 2]; /* a+c */ + m1[i][1] = pSrcDst[j + 1] + pSrcDst[j + 3]; /* b+d */ + m1[i][2] = pSrcDst[j + 0] - pSrcDst[j + 2]; /* a-c */ + m1[i][3] = pSrcDst[j + 1] - pSrcDst[j + 3]; /* b-d */ + + m2[i][0] = m1[i][0] + m1[i][1]; /* a+b+c+d */ + m2[i][1] = m1[i][2] + m1[i][3]; /* a+b-c-d */ + m2[i][2] = m1[i][2] - m1[i][3]; /* a-b-c+d */ + m2[i][3] = m1[i][0] - m1[i][1]; /* a-b+c-d */ + + } + + /* Vertical */ + for (i = 0; i < 4; i++) + { + m1[0][i] = m2[0][i] + m2[2][i]; + m1[1][i] = m2[1][i] + m2[3][i]; + m1[2][i] = m2[0][i] - m2[2][i]; + m1[3][i] = m2[1][i] - m2[3][i]; + + m2[0][i] = m1[0][i] + m1[1][i]; + m2[1][i] = m1[2][i] + m1[3][i]; + m2[2][i] = m1[2][i] - m1[3][i]; + m2[3][i] = m1[0][i] - m1[1][i]; + } + + + /* Quantization */ + QbitsPlusOne = ARM_M4P10_Q_OFFSET + 1 + (iQP / 6); /*floor (QP/6)*/ + Two_f = (1 << QbitsPlusOne) / 3; /* 3->INTRA, 6->INTER */ + MF = armVCM4P10_MFMatrix [iQP % 6][0]; + + /* Scaling */ + for (j = 0; j < 4; j++) + { + for (i = 0; i < 4; i++) + { + Value = (armAbs((m2[j][i]/* + 1*/) / 2) * MF + Two_f) >> QbitsPlusOne; + pSrcDst[j * 4 + i] = (OMX_S16)((m2[j][i] < 0) ? -Value : Value); + } + } + return OMX_Sts_NoErr; +} + +/***************************************************************************** + * END OF FILE + *****************************************************************************/ + |