⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
*
*  T264 AVC CODEC
*
*  Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
*               2004-2005 visionany <visionany@yahoo.com.cn>
*   2005.2.24 CloudWu<sywu@sohu.com>	added support for B-frame MB16x16 support 
*   2005.3.2 CloudWu<sywu@sohu.com>	added support for B-frame MB16x8 and MB8x16,MB8x8 support
*
*  This program is free software ; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation ; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY ; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program ; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*
****************************************************************************/

#include "stdio.h"
#include "T264.h"
#include "utility.h"
#ifndef CHIP_DM642
#include "memory.h"
#endif
#include "assert.h"
#include "block.h"

/* intra */

static void __inline
T264dec_mb_decode_predict_i16x16_y(T264_t* t, uint8_t mode, uint8_t* pred, uint8_t* src)
{
    DECLARE_ALIGNED_MATRIX(topcache, 1, 16 + CACHE_SIZE, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(leftcache, 1, 16 + CACHE_SIZE, uint8_t, CACHE_SIZE);

    uint8_t* p;
    int32_t i;
    uint8_t* top, *left;

    top  =  &topcache[CACHE_SIZE];
    left = &leftcache[CACHE_SIZE];

    if (mode == Intra_16x16_DC)
    {
        if ((t->mb.mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
        {
            mode = Intra_16x16_DC;

            p = src - t->edged_stride;
            for(i = 0 ; i < 16 ; i ++)
            {
                top[i] = p[i];
            }

            p = src - 1;
            for(i = 0 ; i < 16 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
        }
        else if(t->mb.mb_neighbour & MB_LEFT)
        {
            mode = Intra_16x16_DCLEFT;

            p = src - 1;

            for(i = 0 ; i < 16 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
        }
        else if(t->mb.mb_neighbour & MB_TOP)
        {
            mode = Intra_16x16_DCTOP;

            p = src - t->edged_stride;
            for(i = 0 ; i < 16 ; i ++)
            {
                top[i] = p[i];
            }
        }
        else
        {
            mode = Intra_16x16_DC128;
        }
    }
    else
    {
        switch(mode)
        {
        case Intra_16x16_TOP:
            p = src - t->edged_stride;
            for(i = 0 ; i < 16 ; i ++)
            {
                top[i] = p[i];
            }
            break;
        case Intra_16x16_LEFT:
            p = src - 1;

            for(i = 0 ; i < 16 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
            break;
        case Intra_16x16_PLANE:
            p = src - t->edged_stride;
            for(i = -1 ; i < 16 ; i ++)
            {
                top[i] = p[i];
            }

            p -= 1;
            for(i = -1 ; i < 16 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
            break;
        default:
            assert(0);
            break;
        }
    }

    t->pred16x16[mode](pred, 16, top, left);
}


static void __inline
T264dec_mb_decode_predict_i4x4_y(T264_t* t, uint8_t idx, uint8_t mode, uint8_t* pred, uint8_t* src)
{
    DECLARE_ALIGNED_MATRIX(topcache,  8 + CACHE_SIZE, 1, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(leftcache, 4 + CACHE_SIZE, 1, uint8_t, CACHE_SIZE);

    static const int32_t neighbour[] =
    {
        0, MB_LEFT, MB_LEFT, MB_LEFT,
        MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,              MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,
        MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP| MB_TOPRIGHT, MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,
        MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,              MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP
    };
    static const int32_t fix[] =
    {
        ~0, ~0, ~0, ~0,
        ~0, ~MB_TOPRIGHT, ~0, ~MB_TOPRIGHT,
        ~0, ~0, ~0, ~MB_TOPRIGHT,
        ~0, ~MB_TOPRIGHT, ~0, ~MB_TOPRIGHT
    };

    uint8_t* p;
    int32_t i;
    uint8_t* top  = &topcache[CACHE_SIZE];
    uint8_t* left = &leftcache[CACHE_SIZE];

    if (mode == Intra_4x4_DC)
    {
        int32_t mb_neighbour = (t->mb.mb_neighbour| neighbour[idx]) & fix[idx];
        if ((mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
        {
            mode = Intra_4x4_DC;

            p = src - t->edged_stride;
            for(i = 0 ; i < 4 ; i ++)
            {
                top[i] = p[i];
            }

            p = src - 1;
            for(i = 0 ; i < 4 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
        }
        else if(mb_neighbour & MB_LEFT)
        {
            mode = Intra_4x4_DCLEFT;

            p = src - 1;

            for(i = 0 ; i < 4 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
        }
        else if(mb_neighbour & MB_TOP)
        {
            mode = Intra_4x4_DCTOP;

            p = src - t->edged_stride;
            for(i = 0 ; i < 4 ; i ++)
            {
                top[i] = p[i];
            }
        }
        else
        {
            mode = Intra_4x4_DC128;
        }
    }
    else
    {
        switch(mode)
        {
        case Intra_4x4_TOP:
            p = src - t->edged_stride;
            for(i = 0 ; i < 4 ; i ++)
            {
                top[i] = p[i];
            }
            break;
        case Intra_4x4_LEFT:
        case Intra_4x4_HORIZONTAL_UP:
            p = src - 1;
            for(i = 0 ; i < 4 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
            break;
        case Intra_4x4_DIAGONAL_DOWNLEFT:
        case Intra_4x4_VERTICAL_LEFT:
            {
                int32_t mb_neighbour = (t->mb.mb_neighbour| neighbour[idx]) & fix[idx];
            
                p = src - t->edged_stride;
                if((idx & 3) == 3 && t->mb.mb_x == t->mb_width - 1)    //if is the right-most sub-block, if is th last MB in horizontal, no top-right exist
                    mb_neighbour &= ~MB_TOPRIGHT;

                if (mb_neighbour & MB_TOPRIGHT)
                {
                    for(i = 0 ; i < 8 ; i ++)
                    {
                        top[i] = p[i];
                    }
                }
                else
                {
                    for(i = 0 ; i < 4 ; i ++)
                    {
                        top[i] = p[i];
                    }
                    top[4] = p[3];
                    top[5] = p[3];
                    top[6] = p[3];
                    top[7] = p[3];
                }
            }
            break;
        case Intra_4x4_DIAGONAL_DOWNRIGHT:
        case Intra_4x4_VERTICAL_RIGHT:
        case Intra_4x4_HORIZONTAL_DOWN:
            p = src - t->edged_stride;
            for(i = -1 ; i < 4 ; i ++)
            {
                top[i] = p[i];
            }

            p -= 1;
            for(i = -1 ; i < 4 ; i ++)
            {
                left[i] = p[0];
                p += t->edged_stride;
            }
            break;
        default:
            assert(0);
            break;
        }
    }

    t->pred4x4[mode](pred, 4, top, left);
}

static void __inline
T264dec_mb_decode_predict_i8x8_y(T264_t* t, uint8_t mode, uint8_t* pred_u, uint8_t* pred_v)
{
    DECLARE_ALIGNED_MATRIX(topcacheu, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(leftcacheu, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(topcachev, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(leftcachev, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);

    uint8_t* p_u, *p_v;
    int32_t i;
    uint8_t* top_u, *left_u;
    uint8_t* top_v, *left_v;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -