📄 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.cpp
Abstract:
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_FILE
static 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 + -