diff options
Diffstat (limited to 'mpeglib/lib/mpegplay/recon.cpp')
-rw-r--r-- | mpeglib/lib/mpegplay/recon.cpp | 735 |
1 files changed, 735 insertions, 0 deletions
diff --git a/mpeglib/lib/mpegplay/recon.cpp b/mpeglib/lib/mpegplay/recon.cpp new file mode 100644 index 00000000..6116157a --- /dev/null +++ b/mpeglib/lib/mpegplay/recon.cpp @@ -0,0 +1,735 @@ +/* + class for reconstruction + Copyright (C) 1999 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "recon.h" + + +#define DEBUG_RECON(x) +//#define DEBUG_RECON(x) x + + + +Recon::Recon() { + copyFunctions=new CopyFunctions(); +} + + +Recon::~Recon() { + delete copyFunctions; +} + + +/* + *-------------------------------------------------------------- + * + * ReconIMBlock -- + * + * Reconstructs intra coded macroblock. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +int Recon::ReconIMBlock(int bnum,int mb_row,int mb_col,int row_size, + short int* dct_start,PictureArray* pictureArray) { + int row, col; + unsigned char *dest; + unsigned char *picDest; + int lumLength=(pictureArray->getCurrent())->getLumLength(); + int colorLength=(pictureArray->getCurrent())->getColorLength(); + int endDest=0; + + + + /* If block is luminance block... */ + + if (bnum < 4) { + + /* Calculate row and col values for upper left pixel of block. */ + + row = mb_row << 4; + col = mb_col << 4; + if (bnum > 1) + row += 8; + if (bnum % 2) + col += 8; + + /* Set dest to luminance plane of current pict image. */ + + picDest = (pictureArray->getCurrent())->getLuminancePtr(); + endDest=lumLength; + + } + /* Otherwise if block is Cr block... */ + /* Cr first because of the earlier mixup */ + + else if (bnum == 5) { + + /* Set dest to Cr plane of current pict image. */ + + picDest = (pictureArray->getCurrent())->getCrPtr(); + endDest=colorLength; + + /* Establish row size. yuv color is half of whole size*/ + row_size >>=1; + + /* Calculate row,col for upper left pixel of block. */ + + row = mb_row << 3; + col = mb_col << 3; + } + /* Otherwise block is Cb block, and ... */ + + else { + + /* Set dest to Cb plane of current pict image. */ + + picDest = (pictureArray->getCurrent())->getCbPtr(); + endDest=colorLength; + + + /* Establish row size. yuv color is half of whole size*/ + + row_size /=2; + + /* Calculate row,col for upper left pixel value of block. */ + + row = mb_row << 3; + col = mb_col << 3; + } + + + /* + * For each pixel in block, set to cropped reconstructed value from inverse + * dct. + */ + + dest = picDest+row * row_size + col; + + + if ((dest+7*row_size+7 >= picDest+endDest) || (dest < picDest)) { + DEBUG_RECON(cout << "urg! last resort caught before sigsev -4"<<endl;) + return false; + } + + + copyFunctions->copy8_src1linear_crop(dct_start,dest,row_size); + + + return true; +} + + + +/* + *-------------------------------------------------------------- + * + * ReconPMBlock -- + * + * Reconstructs forward predicted macroblocks. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +int Recon::ReconPMBlock(int bnum, + int recon_right_for, + int recon_down_for, + int zflag, + int mb_row,int mb_col, + int row_size,short int* dct_start, + PictureArray* pictureArray,int codeType) { + int row, col, rr; + unsigned char *picDest, *past; + unsigned char *rindex1, *rindex2, *rindex3, *rindex4; + unsigned char *index; + int lumLength=(pictureArray->getCurrent())->getLumLength(); + int colorLength=(pictureArray->getCurrent())->getColorLength(); + int endPast=0; + int endDest=0; + + + int right_for; + int down_for; + int right_half_for; + int down_half_for; + + + + picDest=0; + + if (bnum < 4) { + + + + /* Set dest to luminance plane of current pict image. */ + + picDest = (pictureArray->getCurrent())->getLuminancePtr(); + endDest=lumLength; + + if (codeType == B_TYPE) { + past = (pictureArray->getPast())->getLuminancePtr(); + } else { + + /* Set predictive frame to current future frame. */ + + past = (pictureArray->getFuture())->getLuminancePtr(); + } + endPast=lumLength; + + + /* Calculate row,col of upper left pixel in block. */ + + row = mb_row << 4; + col = mb_col << 4; + if (bnum > 1) + row += 8; + if (bnum % 2) + col += 8; + + /* Otherwise, block is NOT luminance block, ... */ + + } else { + + /* Construct motion vectors. */ + + recon_right_for >>= 1; + recon_down_for >>= 1; + + /* Establish row size. yuv color is half of whole size*/ + + row_size /= 2; + + + /* Calculate row,col of upper left pixel in block. */ + + row = mb_row << 3; + col = mb_col << 3; + + /* If block is Cr block... */ + /* 5 first because order was mixed up in earlier versions */ + + if (bnum == 5) { + + /* Set dest to Cr plane of current pict image. */ + + picDest = (pictureArray->getCurrent())->getCrPtr(); + + if (codeType == B_TYPE) { + + past = (pictureArray->getPast())->getCrPtr(); + } else { + past = (pictureArray->getFuture())->getCrPtr(); + } + } + /* Otherwise, block is Cb block... */ + + else { + + /* Set dest to Cb plane of current pict image. */ + + picDest = (pictureArray->getCurrent())->getCbPtr(); + + if (codeType == B_TYPE) { + past = (pictureArray->getPast())->getCbPtr(); + } else { + past = (pictureArray->getFuture())->getCbPtr(); + } + } + endPast=colorLength; + endDest=colorLength; + + } + + /* Calculate right_back, down_back motion vectors. */ + right_for = recon_right_for >> 1; + down_for = recon_down_for >> 1; + right_half_for = recon_right_for & 0x1; + down_half_for = recon_down_for & 0x1; + + + /* For each pixel in block... */ + + index = picDest + (row * row_size) + col; + rindex1 = past + (row + down_for) * row_size + col + right_for; + + + + + if ((rindex1+7*row_size+7 >= past+endPast) || (rindex1 < past)) { + DEBUG_RECON(cout << "urg! last resort caught before sigsev -1"<<endl;) + return false; + } + if ((index+7*row_size+7 >= picDest+endDest) || (index < picDest)) { + DEBUG_RECON(cout << "urg! last resort caught before sigsev -2"<<endl;) + return false; + } + + + /* + * Calculate predictive pixel value based on motion vectors and copy to + * dest plane. + */ + + if ((!down_half_for) && (!right_half_for)) { + + if (!zflag) { + copyFunctions->copy8_src2linear_crop(rindex1,dct_start,index,row_size); + } else { + if (right_for & 0x1) { + + /* No alignment, used byte copy */ + copyFunctions->copy8_byte(rindex1,index,row_size); + + + } else if (right_for & 0x2) { + /* Half-word bit aligned, use 16 bit copy */ + unsigned short *src = (unsigned short *)rindex1; + unsigned short *dest = (unsigned short *)index; + row_size >>= 1; + copyFunctions->copy8_word(src,dest,row_size); + + } else { + /* Word aligned, use 32 bit copy */ + int *src = (int*) rindex1; + int *dest = (int*) index; + + row_size >>= 2; + + + for (rr = 0; rr < 8; rr++) { + dest[0] = src[0]; + dest[1] = src[1]; + dest += row_size; + src += row_size; + } + + } + } + } else { + rindex2 = rindex1 + right_half_for + (down_half_for * row_size); + + /* if one of the two is zero, then quality makes no difference */ + if ((!right_half_for) || (!down_half_for) || (!qualityFlag)) { + + if (!zflag) { + // was +1 + copyFunctions->copy8_div2_src3linear_crop(rindex1,rindex2,dct_start, + index,row_size); + } else { /* zflag */ + // was +1 + copyFunctions->copy8_div2_nocrop(rindex1,rindex2,index,row_size); + } + } else { /* qualityFlag on and both vectors are non-zero */ + rindex3 = rindex1 + right_half_for; + rindex4 = rindex1 + (down_half_for * row_size); + if (!zflag) { + copyFunctions->copy8_div4_src5linear_crop(rindex1,rindex2,rindex3, + rindex4,dct_start, + index,row_size); + } else { /* zflag */ + copyFunctions->copy8_div4_nocrop(rindex1,rindex2,rindex3,rindex4, + index,row_size); + } + } + + } + + return true; +} + + +/* + *-------------------------------------------------------------- + * + * ReconBMBlock -- + * + * Reconstructs back predicted macroblocks. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +int Recon::ReconBMBlock(int bnum, + int recon_right_back, + int recon_down_back, + int zflag, + int mb_row,int mb_col, + int row_size,short int* dct_start, + PictureArray* pictureArray) { + int row, col, rr; + unsigned char *dest, *future; + int right_back, down_back, right_half_back, down_half_back; + unsigned char *rindex1, *rindex2, *rindex3, *rindex4; + unsigned char *index; + int lumLength=(pictureArray->getCurrent())->getLumLength(); + int colorLength=(pictureArray->getCurrent())->getColorLength(); + + int endFuture=0; + int endDest=0; + + + /* If block is luminance block... */ + + if (bnum < 4) { + + + /* Set dest to luminance plane of current pict image. */ + + dest = (pictureArray->getCurrent())->getLuminancePtr(); + endDest=lumLength; + /* + * If future frame exists, set future to luminance plane of future frame. + */ + + future = (pictureArray->getFuture())->getLuminancePtr(); + endFuture=lumLength; + + /* Calculate row,col of upper left pixel in block. */ + + row = mb_row << 4; + col = mb_col << 4; + if (bnum > 1) + row += 8; + if (bnum % 2) + col += 8; + + + } + /* Otherwise, block is NOT luminance block, ... */ + + else { + + /* Construct motion vectors. */ + + recon_right_back >>= 1; + recon_down_back >>= 1; + + /* Establish row size. yuv color is half of whole size*/ + + row_size >>= 1; + + /* Calculate row,col of upper left pixel in block. */ + + row = mb_row << 3; + col = mb_col << 3; + + + /* If block is Cr block... */ + /* They were switched earlier, so 5 is first - eyhung */ + + if (bnum == 5) { + + /* Set dest to Cr plane of current pict image. */ + + dest = (pictureArray->getCurrent())->getCrPtr(); + + /* + * If future frame exists, set future to Cr plane of future image. + */ + + future = (pictureArray->getFuture())->getCrPtr(); + } + /* Otherwise, block is Cb block... */ + + else { + + /* Set dest to Cb plane of current pict image. */ + + dest = (pictureArray->getCurrent())->getCbPtr(); + + /* + * If future frame exists, set future to Cb plane of future frame. + */ + + future = (pictureArray->getFuture())->getCbPtr(); + } + endDest=colorLength; + endFuture=colorLength; + } + + /* Calculate right_back, down_back motion vectors. */ + right_back = recon_right_back >> 1; + down_back = recon_down_back >> 1; + right_half_back = recon_right_back & 0x1; + down_half_back = recon_down_back & 0x1; + + /* For each pixel in block do... */ + + index = dest + (row * row_size) + col; + rindex1 = future + (row + down_back) * row_size + col + right_back; + + if ((index+7*row_size+7 >= dest+endDest) || (index < dest)) { + DEBUG_RECON(cout << "urg! last resort -9"<<endl;) + return false; + } + if ((rindex1+7*row_size+7 >= future+endFuture) || (rindex1 < future)) { + DEBUG_RECON(cout << "urg! last resort -8"<<endl;) + return false; + } + + if ((!right_half_back) && (!down_half_back)) { + if (!zflag) { + copyFunctions->copy8_src2linear_crop(rindex1,dct_start,index,row_size); + } else { + if (right_back & 0x1) { + /* No alignment, use byte copy */ + + copyFunctions->copy8_byte(rindex1,index,row_size); + + } else if (right_back & 0x2) { + /* Half-word bit aligned, use 16 bit copy */ + unsigned short *src = (unsigned short *)rindex1; + unsigned short *dest = (unsigned short *)index; + row_size >>= 1; + copyFunctions->copy8_word(src,dest,row_size); + + } else { + /* Word aligned, use 32 bit copy */ + int *src = (int *)rindex1; + int *dest = (int *)index; + row_size >>= 2; + for (rr = 0; rr < 8; rr++) { + dest[0] = src[0]; + dest[1] = src[1]; + dest += row_size; + src += row_size; + } + } + } + } else { + rindex2 = rindex1 + right_half_back + (down_half_back * row_size); + if (!qualityFlag) { + + if (!zflag) { + // was +1 + copyFunctions->copy8_div2_src3linear_crop(rindex1,rindex2,dct_start, + index,row_size); + } else { /* zflag */ + // was +1 + copyFunctions->copy8_div2_nocrop(rindex1,rindex2,index,row_size); + } + } else { /* qualityFlag on */ + rindex3 = rindex1 + right_half_back; + rindex4 = rindex1 + (down_half_back * row_size); + if (!zflag) { + copyFunctions->copy8_div4_src5linear_crop(rindex1,rindex2,rindex3, + rindex4,dct_start, + index,row_size); + } else { /* zflag */ + copyFunctions->copy8_div4_nocrop(rindex1,rindex2,rindex3,rindex4, + index,row_size); + } + } + + } + return true; +} + + +/* + *-------------------------------------------------------------- + * + * ReconBiMBlock -- + * + * Reconstructs bidirectionally predicted macroblocks. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ +int Recon::ReconBiMBlock(int bnum, + int recon_right_for, + int recon_down_for, + int recon_right_back, + int recon_down_back, + int zflag,int mb_row, + int mb_col,int row_size,short int* dct_start, + PictureArray* pictureArray) { + int row, col; + unsigned char *dest, *past=NULL, *future=NULL; + int right_for, down_for, right_half_for, down_half_for; + int right_back, down_back, right_half_back, down_half_back; + unsigned char *index, *rindex1, *bindex1; + int forw_row_start, back_row_start, forw_col_start, back_col_start; + int lumLength=(pictureArray->getCurrent())->getLumLength(); + int colorLength=(pictureArray->getCurrent())->getColorLength(); + int endPast=0; + int endFuture=0; + + + + + /* If block is luminance block... */ + + if (bnum < 4) { + + + /* Set dest to luminance plane of current pict image. */ + + dest = (pictureArray->getCurrent())->getLuminancePtr(); + + /* If past frame exists, set past to luminance plane of past frame. */ + + past = (pictureArray->getPast())->getLuminancePtr(); + endPast=lumLength; + + /* + * If future frame exists, set future to luminance plane of future frame. + */ + + future = (pictureArray->getFuture())->getLuminancePtr(); + endFuture=lumLength; + + /* Calculate row,col of upper left pixel in block. */ + + row = (mb_row << 4); + col = (mb_col << 4); + if (bnum > 1) + row += 8; + if (bnum & 0x01) + col += 8; + + + + } else { + /* Otherwise, block is NOT luminance block, ... */ + + /* Construct motion vectors. */ + recon_right_for >>= 1; + recon_down_for >>= 1; + recon_right_back >>= 1; + recon_down_back >>= 1; + + /* Establish row size. yuv color is half of whole size*/ + + row_size /= 2; + + + /* Calculate row,col of upper left pixel in block. */ + + row = (mb_row << 3); + col = (mb_col << 3); + + + + + /* If block is Cr block... */ + /* Switched earlier, so we test Cr first - eyhung */ + + if (bnum == 5) { + /* Set dest to Cr plane of current pict image. */ + + dest = (pictureArray->getCurrent())->getCrPtr(); + + /* If past frame exists, set past to Cr plane of past image. */ + + past = (pictureArray->getPast())->getCrPtr(); + endPast=colorLength; + /* + * If future frame exists, set future to Cr plane of future image. + */ + + future = (pictureArray->getFuture())->getCrPtr(); + endFuture=colorLength; + } + /* Otherwise, block is Cb block... */ + + else { + /* Set dest to Cb plane of current pict image. */ + dest = (pictureArray->getCurrent())->getCbPtr(); + + /* If past frame exists, set past to Cb plane of past frame. */ + + past = (pictureArray->getPast())->getCbPtr(); + endPast=colorLength; + + /* + * If future frame exists, set future to Cb plane of future frame. + */ + + future = (pictureArray->getFuture())->getCbPtr(); + endFuture=colorLength; + } + } + /* + * Calculate right_for, down_for, right_half_for, down_half_for, + * right_back, down_bakc, right_half_back, and down_half_back, motion + * vectors. + */ + + right_for = recon_right_for >> 1; + down_for = recon_down_for >> 1; + right_half_for = recon_right_for & 0x1; + down_half_for = recon_down_for & 0x1; + + right_back = recon_right_back >> 1; + down_back = recon_down_back >> 1; + right_half_back = recon_right_back & 0x1; + down_half_back = recon_down_back & 0x1; + + forw_col_start = col + right_for; + forw_row_start = row + down_for; + + back_col_start = col + right_back; + back_row_start = row + down_back; + + /* For each pixel in block... */ + + index = dest + (row * row_size) + col; + + rindex1 = past + forw_row_start * row_size + forw_col_start; + + bindex1 = future + back_row_start * row_size + back_col_start; + + if ((rindex1+7*row_size+7 >= past+endPast) || (rindex1 < past)) { + DEBUG_RECON(cout << "urg! last resort -1"<<endl;) + return false; + } + if ((bindex1+7*row_size+7 >= future+endFuture) || (bindex1 < future)) { + DEBUG_RECON(cout << "urg! last resort -2"<<endl;) + return false; + } + + + + if (!zflag) { + copyFunctions->copy8_div2_src3linear_crop(rindex1,bindex1,dct_start, + index,row_size); + } else { + copyFunctions->copy8_div2_nocrop(rindex1,bindex1,index,row_size); + } + + return true; +} + + |