📄 wmv9_filters.c
字号:
/* <LIC_AMD_STD> * Copyright (C) 2003-2005 Advanced Micro Devices, Inc. All Rights Reserved. * * Unless otherwise designated in writing, this software and any related * documentation are the confidential proprietary information of AMD. * THESE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY * UNLESS OTHERWISE NOTED IN WRITING, EXPRESS OR IMPLIED WARRANTY OF ANY * KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE AND IN NO * EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER. * * AMD does not assume any responsibility for any errors which may appear * in the Materials nor any responsibility to support or update the * Materials. AMD retains the right to modify the Materials at any time, * without notice, and is not obligated to provide such modified * Materials to you. AMD is not obligated to furnish, support, or make * any further information available to you. * </LIC_AMD_STD> *//* <CTL_AMD_STD> * </CTL_AMD_STD> *//* <DOC_AMD_STD> * </DOC_AMD_STD> */#ifdef HAVE_MAE
#include "fcov.h"
#else
#define fcov_coverage_point_hit(x)
#endif
#include "mae_global.h"
#include <stdio.h> // for printf
#include <string.h>
#define MAE_TRUE 1
#define MAE_FALSE 0
#ifdef REF_WMV9
extern int nFileUpdates;
extern unsigned int nFrameNumber;
void PrintLoopFilterForMAE(MAE_CWMVMBMode*, MAE_tWMVDecInternalMember *, int, int, int);
#endif
/****************************************************************************************
MAE_OverlapMBRow : complete overlapped transform reconstruction for I blocks in row of MBs
// TBD: speedup (e.g. skip if no intra blocks in current and previous rows)
****************************************************************************************/
void MAE_OverlapMBRow (MAE_tWMVDecInternalMember * MAE_pWMVDec, I32_WMV imbY, U8_WMV *ppxliRecnY, U8_WMV *ppxliRecnU,
U8_WMV *ppxliRecnV, I32_WMV iMBYEnd, I32_WMV iMBYStart,
I32_WMV iThreadID)
{
I32_WMV ii;
I32_WMV iXBlocks = (I32_WMV) MAE_pWMVDec->m_uintNumMBX * 2; // Number of 8x8 blocks
I32_WMV iStrideUV = (I32_WMV) MAE_pWMVDec->m_uintNumMBX * 8; // Width of UV frame in pixels
I32_WMV iStride = iStrideUV * 2; // Width of Y frame in pixels
I32_WMV iBlockIndex = imbY * iXBlocks * 2; // R->L, T->B, 8x8 block index
I16_WMV *pMotion = MAE_pWMVDec->m_pXMotion + iBlockIndex; // m_pXMotion is array that tells if 8x8
// is Intra or not (for Y)
I16_WMV *pMotionUV = MAE_pWMVDec->m_pXMotionC + imbY // m_pXMotionC is array that tells if 8x8
* (I32_WMV) MAE_pWMVDec->m_uintNumMBX; // is Intra or not (for UV)
I16_WMV **pIntraBlockRow, **pIntraMBRowU, **pIntraMBRowV;
//int i,j;
// Note that for Luma,
// pIntraBlockRow[0] == top row of 8x8 in current row of MBs
// pIntraBlockRow[1] == row of 8x8 above current row of MBs
// pIntraBlockRow[2] == bottom row of 8x8 in current row of MBs
// Note that for chroma,
// pIntraMBRow[U/V][0] == current row of 8x8 in current row of MBs
// pIntraMBRow[U/V][1] == row of 8x8 above current row of MBs
pIntraBlockRow = MAE_pWMVDec->m_pIntraBlockRow0;
pIntraMBRowU = MAE_pWMVDec->m_pIntraMBRowU0;
pIntraMBRowV = MAE_pWMVDec->m_pIntraMBRowV0;
// Not Used
if (iThreadID) {
pIntraBlockRow = MAE_pWMVDec->m_pIntraBlockRow1;
pIntraMBRowU = MAE_pWMVDec->m_pIntraMBRowU1;
pIntraMBRowV = MAE_pWMVDec->m_pIntraMBRowV1;
}
/*
log_printf("Row %d: Before Vertical, Above Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", pIntraBlockRow[1][i*iStride+j]);
}
log_printf("\n");
}
log_printf("Row %d: Before Vertical, Top Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", pIntraBlockRow[0][i*iStride+j]);
}
log_printf("\n");
}
log_printf("Row %d: Before Vertical, Bottom Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", pIntraBlockRow[2][i*iStride+j]);
}
log_printf("\n");
}
*/
// as long as there are I blocks in the current rows, filter vertical edges
// Don't do this if last row?????
if (imbY < iMBYEnd) {
// Luma Vertical
for (ii = 1; ii < iXBlocks; ii++) { // For each 8x8 in row
// if top 8x8 and 8x8 to left are both Intra, filter vertically
if (pMotion[ii] == MAE_IBLOCKMV && pMotion[ii - 1] == MAE_IBLOCKMV) {
MAE_g_OverlapBlockVerticalEdge (pIntraBlockRow[0] + ii * 8, iStride);
}
// if bottom 8x8 and 8x8 to left of it are both Intra, filter vertically
if (pMotion[ii + iXBlocks] == MAE_IBLOCKMV && pMotion[ii + iXBlocks - 1] == MAE_IBLOCKMV) {
MAE_g_OverlapBlockVerticalEdge (pIntraBlockRow[2] + ii * 8, iStride);
}
}
/*
log_printf("Row %d: After Vertical, Above Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", pIntraBlockRow[1][i*iStride+j]);
}
log_printf("\n");
}
log_printf("Row %d: After Vertical, Top Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", pIntraBlockRow[0][i*iStride+j]);
}
log_printf("\n");
}
log_printf("Row %d: After Vertical, Bottom Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", pIntraBlockRow[2][i*iStride+j]);
}
log_printf("\n");
}
log_printf("Row %d: Before Vertical, Above Row Cb:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStrideUV; j++) {
log_printf("%x ", pIntraMBRowU[1][i*iStrideUV+j]);
}
log_printf("\n");
}
log_printf("Row %d: Before Vertical, Top Row Cb:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStrideUV; j++) {
log_printf("%x ", pIntraBlockRow[0][i*iStrideUV+j]);
}
log_printf("\n");
}
*/
// Chroma Vertical
for (ii = 1; ii < (I32_WMV) MAE_pWMVDec->m_uintNumMBX; ii++) { // For each 8x8 in row
// if 8x8 and 8x8 to left are both Intra, filter vertically
if (pMotionUV[ii] == MAE_IBLOCKMV && pMotionUV[ii - 1] == MAE_IBLOCKMV) {
MAE_g_OverlapBlockVerticalEdge (pIntraMBRowU[0] + ii * 8, iStrideUV);
MAE_g_OverlapBlockVerticalEdge (pIntraMBRowV[0] + ii * 8, iStrideUV);
}
}
}
/*
log_printf("Row %d: After Vertical, Above Row Cb:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStrideUV; j++) {
log_printf("%x ", pIntraMBRowU[1][i*iStrideUV+j]);
}
log_printf("\n");
}
log_printf("Row %d: After Vertical, Top Row Cb:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStrideUV; j++) {
log_printf("%x ", pIntraBlockRow[0][i*iStrideUV+j]);
}
log_printf("\n");
}
*/
// Luma Horizontal
for (ii = 0; ii < iXBlocks; ii++) {
Bool_WMV bTop = (imbY > iMBYStart) && pMotion[ii - iXBlocks] == MAE_IBLOCKMV; // bTop set if 8x8 above is Intra
Bool_WMV bDn = (imbY < iMBYEnd), bUp = MAE_FALSE;
if (bDn) { // Don't set bUp or bDn if last row
bUp = pMotion[ii] == MAE_IBLOCKMV; // bUp set if top 8x8 is Intra
bDn = pMotion[ii + iXBlocks] == MAE_IBLOCKMV; // bDn set if bottom 8x8 is Intra
}
// If either 8x8 above or top 8x8 is Intra, Filter top horizontal edge
if (bTop || bUp) {
// In this case, top row == pIntraBlockRow[1], current row == pIntraBlockRow[0]
MAE_g_OverlapBlockHorizontalEdge ( pIntraBlockRow[1] + ii * 8, pIntraBlockRow[0] + ii * 8,
iStride, ppxliRecnY + ii * 8, MAE_pWMVDec->m_iWidthPrevY, bTop, bUp, MAE_FALSE);
}
// If either top 8x8 or bottom 8x8 is Intra, Filter middle horizontal edge
if (bUp || bDn) {
// In this case, top row == pIntraBlockRow[0], current row == pIntraBlockRow[2]
MAE_g_OverlapBlockHorizontalEdge ( pIntraBlockRow[0] + ii * 8, pIntraBlockRow[2] + ii * 8,
iStride, ppxliRecnY + MAE_pWMVDec->m_iWidthPrevY * 8 + ii * 8, MAE_pWMVDec->m_iWidthPrevY, bUp, bDn, MAE_FALSE);
}
}
/*
log_printf("Row %d: After Horizontal, Top Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", ppxliRecnY[i*iStride+j]);
}
log_printf("\n");
}
log_printf("Row %d: After Horizontal, Bottom Row Y:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStride; j++) {
log_printf("%x ", (ppxliRecnY+ MAE_pWMVDec->m_iWidthPrevY * 8)[i*iStride+j]);
}
log_printf("\n");
}
*/
// Chroma Horizontal
for (ii = 0; ii < (I32_WMV) MAE_pWMVDec->m_uintNumMBX; ii++) {
Bool_WMV bUp = (imbY > iMBYStart) && (pMotionUV[ii - (I32_WMV) MAE_pWMVDec->m_uintNumMBX] == MAE_IBLOCKMV);
Bool_WMV bDn = (imbY < iMBYEnd) && (pMotionUV[ii] == MAE_IBLOCKMV);
// If either 8x8 above or current 8x8 is Intra, Filter top horizontal edge
if (bUp || bDn) {
MAE_g_OverlapBlockHorizontalEdge ( pIntraMBRowU[1] + ii * 8, pIntraMBRowU[0] + ii * 8,
iStrideUV, ppxliRecnU + ii * 8, MAE_pWMVDec->m_iWidthPrevUV, bUp, bDn, MAE_FALSE);
MAE_g_OverlapBlockHorizontalEdge ( pIntraMBRowV[1] + ii * 8, pIntraMBRowV[0] + ii * 8,
iStrideUV, ppxliRecnV + ii * 8, MAE_pWMVDec->m_iWidthPrevUV, bUp, bDn, MAE_FALSE);
}
}
/*
log_printf("Row %d: After Horizontal, Top Row Cb:\n", imbY);
for(i = 0; i < 8; i++) {
for(j =0; j < iStrideUV; j++) {
log_printf("%x ", ppxliRecnU[i*iStrideUV+j]);
}
log_printf("\n");
}
*/
// switch pointers - use pMotion as a temp
if (iThreadID == 0) {
/*
pMotion = MAE_pWMVDec->m_pIntraBlockRow0[1];
MAE_pWMVDec->m_pIntraBlockRow0[1] = MAE_pWMVDec->m_pIntraBlockRow0[2]; // bottom -> above
MAE_pWMVDec->m_pIntraBlockRow0[2] = pMotion; // above -> bottom???
pMotion = MAE_pWMVDec->m_pIntraMBRowU0[0];
MAE_pWMVDec->m_pIntraMBRowU0[0] = MAE_pWMVDec->m_pIntraMBRowU0[1]; // above -> current???
MAE_pWMVDec->m_pIntraMBRowU0[1] = pMotion; // current -> above
pMotion = MAE_pWMVDec->m_pIntraMBRowV0[0];
MAE_pWMVDec->m_pIntraMBRowV0[0] = MAE_pWMVDec->m_pIntraMBRowV0[1]; // above -> current???
MAE_pWMVDec->m_pIntraMBRowV0[1] = pMotion; // current -> above
*/
} else {
// Not used
if (imbY == iMBYStart) {
// move block row 0 to backup area 3
pMotion = MAE_pWMVDec->m_pIntraBlockRow1[3];
MAE_pWMVDec->m_pIntraBlockRow1[3] = MAE_pWMVDec->m_pIntraBlockRow1[0];
MAE_pWMVDec->m_pIntraBlockRow1[0] = pMotion;
// copy to backup for UV
memcpy (MAE_pWMVDec->m_pIntraMBRowU1[2], MAE_pWMVDec->m_pIntraMBRowU1[0], MAE_pWMVDec->m_uintNumMBX * 8 * 8);
memcpy (MAE_pWMVDec->m_pIntraMBRowV1[2], MAE_pWMVDec->m_pIntraMBRowV1[0], MAE_pWMVDec->m_uintNumMBX * 8 * 8);
}
pMotion = MAE_pWMVDec->m_pIntraBlockRow1[1];
MAE_pWMVDec->m_pIntraBlockRow1[1] = MAE_pWMVDec->m_pIntraBlockRow1[2];
MAE_pWMVDec->m_pIntraBlockRow1[2] = pMotion;
pMotion = MAE_pWMVDec->m_pIntraMBRowU1[0];
MAE_pWMVDec->m_pIntraMBRowU1[0] = MAE_pWMVDec->m_pIntraMBRowU1[1];
MAE_pWMVDec->m_pIntraMBRowU1[1] = pMotion;
pMotion = MAE_pWMVDec->m_pIntraMBRowV1[0];
MAE_pWMVDec->m_pIntraMBRowV1[0] = MAE_pWMVDec->m_pIntraMBRowV1[1];
MAE_pWMVDec->m_pIntraMBRowV1[1] = pMotion;
}
}
/****************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -