Sam LeitchInitial commit4e6482e12 years agoHistory
405 lines · 12.0 KB · C
RawDownload
/* * Copyright (C) 2009 The Android Open Source Project * Modified for use by h264bsd standalone library   * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*------------------------------------------------------------------------------     Table of contents      1. Include headers     2. External compiler flags     3. Module defines     4. Local function prototypes     5. Functions          h264bsdProcessBlock          h264bsdProcessLumaDc          h264bsdProcessChromaDc ------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------    1. Include headers------------------------------------------------------------------------------*/ #include "basetype.h"#include "h264bsd_transform.h"#include "h264bsd_util.h" /*------------------------------------------------------------------------------    2. External compiler flags-------------------------------------------------------------------------------- --------------------------------------------------------------------------------    3. Module defines------------------------------------------------------------------------------*/ /* Switch off the following Lint messages for this file: * Info 701: Shift left of signed quantity (int) * Info 702: Shift right of signed quantity (int) *//*lint -e701 -e702 */ /* LevelScale function */static const i32 levelScale[6][3] = {    {10,13,16}, {11,14,18}, {13,16,20}, {14,18,23}, {16,20,25}, {18,23,29}}; /* qp % 6 as a function of qp */static const u8 qpMod6[52] = {0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,    0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3}; /* qp / 6 as a function of qp */static const u8 qpDiv6[52] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,    4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8}; /*------------------------------------------------------------------------------    4. Local function prototypes------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------     Function: h264bsdProcessBlock         Functional description:            Function performs inverse zig-zag scan, inverse scaling and            inverse transform for a luma or a chroma residual block         Inputs:            data            pointer to data to be processed            qp              quantization parameter            skip            skip processing of data[0], set to non-zero value                            if dc coeff hanled separately            coeffMap        16 lsb's indicate which coeffs are non-zero,                            bit 0 (lsb) for coeff 0, bit 1 for coeff 1 etc.         Outputs:            data            processed data         Returns:            HANTRO_OK       success            HANTRO_NOK      processed data not in valid range [-512, 511] ------------------------------------------------------------------------------*/u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap){ /* Variables */     i32 tmp0, tmp1, tmp2, tmp3;    i32 d1, d2, d3;    u32 row,col;    u32 qpDiv;    i32 *ptr; /* Code */     qpDiv = qpDiv6[qp];    tmp1 = levelScale[qpMod6[qp]][0] << qpDiv;    tmp2 = levelScale[qpMod6[qp]][1] << qpDiv;    tmp3 = levelScale[qpMod6[qp]][2] << qpDiv;     if (!skip)        data[0] = (data[0] * tmp1);     /* at least one of the rows 1, 2 or 3 contain non-zero coeffs, mask takes     * the scanning order into account */    if (coeffMap & 0xFF9C)    {        /* do the zig-zag scan and inverse quantization */        d1 = data[1];        d2 = data[14];        d3 = data[15];        data[1] = (d1 * tmp2);        data[14] = (d2 * tmp2);        data[15] = (d3 * tmp3);         d1 = data[2];        d2 = data[5];        d3 = data[4];        data[4] = (d1 * tmp2);        data[2]  = (d2 * tmp1);        data[5] = (d3 * tmp3);         d1 = data[8];        d2 = data[3];        d3 = data[6];        tmp0 = (d1 * tmp2);        data[8] = (d2 * tmp1);        data[3]  = (d3 * tmp2);        d1 = data[7];        d2 = data[12];        d3 = data[9];        data[6]  = (d1 * tmp2);        data[7]  = (d2 * tmp3);        data[12] = (d3 * tmp2);        data[9]  = tmp0;         d1 = data[10];        d2 = data[11];        d3 = data[13];        data[13] = (d1 * tmp3);        data[10] = (d2 * tmp1);        data[11] = (d3 * tmp2);         /* horizontal transform */        for (row = 4, ptr = data; row--; ptr += 4)        {            tmp0 = ptr[0] + ptr[2];            tmp1 = ptr[0] - ptr[2];            tmp2 = (ptr[1] >> 1) - ptr[3];            tmp3 = ptr[1] + (ptr[3] >> 1);            ptr[0] = tmp0 + tmp3;            ptr[1] = tmp1 + tmp2;            ptr[2] = tmp1 - tmp2;            ptr[3] = tmp0 - tmp3;        }         /*lint +e661 +e662*/        /* then vertical transform */        for (col = 4; col--; data++)        {            tmp0 = data[0] + data[8];            tmp1 = data[0] - data[8];            tmp2 = (data[4] >> 1) - data[12];            tmp3 = data[4] + (data[12] >> 1);            data[0 ] = (tmp0 + tmp3 + 32)>>6;            data[4 ] = (tmp1 + tmp2 + 32)>>6;            data[8 ] = (tmp1 - tmp2 + 32)>>6;            data[12] = (tmp0 - tmp3 + 32)>>6;            /* check that each value is in the range [-512,511] */            if (((u32)(data[0] + 512) > 1023) ||                ((u32)(data[4] + 512) > 1023) ||                ((u32)(data[8] + 512) > 1023) ||                ((u32)(data[12] + 512) > 1023) )                return(HANTRO_NOK);        }    }    else /* rows 1, 2 and 3 are zero */    {        /* only dc-coeff is non-zero, i.e. coeffs at original positions         * 1, 5 and 6 are zero */        if ((coeffMap & 0x62) == 0)        {            tmp0 = (data[0] + 32) >> 6;            /* check that value is in the range [-512,511] */            if ((u32)(tmp0 + 512) > 1023)                return(HANTRO_NOK);            data[0] = data[1]  = data[2]  = data[3]  = data[4]  = data[5]  =                      data[6]  = data[7]  = data[8]  = data[9]  = data[10] =                      data[11] = data[12] = data[13] = data[14] = data[15] =                      tmp0;        }        else /* at least one of the coeffs 1, 5 or 6 is non-zero */        {            data[1] = (data[1] * tmp2);            data[2] = (data[5] * tmp1);            data[3] = (data[6] * tmp2);            tmp0 = data[0] + data[2];            tmp1 = data[0] - data[2];            tmp2 = (data[1] >> 1) - data[3];            tmp3 = data[1] + (data[3] >> 1);            data[0] = (tmp0 + tmp3 + 32)>>6;            data[1] = (tmp1 + tmp2 + 32)>>6;            data[2] = (tmp1 - tmp2 + 32)>>6;            data[3] = (tmp0 - tmp3 + 32)>>6;            data[4] = data[8] = data[12] = data[0];            data[5] = data[9] = data[13] = data[1];            data[6] = data[10] = data[14] = data[2];            data[7] = data[11] = data[15] = data[3];            /* check that each value is in the range [-512,511] */            if (((u32)(data[0] + 512) > 1023) ||                ((u32)(data[1] + 512) > 1023) ||                ((u32)(data[2] + 512) > 1023) ||                ((u32)(data[3] + 512) > 1023) )                return(HANTRO_NOK);        }    }     return(HANTRO_OK); } /*------------------------------------------------------------------------------     Function: h264bsdProcessLumaDc         Functional description:            Function performs inverse zig-zag scan, inverse transform and            inverse scaling for a luma DC coefficients block         Inputs:            data            pointer to data to be processed            qp              quantization parameter         Outputs:            data            processed data         Returns:            none ------------------------------------------------------------------------------*/void h264bsdProcessLumaDc(i32 *data, u32 qp){ /* Variables */     i32 tmp0, tmp1, tmp2, tmp3;    u32 row,col;    u32 qpMod, qpDiv;    i32 levScale;    i32 *ptr; /* Code */     qpMod = qpMod6[qp];    qpDiv = qpDiv6[qp];     /* zig-zag scan */    tmp0 = data[2];    data[2]  = data[5];    data[5] = data[4];    data[4] = tmp0;     tmp0 = data[8];    data[8] = data[3];    data[3]  = data[6];    data[6]  = data[7];    data[7]  = data[12];    data[12] = data[9];    data[9]  = tmp0;     tmp0 = data[10];    data[10] = data[11];    data[11] = data[13];    data[13] = tmp0;     /* horizontal transform */    for (row = 4, ptr = data; row--; ptr += 4)    {        tmp0 = ptr[0] + ptr[2];        tmp1 = ptr[0] - ptr[2];        tmp2 = ptr[1] - ptr[3];        tmp3 = ptr[1] + ptr[3];        ptr[0] = tmp0 + tmp3;        ptr[1] = tmp1 + tmp2;        ptr[2] = tmp1 - tmp2;        ptr[3] = tmp0 - tmp3;    }     /*lint +e661 +e662*/    /* then vertical transform and inverse scaling */    levScale = levelScale[ qpMod ][0];    if (qp >= 12)    {        levScale <<= (qpDiv-2);        for (col = 4; col--; data++)        {            tmp0 = data[0] + data[8 ];            tmp1 = data[0] - data[8 ];            tmp2 = data[4] - data[12];            tmp3 = data[4] + data[12];            data[0 ] = ((tmp0 + tmp3)*levScale);            data[4 ] = ((tmp1 + tmp2)*levScale);            data[8 ] = ((tmp1 - tmp2)*levScale);            data[12] = ((tmp0 - tmp3)*levScale);        }    }    else    {        i32 tmp;        tmp = ((1 - qpDiv) == 0) ? 1 : 2;        for (col = 4; col--; data++)        {            tmp0 = data[0] + data[8 ];            tmp1 = data[0] - data[8 ];            tmp2 = data[4] - data[12];            tmp3 = data[4] + data[12];            data[0 ] = ((tmp0 + tmp3)*levScale+tmp) >> (2-qpDiv);            data[4 ] = ((tmp1 + tmp2)*levScale+tmp) >> (2-qpDiv);            data[8 ] = ((tmp1 - tmp2)*levScale+tmp) >> (2-qpDiv);            data[12] = ((tmp0 - tmp3)*levScale+tmp) >> (2-qpDiv);        }    } } /*------------------------------------------------------------------------------     Function: h264bsdProcessChromaDc         Functional description:            Function performs inverse transform and inverse scaling for a            chroma DC coefficients block         Inputs:            data            pointer to data to be processed            qp              quantization parameter         Outputs:            data            processed data         Returns:            none ------------------------------------------------------------------------------*/void h264bsdProcessChromaDc(i32 *data, u32 qp){ /* Variables */     i32 tmp0, tmp1, tmp2, tmp3;    u32 qpDiv;    i32 levScale;    u32 levShift; /* Code */     qpDiv = qpDiv6[qp];    levScale = levelScale[ qpMod6[qp] ][0];     if (qp >= 6)    {        levScale <<= (qpDiv-1);        levShift = 0;    }    else    {        levShift = 1;    }     tmp0 = data[0] + data[2];    tmp1 = data[0] - data[2];    tmp2 = data[1] - data[3];    tmp3 = data[1] + data[3];    data[0] = ((tmp0 + tmp3) * levScale) >> levShift;    data[1] = ((tmp0 - tmp3) * levScale) >> levShift;    data[2] = ((tmp1 + tmp2) * levScale) >> levShift;    data[3] = ((tmp1 - tmp2) * levScale) >> levShift;    tmp0 = data[4] + data[6];    tmp1 = data[4] - data[6];    tmp2 = data[5] - data[7];    tmp3 = data[5] + data[7];    data[4] = ((tmp0 + tmp3) * levScale) >> levShift;    data[5] = ((tmp0 - tmp3) * levScale) >> levShift;    data[6] = ((tmp1 + tmp2) * levScale) >> levShift;    data[7] = ((tmp1 - tmp2) * levScale) >> levShift; } /*lint +e701 +e702 */  

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t