📄 dct_decode.c
字号:
//==========================================================================//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR// PURPOSE.//// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.////--------------------------------------------------------------------------/****************************************************************************** Module Title : DCT_Decode.c** Description : DCT block expansion, decode and reconstruction functions********************************************************************************//***************************************************************************** Header Frames******************************************************************************/#define STRICT /* Strict type checking. */#include "pbdll.h"#include "dct.h"#include "Huffman.h"#include "Quantize.h"#include "Reconstruct.h"#include <math.h>#include <stdio.h>#include <string.h>#include <stdlib.h>/***************************************************************************** Module constants.******************************************************************************/ #define GOLDEN_FRAME_THRESH_Q 50/***************************************************************************** Explicit Imports******************************************************************************/ //extern AverageBlock( UINT8 *, UINT8 *, INT16 *, UINT32 );//extern UnpackBlock ( UINT8 *, INT16 *, UINT32 );//extern ReconBlock ( INT16 *, INT16 *, UINT8 *, UINT32);extern void ReconMotionBlock(PB_INSTANCE *pbi, UINT32 FragmentNumber, INT32 MvShift, INT32 MvModMask, UINT32 ReconPixelIndex, UINT32 ReconPixelsPerLine);/* Last Inter frame DC values *//*extern Q_LIST_ENTRY InvLastInterDC;extern Q_LIST_ENTRY InvLastIntraDC;*//***************************************************************************** Exported Global Variables******************************************************************************//***************************************************************************** Exported Functions******************************************************************************/ /***************************************************************************** Module Statics******************************************************************************/ //****************************************************************************// Copied From DCT_decode.c UINT32 LoopFilterLimitValuesV1[Q_TABLE_SIZE] = { 30, 25, 20, 20, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };UINT32 LoopFilterLimitValuesV2[Q_TABLE_SIZE] = { 30, 25, 20, 20, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 };/***************************************************************************** Foreward References******************************************************************************/ void ExpandBlock2 ( PB_INSTANCE *pbi, INT32 FragmentNumber );void CopyRecon( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT8 * SrcReconPtr );void CopyNotRecon( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT8 * SrcReconPtr );void UpdateUMVBorder( PB_INSTANCE *pbi, UINT8 * DestReconPtr );void UpdateUMV_HBorders( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT32 PlaneFragOffset );void UpdateUMV_VBorders( PB_INSTANCE *pbi, UINT8 * DestReconPtr, UINT32 PlaneFragOffset );void ApplyReconLoopFilter(PB_INSTANCE *pbi);void LoopFilter(PB_INSTANCE *pbi);/**************************************************************************** * * ROUTINE : SetupLoopFilter * * INPUTS : None * * OUTPUTS : None * * RETURNS : None * * FUNCTION : prepares to Apply a loop filter * * SPECIAL NOTES : * * * ERRORS : None. * ****************************************************************************/void SetupLoopFilter(PB_INSTANCE *pbi){ INT32 FLimit; FLimit = LoopFilterLimitValuesV2[pbi->FrameQIndex]; pbi->BoundingValuePtr = pbi->SetupBoundingValueArray(pbi, FLimit);}/**************************************************************************** * * ROUTINE : CopyBlock * * INPUTS : None * * OUTPUTS : None * * RETURNS : None. * * FUNCTION : Copies a block from source to destination * * SPECIAL NOTES : None. * * * ERRORS : None. * ****************************************************************************/void CopyBlock(unsigned char *src, unsigned char *dest, unsigned int srcstride){ unsigned char *s = src; unsigned char *d = dest; unsigned int stride = srcstride; int j; for ( j = 0; j < 8; j++ ) { ((UINT32*)d)[0] = ((UINT32*)s)[0]; ((UINT32*)d)[1] = ((UINT32*)s)[1]; s+=stride; d+=stride; }}/**************************************************************************** * * ROUTINE : ReconRefFrames * * INPUTS : None * * OUTPUTS : None * * RETURNS : None. * * FUNCTION : Reconstructs the various reference frames * * SPECIAL NOTES : None. * * * ERRORS : None. * ****************************************************************************/void ReconRefFrames (PB_INSTANCE *pbi){ INT32 i; INT32 FragIndex; // Fragment number UINT8 *SwapReconBuffersTemp;#define PUL 8#define PU 4#define PUR 2#define PL 1 short pc[16][6]= { {0,0,0,0,0,0}, {0,0,0,1,0,0}, // PL {0,0,1,0,0,0}, // PUR {0,0,53,75,7,127}, // PUR|PL {0,1,0,0,0,0}, // PU {0,1,0,1,1,1}, // PU|PL {0,1,0,0,0,0}, // PU|PUR {0,0,53,75,7,127}, // PU|PUR|PL {1,0,0,0,0,0}, // PUL| {0,0,0,1,0,0}, // PUL|PL {1,0,1,0,1,1}, // PUL|PUR {0,0,53,75,7,127}, // PUL|PUR|PL {0,1,0,0,0,0}, // PUL|PU {-26,29,0,29,5,31}, // PUL|PU|PL {3,10,3,0,4,15}, // PUL|PU|PUR {-26,29,0,29,5,31} // PUL|PU|PUR|PL }; // fragment left fragment up-left, fragment up, fragment up-right int fl,ful,fu,fur; // value left value up-left, value up, value up-right int vl,vul,vu,vur; // fragment number left, up-left, up, up-right int l,ul,u,ur; //which predictor constants to use short wpc; short Mode2Frame[] = { 1, // CODE_INTER_NO_MV 0 => Encoded diff from same MB last frame 0, // CODE_INTRA 1 => DCT Encoded Block 1, // CODE_INTER_PLUS_MV 2 => Encoded diff from included MV MB last frame 1, // CODE_INTER_LAST_MV 3 => Encoded diff from MRU MV MB last frame 1, // CODE_INTER_PRIOR_MV 4 => Encoded diff from included 4 separate MV blocks 2, // CODE_USING_GOLDEN 5 => Encoded diff from same MB golden frame 2, // CODE_GOLDEN_MV 6 => Encoded diff from included MV MB golden frame 1 // CODE_INTER_FOUR_MV 7 => Encoded diff from included 4 separate MV blocks }; short Last[3]; // last value used for given frame short PredictedDC; void (*ExpandBlockA) ( PB_INSTANCE *pbi, INT32 FragmentNumber ); #define HIGHBITDUPPED(X) (((signed short) X) >> 15) int FragsAcross=pbi->HFragments; int FromFragment,ToFragment; int FragsDown = pbi->VFragments; int WhichFrame; int WhichCase; int j,k,m,n; /* Search Points are ordered by distance from 0,0 only DCSearchpointCount positions checked! -4 -3 -2 -1 0 1 2 3 4 -4 21 19 22 -3 24 15 11 9 12 16 25 -2 14 6 3 1 4 7 17 -1 20 10 2 z z z 5 13 23 0 18 8 0 z z z z z z */ struct SearchPoints { int RowOffset; int ColOffset; } DCSearchPoints[]= { {0,-2},{-2,0},{-1,-2},{-2,-1},{-2,1},{-1,2},{-2,-2},{-2,2},{0,-3}, {-3,0},{-1,-3},{-3,-1},{-3,1},{-1,3},{-2,-3},{-3,-2},{-3,2},{-2,3}, {0,-4},{-4,0},{-1,-4},{-4,-1},{-4,1},{-1,4},{-3,-3},{-3,3} }; //int DCSearchPointCount = sizeof(DCSearchPoints) / ( 2 * sizeof(int)); int DCSearchPointCount = 0;#ifdef DEBUG vl = vul = vu = vur = 0;#endif if ( GetFrameType(pbi) == BASE_FRAME ) ExpandBlockA=ExpandKFBlock; else { ExpandBlockA=ExpandBlock; } // testing ? SetupLoopFilter(pbi); // for y,u,v for ( j = 0; j < 3 ; j++) { // pick which fragments based on Y, U, V switch(j) { case 0: // y FromFragment = 0; ToFragment = pbi->YPlaneFragments; FragsAcross = pbi->HFragments; FragsDown = pbi->VFragments; break; case 1: // u FromFragment = pbi->YPlaneFragments; ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; break; case 2: // v default: // Johns: to avoid uninitialized warnings FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments; ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ; FragsAcross = pbi->HFragments >> 1; FragsDown = pbi->VFragments >> 1; break; } // initialize our array of last used DC Components for(k=0;k<3;k++) Last[k]=0; i=FromFragment; // do prediction on all of Y, U or V for ( m = 0 ; m < FragsDown ; m++) { for ( n = 0 ; n < FragsAcross ; n++, i++) { // only do 2 prediction if fragment coded and on non intra or if all fragments are intra if( pbi->display_fragments[i] || (GetFrameType(pbi) == BASE_FRAME) ) { // Type of Fragment WhichFrame = Mode2Frame[pbi->FragCodingMethod[i]]; // Check Borderline Cases WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == FragsAcross) << 2); switch(WhichCase) { case 0: // normal case no border condition // calculate values left, up, up-right and up-left l = i-1; u = i - FragsAcross; ur = i - FragsAcross + 1; ul = i - FragsAcross - 1; // calculate values vl = pbi->QFragData[l][0]; vu = pbi->QFragData[u][0]; vur = pbi->QFragData[ur][0]; vul = pbi->QFragData[ul][0]; // fragment valid for prediction use if coded and it comes from same frame as the one we are predicting fl = pbi->display_fragments[l] && (Mode2Frame[pbi->FragCodingMethod[l]] == WhichFrame); fu = pbi->display_fragments[u] && (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame); fur = pbi->display_fragments[ur] && (Mode2Frame[pbi->FragCodingMethod[ur]] == WhichFrame); ful = pbi->display_fragments[ul] && (Mode2Frame[pbi->FragCodingMethod[ul]] == WhichFrame); // calculate which predictor to use wpc = (fl*PL) | (fu*PU) | (ful*PUL) | (fur*PUR); break; case 1: // n == 0 Left Column // calculate values left, up, up-right and up-left u = i - FragsAcross; ur = i - FragsAcross + 1; // calculate values vu = pbi->QFragData[u][0]; vur = pbi->QFragData[ur][0]; // fragment valid for prediction if coded and it comes from same frame as the one we are predicting fu = pbi->display_fragments[u] && (Mode2Frame[pbi->FragCodingMethod[u]] == WhichFrame); fur = pbi->display_fragments[ur] && (Mode2Frame[pbi->FragCodingMethod[ur]] == WhichFrame); // calculate which predictor to use wpc = (fu*PU) | (fur*PUR); break; case 2: // m == 0 Top Row case 6: // m == 0 and n+1 == FragsAcross or Top Row Right Column // calculate values left, up, up-right and up-left l = i-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -