📄 spt.cpp
字号:
/*************************************************************************This software module was originally developed by Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation (date: Auguest, 1997)and also edited by Yoshinori Suzuki (Hitachi, Ltd.) Yuichiro Nakaya (Hitachi, Ltd.)in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). This software module is an implementation of a part of one or more MPEG-4 Video tools as specified by the MPEG-4 Video. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-4 Video conforming products. Microsoft retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1996, 1997.Module Name: spt.cppAbstract: Functions for sprite warping Revision History: Nov. 14, 1997: Fast Affine Warping functions added by Hitachi, Ltd. Jan. 13, 1999: Code for disallowing zero demoninators in perspective warping added by Hitachi, Ltd.*************************************************************************/#include <stdio.h>#include <math.h>#include "typeapi.h"#include "mode.hpp"#include "vopses.hpp"#include "codehead.h"#ifdef __MFC_#ifdef _DEBUG#undef THIS_FILEstatic char BASED_CODE THIS_FILE[] = __FILE__;#endif#define new DEBUG_NEW #endif // __MFC_#define _FOR_GSSP_Void CVideoObject::warpYA (const CPerspective2D& persp, const CRct& rctWarpedBound, UInt accuracy) // warp m_pvopcSptQ's Y and A components to m_pvopcCurrQs{ assert (m_pvopcCurrQ -> whereY ().includes (rctWarpedBound)); const CU8Image* puciCurrY = m_pvopcCurrQ -> getPlane (Y_PLANE);#ifdef _FOR_GSSP_ const CU8Image* puciCurrBY = m_pvopcCurrQ -> getPlane (BY_PLANE);#endif const CU8Image* puciCurrA = (m_pvopcSptQ -> fAUsage () == EIGHT_BIT)? m_pvopcCurrQ -> getPlane (A_PLANE) : m_pvopcCurrQ -> getPlane (BY_PLANE); const CU8Image* puciSptY = m_pvopcSptQ -> getPlane (Y_PLANE);#ifdef _FOR_GSSP_ const CU8Image* puciSptBY = m_pvopcSptQ -> getPlane (BY_PLANE);#endif const CU8Image* puciSptA = (m_pvopcSptQ -> fAUsage () == EIGHT_BIT)? m_pvopcSptQ -> getPlane (A_PLANE) : m_pvopcSptQ -> getPlane (BY_PLANE); const CRct rctSptY = m_pvopcSptQ -> whereY (); const UInt offsetSlice = m_pvopcCurrQ -> whereY ().width * MB_SIZE; UInt accuracy1 = accuracy + 1; PixelC* ppxlcCurrQYSlice = (PixelC*) puciCurrY -> pixels ();#ifdef _FOR_GSSP_ PixelC* ppxlcCurrQBYSlice = (PixelC*) puciCurrBY -> pixels ();#endif PixelC* ppxlcCurrQASlice = (PixelC*) puciCurrA -> pixels (); memset (ppxlcCurrQYSlice, 0, puciCurrY -> where ().area () * sizeof(PixelC));#ifdef _FOR_GSSP_ memset (ppxlcCurrQBYSlice, 0, puciCurrBY -> where ().area () * sizeof(PixelC));#endif memset (ppxlcCurrQASlice, 0, puciCurrA -> where ().area () * sizeof(PixelC)); ppxlcCurrQYSlice = (PixelC*) puciCurrY -> pixels (rctWarpedBound.left, rctWarpedBound.top);#ifdef _FOR_GSSP_ ppxlcCurrQBYSlice = (PixelC*) puciCurrBY -> pixels (rctWarpedBound.left, rctWarpedBound.top);#endif ppxlcCurrQASlice = (PixelC*) puciCurrA -> pixels (rctWarpedBound.left, rctWarpedBound.top); for (Int topMB = rctWarpedBound.top; topMB < rctWarpedBound.bottom; topMB += MB_SIZE) { PixelC * ppxlcCurrQYBlock = ppxlcCurrQYSlice; PixelC * ppxlcCurrQABlock = ppxlcCurrQASlice; PixelC * ppxlcCurrQBYBlock = ppxlcCurrQBYSlice; for (Int leftMB = rctWarpedBound.left; leftMB < rctWarpedBound.right; leftMB += MB_SIZE) { UInt offsetLine = m_pvopcCurrQ -> whereY ().width - min(MB_SIZE, rctWarpedBound.right - leftMB); Bool existOpaguePixelMB = (m_pvopcSptQ -> fAUsage () == RECTANGLE); Bool existZeroDenomMB = FALSE; PixelC * ppxlcCurrQY = ppxlcCurrQYBlock; PixelC * ppxlcCurrQBY = ppxlcCurrQBYBlock; PixelC * ppxlcCurrQA = ppxlcCurrQABlock; for (CoordI y = topMB; y < min(topMB + MB_SIZE, rctWarpedBound.bottom); y++) { for (CoordI x = leftMB; x < min(leftMB + MB_SIZE, rctWarpedBound.right); x++) { CSiteWFlag src = persp * (CSite (x, y)); if (src.f) { existZeroDenomMB = TRUE; continue; } CoordD dx = (CoordD)src.s.x / (1 << accuracy1); CoordD dy = (CoordD)src.s.y / (1 << accuracy1); CoordI fx = (CoordI) floor (dx); CoordI fy = (CoordI) floor (dy); CoordI cx = (CoordI) ceil (dx); CoordI cy = (CoordI) ceil (dy); if (rctSptY.includes (fx, fy) && rctSptY.includes (fx, cy) && rctSptY.includes (cx, fy) && rctSptY.includes (cx, cy)) {#ifdef _FOR_GSSP_ PixelC pxlcWarpedBY = puciSptBY -> pixel (src.s, accuracy); if (pxlcWarpedBY >= 128) { *ppxlcCurrQBY = MPEG4_OPAQUE;#else PixelC pxlcWarpedA = puciSptA -> pixel (src.s, accuracy); if (pxlcWarpedA >= 128) { *ppxlcCurrQA = MPEG4_OPAQUE;#endif existOpaguePixelMB = TRUE; *ppxlcCurrQY = puciSptY -> pixel (src.s, accuracy);#ifdef _FOR_GSSP_ if(m_pvopcSptQ -> fAUsage () == EIGHT_BIT) *ppxlcCurrQA = puciSptA -> pixel (src.s, accuracy);#endif } } ppxlcCurrQY++; #ifdef _FOR_GSSP_ ppxlcCurrQBY++;#endif ppxlcCurrQA++; } ppxlcCurrQY += offsetLine;#ifdef _FOR_GSSP_ ppxlcCurrQBY += offsetLine;#endif ppxlcCurrQA += offsetLine; } assert (!(existOpaguePixelMB && existZeroDenomMB)); ppxlcCurrQYBlock += MB_SIZE;#ifdef _FOR_GSSP_ ppxlcCurrQBYBlock += MB_SIZE;#endif ppxlcCurrQABlock += MB_SIZE; } ppxlcCurrQYSlice += offsetSlice;#ifdef _FOR_GSSP_ ppxlcCurrQBYSlice += offsetSlice;#endif ppxlcCurrQASlice += offsetSlice; }} Void CVideoObject::warpUV (const CPerspective2D& persp, const CRct& rctWarpedBound, UInt accuracy) // warp m_pvopcSptQ's U and V components to m_pvopcCurrQs{ assert (m_pvopcCurrQ -> whereUV ().includes (rctWarpedBound)); const CU8Image* puciCurrU = m_pvopcCurrQ -> getPlane (U_PLANE); const CU8Image* puciCurrV = m_pvopcCurrQ -> getPlane (V_PLANE); const CU8Image* puciCurrBY = m_pvopcCurrQ -> getPlane (BY_PLANE); const CU8Image* puciSptU = m_pvopcSptQ -> getPlane (U_PLANE); const CU8Image* puciSptV = m_pvopcSptQ -> getPlane (V_PLANE); const CRct rctSptUV = m_pvopcSptQ -> whereUV (); const UInt offsetSliceUV = m_pvopcCurrQ -> whereUV ().width * BLOCK_SIZE; const UInt offsetSliceBY = m_pvopcCurrQ -> whereY ().width * MB_SIZE; const UInt nextRowBY = m_pvopcCurrQ -> whereY ().width; UInt accuracy1 = accuracy + 1; PixelC* ppxlcCurrQUSlice = (PixelC*) puciCurrU -> pixels (); PixelC* ppxlcCurrQVSlice = (PixelC*) puciCurrV -> pixels (); PixelC pxlcVal = 128; // not sure if this is needed swinder if(m_volmd.nBits>8) pxlcVal = 1<<(m_volmd.nBits - 1); pxlcmemset (ppxlcCurrQUSlice, pxlcVal, puciCurrU -> where ().area ()); pxlcmemset (ppxlcCurrQVSlice, pxlcVal, puciCurrV -> where ().area ()); ppxlcCurrQUSlice = (PixelC*) puciCurrU -> pixels (rctWarpedBound.left, rctWarpedBound.top); ppxlcCurrQVSlice = (PixelC*) puciCurrV -> pixels (rctWarpedBound.left, rctWarpedBound.top); PixelC* ppxlcCurrQBYSlice = (PixelC*) puciCurrBY -> pixels (2 * rctWarpedBound.left, 2 * rctWarpedBound.top); for (Int topMB = rctWarpedBound.top; topMB < rctWarpedBound.bottom; topMB += BLOCK_SIZE) { PixelC * ppxlcCurrQUBlock = ppxlcCurrQUSlice; PixelC * ppxlcCurrQVBlock = ppxlcCurrQVSlice; PixelC * ppxlcCurrQBYBlock = ppxlcCurrQBYSlice; for (Int leftMB = rctWarpedBound.left; leftMB < rctWarpedBound.right; leftMB += BLOCK_SIZE) { PixelC *ppxlcCurrQU = ppxlcCurrQUBlock; PixelC *ppxlcCurrQV = ppxlcCurrQVBlock; PixelC *ppxlcCurrQBY = ppxlcCurrQBYBlock; PixelC *ppxlcCurrQBYNextRow = ppxlcCurrQBYBlock + nextRowBY; UInt offsetLineUV = m_pvopcCurrQ -> whereUV ().width - min(BLOCK_SIZE, rctWarpedBound.right - leftMB); UInt offsetLineBY = 2 * (m_pvopcCurrQ -> whereY ().width - min(BLOCK_SIZE, rctWarpedBound.right - leftMB)); Bool existOpaguePixelMBUV = (m_pvopcSptQ -> fAUsage () == RECTANGLE); Bool existZeroDenomMBUV = FALSE; for (CoordI y = topMB; y < min(topMB + BLOCK_SIZE, rctWarpedBound.bottom); y++) { for (CoordI x = leftMB; x < min(leftMB + BLOCK_SIZE, rctWarpedBound.right); x++) { CSiteWFlag src = persp * (CSite (x, y)); if (src.f) { existZeroDenomMBUV = TRUE; continue; } CoordD dx = (CoordD)src.s.x / (1 << accuracy1); CoordD dy = (CoordD)src.s.y / (1 << accuracy1); CoordI fx = (CoordI) floor (dx); CoordI fy = (CoordI) floor (dy); CoordI cx = (CoordI) ceil (dx); CoordI cy = (CoordI) ceil (dy); if (rctSptUV.includes (fx, fy) && rctSptUV.includes (fx, cy) && rctSptUV.includes (cx, fy) && rctSptUV.includes (cx, cy)) { if (*ppxlcCurrQBY | *(ppxlcCurrQBY + 1) | *ppxlcCurrQBYNextRow | *(ppxlcCurrQBYNextRow+1)) { existOpaguePixelMBUV = TRUE; *ppxlcCurrQU = puciSptU -> pixel (src.s, accuracy); *ppxlcCurrQV = puciSptV -> pixel (src.s, accuracy); } } ppxlcCurrQBY += 2; ppxlcCurrQBYNextRow += 2; ppxlcCurrQU++; ppxlcCurrQV++; } ppxlcCurrQBY += offsetLineBY; ppxlcCurrQBYNextRow += offsetLineBY; ppxlcCurrQU += offsetLineUV; ppxlcCurrQV += offsetLineUV; } assert (!(existOpaguePixelMBUV && existZeroDenomMBUV)); ppxlcCurrQBYBlock += MB_SIZE; ppxlcCurrQUBlock += BLOCK_SIZE; ppxlcCurrQVBlock += BLOCK_SIZE; } ppxlcCurrQBYSlice += offsetSliceBY; ppxlcCurrQUSlice += offsetSliceUV; ppxlcCurrQVSlice += offsetSliceUV; }} Void CVideoObject::FastAffineWarp (const CRct& rctWarpedBound, const CRct& rctWarpedBoundUV, UInt accuracy, UInt pntNum) { assert (m_pvopcCurrQ -> whereY ().includes (rctWarpedBound)); const CU8Image* puciCurrY = m_pvopcCurrQ -> getPlane (Y_PLANE);#ifdef _FOR_GSSP_ const CU8Image* puciCurrBY = m_pvopcCurrQ -> getPlane (BY_PLANE);#endif const CU8Image* puciCurrA = (m_pvopcSptQ -> fAUsage () == EIGHT_BIT)? m_pvopcCurrQ -> getPlane (A_PLANE) : m_pvopcCurrQ -> getPlane (BY_PLANE); const CU8Image* puciSptY = m_pvopcSptQ -> getPlane (Y_PLANE);#ifdef _FOR_GSSP_ const CU8Image* puciSptBY = m_pvopcSptQ -> getPlane (BY_PLANE);#endif const CU8Image* puciSptA = (m_pvopcSptQ -> fAUsage () == EIGHT_BIT)? m_pvopcSptQ -> getPlane (A_PLANE) : m_pvopcSptQ -> getPlane (BY_PLANE); const UInt offset = m_pvopcCurrQ -> whereY ().width - rctWarpedBound.width; PixelC* ppxlcCurrQY = (PixelC*) puciCurrY -> pixels ();#ifdef _FOR_GSSP_ PixelC* ppxlcCurrQBY = (PixelC*) puciCurrBY -> pixels ();#endif PixelC* ppxlcCurrQA = (PixelC*) puciCurrA -> pixels (); memset (ppxlcCurrQY, 0, puciCurrY -> where ().area () * sizeof(PixelC));#ifdef _FOR_GSSP_ memset (ppxlcCurrQBY, 0, puciCurrBY -> where ().area () * sizeof(PixelC));#endif memset (ppxlcCurrQA, 0, puciCurrA -> where ().area () * sizeof(PixelC)); ppxlcCurrQY = (PixelC*) puciCurrY -> pixels (rctWarpedBound.left, rctWarpedBound.top);#ifdef _FOR_GSSP_ ppxlcCurrQBY = (PixelC*) puciCurrBY -> pixels (rctWarpedBound.left, rctWarpedBound.top);#endif ppxlcCurrQA = (PixelC*) puciCurrA -> pixels (rctWarpedBound.left, rctWarpedBound.top); PixelC* ppxlcSptQY = (PixelC*) puciSptY -> pixels ();#ifdef _FOR_GSSP_ PixelC* ppxlcSptQBY = (PixelC*) puciSptBY -> pixels ();#endif PixelC* ppxlcSptQA = (PixelC*) puciSptA -> pixels (); Int sprite_left_edge = m_pvopcSptQ -> whereY ().left; Int sprite_top_edge = m_pvopcSptQ -> whereY ().top; ppxlcSptQY = (PixelC*) puciSptY -> pixels (sprite_left_edge, sprite_top_edge);#ifdef _FOR_GSSP_ ppxlcSptQBY = (PixelC*) puciSptBY -> pixels (sprite_left_edge, sprite_top_edge);#endif ppxlcSptQA = (PixelC*) puciSptA -> pixels (sprite_left_edge, sprite_top_edge); assert (m_pvopcCurrQ -> whereUV ().includes (rctWarpedBoundUV)); const CU8Image* puciCurrU = m_pvopcCurrQ -> getPlane (U_PLANE); const CU8Image* puciCurrV = m_pvopcCurrQ -> getPlane (V_PLANE);#ifndef _FOR_GSSP_ const CU8Image* puciCurrBY = m_pvopcCurrQ -> getPlane (BY_PLANE);#endif const CU8Image* puciSptU = m_pvopcSptQ -> getPlane (U_PLANE); const CU8Image* puciSptV = m_pvopcSptQ -> getPlane (V_PLANE); const UInt offsetUV = m_pvopcCurrQ -> whereUV ().width - rctWarpedBoundUV.width; const UInt offsetBY = 2 * (m_pvopcCurrQ -> whereY ().width - rctWarpedBoundUV.width); PixelC* ppxlcCurrQU = (PixelC*) puciCurrU -> pixels (); PixelC* ppxlcCurrQV = (PixelC*) puciCurrV -> pixels (); PixelC pxlcVal = 128; // not sure if this is needed swinder if(m_volmd.nBits>8) pxlcVal = 1<<(m_volmd.nBits - 1); memset (ppxlcCurrQU, pxlcVal, puciCurrU -> where ().area () * sizeof(PixelC)); memset (ppxlcCurrQV, pxlcVal, puciCurrV -> where ().area () * sizeof(PixelC)); ppxlcCurrQU = (PixelC*) puciCurrU -> pixels (rctWarpedBoundUV.left, rctWarpedBoundUV.top); ppxlcCurrQV = (PixelC*) puciCurrV -> pixels (rctWarpedBoundUV.left, rctWarpedBoundUV.top); PixelC* ppxlcSptQU = (PixelC*) puciSptU -> pixels (); PixelC* ppxlcSptQV = (PixelC*) puciSptV -> pixels (); ppxlcSptQU = (PixelC*) puciSptU -> pixels (sprite_left_edge/2, sprite_top_edge/2); ppxlcSptQV = (PixelC*) puciSptV -> pixels (sprite_left_edge/2, sprite_top_edge/2); UInt accuracy1 = accuracy + 1; UInt uiScale = 1 << accuracy1; Int a = 0, b = 0, c, d = 0, e = 0, f; Int cyy = 0, cxy = 0, dnm_pwr = 0; //wchen: get rid of unreferenced local variable cxx and cyx Int width = rctWarpedBound.right - rctWarpedBound.left; Int height = rctWarpedBound.bottom - rctWarpedBound.top; Int W, H, VW, VH = 0, VWH = 0, vh_pwr, vw_pwr, vwh_pwr = 0; Int r_pwr = 3 - accuracy; Int r = 1 << r_pwr; Int x0p = (Int)(m_rgstDstQ [0].x * uiScale * r); Int y0p = (Int)(m_rgstDstQ [0].y * uiScale * r); Int x1p = (Int)(m_rgstDstQ [1].x * uiScale * r); Int y1p = (Int)(m_rgstDstQ [1].y * uiScale * r); W = width; VW = 1; vw_pwr = 0; while (VW < W) { VW <<= 1; vw_pwr++; } Int ex2p = 0, ey2p = 0; Int x0 = 0; Int y0 = 0; Int x1 = W; Int y1 = 0; Int ex1p = LinearExtrapolation(x0, x1, x0p, x1p, W, VW) + ((x0+VW)<<4); Int ey1p = LinearExtrapolation(y0, y1, y0p, y1p, W, VW) + (y0<<4); if (pntNum==3) { Int x2p = (Int)(m_rgstDstQ [2].x * uiScale * r); Int y2p = (Int)(m_rgstDstQ [2].y * uiScale * r); H = height; VH = 1; vh_pwr = 0; while (VH < H) { VH <<= 1; vh_pwr++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -