|
|
/*!
|
/*!
|
***********************************************************************
|
***********************************************************************
|
* \file macroblock.c
|
* \file macroblock.c
|
*
|
*
|
* \brief
|
* \brief
|
* Decode a Macroblock
|
* Decode a Macroblock
|
*
|
*
|
* \author
|
* \author
|
* Main contributors (see contributors.h for copyright, address and affiliation details)
|
* Main contributors (see contributors.h for copyright, address and affiliation details)
|
* - Inge Lille-Langøy <inge.lille-langoy@telenor.com>
|
* - Inge Lille-Langøy <inge.lille-langoy@telenor.com>
|
* - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
|
* - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
|
* - Jani Lainema <jani.lainema@nokia.com>
|
* - Jani Lainema <jani.lainema@nokia.com>
|
* - Sebastian Purreiter <sebastian.purreiter@mch.siemens.de>
|
* - Sebastian Purreiter <sebastian.purreiter@mch.siemens.de>
|
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
|
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
|
* - Detlev Marpe <marpe@hhi.de>
|
* - Detlev Marpe <marpe@hhi.de>
|
* - Gabi Blaettermann <blaetter@hhi.de>
|
* - Gabi Blaettermann <blaetter@hhi.de>
|
* - Ye-Kui Wang <wyk@ieee.org>
|
* - Ye-Kui Wang <wyk@ieee.org>
|
* - Lowell Winger <lwinger@lsil.com>
|
* - Lowell Winger <lwinger@lsil.com>
|
***********************************************************************
|
***********************************************************************
|
*/
|
*/
|
|
|
#include "contributors.h"
|
#include "contributors.h"
|
|
|
#include <math.h>
|
#include <math.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <assert.h>
|
#include <assert.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#include "global.h"
|
#include "global.h"
|
#include "mbuffer.h"
|
#include "mbuffer.h"
|
#include "elements.h"
|
#include "elements.h"
|
#include "errorconcealment.h"
|
#include "errorconcealment.h"
|
#include "macroblock.h"
|
#include "macroblock.h"
|
#include "fmo.h"
|
#include "fmo.h"
|
#include "cabac.h"
|
#include "cabac.h"
|
#include "vlc.h"
|
#include "vlc.h"
|
#include "image.h"
|
#include "image.h"
|
#include "mb_access.h"
|
#include "mb_access.h"
|
#include "biaridecod.h"
|
#include "biaridecod.h"
|
|
|
#include "transform8x8.h"
|
#include "transform8x8.h"
|
|
|
#if TRACE
|
#if TRACE
|
#define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE)
|
#define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE)
|
#else
|
#else
|
#define TRACE_STRING(s) // do nothing
|
#define TRACE_STRING(s) // do nothing
|
#endif
|
#endif
|
|
|
extern int last_dquant;
|
extern int last_dquant;
|
extern ColocatedParams *Co_located;
|
extern ColocatedParams *Co_located;
|
|
|
|
|
static void SetMotionVectorPredictor (struct img_par *img,
|
static void SetMotionVectorPredictor (struct img_par *img,
|
short pmv[2],
|
short pmv[2],
|
char ref_frame,
|
char ref_frame,
|
byte list,
|
byte list,
|
char ***refPic,
|
char ***refPic,
|
short ****tmp_mv,
|
short ****tmp_mv,
|
int block_x,
|
int block_x,
|
int block_y,
|
int block_y,
|
int blockshape_x,
|
int blockshape_x,
|
int blockshape_y);
|
int blockshape_y);
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* initializes the current macroblock
|
* initializes the current macroblock
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void start_macroblock(struct img_par *img,int CurrentMBInScanOrder)
|
void start_macroblock(struct img_par *img,int CurrentMBInScanOrder)
|
{
|
{
|
int l,j;
|
int l,j;
|
Macroblock *currMB; // intialization code deleted, see below, StW
|
Macroblock *currMB; // intialization code deleted, see below, StW
|
|
|
assert (img->current_mb_nr < img->PicSizeInMbs);
|
assert (img->current_mb_nr < img->PicSizeInMbs);
|
|
|
currMB = &img->mb_data[img->current_mb_nr];
|
currMB = &img->mb_data[img->current_mb_nr];
|
|
|
/* Update coordinates of the current macroblock */
|
/* Update coordinates of the current macroblock */
|
if (img->MbaffFrameFlag)
|
if (img->MbaffFrameFlag)
|
{
|
{
|
img->mb_x = (img->current_mb_nr)%((2*img->width)/MB_BLOCK_SIZE);
|
img->mb_x = (img->current_mb_nr)%((2*img->width)/MB_BLOCK_SIZE);
|
img->mb_y = 2*((img->current_mb_nr)/((2*img->width)/MB_BLOCK_SIZE));
|
img->mb_y = 2*((img->current_mb_nr)/((2*img->width)/MB_BLOCK_SIZE));
|
|
|
if (img->mb_x & 0x01)
|
if (img->mb_x & 0x01)
|
{
|
{
|
img->mb_y++;
|
img->mb_y++;
|
}
|
}
|
|
|
img->mb_x /= 2;
|
img->mb_x /= 2;
|
}
|
}
|
else
|
else
|
{
|
{
|
img->mb_x = PicPos[img->current_mb_nr][0];
|
img->mb_x = PicPos[img->current_mb_nr][0];
|
img->mb_y = PicPos[img->current_mb_nr][1];
|
img->mb_y = PicPos[img->current_mb_nr][1];
|
}
|
}
|
|
|
/* Define vertical positions */
|
/* Define vertical positions */
|
img->block_y = img->mb_y * BLOCK_SIZE; /* luma block position */
|
img->block_y = img->mb_y * BLOCK_SIZE; /* luma block position */
|
img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
|
img->pix_y = img->mb_y * MB_BLOCK_SIZE; /* luma macroblock position */
|
img->pix_c_y = img->mb_y * img->mb_cr_size_y; /* chroma macroblock position */
|
img->pix_c_y = img->mb_y * img->mb_cr_size_y; /* chroma macroblock position */
|
|
|
/* Define horizontal positions */
|
/* Define horizontal positions */
|
img->block_x = img->mb_x * BLOCK_SIZE; /* luma block position */
|
img->block_x = img->mb_x * BLOCK_SIZE; /* luma block position */
|
img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
|
img->pix_x = img->mb_x * MB_BLOCK_SIZE; /* luma pixel position */
|
img->pix_c_x = img->mb_x * img->mb_cr_size_x; /* chroma pixel position */
|
img->pix_c_x = img->mb_x * img->mb_cr_size_x; /* chroma pixel position */
|
|
|
// Save the slice number of this macroblock. When the macroblock below
|
// Save the slice number of this macroblock. When the macroblock below
|
// is coded it will use this to decide if prediction for above is possible
|
// is coded it will use this to decide if prediction for above is possible
|
currMB->slice_nr = img->current_slice_nr;
|
currMB->slice_nr = img->current_slice_nr;
|
|
|
if (img->current_slice_nr >= MAX_NUM_SLICES)
|
if (img->current_slice_nr >= MAX_NUM_SLICES)
|
{
|
{
|
error ("maximum number of supported slices exceeded, please recompile with increased value for MAX_NUM_SLICES", 200);
|
error ("maximum number of supported slices exceeded, please recompile with increased value for MAX_NUM_SLICES", 200);
|
}
|
}
|
|
|
dec_picture->slice_id[img->mb_y][img->mb_x] = img->current_slice_nr;
|
dec_picture->slice_id[img->mb_y][img->mb_x] = img->current_slice_nr;
|
if (img->current_slice_nr > dec_picture->max_slice_id)
|
if (img->current_slice_nr > dec_picture->max_slice_id)
|
{
|
{
|
dec_picture->max_slice_id=img->current_slice_nr;
|
dec_picture->max_slice_id=img->current_slice_nr;
|
}
|
}
|
|
|
CheckAvailabilityOfNeighbors();
|
CheckAvailabilityOfNeighbors();
|
|
|
// Reset syntax element entries in MB struct
|
// Reset syntax element entries in MB struct
|
currMB->qp = img->qp ;
|
currMB->qp = img->qp ;
|
currMB->mb_type = 0;
|
currMB->mb_type = 0;
|
currMB->delta_quant = 0;
|
currMB->delta_quant = 0;
|
currMB->cbp = 0;
|
currMB->cbp = 0;
|
currMB->cbp_blk = 0;
|
currMB->cbp_blk = 0;
|
currMB->c_ipred_mode= DC_PRED_8; //GB
|
currMB->c_ipred_mode= DC_PRED_8; //GB
|
|
|
for (l=0; l < 2; l++)
|
for (l=0; l < 2; l++)
|
for (j=0; j < BLOCK_MULTIPLE; j++)
|
for (j=0; j < BLOCK_MULTIPLE; j++)
|
memset(&(currMB->mvd[l][j][0][0]),0, BLOCK_MULTIPLE * 2 * sizeof(int));
|
memset(&(currMB->mvd[l][j][0][0]),0, BLOCK_MULTIPLE * 2 * sizeof(int));
|
|
|
currMB->cbp_bits = 0;
|
currMB->cbp_bits = 0;
|
|
|
// initialize img->m7
|
// initialize img->m7
|
memset(&(img->m7[0][0]), 0, MB_BLOCK_PIXELS * sizeof(int));
|
memset(&(img->m7[0][0]), 0, MB_BLOCK_PIXELS * sizeof(int));
|
|
|
// store filtering parameters for this MB
|
// store filtering parameters for this MB
|
currMB->LFDisableIdc = img->currentSlice->LFDisableIdc;
|
currMB->LFDisableIdc = img->currentSlice->LFDisableIdc;
|
currMB->LFAlphaC0Offset = img->currentSlice->LFAlphaC0Offset;
|
currMB->LFAlphaC0Offset = img->currentSlice->LFAlphaC0Offset;
|
currMB->LFBetaOffset = img->currentSlice->LFBetaOffset;
|
currMB->LFBetaOffset = img->currentSlice->LFBetaOffset;
|
|
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* set coordinates of the next macroblock
|
* set coordinates of the next macroblock
|
* check end_of_slice condition
|
* check end_of_slice condition
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
Boolean exit_macroblock(struct img_par *img,struct inp_par *inp,int eos_bit)
|
Boolean exit_macroblock(struct img_par *img,struct inp_par *inp,int eos_bit)
|
{
|
{
|
//! The if() statement below resembles the original code, which tested
|
//! The if() statement below resembles the original code, which tested
|
//! img->current_mb_nr == img->PicSizeInMbs. Both is, of course, nonsense
|
//! img->current_mb_nr == img->PicSizeInMbs. Both is, of course, nonsense
|
//! In an error prone environment, one can only be sure to have a new
|
//! In an error prone environment, one can only be sure to have a new
|
//! picture by checking the tr of the next slice header!
|
//! picture by checking the tr of the next slice header!
|
|
|
// printf ("exit_macroblock: FmoGetLastMBOfPicture %d, img->current_mb_nr %d\n", FmoGetLastMBOfPicture(), img->current_mb_nr);
|
// printf ("exit_macroblock: FmoGetLastMBOfPicture %d, img->current_mb_nr %d\n", FmoGetLastMBOfPicture(), img->current_mb_nr);
|
img->num_dec_mb++;
|
img->num_dec_mb++;
|
|
|
if (img->num_dec_mb == img->PicSizeInMbs)
|
if (img->num_dec_mb == img->PicSizeInMbs)
|
// if (img->current_mb_nr == FmoGetLastMBOfPicture(currSlice->structure))
|
// if (img->current_mb_nr == FmoGetLastMBOfPicture(currSlice->structure))
|
{
|
{
|
//thb
|
//thb
|
/*
|
/*
|
if (currSlice->next_header != EOS)
|
if (currSlice->next_header != EOS)
|
currSlice->next_header = SOP;
|
currSlice->next_header = SOP;
|
*/
|
*/
|
//the
|
//the
|
// assert (nal_startcode_follows (img, eos_bit) == TRUE);
|
// assert (nal_startcode_follows (img, eos_bit) == TRUE);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
// ask for last mb in the slice UVLC
|
// ask for last mb in the slice UVLC
|
else
|
else
|
{
|
{
|
// printf ("exit_macroblock: Slice %d old MB %d, now using MB %d\n", img->current_slice_nr, img->current_mb_nr, FmoGetNextMBNr (img->current_mb_nr));
|
// printf ("exit_macroblock: Slice %d old MB %d, now using MB %d\n", img->current_slice_nr, img->current_mb_nr, FmoGetNextMBNr (img->current_mb_nr));
|
|
|
img->current_mb_nr = FmoGetNextMBNr (img->current_mb_nr);
|
img->current_mb_nr = FmoGetNextMBNr (img->current_mb_nr);
|
|
|
if (img->current_mb_nr == -1) // End of Slice group, MUST be end of slice
|
if (img->current_mb_nr == -1) // End of Slice group, MUST be end of slice
|
{
|
{
|
assert (nal_startcode_follows (img, eos_bit) == TRUE);
|
assert (nal_startcode_follows (img, eos_bit) == TRUE);
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
if(nal_startcode_follows(img, eos_bit) == FALSE)
|
if(nal_startcode_follows(img, eos_bit) == FALSE)
|
return FALSE;
|
return FALSE;
|
|
|
if(img->type == I_SLICE || img->type == SI_SLICE || active_pps->entropy_coding_mode_flag == CABAC)
|
if(img->type == I_SLICE || img->type == SI_SLICE || active_pps->entropy_coding_mode_flag == CABAC)
|
return TRUE;
|
return TRUE;
|
if(img->cod_counter<=0)
|
if(img->cod_counter<=0)
|
return TRUE;
|
return TRUE;
|
return FALSE;
|
return FALSE;
|
}
|
}
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Interpret the mb mode for P-Frames
|
* Interpret the mb mode for P-Frames
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void interpret_mb_mode_P(struct img_par *img)
|
void interpret_mb_mode_P(struct img_par *img)
|
{
|
{
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
int mbmode = currMB->mb_type;
|
int mbmode = currMB->mb_type;
|
|
|
#define ZERO_P8x8 (mbmode==5)
|
#define ZERO_P8x8 (mbmode==5)
|
#define MODE_IS_P8x8 (mbmode==4 || mbmode==5)
|
#define MODE_IS_P8x8 (mbmode==4 || mbmode==5)
|
#define MODE_IS_I4x4 (mbmode==6)
|
#define MODE_IS_I4x4 (mbmode==6)
|
#define I16OFFSET (mbmode-7)
|
#define I16OFFSET (mbmode-7)
|
#define MODE_IS_IPCM (mbmode==31)
|
#define MODE_IS_IPCM (mbmode==31)
|
|
|
if(mbmode <4)
|
if(mbmode <4)
|
{
|
{
|
currMB->mb_type = mbmode;
|
currMB->mb_type = mbmode;
|
memset(&currMB->b8mode[0],mbmode,4 * sizeof(char));
|
memset(&currMB->b8mode[0],mbmode,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],0,4 * sizeof(char));
|
}
|
}
|
else if(MODE_IS_P8x8)
|
else if(MODE_IS_P8x8)
|
{
|
{
|
currMB->mb_type = P8x8;
|
currMB->mb_type = P8x8;
|
img->allrefzero = ZERO_P8x8;
|
img->allrefzero = ZERO_P8x8;
|
}
|
}
|
else if(MODE_IS_I4x4)
|
else if(MODE_IS_I4x4)
|
{
|
{
|
currMB->mb_type = I4MB;
|
currMB->mb_type = I4MB;
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
else if(MODE_IS_IPCM)
|
else if(MODE_IS_IPCM)
|
{
|
{
|
currMB->mb_type=IPCM;
|
currMB->mb_type=IPCM;
|
currMB->cbp= -1;
|
currMB->cbp= -1;
|
currMB->i16mode = 0;
|
currMB->i16mode = 0;
|
|
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
else
|
else
|
{
|
{
|
currMB->mb_type = I16MB;
|
currMB->mb_type = I16MB;
|
currMB->cbp= ICBPTAB[(I16OFFSET)>>2];
|
currMB->cbp= ICBPTAB[(I16OFFSET)>>2];
|
currMB->i16mode = (I16OFFSET) & 0x03;
|
currMB->i16mode = (I16OFFSET) & 0x03;
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Interpret the mb mode for I-Frames
|
* Interpret the mb mode for I-Frames
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void interpret_mb_mode_I(struct img_par *img)
|
void interpret_mb_mode_I(struct img_par *img)
|
{
|
{
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
int mbmode = currMB->mb_type;
|
int mbmode = currMB->mb_type;
|
|
|
if (mbmode==0)
|
if (mbmode==0)
|
{
|
{
|
currMB->mb_type = I4MB;
|
currMB->mb_type = I4MB;
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
else if(mbmode==25)
|
else if(mbmode==25)
|
{
|
{
|
currMB->mb_type=IPCM;
|
currMB->mb_type=IPCM;
|
currMB->cbp= -1;
|
currMB->cbp= -1;
|
currMB->i16mode = 0;
|
currMB->i16mode = 0;
|
|
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
else
|
else
|
{
|
{
|
currMB->mb_type = I16MB;
|
currMB->mb_type = I16MB;
|
currMB->cbp= ICBPTAB[(mbmode-1)>>2];
|
currMB->cbp= ICBPTAB[(mbmode-1)>>2];
|
currMB->i16mode = (mbmode-1) & 0x03;
|
currMB->i16mode = (mbmode-1) & 0x03;
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Interpret the mb mode for B-Frames
|
* Interpret the mb mode for B-Frames
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void interpret_mb_mode_B(struct img_par *img)
|
void interpret_mb_mode_B(struct img_par *img)
|
{
|
{
|
static const int offset2pdir16x16[12] = {0, 0, 1, 2, 0,0,0,0,0,0,0,0};
|
static const int offset2pdir16x16[12] = {0, 0, 1, 2, 0,0,0,0,0,0,0,0};
|
static const int offset2pdir16x8[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},{1,0},
|
static const int offset2pdir16x8[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},{1,0},
|
{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2},{0,0}};
|
{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2},{0,0}};
|
static const int offset2pdir8x16[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},
|
static const int offset2pdir8x16[22][2] = {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{1,1},{0,0},{0,1},{0,0},
|
{1,0},{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2}};
|
{1,0},{0,0},{0,2},{0,0},{1,2},{0,0},{2,0},{0,0},{2,1},{0,0},{2,2}};
|
|
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
|
|
int i, mbmode;
|
int i, mbmode;
|
int mbtype = currMB->mb_type;
|
int mbtype = currMB->mb_type;
|
|
|
//--- set mbtype, b8type, and b8pdir ---
|
//--- set mbtype, b8type, and b8pdir ---
|
if (mbtype==0) // direct
|
if (mbtype==0) // direct
|
{
|
{
|
mbmode=0;
|
mbmode=0;
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],2,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],2,4 * sizeof(char));
|
}
|
}
|
else if (mbtype==23) // intra4x4
|
else if (mbtype==23) // intra4x4
|
{
|
{
|
mbmode=I4MB;
|
mbmode=I4MB;
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
else if ((mbtype>23) && (mbtype<48) ) // intra16x16
|
else if ((mbtype>23) && (mbtype<48) ) // intra16x16
|
{
|
{
|
mbmode=I16MB;
|
mbmode=I16MB;
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
|
|
currMB->cbp = ICBPTAB[(mbtype-24)>>2];
|
currMB->cbp = ICBPTAB[(mbtype-24)>>2];
|
currMB->i16mode = (mbtype-24) & 0x03;
|
currMB->i16mode = (mbtype-24) & 0x03;
|
}
|
}
|
else if (mbtype==22) // 8x8(+split)
|
else if (mbtype==22) // 8x8(+split)
|
{
|
{
|
mbmode=P8x8; // b8mode and pdir is transmitted in additional codewords
|
mbmode=P8x8; // b8mode and pdir is transmitted in additional codewords
|
}
|
}
|
else if (mbtype<4) // 16x16
|
else if (mbtype<4) // 16x16
|
{
|
{
|
mbmode=1;
|
mbmode=1;
|
memset(&currMB->b8mode[0], 1,4 * sizeof(char));
|
memset(&currMB->b8mode[0], 1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],offset2pdir16x16[mbtype],4 * sizeof(char));
|
memset(&currMB->b8pdir[0],offset2pdir16x16[mbtype],4 * sizeof(char));
|
}
|
}
|
else if(mbtype==48)
|
else if(mbtype==48)
|
{
|
{
|
mbmode=IPCM;
|
mbmode=IPCM;
|
memset(&currMB->b8mode[0], 0,4 * sizeof(char));
|
memset(&currMB->b8mode[0], 0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
|
|
currMB->cbp= -1;
|
currMB->cbp= -1;
|
currMB->i16mode = 0;
|
currMB->i16mode = 0;
|
}
|
}
|
|
|
else if ((mbtype&0x01)==0) // 16x8
|
else if ((mbtype&0x01)==0) // 16x8
|
{
|
{
|
mbmode=2;
|
mbmode=2;
|
memset(&currMB->b8mode[0], 2,4 * sizeof(char));
|
memset(&currMB->b8mode[0], 2,4 * sizeof(char));
|
for(i=0;i<4;i++)
|
for(i=0;i<4;i++)
|
{
|
{
|
currMB->b8pdir[i]=offset2pdir16x8 [mbtype][i>>1];
|
currMB->b8pdir[i]=offset2pdir16x8 [mbtype][i>>1];
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
mbmode=3;
|
mbmode=3;
|
memset(&currMB->b8mode[0], 3,4 * sizeof(char));
|
memset(&currMB->b8mode[0], 3,4 * sizeof(char));
|
for(i=0;i<4;i++)
|
for(i=0;i<4;i++)
|
{
|
{
|
currMB->b8pdir[i]=offset2pdir8x16 [mbtype][i&0x01];
|
currMB->b8pdir[i]=offset2pdir8x16 [mbtype][i&0x01];
|
}
|
}
|
}
|
}
|
currMB->mb_type = mbmode;
|
currMB->mb_type = mbmode;
|
}
|
}
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Interpret the mb mode for SI-Frames
|
* Interpret the mb mode for SI-Frames
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void interpret_mb_mode_SI(struct img_par *img)
|
void interpret_mb_mode_SI(struct img_par *img)
|
{
|
{
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
const int ICBPTAB[6] = {0,16,32,15,31,47};
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
int mbmode = currMB->mb_type;
|
int mbmode = currMB->mb_type;
|
|
|
if (mbmode==0)
|
if (mbmode==0)
|
{
|
{
|
currMB->mb_type = SI4MB;
|
currMB->mb_type = SI4MB;
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
img->siblock[img->mb_y][img->mb_x]=1;
|
img->siblock[img->mb_y][img->mb_x]=1;
|
}
|
}
|
else if (mbmode==1)
|
else if (mbmode==1)
|
{
|
{
|
currMB->mb_type = I4MB;
|
currMB->mb_type = I4MB;
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
else if(mbmode==26)
|
else if(mbmode==26)
|
{
|
{
|
currMB->mb_type=IPCM;
|
currMB->mb_type=IPCM;
|
currMB->cbp= -1;
|
currMB->cbp= -1;
|
currMB->i16mode = 0;
|
currMB->i16mode = 0;
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
|
|
else
|
else
|
{
|
{
|
currMB->mb_type = I16MB;
|
currMB->mb_type = I16MB;
|
currMB->cbp= ICBPTAB[(mbmode-1)>>2];
|
currMB->cbp= ICBPTAB[(mbmode-1)>>2];
|
currMB->i16mode = (mbmode-2) & 0x03;
|
currMB->i16mode = (mbmode-2) & 0x03;
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8mode[0],0,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
|
}
|
}
|
}
|
}
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* init macroblock I and P frames
|
* init macroblock I and P frames
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void init_macroblock(struct img_par *img)
|
void init_macroblock(struct img_par *img)
|
{
|
{
|
int i,j;
|
int i,j;
|
|
|
for(j=img->block_y;j<img->block_y+BLOCK_SIZE;j++)
|
for(j=img->block_y;j<img->block_y+BLOCK_SIZE;j++)
|
{ // reset vectors and pred. modes
|
{ // reset vectors and pred. modes
|
memset(&dec_picture->mv[LIST_0][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
|
memset(&dec_picture->mv[LIST_0][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
|
memset(&dec_picture->mv[LIST_1][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
|
memset(&dec_picture->mv[LIST_1][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
|
memset(&dec_picture->ref_idx[LIST_0][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_0][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_1][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_1][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
|
memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(char));
|
memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(char));
|
for (i=img->block_x;i<img->block_x+BLOCK_SIZE;i++)
|
for (i=img->block_x;i<img->block_x+BLOCK_SIZE;i++)
|
{
|
{
|
dec_picture->ref_pic_id[LIST_0][j][i] = INT64_MIN;
|
dec_picture->ref_pic_id[LIST_0][j][i] = INT64_MIN;
|
dec_picture->ref_pic_id[LIST_1][j][i] = INT64_MIN;
|
dec_picture->ref_pic_id[LIST_1][j][i] = INT64_MIN;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Sets mode for 8x8 block
|
* Sets mode for 8x8 block
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void SetB8Mode (struct img_par* img, Macroblock* currMB, int value, int i)
|
void SetB8Mode (struct img_par* img, Macroblock* currMB, int value, int i)
|
{
|
{
|
static const int p_v2b8 [ 5] = {4, 5, 6, 7, IBLOCK};
|
static const int p_v2b8 [ 5] = {4, 5, 6, 7, IBLOCK};
|
static const int p_v2pd [ 5] = {0, 0, 0, 0, -1};
|
static const int p_v2pd [ 5] = {0, 0, 0, 0, -1};
|
static const int b_v2b8 [14] = {0, 4, 4, 4, 5, 6, 5, 6, 5, 6, 7, 7, 7, IBLOCK};
|
static const int b_v2b8 [14] = {0, 4, 4, 4, 5, 6, 5, 6, 5, 6, 7, 7, 7, IBLOCK};
|
static const int b_v2pd [14] = {2, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2, -1};
|
static const int b_v2pd [14] = {2, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2, -1};
|
|
|
if (img->type==B_SLICE)
|
if (img->type==B_SLICE)
|
{
|
{
|
currMB->b8mode[i] = b_v2b8[value];
|
currMB->b8mode[i] = b_v2b8[value];
|
currMB->b8pdir[i] = b_v2pd[value];
|
currMB->b8pdir[i] = b_v2pd[value];
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
currMB->b8mode[i] = p_v2b8[value];
|
currMB->b8mode[i] = p_v2b8[value];
|
currMB->b8pdir[i] = p_v2pd[value];
|
currMB->b8pdir[i] = p_v2pd[value];
|
}
|
}
|
|
|
}
|
}
|
|
|
|
|
void reset_coeffs()
|
void reset_coeffs()
|
{
|
{
|
int i, j;
|
int i, j;
|
|
|
// reset all coeffs
|
// reset all coeffs
|
for (i=0;i<BLOCK_SIZE;i++)
|
for (i=0;i<BLOCK_SIZE;i++)
|
{
|
{
|
for (j=0;j<BLOCK_SIZE +img->num_blk8x8_uv;j++)
|
for (j=0;j<BLOCK_SIZE +img->num_blk8x8_uv;j++)
|
memset(&img->cof[i][j][0][0],0,BLOCK_SIZE * BLOCK_SIZE * sizeof(int));
|
memset(&img->cof[i][j][0][0],0,BLOCK_SIZE * BLOCK_SIZE * sizeof(int));
|
}
|
}
|
|
|
// CAVLC
|
// CAVLC
|
memset(&img->nz_coeff[img->current_mb_nr][0][0],0, BLOCK_SIZE * (BLOCK_SIZE + img->num_blk8x8_uv) * sizeof(int));
|
memset(&img->nz_coeff[img->current_mb_nr][0][0],0, BLOCK_SIZE * (BLOCK_SIZE + img->num_blk8x8_uv) * sizeof(int));
|
}
|
}
|
|
|
void field_flag_inference()
|
void field_flag_inference()
|
{
|
{
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
|
|
if (currMB->mbAvailA)
|
if (currMB->mbAvailA)
|
{
|
{
|
currMB->mb_field = img->mb_data[currMB->mbAddrA].mb_field;
|
currMB->mb_field = img->mb_data[currMB->mbAddrA].mb_field;
|
}
|
}
|
else
|
else
|
{
|
{
|
// check top macroblock pair
|
// check top macroblock pair
|
if (currMB->mbAvailB)
|
if (currMB->mbAvailB)
|
{
|
{
|
currMB->mb_field = img->mb_data[currMB->mbAddrB].mb_field;
|
currMB->mb_field = img->mb_data[currMB->mbAddrB].mb_field;
|
}
|
}
|
else
|
else
|
currMB->mb_field = 0;
|
currMB->mb_field = 0;
|
}
|
}
|
|
|
}
|
}
|
|
|
void set_chroma_qp(Macroblock* currMB)
|
void set_chroma_qp(Macroblock* currMB)
|
{
|
{
|
int i;
|
int i;
|
for (i=0; i<2; i++)
|
for (i=0; i<2; i++)
|
{
|
{
|
currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + dec_picture->chroma_qp_offset[i] );
|
currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, currMB->qp + dec_picture->chroma_qp_offset[i] );
|
currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
|
currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
|
}
|
}
|
}
|
}
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Get the syntax elements from the NAL
|
* Get the syntax elements from the NAL
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
int read_one_macroblock(struct img_par *img,struct inp_par *inp)
|
int read_one_macroblock(struct img_par *img,struct inp_par *inp)
|
{
|
{
|
int i;
|
int i;
|
|
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
|
|
Slice *currSlice = img->currentSlice;
|
Slice *currSlice = img->currentSlice;
|
DataPartition *dP;
|
DataPartition *dP;
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
Macroblock *topMB = NULL;
|
Macroblock *topMB = NULL;
|
int prevMbSkipped = 0;
|
int prevMbSkipped = 0;
|
int img_block_y;
|
int img_block_y;
|
int check_bottom, read_bottom, read_top;
|
int check_bottom, read_bottom, read_top;
|
|
|
if (img->MbaffFrameFlag)
|
if (img->MbaffFrameFlag)
|
{
|
{
|
if (img->current_mb_nr&0x01)
|
if (img->current_mb_nr&0x01)
|
{
|
{
|
topMB= &img->mb_data[img->current_mb_nr-1];
|
topMB= &img->mb_data[img->current_mb_nr-1];
|
if(!(img->type == B_SLICE))
|
if(!(img->type == B_SLICE))
|
prevMbSkipped = (topMB->mb_type == 0);
|
prevMbSkipped = (topMB->mb_type == 0);
|
else
|
else
|
prevMbSkipped = topMB->skip_flag;
|
prevMbSkipped = topMB->skip_flag;
|
}
|
}
|
else
|
else
|
prevMbSkipped = 0;
|
prevMbSkipped = 0;
|
}
|
}
|
|
|
if ((img->current_mb_nr&0x01) == 0)
|
if ((img->current_mb_nr&0x01) == 0)
|
currMB->mb_field = 0;
|
currMB->mb_field = 0;
|
else
|
else
|
currMB->mb_field = img->mb_data[img->current_mb_nr-1].mb_field;
|
currMB->mb_field = img->mb_data[img->current_mb_nr-1].mb_field;
|
|
|
|
|
currMB->qp = img->qp ;
|
currMB->qp = img->qp ;
|
for (i=0; i<2; i++)
|
for (i=0; i<2; i++)
|
{
|
{
|
currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, img->qp + dec_picture->chroma_qp_offset[i] );
|
currMB->qpc[i] = iClip3 ( -img->bitdepth_chroma_qp_scale, 51, img->qp + dec_picture->chroma_qp_offset[i] );
|
currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
|
currMB->qpc[i] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
|
}
|
}
|
|
|
currSE.type = SE_MBTYPE;
|
currSE.type = SE_MBTYPE;
|
|
|
// read MB mode *****************************************************************
|
// read MB mode *****************************************************************
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
|
|
if(img->type == I_SLICE || img->type == SI_SLICE)
|
if(img->type == I_SLICE || img->type == SI_SLICE)
|
{
|
{
|
// read MB aff
|
// read MB aff
|
if (img->MbaffFrameFlag && (img->current_mb_nr&0x01)==0)
|
if (img->MbaffFrameFlag && (img->current_mb_nr&0x01)==0)
|
{
|
{
|
TRACE_STRING("mb_field_decoding_flag");
|
TRACE_STRING("mb_field_decoding_flag");
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
}
|
}
|
else
|
else
|
{
|
{
|
currSE.reading = readFieldModeInfo_CABAC;
|
currSE.reading = readFieldModeInfo_CABAC;
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
}
|
}
|
currMB->mb_field = currSE.value1;
|
currMB->mb_field = currSE.value1;
|
}
|
}
|
if(active_pps->entropy_coding_mode_flag == CABAC)
|
if(active_pps->entropy_coding_mode_flag == CABAC)
|
CheckAvailabilityOfNeighborsCABAC();
|
CheckAvailabilityOfNeighborsCABAC();
|
|
|
// read MB type
|
// read MB type
|
TRACE_STRING("mb_type");
|
TRACE_STRING("mb_type");
|
currSE.reading = readMB_typeInfo_CABAC;
|
currSE.reading = readMB_typeInfo_CABAC;
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
|
|
currMB->mb_type = currSE.value1;
|
currMB->mb_type = currSE.value1;
|
if(!dP->bitstream->ei_flag)
|
if(!dP->bitstream->ei_flag)
|
currMB->ei_flag = 0;
|
currMB->ei_flag = 0;
|
}
|
}
|
// non I/SI-slice CABAC
|
// non I/SI-slice CABAC
|
else if (active_pps->entropy_coding_mode_flag == CABAC)
|
else if (active_pps->entropy_coding_mode_flag == CABAC)
|
{
|
{
|
// read MB skip_flag
|
// read MB skip_flag
|
if (img->MbaffFrameFlag && ((img->current_mb_nr&0x01) == 0||prevMbSkipped))
|
if (img->MbaffFrameFlag && ((img->current_mb_nr&0x01) == 0||prevMbSkipped))
|
field_flag_inference();
|
field_flag_inference();
|
|
|
CheckAvailabilityOfNeighborsCABAC();
|
CheckAvailabilityOfNeighborsCABAC();
|
TRACE_STRING("mb_skip_flag");
|
TRACE_STRING("mb_skip_flag");
|
currSE.reading = readMB_skip_flagInfo_CABAC;
|
currSE.reading = readMB_skip_flagInfo_CABAC;
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
|
|
currMB->mb_type = currSE.value1;
|
currMB->mb_type = currSE.value1;
|
currMB->skip_flag = !(currSE.value1);
|
currMB->skip_flag = !(currSE.value1);
|
|
|
if (img->type==B_SLICE)
|
if (img->type==B_SLICE)
|
currMB->cbp = currSE.value2;
|
currMB->cbp = currSE.value2;
|
|
|
if(!dP->bitstream->ei_flag)
|
if(!dP->bitstream->ei_flag)
|
currMB->ei_flag = 0;
|
currMB->ei_flag = 0;
|
|
|
if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0)
|
if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0)
|
img->cod_counter=0;
|
img->cod_counter=0;
|
|
|
// read MB AFF
|
// read MB AFF
|
if (img->MbaffFrameFlag)
|
if (img->MbaffFrameFlag)
|
{
|
{
|
check_bottom=read_bottom=read_top=0;
|
check_bottom=read_bottom=read_top=0;
|
if ((img->current_mb_nr&0x01)==0)
|
if ((img->current_mb_nr&0x01)==0)
|
{
|
{
|
check_bottom = currMB->skip_flag;
|
check_bottom = currMB->skip_flag;
|
read_top = !check_bottom;
|
read_top = !check_bottom;
|
}
|
}
|
else
|
else
|
{
|
{
|
read_bottom = (topMB->skip_flag && (!currMB->skip_flag));
|
read_bottom = (topMB->skip_flag && (!currMB->skip_flag));
|
}
|
}
|
|
|
if (read_bottom || read_top)
|
if (read_bottom || read_top)
|
{
|
{
|
TRACE_STRING("mb_field_decoding_flag");
|
TRACE_STRING("mb_field_decoding_flag");
|
currSE.reading = readFieldModeInfo_CABAC;
|
currSE.reading = readFieldModeInfo_CABAC;
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
currMB->mb_field = currSE.value1;
|
currMB->mb_field = currSE.value1;
|
}
|
}
|
if (check_bottom)
|
if (check_bottom)
|
check_next_mb_and_get_field_mode_CABAC(&currSE,img,dP);
|
check_next_mb_and_get_field_mode_CABAC(&currSE,img,dP);
|
|
|
}
|
}
|
|
|
CheckAvailabilityOfNeighborsCABAC();
|
CheckAvailabilityOfNeighborsCABAC();
|
|
|
// read MB type
|
// read MB type
|
if (currMB->mb_type != 0 )
|
if (currMB->mb_type != 0 )
|
{
|
{
|
currSE.reading = readMB_typeInfo_CABAC;
|
currSE.reading = readMB_typeInfo_CABAC;
|
TRACE_STRING("mb_type");
|
TRACE_STRING("mb_type");
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
currMB->mb_type = currSE.value1;
|
currMB->mb_type = currSE.value1;
|
if(!dP->bitstream->ei_flag)
|
if(!dP->bitstream->ei_flag)
|
currMB->ei_flag = 0;
|
currMB->ei_flag = 0;
|
}
|
}
|
}
|
}
|
// VLC Non-Intra
|
// VLC Non-Intra
|
else
|
else
|
{
|
{
|
if(img->cod_counter == -1)
|
if(img->cod_counter == -1)
|
{
|
{
|
TRACE_STRING("mb_skip_run");
|
TRACE_STRING("mb_skip_run");
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
img->cod_counter = currSE.value1;
|
img->cod_counter = currSE.value1;
|
}
|
}
|
if (img->cod_counter==0)
|
if (img->cod_counter==0)
|
{
|
{
|
// read MB aff
|
// read MB aff
|
if ((img->MbaffFrameFlag) && (((img->current_mb_nr&0x01)==0) || ((img->current_mb_nr&0x01) && prevMbSkipped)))
|
if ((img->MbaffFrameFlag) && (((img->current_mb_nr&0x01)==0) || ((img->current_mb_nr&0x01) && prevMbSkipped)))
|
{
|
{
|
TRACE_STRING("mb_field_decoding_flag");
|
TRACE_STRING("mb_field_decoding_flag");
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
currMB->mb_field = currSE.value1;
|
currMB->mb_field = currSE.value1;
|
}
|
}
|
|
|
// read MB type
|
// read MB type
|
TRACE_STRING("mb_type");
|
TRACE_STRING("mb_type");
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
if(img->type == P_SLICE || img->type == SP_SLICE)
|
if(img->type == P_SLICE || img->type == SP_SLICE)
|
currSE.value1++;
|
currSE.value1++;
|
currMB->mb_type = currSE.value1;
|
currMB->mb_type = currSE.value1;
|
if(!dP->bitstream->ei_flag)
|
if(!dP->bitstream->ei_flag)
|
currMB->ei_flag = 0;
|
currMB->ei_flag = 0;
|
img->cod_counter--;
|
img->cod_counter--;
|
currMB->skip_flag = 0;
|
currMB->skip_flag = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
img->cod_counter--;
|
img->cod_counter--;
|
currMB->mb_type = 0;
|
currMB->mb_type = 0;
|
currMB->ei_flag = 0;
|
currMB->ei_flag = 0;
|
currMB->skip_flag = 1;
|
currMB->skip_flag = 1;
|
|
|
// read field flag of bottom block
|
// read field flag of bottom block
|
if(img->MbaffFrameFlag)
|
if(img->MbaffFrameFlag)
|
{
|
{
|
if(img->cod_counter == 0 && ((img->current_mb_nr&0x01) == 0))
|
if(img->cod_counter == 0 && ((img->current_mb_nr&0x01) == 0))
|
{
|
{
|
TRACE_STRING("mb_field_decoding_flag (of coded bottom mb)");
|
TRACE_STRING("mb_field_decoding_flag (of coded bottom mb)");
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
dP->bitstream->frame_bitoffset--;
|
dP->bitstream->frame_bitoffset--;
|
currMB->mb_field = currSE.value1;
|
currMB->mb_field = currSE.value1;
|
}
|
}
|
else if(img->cod_counter > 0 && ((img->current_mb_nr&0x01) == 0))
|
else if(img->cod_counter > 0 && ((img->current_mb_nr&0x01) == 0))
|
{
|
{
|
// check left macroblock pair first
|
// check left macroblock pair first
|
if (mb_is_available(img->current_mb_nr-2, img->current_mb_nr)&&((img->current_mb_nr%(img->PicWidthInMbs*2))!=0))
|
if (mb_is_available(img->current_mb_nr-2, img->current_mb_nr)&&((img->current_mb_nr%(img->PicWidthInMbs*2))!=0))
|
{
|
{
|
currMB->mb_field = img->mb_data[img->current_mb_nr-2].mb_field;
|
currMB->mb_field = img->mb_data[img->current_mb_nr-2].mb_field;
|
}
|
}
|
else
|
else
|
{
|
{
|
// check top macroblock pair
|
// check top macroblock pair
|
if (mb_is_available(img->current_mb_nr-2*img->PicWidthInMbs, img->current_mb_nr))
|
if (mb_is_available(img->current_mb_nr-2*img->PicWidthInMbs, img->current_mb_nr))
|
{
|
{
|
currMB->mb_field = img->mb_data[img->current_mb_nr-2*img->PicWidthInMbs].mb_field;
|
currMB->mb_field = img->mb_data[img->current_mb_nr-2*img->PicWidthInMbs].mb_field;
|
}
|
}
|
else
|
else
|
currMB->mb_field = 0;
|
currMB->mb_field = 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
dec_picture->mb_field[img->current_mb_nr] = currMB->mb_field;
|
dec_picture->mb_field[img->current_mb_nr] = currMB->mb_field;
|
|
|
img->siblock[img->mb_y][img->mb_x]=0;
|
img->siblock[img->mb_y][img->mb_x]=0;
|
|
|
if ((img->type==P_SLICE )) // inter frame
|
if ((img->type==P_SLICE )) // inter frame
|
interpret_mb_mode_P(img);
|
interpret_mb_mode_P(img);
|
else if (img->type==I_SLICE) // intra frame
|
else if (img->type==I_SLICE) // intra frame
|
interpret_mb_mode_I(img);
|
interpret_mb_mode_I(img);
|
else if ((img->type==B_SLICE)) // B frame
|
else if ((img->type==B_SLICE)) // B frame
|
interpret_mb_mode_B(img);
|
interpret_mb_mode_B(img);
|
else if ((img->type==SP_SLICE)) // SP frame
|
else if ((img->type==SP_SLICE)) // SP frame
|
interpret_mb_mode_P(img);
|
interpret_mb_mode_P(img);
|
else if (img->type==SI_SLICE) // SI frame
|
else if (img->type==SI_SLICE) // SI frame
|
interpret_mb_mode_SI(img);
|
interpret_mb_mode_SI(img);
|
|
|
if(img->MbaffFrameFlag)
|
if(img->MbaffFrameFlag)
|
{
|
{
|
if(currMB->mb_field)
|
if(currMB->mb_field)
|
{
|
{
|
img->num_ref_idx_l0_active <<=1;
|
img->num_ref_idx_l0_active <<=1;
|
img->num_ref_idx_l1_active <<=1;
|
img->num_ref_idx_l1_active <<=1;
|
}
|
}
|
}
|
}
|
|
|
//init NoMbPartLessThan8x8Flag
|
//init NoMbPartLessThan8x8Flag
|
currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;
|
currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;
|
|
|
//====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ======
|
//====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ======
|
if (IS_P8x8 (currMB))
|
if (IS_P8x8 (currMB))
|
{
|
{
|
currSE.type = SE_MBTYPE;
|
currSE.type = SE_MBTYPE;
|
dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
|
dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
|
|
|
for (i=0; i<4; i++)
|
for (i=0; i<4; i++)
|
{
|
{
|
if (active_pps->entropy_coding_mode_flag ==UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
if (active_pps->entropy_coding_mode_flag ==UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
else currSE.reading = readB8_typeInfo_CABAC;
|
else currSE.reading = readB8_typeInfo_CABAC;
|
|
|
TRACE_STRING("sub_mb_type");
|
TRACE_STRING("sub_mb_type");
|
dP->readSyntaxElement (&currSE, img, dP);
|
dP->readSyntaxElement (&currSE, img, dP);
|
SetB8Mode (img, currMB, currSE.value1, i);
|
SetB8Mode (img, currMB, currSE.value1, i);
|
|
|
//set NoMbPartLessThan8x8Flag for P8x8 mode
|
//set NoMbPartLessThan8x8Flag for P8x8 mode
|
currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && active_sps->direct_8x8_inference_flag) ||
|
currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && active_sps->direct_8x8_inference_flag) ||
|
(currMB->b8mode[i]==4);
|
(currMB->b8mode[i]==4);
|
}
|
}
|
//--- init macroblock data ---
|
//--- init macroblock data ---
|
init_macroblock (img);
|
init_macroblock (img);
|
readMotionInfoFromNAL (img, inp);
|
readMotionInfoFromNAL (img, inp);
|
}
|
}
|
|
|
|
|
//============= Transform Size Flag for INTRA MBs =============
|
//============= Transform Size Flag for INTRA MBs =============
|
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
//transform size flag for INTRA_4x4 and INTRA_8x8 modes
|
//transform size flag for INTRA_4x4 and INTRA_8x8 modes
|
if (currMB->mb_type == I4MB && img->Transform8x8Mode)
|
if (currMB->mb_type == I4MB && img->Transform8x8Mode)
|
{
|
{
|
currSE.type = SE_HEADER;
|
currSE.type = SE_HEADER;
|
dP = &(currSlice->partArr[partMap[SE_HEADER]]);
|
dP = &(currSlice->partArr[partMap[SE_HEADER]]);
|
currSE.reading = readMB_transform_size_flag_CABAC;
|
currSE.reading = readMB_transform_size_flag_CABAC;
|
TRACE_STRING("transform_size_8x8_flag");
|
TRACE_STRING("transform_size_8x8_flag");
|
|
|
// read UVLC transform_size_8x8_flag
|
// read UVLC transform_size_8x8_flag
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
}
|
}
|
else
|
else
|
{
|
{
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
}
|
}
|
|
|
currMB->luma_transform_size_8x8_flag = currSE.value1;
|
currMB->luma_transform_size_8x8_flag = currSE.value1;
|
|
|
if (currMB->luma_transform_size_8x8_flag)
|
if (currMB->luma_transform_size_8x8_flag)
|
{
|
{
|
currMB->mb_type = I8MB;
|
currMB->mb_type = I8MB;
|
for (i=0;i<4;i++)
|
for (i=0;i<4;i++)
|
{
|
{
|
currMB->b8mode[i]=I8MB;
|
currMB->b8mode[i]=I8MB;
|
currMB->b8pdir[i]=-1;
|
currMB->b8pdir[i]=-1;
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
currMB->luma_transform_size_8x8_flag = 0;
|
currMB->luma_transform_size_8x8_flag = 0;
|
}
|
}
|
|
|
if(active_pps->constrained_intra_pred_flag && (img->type==P_SLICE|| img->type==B_SLICE)) // inter frame
|
if(active_pps->constrained_intra_pred_flag && (img->type==P_SLICE|| img->type==B_SLICE)) // inter frame
|
{
|
{
|
if( !IS_INTRA(currMB) )
|
if( !IS_INTRA(currMB) )
|
{
|
{
|
img->intra_block[img->current_mb_nr] = 0;
|
img->intra_block[img->current_mb_nr] = 0;
|
}
|
}
|
}
|
}
|
|
|
//! TO for error concealment
|
//! TO for error concealment
|
//! If we have an INTRA Macroblock and we lost the partition
|
//! If we have an INTRA Macroblock and we lost the partition
|
//! which contains the intra coefficients Copy MB would be better
|
//! which contains the intra coefficients Copy MB would be better
|
//! than just a gray block.
|
//! than just a gray block.
|
//! Seems to be a bit at the wrong place to do this right here, but for this case
|
//! Seems to be a bit at the wrong place to do this right here, but for this case
|
//! up to now there is no other way.
|
//! up to now there is no other way.
|
dP = &(currSlice->partArr[partMap[SE_CBP_INTRA]]);
|
dP = &(currSlice->partArr[partMap[SE_CBP_INTRA]]);
|
if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)
|
if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)
|
{
|
{
|
currMB->mb_type = 0;
|
currMB->mb_type = 0;
|
currMB->ei_flag = 1;
|
currMB->ei_flag = 1;
|
for (i=0;i<4;i++) {currMB->b8mode[i]=currMB->b8pdir[i]=0; }
|
for (i=0;i<4;i++) {currMB->b8mode[i]=currMB->b8pdir[i]=0; }
|
}
|
}
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
//! End TO
|
//! End TO
|
|
|
|
|
//--- init macroblock data ---
|
//--- init macroblock data ---
|
if (!IS_P8x8 (currMB))
|
if (!IS_P8x8 (currMB))
|
init_macroblock (img);
|
init_macroblock (img);
|
|
|
if (IS_DIRECT (currMB) && img->cod_counter >= 0)
|
if (IS_DIRECT (currMB) && img->cod_counter >= 0)
|
{
|
{
|
currMB->cbp = 0;
|
currMB->cbp = 0;
|
reset_coeffs();
|
reset_coeffs();
|
|
|
if (active_pps->entropy_coding_mode_flag ==CABAC)
|
if (active_pps->entropy_coding_mode_flag ==CABAC)
|
img->cod_counter=-1;
|
img->cod_counter=-1;
|
|
|
return DECODE_MB;
|
return DECODE_MB;
|
}
|
}
|
|
|
if (IS_COPY (currMB)) //keep last macroblock
|
if (IS_COPY (currMB)) //keep last macroblock
|
{
|
{
|
int i, j, k;
|
int i, j, k;
|
short pmv[2];
|
short pmv[2];
|
int zeroMotionAbove;
|
int zeroMotionAbove;
|
int zeroMotionLeft;
|
int zeroMotionLeft;
|
PixelPos mb_a, mb_b;
|
PixelPos mb_a, mb_b;
|
int a_mv_y = 0;
|
int a_mv_y = 0;
|
int a_ref_idx = 0;
|
int a_ref_idx = 0;
|
int b_mv_y = 0;
|
int b_mv_y = 0;
|
int b_ref_idx = 0;
|
int b_ref_idx = 0;
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
short ***cur_mv = dec_picture->mv[LIST_0];
|
short ***cur_mv = dec_picture->mv[LIST_0];
|
getLuma4x4Neighbour(img->current_mb_nr,-1, 0, &mb_a);
|
getLuma4x4Neighbour(img->current_mb_nr,-1, 0, &mb_a);
|
getLuma4x4Neighbour(img->current_mb_nr, 0,-1, &mb_b);
|
getLuma4x4Neighbour(img->current_mb_nr, 0,-1, &mb_b);
|
|
|
if (mb_a.available)
|
if (mb_a.available)
|
{
|
{
|
a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1];
|
a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1];
|
a_ref_idx = dec_picture->ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
|
a_ref_idx = dec_picture->ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
|
|
|
if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
|
if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
|
{
|
{
|
a_mv_y /=2;
|
a_mv_y /=2;
|
a_ref_idx *=2;
|
a_ref_idx *=2;
|
}
|
}
|
if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
|
if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
|
{
|
{
|
a_mv_y *=2;
|
a_mv_y *=2;
|
a_ref_idx >>=1;
|
a_ref_idx >>=1;
|
}
|
}
|
}
|
}
|
|
|
if (mb_b.available)
|
if (mb_b.available)
|
{
|
{
|
b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1];
|
b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1];
|
b_ref_idx = dec_picture->ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
|
b_ref_idx = dec_picture->ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
|
|
|
if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
|
if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
|
{
|
{
|
b_mv_y /=2;
|
b_mv_y /=2;
|
b_ref_idx *=2;
|
b_ref_idx *=2;
|
}
|
}
|
if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
|
if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
|
{
|
{
|
b_mv_y *=2;
|
b_mv_y *=2;
|
b_ref_idx >>=1;
|
b_ref_idx >>=1;
|
}
|
}
|
}
|
}
|
|
|
zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && cur_mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
|
zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && cur_mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
|
zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && cur_mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
|
zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && cur_mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
|
|
|
currMB->cbp = 0;
|
currMB->cbp = 0;
|
reset_coeffs();
|
reset_coeffs();
|
|
|
img_block_y = img->block_y;
|
img_block_y = img->block_y;
|
|
|
if (zeroMotionAbove || zeroMotionLeft)
|
if (zeroMotionAbove || zeroMotionLeft)
|
{
|
{
|
for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
|
for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
|
{
|
{
|
memset(&cur_mv[j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
|
memset(&cur_mv[j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
SetMotionVectorPredictor (img, pmv, 0, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
SetMotionVectorPredictor (img, pmv, 0, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
|
|
for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
|
for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
|
{
|
{
|
for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
|
for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
|
for (k=0;k<2;k++)
|
for (k=0;k<2;k++)
|
{
|
{
|
cur_mv[j][i][k] = pmv[k];
|
cur_mv[j][i][k] = pmv[k];
|
}
|
}
|
}
|
}
|
}
|
}
|
for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++)
|
for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++)
|
{
|
{
|
for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
|
for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
|
{
|
{
|
dec_picture->ref_idx[LIST_0][j][i] = 0;
|
dec_picture->ref_idx[LIST_0][j][i] = 0;
|
dec_picture->ref_pic_id[LIST_0][j][i] =
|
dec_picture->ref_pic_id[LIST_0][j][i] =
|
dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j][i]];
|
dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j][i]];
|
}
|
}
|
}
|
}
|
return DECODE_MB;
|
return DECODE_MB;
|
}
|
}
|
if(currMB->mb_type!=IPCM)
|
if(currMB->mb_type!=IPCM)
|
{
|
{
|
|
|
// intra prediction modes for a macroblock 4x4 **********************************************
|
// intra prediction modes for a macroblock 4x4 **********************************************
|
read_ipred_modes(img,inp);
|
read_ipred_modes(img,inp);
|
|
|
// read inter frame vector data *********************************************************
|
// read inter frame vector data *********************************************************
|
if (IS_INTERMV (currMB) && (!IS_P8x8(currMB)))
|
if (IS_INTERMV (currMB) && (!IS_P8x8(currMB)))
|
{
|
{
|
readMotionInfoFromNAL (img, inp);
|
readMotionInfoFromNAL (img, inp);
|
}
|
}
|
// read CBP and Coeffs ***************************************************************
|
// read CBP and Coeffs ***************************************************************
|
readCBPandCoeffsFromNAL (img,inp);
|
readCBPandCoeffsFromNAL (img,inp);
|
}
|
}
|
else
|
else
|
{
|
{
|
//read pcm_alignment_zero_bit and pcm_byte[i]
|
//read pcm_alignment_zero_bit and pcm_byte[i]
|
|
|
// here dP is assigned with the same dP as SE_MBTYPE, because IPCM syntax is in the
|
// here dP is assigned with the same dP as SE_MBTYPE, because IPCM syntax is in the
|
// same category as MBTYPE
|
// same category as MBTYPE
|
dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
|
dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
|
readIPCMcoeffsFromNAL(img,inp,dP);
|
readIPCMcoeffsFromNAL(img,inp,dP);
|
}
|
}
|
|
|
|
|
return DECODE_MB;
|
return DECODE_MB;
|
}
|
}
|
|
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Initialize decoding engine after decoding an IPCM macroblock
|
* Initialize decoding engine after decoding an IPCM macroblock
|
* (for IPCM CABAC 28/11/2003)
|
* (for IPCM CABAC 28/11/2003)
|
*
|
*
|
* \author
|
* \author
|
* Dong Wang <Dong.Wang@bristol.ac.uk>
|
* Dong Wang <Dong.Wang@bristol.ac.uk>
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void init_decoding_engine_IPCM(struct img_par *img)
|
void init_decoding_engine_IPCM(struct img_par *img)
|
{
|
{
|
Slice *currSlice = img->currentSlice;
|
Slice *currSlice = img->currentSlice;
|
Bitstream *currStream;
|
Bitstream *currStream;
|
int ByteStartPosition;
|
int ByteStartPosition;
|
int PartitionNumber;
|
int PartitionNumber;
|
int i;
|
int i;
|
|
|
if(currSlice->dp_mode==PAR_DP_1)
|
if(currSlice->dp_mode==PAR_DP_1)
|
PartitionNumber=1;
|
PartitionNumber=1;
|
else if(currSlice->dp_mode==PAR_DP_3)
|
else if(currSlice->dp_mode==PAR_DP_3)
|
PartitionNumber=3;
|
PartitionNumber=3;
|
else
|
else
|
{
|
{
|
printf("Partition Mode is not supported\n");
|
printf("Partition Mode is not supported\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
for(i=0;i<PartitionNumber;i++)
|
for(i=0;i<PartitionNumber;i++)
|
{
|
{
|
currStream = currSlice->partArr[i].bitstream;
|
currStream = currSlice->partArr[i].bitstream;
|
ByteStartPosition = currStream->read_len;
|
ByteStartPosition = currStream->read_len;
|
|
|
|
|
arideco_start_decoding (&currSlice->partArr[i].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
|
arideco_start_decoding (&currSlice->partArr[i].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
|
* Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
|
* (for IPCM CABAC and IPCM CAVLC)
|
* (for IPCM CABAC and IPCM CAVLC)
|
*
|
*
|
* \author
|
* \author
|
* Dong Wang <Dong.Wang@bristol.ac.uk>
|
* Dong Wang <Dong.Wang@bristol.ac.uk>
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
|
|
void readIPCMcoeffsFromNAL(struct img_par *img, struct inp_par *inp, struct datapartition *dP)
|
void readIPCMcoeffsFromNAL(struct img_par *img, struct inp_par *inp, struct datapartition *dP)
|
{
|
{
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
int i,j;
|
int i,j;
|
|
|
//For CABAC, we don't need to read bits to let stream byte aligned
|
//For CABAC, we don't need to read bits to let stream byte aligned
|
// because we have variable for integer bytes position
|
// because we have variable for integer bytes position
|
if(active_pps->entropy_coding_mode_flag == CABAC)
|
if(active_pps->entropy_coding_mode_flag == CABAC)
|
{
|
{
|
//read luma and chroma IPCM coefficients
|
//read luma and chroma IPCM coefficients
|
currSE.len=8;
|
currSE.len=8;
|
TRACE_STRING("pcm_byte luma");
|
TRACE_STRING("pcm_byte luma");
|
|
|
for(i=0;i<MB_BLOCK_SIZE;i++)
|
for(i=0;i<MB_BLOCK_SIZE;i++)
|
{
|
{
|
for(j=0;j<MB_BLOCK_SIZE;j++)
|
for(j=0;j<MB_BLOCK_SIZE;j++)
|
{
|
{
|
readIPCMBytes_CABAC(&currSE, dP->bitstream);
|
readIPCMBytes_CABAC(&currSE, dP->bitstream);
|
img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03]=currSE.value1;
|
img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03]=currSE.value1;
|
}
|
}
|
}
|
}
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
TRACE_STRING("pcm_byte chroma");
|
TRACE_STRING("pcm_byte chroma");
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(i=0;i<img->mb_cr_size_y;i++)
|
{
|
{
|
for(j=0;j<img->mb_cr_size_x;j++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
{
|
{
|
readIPCMBytes_CABAC(&currSE, dP->bitstream);
|
readIPCMBytes_CABAC(&currSE, dP->bitstream);
|
img->cof[(i>>2)][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
img->cof[(i>>2)][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
}
|
}
|
}
|
}
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(i=0;i<img->mb_cr_size_y;i++)
|
{
|
{
|
for(j=0;j<img->mb_cr_size_x;j++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
{
|
{
|
readIPCMBytes_CABAC(&currSE, dP->bitstream);
|
readIPCMBytes_CABAC(&currSE, dP->bitstream);
|
img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
}
|
}
|
}
|
}
|
}
|
}
|
//If the decoded MB is IPCM MB, decoding engine is initialized
|
//If the decoded MB is IPCM MB, decoding engine is initialized
|
|
|
// here the decoding engine is directly initialized without checking End of Slice
|
// here the decoding engine is directly initialized without checking End of Slice
|
// The reason is that, whether current MB is the last MB in slice or not, there is
|
// The reason is that, whether current MB is the last MB in slice or not, there is
|
// at least one 'end of slice' syntax after this MB. So when fetching bytes in this
|
// at least one 'end of slice' syntax after this MB. So when fetching bytes in this
|
// initialisation process, we can guarantee there is bits available in bitstream.
|
// initialisation process, we can guarantee there is bits available in bitstream.
|
|
|
init_decoding_engine_IPCM(img);
|
init_decoding_engine_IPCM(img);
|
}
|
}
|
else
|
else
|
{
|
{
|
//read bits to let stream byte aligned
|
//read bits to let stream byte aligned
|
|
|
if((dP->bitstream->frame_bitoffset)%8!=0)
|
if((dP->bitstream->frame_bitoffset)%8!=0)
|
{
|
{
|
TRACE_STRING("pcm_alignment_zero_bit");
|
TRACE_STRING("pcm_alignment_zero_bit");
|
currSE.len=8-(dP->bitstream->frame_bitoffset)%8;
|
currSE.len=8-(dP->bitstream->frame_bitoffset)%8;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
}
|
}
|
|
|
//read luma and chroma IPCM coefficients
|
//read luma and chroma IPCM coefficients
|
currSE.len=img->bitdepth_luma;
|
currSE.len=img->bitdepth_luma;
|
TRACE_STRING("pcm_sample_luma");
|
TRACE_STRING("pcm_sample_luma");
|
|
|
for(i=0;i<MB_BLOCK_SIZE;i++)
|
for(i=0;i<MB_BLOCK_SIZE;i++)
|
{
|
{
|
for(j=0;j<MB_BLOCK_SIZE;j++)
|
for(j=0;j<MB_BLOCK_SIZE;j++)
|
{
|
{
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03]=currSE.value1;
|
img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03]=currSE.value1;
|
}
|
}
|
}
|
}
|
currSE.len=img->bitdepth_chroma;
|
currSE.len=img->bitdepth_chroma;
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
TRACE_STRING("pcm_sample_chroma (u)");
|
TRACE_STRING("pcm_sample_chroma (u)");
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(i=0;i<img->mb_cr_size_y;i++)
|
{
|
{
|
for(j=0;j<img->mb_cr_size_x;j++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
{
|
{
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
img->cof[(i>>2)][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
img->cof[(i>>2)][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
}
|
}
|
}
|
}
|
TRACE_STRING("pcm_sample_chroma (v)");
|
TRACE_STRING("pcm_sample_chroma (v)");
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(i=0;i<img->mb_cr_size_y;i++)
|
{
|
{
|
for(j=0;j<img->mb_cr_size_x;j++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
{
|
{
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03]=currSE.value1;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
void read_ipred_modes(struct img_par *img,struct inp_par *inp)
|
void read_ipred_modes(struct img_par *img,struct inp_par *inp)
|
{
|
{
|
int b8,i,j,bi,bj,bx,by,dec;
|
int b8,i,j,bi,bj,bx,by,dec;
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
Slice *currSlice;
|
Slice *currSlice;
|
DataPartition *dP;
|
DataPartition *dP;
|
int *partMap;
|
int *partMap;
|
Macroblock *currMB;
|
Macroblock *currMB;
|
int ts, ls;
|
int ts, ls;
|
int mostProbableIntraPredMode;
|
int mostProbableIntraPredMode;
|
int upIntraPredMode;
|
int upIntraPredMode;
|
int leftIntraPredMode;
|
int leftIntraPredMode;
|
int IntraChromaPredModeFlag;
|
int IntraChromaPredModeFlag;
|
int bs_x, bs_y;
|
int bs_x, bs_y;
|
int ii,jj;
|
int ii,jj;
|
|
|
PixelPos left_block;
|
PixelPos left_block;
|
PixelPos top_block;
|
PixelPos top_block;
|
|
|
currMB = &img->mb_data[img->current_mb_nr];
|
currMB = &img->mb_data[img->current_mb_nr];
|
|
|
IntraChromaPredModeFlag = IS_INTRA(currMB);
|
IntraChromaPredModeFlag = IS_INTRA(currMB);
|
|
|
currSlice = img->currentSlice;
|
currSlice = img->currentSlice;
|
partMap = assignSE2partition[currSlice->dp_mode];
|
partMap = assignSE2partition[currSlice->dp_mode];
|
|
|
currSE.type = SE_INTRAPREDMODE;
|
currSE.type = SE_INTRAPREDMODE;
|
|
|
TRACE_STRING("intra4x4_pred_mode");
|
TRACE_STRING("intra4x4_pred_mode");
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (!(active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag))
|
if (!(active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag))
|
currSE.reading = readIntraPredMode_CABAC;
|
currSE.reading = readIntraPredMode_CABAC;
|
|
|
for(b8=0;b8<4;b8++) //loop 8x8 blocks
|
for(b8=0;b8<4;b8++) //loop 8x8 blocks
|
{
|
{
|
if((currMB->b8mode[b8]==IBLOCK )||(currMB->b8mode[b8]==I8MB))
|
if((currMB->b8mode[b8]==IBLOCK )||(currMB->b8mode[b8]==I8MB))
|
{
|
{
|
bs_x = bs_y = (currMB->b8mode[b8] == I8MB)?8:4;
|
bs_x = bs_y = (currMB->b8mode[b8] == I8MB)?8:4;
|
|
|
IntraChromaPredModeFlag = 1;
|
IntraChromaPredModeFlag = 1;
|
|
|
ii=(bs_x>>2);
|
ii=(bs_x>>2);
|
jj=(bs_y>>2);
|
jj=(bs_y>>2);
|
|
|
for(j=0;j<2;j+=jj) //loop subblocks
|
for(j=0;j<2;j+=jj) //loop subblocks
|
{
|
{
|
by = (b8&2) + j;
|
by = (b8&2) + j;
|
bj = img->block_y + by;
|
bj = img->block_y + by;
|
for(i=0;i<2;i+=ii)
|
for(i=0;i<2;i+=ii)
|
{
|
{
|
bx = ((b8&1)<<1) + i;
|
bx = ((b8&1)<<1) + i;
|
bi = img->block_x + bx;
|
bi = img->block_x + bx;
|
//get from stream
|
//get from stream
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
readSyntaxElement_Intra4x4PredictionMode(&currSE,img,dP);
|
readSyntaxElement_Intra4x4PredictionMode(&currSE,img,dP);
|
else
|
else
|
{
|
{
|
currSE.context=(b8<<2)+(j<<1)+i;
|
currSE.context=(b8<<2)+(j<<1)+i;
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
}
|
}
|
|
|
getLuma4x4Neighbour(img->current_mb_nr, (bx<<2) - 1, (by<<2), &left_block);
|
getLuma4x4Neighbour(img->current_mb_nr, (bx<<2) - 1, (by<<2), &left_block);
|
getLuma4x4Neighbour(img->current_mb_nr, (bx<<2), (by<<2) - 1, &top_block);
|
getLuma4x4Neighbour(img->current_mb_nr, (bx<<2), (by<<2) - 1, &top_block);
|
|
|
//get from array and decode
|
//get from array and decode
|
|
|
if (active_pps->constrained_intra_pred_flag)
|
if (active_pps->constrained_intra_pred_flag)
|
{
|
{
|
left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
|
left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
|
top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
|
top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
|
}
|
}
|
|
|
// !! KS: not sure if the following is still correct...
|
// !! KS: not sure if the following is still correct...
|
ts = ls = 0; // Check to see if the neighboring block is SI
|
ts = ls = 0; // Check to see if the neighboring block is SI
|
if (IS_OLDINTRA(currMB) && img->type == SI_SLICE) // need support for MBINTLC1
|
if (IS_OLDINTRA(currMB) && img->type == SI_SLICE) // need support for MBINTLC1
|
{
|
{
|
if (left_block.available)
|
if (left_block.available)
|
if (img->siblock [left_block.pos_y][left_block.pos_x])
|
if (img->siblock [left_block.pos_y][left_block.pos_x])
|
ls=1;
|
ls=1;
|
|
|
if (top_block.available)
|
if (top_block.available)
|
if (img->siblock [top_block.pos_y][top_block.pos_x])
|
if (img->siblock [top_block.pos_y][top_block.pos_x])
|
ts=1;
|
ts=1;
|
}
|
}
|
|
|
upIntraPredMode = (top_block.available &&(ts == 0)) ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
|
upIntraPredMode = (top_block.available &&(ts == 0)) ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
|
leftIntraPredMode = (left_block.available &&(ls == 0)) ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
|
leftIntraPredMode = (left_block.available &&(ls == 0)) ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
|
|
|
mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;
|
mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;
|
|
|
dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);
|
dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);
|
|
|
//set
|
//set
|
for(jj=0;jj<(bs_y>>2);jj++) //loop 4x4s in the subblock for 8x8 prediction setting
|
for(jj=0;jj<(bs_y>>2);jj++) //loop 4x4s in the subblock for 8x8 prediction setting
|
memset(&img->ipredmode[bj+jj][bi], dec, (bs_x>>2) * sizeof(char));
|
memset(&img->ipredmode[bj+jj][bi], dec, (bs_x>>2) * sizeof(char));
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (IntraChromaPredModeFlag && dec_picture->chroma_format_idc != YUV400)
|
if (IntraChromaPredModeFlag && dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
currSE.type = SE_INTRAPREDMODE;
|
currSE.type = SE_INTRAPREDMODE;
|
TRACE_STRING("intra_chroma_pred_mode");
|
TRACE_STRING("intra_chroma_pred_mode");
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
else currSE.reading = readCIPredMode_CABAC;
|
else currSE.reading = readCIPredMode_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
currMB->c_ipred_mode = currSE.value1;
|
currMB->c_ipred_mode = currSE.value1;
|
|
|
if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
|
if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
|
{
|
{
|
error("illegal chroma intra pred mode!\n", 600);
|
error("illegal chroma intra pred mode!\n", 600);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Set motion vector predictor
|
* Set motion vector predictor
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
static void SetMotionVectorPredictor (struct img_par *img,
|
static void SetMotionVectorPredictor (struct img_par *img,
|
short pmv[2],
|
short pmv[2],
|
char ref_frame,
|
char ref_frame,
|
byte list,
|
byte list,
|
char ***refPic,
|
char ***refPic,
|
short ****tmp_mv,
|
short ****tmp_mv,
|
int block_x,
|
int block_x,
|
int block_y,
|
int block_y,
|
int blockshape_x,
|
int blockshape_x,
|
int blockshape_y)
|
int blockshape_y)
|
{
|
{
|
int mb_x = BLOCK_SIZE*block_x;
|
int mb_x = BLOCK_SIZE*block_x;
|
int mb_y = BLOCK_SIZE*block_y;
|
int mb_y = BLOCK_SIZE*block_y;
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
|
|
int mv_a, mv_b, mv_c, pred_vec=0;
|
int mv_a, mv_b, mv_c, pred_vec=0;
|
int mvPredType, rFrameL, rFrameU, rFrameUR;
|
int mvPredType, rFrameL, rFrameU, rFrameUR;
|
int hv;
|
int hv;
|
|
|
|
|
PixelPos block_a, block_b, block_c, block_d;
|
PixelPos block_a, block_b, block_c, block_d;
|
|
|
getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y, &block_a);
|
getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y, &block_a);
|
getLuma4x4Neighbour(mb_nr, mb_x, mb_y - 1, &block_b);
|
getLuma4x4Neighbour(mb_nr, mb_x, mb_y - 1, &block_b);
|
getLuma4x4Neighbour(mb_nr, mb_x + blockshape_x, mb_y - 1, &block_c);
|
getLuma4x4Neighbour(mb_nr, mb_x + blockshape_x, mb_y - 1, &block_c);
|
getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y - 1, &block_d);
|
getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y - 1, &block_d);
|
|
|
if (mb_y > 0)
|
if (mb_y > 0)
|
{
|
{
|
if (mb_x < 8) // first column of 8x8 blocks
|
if (mb_x < 8) // first column of 8x8 blocks
|
{
|
{
|
if (mb_y==8)
|
if (mb_y==8)
|
{
|
{
|
if (blockshape_x == 16) block_c.available = 0;
|
if (blockshape_x == 16) block_c.available = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
if (mb_x+blockshape_x == 8) block_c.available = 0;
|
if (mb_x+blockshape_x == 8) block_c.available = 0;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (mb_x+blockshape_x == 16) block_c.available = 0;
|
if (mb_x+blockshape_x == 16) block_c.available = 0;
|
}
|
}
|
}
|
}
|
|
|
if (!block_c.available)
|
if (!block_c.available)
|
{
|
{
|
block_c=block_d;
|
block_c=block_d;
|
}
|
}
|
|
|
mvPredType = MVPRED_MEDIAN;
|
mvPredType = MVPRED_MEDIAN;
|
|
|
if (!img->MbaffFrameFlag)
|
if (!img->MbaffFrameFlag)
|
{
|
{
|
rFrameL = block_a.available ? refPic[list][block_a.pos_y][block_a.pos_x] : -1;
|
rFrameL = block_a.available ? refPic[list][block_a.pos_y][block_a.pos_x] : -1;
|
rFrameU = block_b.available ? refPic[list][block_b.pos_y][block_b.pos_x] : -1;
|
rFrameU = block_b.available ? refPic[list][block_b.pos_y][block_b.pos_x] : -1;
|
rFrameUR = block_c.available ? refPic[list][block_c.pos_y][block_c.pos_x] : -1;
|
rFrameUR = block_c.available ? refPic[list][block_c.pos_y][block_c.pos_x] : -1;
|
}
|
}
|
else
|
else
|
{
|
{
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
{
|
{
|
rFrameL = block_a.available ?
|
rFrameL = block_a.available ?
|
img->mb_data[block_a.mb_addr].mb_field ?
|
img->mb_data[block_a.mb_addr].mb_field ?
|
refPic[list][block_a.pos_y][block_a.pos_x]:
|
refPic[list][block_a.pos_y][block_a.pos_x]:
|
refPic[list][block_a.pos_y][block_a.pos_x] * 2:
|
refPic[list][block_a.pos_y][block_a.pos_x] * 2:
|
-1;
|
-1;
|
rFrameU = block_b.available ?
|
rFrameU = block_b.available ?
|
img->mb_data[block_b.mb_addr].mb_field ?
|
img->mb_data[block_b.mb_addr].mb_field ?
|
refPic[list][block_b.pos_y][block_b.pos_x]:
|
refPic[list][block_b.pos_y][block_b.pos_x]:
|
refPic[list][block_b.pos_y][block_b.pos_x] * 2:
|
refPic[list][block_b.pos_y][block_b.pos_x] * 2:
|
-1;
|
-1;
|
rFrameUR = block_c.available ?
|
rFrameUR = block_c.available ?
|
img->mb_data[block_c.mb_addr].mb_field ?
|
img->mb_data[block_c.mb_addr].mb_field ?
|
refPic[list][block_c.pos_y][block_c.pos_x]:
|
refPic[list][block_c.pos_y][block_c.pos_x]:
|
refPic[list][block_c.pos_y][block_c.pos_x] * 2:
|
refPic[list][block_c.pos_y][block_c.pos_x] * 2:
|
-1;
|
-1;
|
}
|
}
|
else
|
else
|
{
|
{
|
rFrameL = block_a.available ?
|
rFrameL = block_a.available ?
|
img->mb_data[block_a.mb_addr].mb_field ?
|
img->mb_data[block_a.mb_addr].mb_field ?
|
refPic[list][block_a.pos_y][block_a.pos_x] >>1:
|
refPic[list][block_a.pos_y][block_a.pos_x] >>1:
|
refPic[list][block_a.pos_y][block_a.pos_x] :
|
refPic[list][block_a.pos_y][block_a.pos_x] :
|
-1;
|
-1;
|
rFrameU = block_b.available ?
|
rFrameU = block_b.available ?
|
img->mb_data[block_b.mb_addr].mb_field ?
|
img->mb_data[block_b.mb_addr].mb_field ?
|
refPic[list][block_b.pos_y][block_b.pos_x] >>1:
|
refPic[list][block_b.pos_y][block_b.pos_x] >>1:
|
refPic[list][block_b.pos_y][block_b.pos_x] :
|
refPic[list][block_b.pos_y][block_b.pos_x] :
|
-1;
|
-1;
|
rFrameUR = block_c.available ?
|
rFrameUR = block_c.available ?
|
img->mb_data[block_c.mb_addr].mb_field ?
|
img->mb_data[block_c.mb_addr].mb_field ?
|
refPic[list][block_c.pos_y][block_c.pos_x] >>1:
|
refPic[list][block_c.pos_y][block_c.pos_x] >>1:
|
refPic[list][block_c.pos_y][block_c.pos_x] :
|
refPic[list][block_c.pos_y][block_c.pos_x] :
|
-1;
|
-1;
|
}
|
}
|
}
|
}
|
|
|
|
|
/* Prediction if only one of the neighbors uses the reference frame
|
/* Prediction if only one of the neighbors uses the reference frame
|
* we are checking
|
* we are checking
|
*/
|
*/
|
if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L;
|
if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L;
|
else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U;
|
else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U;
|
else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR;
|
else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR;
|
// Directional predictions
|
// Directional predictions
|
if(blockshape_x == 8 && blockshape_y == 16)
|
if(blockshape_x == 8 && blockshape_y == 16)
|
{
|
{
|
if(mb_x == 0)
|
if(mb_x == 0)
|
{
|
{
|
if(rFrameL == ref_frame)
|
if(rFrameL == ref_frame)
|
mvPredType = MVPRED_L;
|
mvPredType = MVPRED_L;
|
}
|
}
|
else
|
else
|
{
|
{
|
if( rFrameUR == ref_frame)
|
if( rFrameUR == ref_frame)
|
mvPredType = MVPRED_UR;
|
mvPredType = MVPRED_UR;
|
}
|
}
|
}
|
}
|
else if(blockshape_x == 16 && blockshape_y == 8)
|
else if(blockshape_x == 16 && blockshape_y == 8)
|
{
|
{
|
if(mb_y == 0)
|
if(mb_y == 0)
|
{
|
{
|
if(rFrameU == ref_frame)
|
if(rFrameU == ref_frame)
|
mvPredType = MVPRED_U;
|
mvPredType = MVPRED_U;
|
}
|
}
|
else
|
else
|
{
|
{
|
if(rFrameL == ref_frame)
|
if(rFrameL == ref_frame)
|
mvPredType = MVPRED_L;
|
mvPredType = MVPRED_L;
|
}
|
}
|
}
|
}
|
|
|
for (hv=0; hv < 2; hv++)
|
for (hv=0; hv < 2; hv++)
|
{
|
{
|
if (!img->MbaffFrameFlag || hv==0)
|
if (!img->MbaffFrameFlag || hv==0)
|
{
|
{
|
mv_a = block_a.available ? tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] : 0;
|
mv_a = block_a.available ? tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] : 0;
|
mv_b = block_b.available ? tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] : 0;
|
mv_b = block_b.available ? tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] : 0;
|
mv_c = block_c.available ? tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] : 0;
|
mv_c = block_c.available ? tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] : 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
{
|
{
|
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
|
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv]:
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv]:
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] / 2:
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] / 2:
|
0;
|
0;
|
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
|
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv]:
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv]:
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] / 2:
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] / 2:
|
0;
|
0;
|
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
|
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv]:
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv]:
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] / 2:
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] / 2:
|
0;
|
0;
|
}
|
}
|
else
|
else
|
{
|
{
|
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
|
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field?
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] * 2:
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] * 2:
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv]:
|
tmp_mv[list][block_a.pos_y][block_a.pos_x][hv]:
|
0;
|
0;
|
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
|
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field?
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] * 2:
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] * 2:
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv]:
|
tmp_mv[list][block_b.pos_y][block_b.pos_x][hv]:
|
0;
|
0;
|
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
|
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field?
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] * 2:
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] * 2:
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv]:
|
tmp_mv[list][block_c.pos_y][block_c.pos_x][hv]:
|
0;
|
0;
|
}
|
}
|
}
|
}
|
|
|
switch (mvPredType)
|
switch (mvPredType)
|
{
|
{
|
case MVPRED_MEDIAN:
|
case MVPRED_MEDIAN:
|
if(!(block_b.available || block_c.available))
|
if(!(block_b.available || block_c.available))
|
pred_vec = mv_a;
|
pred_vec = mv_a;
|
else
|
else
|
pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
|
pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
|
break;
|
break;
|
case MVPRED_L:
|
case MVPRED_L:
|
pred_vec = mv_a;
|
pred_vec = mv_a;
|
break;
|
break;
|
case MVPRED_U:
|
case MVPRED_U:
|
pred_vec = mv_b;
|
pred_vec = mv_b;
|
break;
|
break;
|
case MVPRED_UR:
|
case MVPRED_UR:
|
pred_vec = mv_c;
|
pred_vec = mv_c;
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
|
|
pmv[hv] = pred_vec;
|
pmv[hv] = pred_vec;
|
}
|
}
|
}
|
}
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Set context for reference frames
|
* Set context for reference frames
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
int
|
int
|
BType2CtxRef (int btype)
|
BType2CtxRef (int btype)
|
{
|
{
|
if (btype<4) return 0;
|
if (btype<4) return 0;
|
else return 1;
|
else return 1;
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Read motion info
|
* Read motion info
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
|
void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
|
{
|
{
|
int i,j,k;
|
int i,j,k;
|
int step_h,step_v;
|
int step_h,step_v;
|
int curr_mvd;
|
int curr_mvd;
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
Slice *currSlice = img->currentSlice;
|
Slice *currSlice = img->currentSlice;
|
DataPartition *dP;
|
DataPartition *dP;
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int bframe = (img->type==B_SLICE);
|
int bframe = (img->type==B_SLICE);
|
int partmode = (IS_P8x8(currMB)?4:currMB->mb_type);
|
int partmode = (IS_P8x8(currMB)?4:currMB->mb_type);
|
int step_h0 = BLOCK_STEP [partmode][0];
|
int step_h0 = BLOCK_STEP [partmode][0];
|
int step_v0 = BLOCK_STEP [partmode][1];
|
int step_v0 = BLOCK_STEP [partmode][1];
|
|
|
int mv_mode, i0, j0;
|
int mv_mode, i0, j0;
|
char refframe;
|
char refframe;
|
short pmv[2];
|
short pmv[2];
|
int j4, i4, ii,jj;
|
int j4, i4, ii,jj;
|
int vec;
|
int vec;
|
|
|
int mv_scale = 0;
|
int mv_scale = 0;
|
|
|
int flag_mode;
|
int flag_mode;
|
|
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
|
|
byte ** moving_block;
|
byte ** moving_block;
|
short **** co_located_mv;
|
short **** co_located_mv;
|
char *** co_located_ref_idx;
|
char *** co_located_ref_idx;
|
int64 *** co_located_ref_id;
|
int64 *** co_located_ref_id;
|
|
|
if ((img->MbaffFrameFlag)&&(currMB->mb_field))
|
if ((img->MbaffFrameFlag)&&(currMB->mb_field))
|
{
|
{
|
if(img->current_mb_nr&0x01)
|
if(img->current_mb_nr&0x01)
|
{
|
{
|
moving_block = Co_located->bottom_moving_block;
|
moving_block = Co_located->bottom_moving_block;
|
co_located_mv = Co_located->bottom_mv;
|
co_located_mv = Co_located->bottom_mv;
|
co_located_ref_idx = Co_located->bottom_ref_idx;
|
co_located_ref_idx = Co_located->bottom_ref_idx;
|
co_located_ref_id = Co_located->bottom_ref_pic_id;
|
co_located_ref_id = Co_located->bottom_ref_pic_id;
|
}
|
}
|
else
|
else
|
{
|
{
|
moving_block = Co_located->top_moving_block;
|
moving_block = Co_located->top_moving_block;
|
co_located_mv = Co_located->top_mv;
|
co_located_mv = Co_located->top_mv;
|
co_located_ref_idx = Co_located->top_ref_idx;
|
co_located_ref_idx = Co_located->top_ref_idx;
|
co_located_ref_id = Co_located->top_ref_pic_id;
|
co_located_ref_id = Co_located->top_ref_pic_id;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
moving_block = Co_located->moving_block;
|
moving_block = Co_located->moving_block;
|
co_located_mv = Co_located->mv;
|
co_located_mv = Co_located->mv;
|
co_located_ref_idx = Co_located->ref_idx;
|
co_located_ref_idx = Co_located->ref_idx;
|
co_located_ref_id = Co_located->ref_pic_id;
|
co_located_ref_id = Co_located->ref_pic_id;
|
}
|
}
|
|
|
if (bframe && IS_P8x8 (currMB))
|
if (bframe && IS_P8x8 (currMB))
|
{
|
{
|
if (img->direct_spatial_mv_pred_flag)
|
if (img->direct_spatial_mv_pred_flag)
|
{
|
{
|
int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
|
int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
|
int l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR;
|
int l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR;
|
int l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR;
|
int l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR;
|
|
|
PixelPos mb_left, mb_up, mb_upleft, mb_upright;
|
PixelPos mb_left, mb_up, mb_upleft, mb_upright;
|
|
|
char l0_rFrame,l1_rFrame;
|
char l0_rFrame,l1_rFrame;
|
short pmvl0[2]={0,0}, pmvl1[2]={0,0};
|
short pmvl0[2]={0,0}, pmvl1[2]={0,0};
|
|
|
getLuma4x4Neighbour(img->current_mb_nr, -1, 0, &mb_left);
|
getLuma4x4Neighbour(img->current_mb_nr, -1, 0, &mb_left);
|
getLuma4x4Neighbour(img->current_mb_nr, 0, -1, &mb_up);
|
getLuma4x4Neighbour(img->current_mb_nr, 0, -1, &mb_up);
|
getLuma4x4Neighbour(img->current_mb_nr, 16, -1, &mb_upright);
|
getLuma4x4Neighbour(img->current_mb_nr, 16, -1, &mb_upright);
|
getLuma4x4Neighbour(img->current_mb_nr, -1, -1, &mb_upleft);
|
getLuma4x4Neighbour(img->current_mb_nr, -1, -1, &mb_upleft);
|
|
|
if (!img->MbaffFrameFlag)
|
if (!img->MbaffFrameFlag)
|
{
|
{
|
l0_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1;
|
l0_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1;
|
l0_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
l0_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
l0_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l0_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l0_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
l0_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
|
|
l1_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
l1_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
l1_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
l1_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
l1_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l1_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l1_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
l1_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
}
|
}
|
else
|
else
|
{
|
{
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
{
|
{
|
l0_rFrameL = mb_left.available
|
l0_rFrameL = mb_left.available
|
? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0
|
? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0
|
? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]
|
? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]
|
: dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
: dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
|
|
l0_rFrameU = mb_up.available
|
l0_rFrameU = mb_up.available
|
? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0
|
? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0
|
? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x]
|
? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x]
|
: dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
: dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
|
|
l0_rFrameUL = mb_upleft.available
|
l0_rFrameUL = mb_upleft.available
|
? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0
|
? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0
|
? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]
|
? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]
|
: dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
|
: dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
|
|
|
l0_rFrameUR = mb_upright.available
|
l0_rFrameUR = mb_upright.available
|
? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0
|
? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0
|
? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x]
|
? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x]
|
: dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL;
|
: dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL;
|
|
|
l1_rFrameL = mb_left.available
|
l1_rFrameL = mb_left.available
|
? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0
|
? img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0
|
? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x]
|
? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x]
|
: dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
: dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
|
|
l1_rFrameU = mb_up.available
|
l1_rFrameU = mb_up.available
|
? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0
|
? img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0
|
? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x]
|
? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x]
|
: dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
: dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
|
|
l1_rFrameUL = mb_upleft.available
|
l1_rFrameUL = mb_upleft.available
|
? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0
|
? img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0
|
? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x]
|
? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x]
|
: dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2 : -1;
|
: dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2 : -1;
|
|
|
l1_rFrameUR = mb_upright.available
|
l1_rFrameUR = mb_upright.available
|
? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0
|
? img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0
|
? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x]
|
? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x]
|
: dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL;
|
: dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL;
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
l0_rFrameL = mb_left.available ?
|
l0_rFrameL = mb_left.available ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1;
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1;
|
|
|
l0_rFrameU = mb_up.available ?
|
l0_rFrameU = mb_up.available ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
|
|
l0_rFrameUL = mb_upleft.available ?
|
l0_rFrameUL = mb_upleft.available ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
|
|
l0_rFrameUR = mb_upright.available ?
|
l0_rFrameUR = mb_upright.available ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
|
|
l1_rFrameL = mb_left.available ?
|
l1_rFrameL = mb_left.available ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
l1_rFrameU = mb_up.available ?
|
l1_rFrameU = mb_up.available ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
|
|
l1_rFrameUL = mb_upleft.available ?
|
l1_rFrameUL = mb_upleft.available ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
|
|
l1_rFrameUR = mb_upright.available ?
|
l1_rFrameUR = mb_upright.available ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1:
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1:
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
}
|
}
|
}
|
}
|
|
|
l0_rFrame = (l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU): imax(l0_rFrameL,l0_rFrameU);
|
l0_rFrame = (l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU): imax(l0_rFrameL,l0_rFrameU);
|
l0_rFrame = (l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(l0_rFrame,l0_rFrameUR): imax(l0_rFrame,l0_rFrameUR);
|
l0_rFrame = (l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(l0_rFrame,l0_rFrameUR): imax(l0_rFrame,l0_rFrameUR);
|
|
|
l1_rFrame = (l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU): imax(l1_rFrameL,l1_rFrameU);
|
l1_rFrame = (l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU): imax(l1_rFrameL,l1_rFrameU);
|
l1_rFrame = (l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(l1_rFrame,l1_rFrameUR): imax(l1_rFrame,l1_rFrameUR);
|
l1_rFrame = (l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(l1_rFrame,l1_rFrameUR): imax(l1_rFrame,l1_rFrameUR);
|
|
|
|
|
if (l0_rFrame >=0)
|
if (l0_rFrame >=0)
|
SetMotionVectorPredictor (img, pmvl0, l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
SetMotionVectorPredictor (img, pmvl0, l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
|
|
if (l1_rFrame >=0)
|
if (l1_rFrame >=0)
|
SetMotionVectorPredictor (img, pmvl1, l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
SetMotionVectorPredictor (img, pmvl1, l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
|
|
|
|
for (i=0;i<4;i++)
|
for (i=0;i<4;i++)
|
{
|
{
|
if (currMB->b8mode[i] == 0)
|
if (currMB->b8mode[i] == 0)
|
{
|
{
|
for(j=2*(i>>1);j<2*(i>>1)+2;j++)
|
for(j=2*(i>>1);j<2*(i>>1)+2;j++)
|
{
|
{
|
for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
|
for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
|
{
|
{
|
int j6 = imgblock_y+j;
|
int j6 = imgblock_y+j;
|
j4 = img->block_y+j;
|
j4 = img->block_y+j;
|
i4 = img->block_x+k;
|
i4 = img->block_x+k;
|
|
|
|
|
if (l0_rFrame >= 0)
|
if (l0_rFrame >= 0)
|
{
|
{
|
if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
|
if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
|
dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
|
dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
|
dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
|
dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
|
dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = -1;
|
dec_picture->ref_idx[LIST_0][j4][i4] = -1;
|
}
|
}
|
|
|
if (l1_rFrame >= 0)
|
if (l1_rFrame >= 0)
|
{
|
{
|
if (l1_rFrame==0 && ((!moving_block[j6][i4])&& (!listX[1+list_offset][0]->is_long_term)))
|
if (l1_rFrame==0 && ((!moving_block[j6][i4])&& (!listX[1+list_offset][0]->is_long_term)))
|
{
|
{
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
|
dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
|
dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
|
dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
|
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
|
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = -1;
|
dec_picture->ref_idx[LIST_1][j4][i4] = -1;
|
}
|
}
|
|
|
if (l0_rFrame <0 && l1_rFrame <0)
|
if (l0_rFrame <0 && l1_rFrame <0)
|
{
|
{
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for (i=0;i<4;i++)
|
for (i=0;i<4;i++)
|
{
|
{
|
if (currMB->b8mode[i] == 0)
|
if (currMB->b8mode[i] == 0)
|
{
|
{
|
for(j=2*(i>>1);j<2*(i>>1)+2;j++)
|
for(j=2*(i>>1);j<2*(i>>1)+2;j++)
|
{
|
{
|
for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
|
for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
|
{
|
{
|
|
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
int imgblock_y = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1 : img->block_y>>1 : img->block_y;
|
int imgblock_y = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1 : img->block_y>>1 : img->block_y;
|
int refList = co_located_ref_idx[LIST_0 ][imgblock_y+j][img->block_x+k]== -1 ? LIST_1 : LIST_0;
|
int refList = co_located_ref_idx[LIST_0 ][imgblock_y+j][img->block_x+k]== -1 ? LIST_1 : LIST_0;
|
int ref_idx = co_located_ref_idx[refList][imgblock_y + j][img->block_x + k];
|
int ref_idx = co_located_ref_idx[refList][imgblock_y + j][img->block_x + k];
|
int mapped_idx=-1, iref;
|
int mapped_idx=-1, iref;
|
|
|
if (ref_idx == -1)
|
if (ref_idx == -1)
|
{
|
{
|
dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = 0;
|
dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = 0;
|
dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
|
dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
|
for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
|
{
|
{
|
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
|
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
|
|
|
if(img->structure==0 && curr_mb_field==0)
|
if(img->structure==0 && curr_mb_field==0)
|
{
|
{
|
// If the current MB is a frame MB and the colocated is from a field picture,
|
// If the current MB is a frame MB and the colocated is from a field picture,
|
// then the co_located_ref_id may have been generated from the wrong value of
|
// then the co_located_ref_id may have been generated from the wrong value of
|
// frame_poc if it references it's complementary field, so test both POC values
|
// frame_poc if it references it's complementary field, so test both POC values
|
if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][imgblock_y + j][img->block_x + k]
|
if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][imgblock_y + j][img->block_x + k]
|
|| listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][imgblock_y + j][img->block_x + k])
|
|| listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][imgblock_y + j][img->block_x + k])
|
{
|
{
|
mapped_idx=iref;
|
mapped_idx=iref;
|
break;
|
break;
|
}
|
}
|
else //! invalid index. Default to zero even though this case should not happen
|
else //! invalid index. Default to zero even though this case should not happen
|
mapped_idx=INVALIDINDEX;
|
mapped_idx=INVALIDINDEX;
|
continue;
|
continue;
|
}
|
}
|
if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][imgblock_y + j][img->block_x + k])
|
if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][imgblock_y + j][img->block_x + k])
|
{
|
{
|
mapped_idx=iref;
|
mapped_idx=iref;
|
break;
|
break;
|
}
|
}
|
else //! invalid index. Default to zero even though this case should not happen
|
else //! invalid index. Default to zero even though this case should not happen
|
mapped_idx=INVALIDINDEX;
|
mapped_idx=INVALIDINDEX;
|
}
|
}
|
if (INVALIDINDEX == mapped_idx)
|
if (INVALIDINDEX == mapped_idx)
|
{
|
{
|
error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
|
error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
|
}
|
}
|
dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = mapped_idx;
|
dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = mapped_idx;
|
dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
|
dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// If multiple ref. frames, read reference frame for the MB *********************************
|
// If multiple ref. frames, read reference frame for the MB *********************************
|
if(img->num_ref_idx_l0_active>1)
|
if(img->num_ref_idx_l0_active>1)
|
{
|
{
|
flag_mode = ( img->num_ref_idx_l0_active == 2 ? 1 : 0);
|
flag_mode = ( img->num_ref_idx_l0_active == 2 ? 1 : 0);
|
|
|
currSE.type = SE_REFFRAME;
|
currSE.type = SE_REFFRAME;
|
dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
|
dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
|
else currSE.reading = readRefFrame_CABAC;
|
else currSE.reading = readRefFrame_CABAC;
|
|
|
for (j0=0; j0<4; j0+=step_v0)
|
for (j0=0; j0<4; j0+=step_v0)
|
{
|
{
|
for (i0=0; i0<4; i0+=step_h0)
|
for (i0=0; i0<4; i0+=step_h0)
|
{
|
{
|
k=2*(j0>>1)+(i0>>1);
|
k=2*(j0>>1)+(i0>>1);
|
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
{
|
{
|
TRACE_STRING("ref_idx_l0");
|
TRACE_STRING("ref_idx_l0");
|
|
|
img->subblock_x = i0;
|
img->subblock_x = i0;
|
img->subblock_y = j0;
|
img->subblock_y = j0;
|
|
|
if (!IS_P8x8 (currMB) || bframe || (!bframe && !img->allrefzero))
|
if (!IS_P8x8 (currMB) || bframe || (!bframe && !img->allrefzero))
|
{
|
{
|
currSE.context = BType2CtxRef (currMB->b8mode[k]);
|
currSE.context = BType2CtxRef (currMB->b8mode[k]);
|
if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
|
if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
|
{
|
{
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
currSE.value1 = 1 - currSE.value1;
|
currSE.value1 = 1 - currSE.value1;
|
}
|
}
|
else
|
else
|
{
|
{
|
currSE.value2 = LIST_0;
|
currSE.value2 = LIST_0;
|
dP->readSyntaxElement (&currSE,img,dP);
|
dP->readSyntaxElement (&currSE,img,dP);
|
}
|
}
|
refframe = currSE.value1;
|
refframe = currSE.value1;
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
refframe = 0;
|
refframe = 0;
|
}
|
}
|
|
|
for (j=img->block_y +j0; j<img->block_y +j0+step_v0;j++)
|
for (j=img->block_y +j0; j<img->block_y +j0+step_v0;j++)
|
memset(&dec_picture->ref_idx[LIST_0][j][img->block_x + i0], refframe, step_h0 * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_0][j][img->block_x + i0], refframe, step_h0 * sizeof(char));
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for (j0=0; j0<4; j0+=step_v0)
|
for (j0=0; j0<4; j0+=step_v0)
|
{
|
{
|
for (i0=0; i0<4; i0+=step_h0)
|
for (i0=0; i0<4; i0+=step_h0)
|
{
|
{
|
k=2*(j0>>1)+(i0>>1);
|
k=2*(j0>>1)+(i0>>1);
|
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
{
|
{
|
for (j=img->block_y + j0; j < img->block_y + j0+step_v0;j++)
|
for (j=img->block_y + j0; j < img->block_y + j0+step_v0;j++)
|
memset(&dec_picture->ref_idx[LIST_0][j][img->block_x + i0], 0, step_h0 * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_0][j][img->block_x + i0], 0, step_h0 * sizeof(char));
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// If backward multiple ref. frames, read backward reference frame for the MB *********************************
|
// If backward multiple ref. frames, read backward reference frame for the MB *********************************
|
if(img->num_ref_idx_l1_active>1)
|
if(img->num_ref_idx_l1_active>1)
|
{
|
{
|
flag_mode = ( img->num_ref_idx_l1_active == 2 ? 1 : 0);
|
flag_mode = ( img->num_ref_idx_l1_active == 2 ? 1 : 0);
|
|
|
currSE.type = SE_REFFRAME;
|
currSE.type = SE_REFFRAME;
|
dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
|
dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_ue;
|
currSE.mapping = linfo_ue;
|
else
|
else
|
currSE.reading = readRefFrame_CABAC;
|
currSE.reading = readRefFrame_CABAC;
|
|
|
for (j0=0; j0<4; j0+=step_v0)
|
for (j0=0; j0<4; j0+=step_v0)
|
{
|
{
|
for (i0=0; i0<4; i0+=step_h0)
|
for (i0=0; i0<4; i0+=step_h0)
|
{
|
{
|
k=2*(j0>>1)+(i0>>1);
|
k=2*(j0>>1)+(i0>>1);
|
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
{
|
{
|
TRACE_STRING("ref_idx_l1");
|
TRACE_STRING("ref_idx_l1");
|
|
|
img->subblock_x = i0;
|
img->subblock_x = i0;
|
img->subblock_y = j0;
|
img->subblock_y = j0;
|
|
|
currSE.context = BType2CtxRef (currMB->b8mode[k]);
|
currSE.context = BType2CtxRef (currMB->b8mode[k]);
|
if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
|
if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
|
{
|
{
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
currSE.value1 = 1-currSE.value1;
|
currSE.value1 = 1-currSE.value1;
|
}
|
}
|
else
|
else
|
{
|
{
|
currSE.value2 = LIST_1;
|
currSE.value2 = LIST_1;
|
dP->readSyntaxElement (&currSE,img,dP);
|
dP->readSyntaxElement (&currSE,img,dP);
|
}
|
}
|
refframe = currSE.value1;
|
refframe = currSE.value1;
|
|
|
for (j=img->block_y + j0; j<img->block_y + j0+step_v0;j++)
|
for (j=img->block_y + j0; j<img->block_y + j0+step_v0;j++)
|
{
|
{
|
memset(&dec_picture->ref_idx[LIST_1][j][img->block_x + i0], refframe, step_h0 * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_1][j][img->block_x + i0], refframe, step_h0 * sizeof(char));
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for (j0=0; j0<4; j0+=step_v0)
|
for (j0=0; j0<4; j0+=step_v0)
|
{
|
{
|
for (i0=0; i0<4; i0+=step_h0)
|
for (i0=0; i0<4; i0+=step_h0)
|
{
|
{
|
k=2*(j0>>1)+(i0>>1);
|
k=2*(j0>>1)+(i0>>1);
|
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
|
{
|
{
|
for (j=img->block_y + j0; j<img->block_y + j0+step_v0;j++)
|
for (j=img->block_y + j0; j<img->block_y + j0+step_v0;j++)
|
memset(&dec_picture->ref_idx[LIST_1][ j][img->block_x + i0], 0, step_h0 * sizeof(char));
|
memset(&dec_picture->ref_idx[LIST_1][ j][img->block_x + i0], 0, step_h0 * sizeof(char));
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
//===== READ FORWARD MOTION VECTORS =====
|
//===== READ FORWARD MOTION VECTORS =====
|
currSE.type = SE_MVD;
|
currSE.type = SE_MVD;
|
dP = &(currSlice->partArr[partMap[SE_MVD]]);
|
dP = &(currSlice->partArr[partMap[SE_MVD]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_se;
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_se;
|
else currSE.reading = readMVD_CABAC;
|
else currSE.reading = readMVD_CABAC;
|
|
|
for (j0=0; j0<4; j0+=step_v0)
|
for (j0=0; j0<4; j0+=step_v0)
|
for (i0=0; i0<4; i0+=step_h0)
|
for (i0=0; i0<4; i0+=step_h0)
|
{
|
{
|
k=2*(j0>>1)+(i0>>1);
|
k=2*(j0>>1)+(i0>>1);
|
|
|
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && (currMB->b8mode[k] !=0))//has forward vector
|
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && (currMB->b8mode[k] !=0))//has forward vector
|
{
|
{
|
mv_mode = currMB->b8mode[k];
|
mv_mode = currMB->b8mode[k];
|
step_h = BLOCK_STEP [mv_mode][0];
|
step_h = BLOCK_STEP [mv_mode][0];
|
step_v = BLOCK_STEP [mv_mode][1];
|
step_v = BLOCK_STEP [mv_mode][1];
|
|
|
refframe = dec_picture->ref_idx[LIST_0][img->block_y+j0][img->block_x+i0];
|
refframe = dec_picture->ref_idx[LIST_0][img->block_y+j0][img->block_x+i0];
|
|
|
for (j=j0; j<j0+step_v0; j+=step_v)
|
for (j=j0; j<j0+step_v0; j+=step_v)
|
{
|
{
|
j4 = img->block_y+j;
|
j4 = img->block_y+j;
|
for (i=i0; i<i0+step_h0; i+=step_h)
|
for (i=i0; i<i0+step_h0; i+=step_h)
|
{
|
{
|
i4 = img->block_x+i;
|
i4 = img->block_x+i;
|
|
|
// first make mv-prediction
|
// first make mv-prediction
|
SetMotionVectorPredictor (img, pmv, refframe, LIST_0, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
|
SetMotionVectorPredictor (img, pmv, refframe, LIST_0, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
|
|
|
for (k=0; k < 2; k++)
|
for (k=0; k < 2; k++)
|
{
|
{
|
TRACE_STRING("mvd_l0");
|
TRACE_STRING("mvd_l0");
|
|
|
img->subblock_x = i; // position used for context determination
|
img->subblock_x = i; // position used for context determination
|
img->subblock_y = j; // position used for context determination
|
img->subblock_y = j; // position used for context determination
|
currSE.value2 = k<<1; // identifies the component; only used for context determination
|
currSE.value2 = k<<1; // identifies the component; only used for context determination
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
curr_mvd = currSE.value1;
|
curr_mvd = currSE.value1;
|
|
|
vec=curr_mvd+pmv[k]; /* find motion vector */
|
vec=curr_mvd+pmv[k]; /* find motion vector */
|
|
|
for(jj=0;jj<step_v;jj++)
|
for(jj=0;jj<step_v;jj++)
|
{
|
{
|
for(ii=0;ii<step_h;ii++)
|
for(ii=0;ii<step_h;ii++)
|
{
|
{
|
dec_picture->mv [LIST_0][j4+jj][i4+ii][k] = vec;
|
dec_picture->mv [LIST_0][j4+jj][i4+ii][k] = vec;
|
currMB->mvd [LIST_0][j +jj][i +ii][k] = curr_mvd;
|
currMB->mvd [LIST_0][j +jj][i +ii][k] = curr_mvd;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else if (currMB->b8mode[k=2*(j0>>1)+(i0>>1)]==0)
|
else if (currMB->b8mode[k=2*(j0>>1)+(i0>>1)]==0)
|
{
|
{
|
if (!img->direct_spatial_mv_pred_flag)
|
if (!img->direct_spatial_mv_pred_flag)
|
{
|
{
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? 4 : 2 : 0;
|
int imgblock_y = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1 : img->block_y;
|
int imgblock_y = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1 : img->block_y;
|
|
|
int refList = (co_located_ref_idx[LIST_0 ][imgblock_y+j0][img->block_x+i0]== -1 ? LIST_1 : LIST_0);
|
int refList = (co_located_ref_idx[LIST_0 ][imgblock_y+j0][img->block_x+i0]== -1 ? LIST_1 : LIST_0);
|
int ref_idx = co_located_ref_idx[refList][imgblock_y+j0][img->block_x+i0];
|
int ref_idx = co_located_ref_idx[refList][imgblock_y+j0][img->block_x+i0];
|
|
|
if (ref_idx==-1)
|
if (ref_idx==-1)
|
{
|
{
|
for (j4=img->block_y+j0; j4<img->block_y+j0+step_v0; j4++)
|
for (j4=img->block_y+j0; j4<img->block_y+j0+step_v0; j4++)
|
{
|
{
|
for (i4=img->block_x+i0; i4<img->block_x+i0+step_h0; i4++)
|
for (i4=img->block_x+i0; i4<img->block_x+i0+step_h0; i4++)
|
{
|
{
|
dec_picture->ref_idx [LIST_1][j4][i4]=0;
|
dec_picture->ref_idx [LIST_1][j4][i4]=0;
|
dec_picture->ref_idx [LIST_0][j4][i4]=0;
|
dec_picture->ref_idx [LIST_0][j4][i4]=0;
|
|
|
for (ii=0; ii < 2; ii++)
|
for (ii=0; ii < 2; ii++)
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][ii]=0;
|
dec_picture->mv [LIST_0][j4][i4][ii]=0;
|
dec_picture->mv [LIST_1][j4][i4][ii]=0;
|
dec_picture->mv [LIST_1][j4][i4][ii]=0;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
int mapped_idx=-1, iref;
|
int mapped_idx=-1, iref;
|
int j6;
|
int j6;
|
|
|
for (iref = 0; iref < imin(img->num_ref_idx_l0_active, listXsize[LIST_0 + list_offset]); iref++)
|
for (iref = 0; iref < imin(img->num_ref_idx_l0_active, listXsize[LIST_0 + list_offset]); iref++)
|
{
|
{
|
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
|
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
|
|
|
if(img->structure==0 && curr_mb_field==0)
|
if(img->structure==0 && curr_mb_field==0)
|
{
|
{
|
// If the current MB is a frame MB and the colocated is from a field picture,
|
// If the current MB is a frame MB and the colocated is from a field picture,
|
// then the co_located_ref_id may have been generated from the wrong value of
|
// then the co_located_ref_id may have been generated from the wrong value of
|
// frame_poc if it references it's complementary field, so test both POC values
|
// frame_poc if it references it's complementary field, so test both POC values
|
if(listX[0][iref]->top_poc * 2 == co_located_ref_id[refList][imgblock_y + j0][img->block_x + i0]
|
if(listX[0][iref]->top_poc * 2 == co_located_ref_id[refList][imgblock_y + j0][img->block_x + i0]
|
|| listX[0][iref]->bottom_poc * 2 == co_located_ref_id[refList][imgblock_y + j0][img->block_x + i0])
|
|| listX[0][iref]->bottom_poc * 2 == co_located_ref_id[refList][imgblock_y + j0][img->block_x + i0])
|
{
|
{
|
mapped_idx=iref;
|
mapped_idx=iref;
|
break;
|
break;
|
}
|
}
|
else //! invalid index. Default to zero even though this case should not happen
|
else //! invalid index. Default to zero even though this case should not happen
|
mapped_idx=INVALIDINDEX;
|
mapped_idx=INVALIDINDEX;
|
continue;
|
continue;
|
}
|
}
|
if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][imgblock_y+j0][img->block_x+i0])
|
if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][imgblock_y+j0][img->block_x+i0])
|
{
|
{
|
mapped_idx=iref;
|
mapped_idx=iref;
|
break;
|
break;
|
}
|
}
|
else //! invalid index. Default to zero even though this case should not happen
|
else //! invalid index. Default to zero even though this case should not happen
|
mapped_idx=INVALIDINDEX;
|
mapped_idx=INVALIDINDEX;
|
}
|
}
|
|
|
if (INVALIDINDEX == mapped_idx)
|
if (INVALIDINDEX == mapped_idx)
|
{
|
{
|
error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
|
error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
|
}
|
}
|
|
|
|
|
for (j=j0; j<j0+step_v0; j++)
|
for (j=j0; j<j0+step_v0; j++)
|
{
|
{
|
j4 = img->block_y+j;
|
j4 = img->block_y+j;
|
j6 = imgblock_y + j;
|
j6 = imgblock_y + j;
|
|
|
for (i4=img->block_x+i0; i4<img->block_x+i0+step_h0; i4++)
|
for (i4=img->block_x+i0; i4<img->block_x+i0+step_h0; i4++)
|
{
|
{
|
mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
|
mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
|
|
|
dec_picture->ref_idx [LIST_0][j4][i4] = mapped_idx;
|
dec_picture->ref_idx [LIST_0][j4][i4] = mapped_idx;
|
dec_picture->ref_idx [LIST_1][j4][i4] = 0;
|
dec_picture->ref_idx [LIST_1][j4][i4] = 0;
|
|
|
|
|
for (ii=0; ii < 2; ii++)
|
for (ii=0; ii < 2; ii++)
|
{
|
{
|
if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
|
if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][ii] = co_located_mv[refList][j6][i4][ii];
|
dec_picture->mv [LIST_0][j4][i4][ii] = co_located_mv[refList][j6][i4][ii];
|
dec_picture->mv [LIST_1][j4][i4][ii] = 0;
|
dec_picture->mv [LIST_1][j4][i4][ii] = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][ii] = (mv_scale * co_located_mv[refList][j6][i4][ii] + 128 ) >> 8;
|
dec_picture->mv [LIST_0][j4][i4][ii] = (mv_scale * co_located_mv[refList][j6][i4][ii] + 128 ) >> 8;
|
dec_picture->mv [LIST_1][j4][i4][ii] = dec_picture->mv[LIST_0][j4][i4][ii] - co_located_mv[refList][j6][i4][ii];
|
dec_picture->mv [LIST_1][j4][i4][ii] = dec_picture->mv[LIST_0][j4][i4][ii] - co_located_mv[refList][j6][i4][ii];
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
//===== READ BACKWARD MOTION VECTORS =====
|
//===== READ BACKWARD MOTION VECTORS =====
|
currSE.type = SE_MVD;
|
currSE.type = SE_MVD;
|
dP = &(currSlice->partArr[partMap[SE_MVD]]);
|
dP = &(currSlice->partArr[partMap[SE_MVD]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_se;
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_se;
|
else currSE.reading = readMVD_CABAC;
|
else currSE.reading = readMVD_CABAC;
|
|
|
for (j0=0; j0<4; j0+=step_v0)
|
for (j0=0; j0<4; j0+=step_v0)
|
{
|
{
|
for (i0=0; i0<4; i0+=step_h0)
|
for (i0=0; i0<4; i0+=step_h0)
|
{
|
{
|
k=2*(j0>>1)+(i0>>1);
|
k=2*(j0>>1)+(i0>>1);
|
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && (currMB->b8mode[k]!=0))//has backward vector
|
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && (currMB->b8mode[k]!=0))//has backward vector
|
{
|
{
|
mv_mode = currMB->b8mode[k];
|
mv_mode = currMB->b8mode[k];
|
step_h = BLOCK_STEP [mv_mode][0];
|
step_h = BLOCK_STEP [mv_mode][0];
|
step_v = BLOCK_STEP [mv_mode][1];
|
step_v = BLOCK_STEP [mv_mode][1];
|
|
|
refframe = dec_picture->ref_idx[LIST_1][img->block_y+j0][img->block_x+i0];
|
refframe = dec_picture->ref_idx[LIST_1][img->block_y+j0][img->block_x+i0];
|
|
|
for (j=j0; j<j0+step_v0; j+=step_v)
|
for (j=j0; j<j0+step_v0; j+=step_v)
|
{
|
{
|
j4 = img->block_y+j;
|
j4 = img->block_y+j;
|
for (i=i0; i<i0+step_h0; i+=step_h)
|
for (i=i0; i<i0+step_h0; i+=step_h)
|
{
|
{
|
i4 = img->block_x+i;
|
i4 = img->block_x+i;
|
|
|
// first make mv-prediction
|
// first make mv-prediction
|
SetMotionVectorPredictor (img, pmv, refframe, LIST_1, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
|
SetMotionVectorPredictor (img, pmv, refframe, LIST_1, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
|
|
|
for (k=0; k < 2; k++)
|
for (k=0; k < 2; k++)
|
{
|
{
|
TRACE_STRING("mvd_l1");
|
TRACE_STRING("mvd_l1");
|
|
|
img->subblock_x = i; // position used for context determination
|
img->subblock_x = i; // position used for context determination
|
img->subblock_y = j; // position used for context determination
|
img->subblock_y = j; // position used for context determination
|
currSE.value2 = (k<<1) +1; // identifies the component; only used for context determination
|
currSE.value2 = (k<<1) +1; // identifies the component; only used for context determination
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
curr_mvd = currSE.value1;
|
curr_mvd = currSE.value1;
|
|
|
vec=curr_mvd+pmv[k]; /* find motion vector */
|
vec=curr_mvd+pmv[k]; /* find motion vector */
|
|
|
for(jj=0;jj<step_v;jj++)
|
for(jj=0;jj<step_v;jj++)
|
{
|
{
|
for(ii=0;ii<step_h;ii++)
|
for(ii=0;ii<step_h;ii++)
|
{
|
{
|
dec_picture->mv [LIST_1][j4+jj][i4+ii][k] = vec;
|
dec_picture->mv [LIST_1][j4+jj][i4+ii][k] = vec;
|
currMB->mvd [LIST_1][j+jj] [i+ii] [k] = curr_mvd;
|
currMB->mvd [LIST_1][j+jj] [i+ii] [k] = curr_mvd;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
// record reference picture Ids for deblocking decisions
|
// record reference picture Ids for deblocking decisions
|
|
|
|
|
for(j4=img->block_y;j4<(img->block_y+4);j4++)
|
for(j4=img->block_y;j4<(img->block_y+4);j4++)
|
{
|
{
|
for(i4=img->block_x;i4<(img->block_x+4);i4++)
|
for(i4=img->block_x;i4<(img->block_x+4);i4++)
|
{
|
{
|
if (dec_picture->ref_idx[LIST_0][j4][i4]>=0)
|
if (dec_picture->ref_idx[LIST_0][j4][i4]>=0)
|
dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]];
|
dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]];
|
else
|
else
|
dec_picture->ref_pic_id[LIST_0][j4][i4] = INT64_MIN;
|
dec_picture->ref_pic_id[LIST_0][j4][i4] = INT64_MIN;
|
if (dec_picture->ref_idx[LIST_1][j4][i4]>=0)
|
if (dec_picture->ref_idx[LIST_1][j4][i4]>=0)
|
dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]];
|
dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]];
|
else
|
else
|
dec_picture->ref_pic_id[LIST_1][j4][i4] = INT64_MIN;
|
dec_picture->ref_pic_id[LIST_1][j4][i4] = INT64_MIN;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
|
* Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
|
*
|
*
|
* Luma Blocks
|
* Luma Blocks
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
int predict_nnz(struct img_par *img, int i,int j)
|
int predict_nnz(struct img_par *img, int i,int j)
|
{
|
{
|
PixelPos pix;
|
PixelPos pix;
|
|
|
int pred_nnz = 0;
|
int pred_nnz = 0;
|
int cnt = 0;
|
int cnt = 0;
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
Macroblock *currMB = &(img->mb_data[mb_nr]);
|
Macroblock *currMB = &(img->mb_data[mb_nr]);
|
|
|
// left block
|
// left block
|
getLuma4x4Neighbour(mb_nr, (i<<2) - 1, (j<<2), &pix);
|
getLuma4x4Neighbour(mb_nr, (i<<2) - 1, (j<<2), &pix);
|
|
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
{
|
{
|
pix.available &= img->intra_block[pix.mb_addr];
|
pix.available &= img->intra_block[pix.mb_addr];
|
if (!pix.available)
|
if (!pix.available)
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
if (pix.available)
|
if (pix.available)
|
{
|
{
|
pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
|
pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
// top block
|
// top block
|
getLuma4x4Neighbour(mb_nr, (i<<2), (j<<2) - 1, &pix);
|
getLuma4x4Neighbour(mb_nr, (i<<2), (j<<2) - 1, &pix);
|
|
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
{
|
{
|
pix.available &= img->intra_block[pix.mb_addr];
|
pix.available &= img->intra_block[pix.mb_addr];
|
if (!pix.available)
|
if (!pix.available)
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
if (pix.available)
|
if (pix.available)
|
{
|
{
|
pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
|
pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][pix.y];
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
if (cnt==2)
|
if (cnt==2)
|
{
|
{
|
pred_nnz++;
|
pred_nnz++;
|
pred_nnz>>=1;
|
pred_nnz>>=1;
|
}
|
}
|
|
|
return pred_nnz;
|
return pred_nnz;
|
}
|
}
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
|
* Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
|
*
|
*
|
* Chroma Blocks
|
* Chroma Blocks
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
int predict_nnz_chroma(struct img_par *img, int i,int j)
|
int predict_nnz_chroma(struct img_par *img, int i,int j)
|
{
|
{
|
PixelPos pix;
|
PixelPos pix;
|
|
|
int pred_nnz = 0;
|
int pred_nnz = 0;
|
int cnt =0;
|
int cnt =0;
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
static const int j_off_tab [12] = {0,0,0,0,4,4,4,4,8,8,8,8};
|
static const int j_off_tab [12] = {0,0,0,0,4,4,4,4,8,8,8,8};
|
int j_off = j_off_tab[j];
|
int j_off = j_off_tab[j];
|
Macroblock *currMB = &(img->mb_data[mb_nr]);
|
Macroblock *currMB = &(img->mb_data[mb_nr]);
|
|
|
if (dec_picture->chroma_format_idc != YUV444)
|
if (dec_picture->chroma_format_idc != YUV444)
|
{
|
{
|
//YUV420 and YUV422
|
//YUV420 and YUV422
|
// left block
|
// left block
|
getChroma4x4Neighbour(mb_nr, ((i&0x01)<<2) - 1, ((j-4)<<2), &pix);
|
getChroma4x4Neighbour(mb_nr, ((i&0x01)<<2) - 1, ((j-4)<<2), &pix);
|
|
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
{
|
{
|
pix.available &= img->intra_block[pix.mb_addr];
|
pix.available &= img->intra_block[pix.mb_addr];
|
if (!pix.available)
|
if (!pix.available)
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
if (pix.available)
|
if (pix.available)
|
{
|
{
|
pred_nnz = img->nz_coeff [pix.mb_addr ][2 * (i>>1) + pix.x][4 + pix.y];
|
pred_nnz = img->nz_coeff [pix.mb_addr ][2 * (i>>1) + pix.x][4 + pix.y];
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
// top block
|
// top block
|
getChroma4x4Neighbour(mb_nr, ((i&0x01)<<2), ((j-4)<<2) - 1, &pix);
|
getChroma4x4Neighbour(mb_nr, ((i&0x01)<<2), ((j-4)<<2) - 1, &pix);
|
|
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
{
|
{
|
pix.available &= img->intra_block[pix.mb_addr];
|
pix.available &= img->intra_block[pix.mb_addr];
|
if (!pix.available)
|
if (!pix.available)
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
if (pix.available)
|
if (pix.available)
|
{
|
{
|
pred_nnz += img->nz_coeff [pix.mb_addr ][2 * (i>>1) + pix.x][4 + pix.y];
|
pred_nnz += img->nz_coeff [pix.mb_addr ][2 * (i>>1) + pix.x][4 + pix.y];
|
cnt++;
|
cnt++;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
//YUV444
|
//YUV444
|
// left block
|
// left block
|
getChroma4x4Neighbour(mb_nr, (i<<2) - 1, ((j-j_off)<<2), &pix);
|
getChroma4x4Neighbour(mb_nr, (i<<2) - 1, ((j-j_off)<<2), &pix);
|
|
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
{
|
{
|
pix.available &= img->intra_block[pix.mb_addr];
|
pix.available &= img->intra_block[pix.mb_addr];
|
cnt--;
|
cnt--;
|
}
|
}
|
|
|
if (pix.available)
|
if (pix.available)
|
{
|
{
|
pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
|
pred_nnz = img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
|
cnt++;
|
cnt++;
|
}
|
}
|
|
|
// top block
|
// top block
|
getChroma4x4Neighbour(mb_nr, (i<<2), ((j-j_off)<<2) -1, &pix);
|
getChroma4x4Neighbour(mb_nr, (i<<2), ((j-j_off)<<2) -1, &pix);
|
|
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
if (IS_INTRA(currMB) && pix.available && active_pps->constrained_intra_pred_flag && (img->currentSlice->dp_mode==PAR_DP_3))
|
{
|
{
|
pix.available &= img->intra_block[pix.mb_addr];
|
pix.available &= img->intra_block[pix.mb_addr];
|
cnt--;
|
cnt--;
|
}
|
}
|
|
|
if (pix.available)
|
if (pix.available)
|
{
|
{
|
pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
|
pred_nnz += img->nz_coeff [pix.mb_addr ][pix.x][j_off + pix.y];
|
cnt++;
|
cnt++;
|
}
|
}
|
}
|
}
|
|
|
if (cnt==2)
|
if (cnt==2)
|
{
|
{
|
pred_nnz++;
|
pred_nnz++;
|
pred_nnz>>=1;
|
pred_nnz>>=1;
|
}
|
}
|
|
|
return pred_nnz;
|
return pred_nnz;
|
}
|
}
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Reads coeff of an 4x4 block (CAVLC)
|
* Reads coeff of an 4x4 block (CAVLC)
|
*
|
*
|
* \author
|
* \author
|
* Karl Lillevold <karll@real.com>
|
* Karl Lillevold <karll@real.com>
|
* contributions by James Au <james@ubvideo.com>
|
* contributions by James Au <james@ubvideo.com>
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
|
|
|
|
void readCoeff4x4_CAVLC (struct img_par *img,struct inp_par *inp,
|
void readCoeff4x4_CAVLC (struct img_par *img,struct inp_par *inp,
|
int block_type,
|
int block_type,
|
int i, int j, int levarr[16], int runarr[16],
|
int i, int j, int levarr[16], int runarr[16],
|
int *number_coefficients)
|
int *number_coefficients)
|
{
|
{
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
Macroblock *currMB = &img->mb_data[mb_nr];
|
Macroblock *currMB = &img->mb_data[mb_nr];
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
Slice *currSlice = img->currentSlice;
|
Slice *currSlice = img->currentSlice;
|
DataPartition *dP;
|
DataPartition *dP;
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
|
|
|
|
int k, code, vlcnum;
|
int k, code, vlcnum;
|
int numcoeff, numtrailingones, numcoeff_vlc;
|
int numcoeff, numtrailingones, numcoeff_vlc;
|
int level_two_or_higher;
|
int level_two_or_higher;
|
int numones, totzeros, level, cdc=0, cac=0;
|
int numones, totzeros, level, cdc=0, cac=0;
|
int zerosleft, ntr, dptype = 0;
|
int zerosleft, ntr, dptype = 0;
|
int max_coeff_num = 0, nnz;
|
int max_coeff_num = 0, nnz;
|
char type[15];
|
char type[15];
|
static int incVlc[] = {0,3,6,12,24,48,32768}; // maximum vlc = 6
|
static int incVlc[] = {0,3,6,12,24,48,32768}; // maximum vlc = 6
|
|
|
numcoeff = 0;
|
numcoeff = 0;
|
|
|
switch (block_type)
|
switch (block_type)
|
{
|
{
|
case LUMA:
|
case LUMA:
|
max_coeff_num = 16;
|
max_coeff_num = 16;
|
#if TRACE
|
#if TRACE
|
sprintf(type, "%s", "Luma");
|
sprintf(type, "%s", "Luma");
|
#endif
|
#endif
|
dptype = IS_INTRA (currMB) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER;
|
dptype = IS_INTRA (currMB) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER;
|
break;
|
break;
|
case LUMA_INTRA16x16DC:
|
case LUMA_INTRA16x16DC:
|
max_coeff_num = 16;
|
max_coeff_num = 16;
|
#if TRACE
|
#if TRACE
|
sprintf(type, "%s", "Lum16DC");
|
sprintf(type, "%s", "Lum16DC");
|
#endif
|
#endif
|
dptype = SE_LUM_DC_INTRA;
|
dptype = SE_LUM_DC_INTRA;
|
break;
|
break;
|
case LUMA_INTRA16x16AC:
|
case LUMA_INTRA16x16AC:
|
max_coeff_num = 15;
|
max_coeff_num = 15;
|
#if TRACE
|
#if TRACE
|
sprintf(type, "%s", "Lum16AC");
|
sprintf(type, "%s", "Lum16AC");
|
#endif
|
#endif
|
dptype = SE_LUM_AC_INTRA;
|
dptype = SE_LUM_AC_INTRA;
|
break;
|
break;
|
|
|
case CHROMA_DC:
|
case CHROMA_DC:
|
max_coeff_num = img->num_cdc_coeff;
|
max_coeff_num = img->num_cdc_coeff;
|
cdc = 1;
|
cdc = 1;
|
#if TRACE
|
#if TRACE
|
sprintf(type, "%s", "ChrDC");
|
sprintf(type, "%s", "ChrDC");
|
#endif
|
#endif
|
dptype = IS_INTRA (currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER;
|
dptype = IS_INTRA (currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER;
|
break;
|
break;
|
case CHROMA_AC:
|
case CHROMA_AC:
|
max_coeff_num = 15;
|
max_coeff_num = 15;
|
cac = 1;
|
cac = 1;
|
#if TRACE
|
#if TRACE
|
sprintf(type, "%s", "ChrAC");
|
sprintf(type, "%s", "ChrAC");
|
#endif
|
#endif
|
dptype = IS_INTRA (currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER;
|
dptype = IS_INTRA (currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER;
|
break;
|
break;
|
default:
|
default:
|
error ("readCoeff4x4_CAVLC: invalid block type", 600);
|
error ("readCoeff4x4_CAVLC: invalid block type", 600);
|
break;
|
break;
|
}
|
}
|
|
|
currSE.type = dptype;
|
currSE.type = dptype;
|
dP = &(currSlice->partArr[partMap[dptype]]);
|
dP = &(currSlice->partArr[partMap[dptype]]);
|
|
|
img->nz_coeff[img->current_mb_nr][i][j] = 0;
|
img->nz_coeff[img->current_mb_nr][i][j] = 0;
|
|
|
|
|
if (!cdc)
|
if (!cdc)
|
{
|
{
|
// luma or chroma AC
|
// luma or chroma AC
|
if (!cac)
|
if (!cac)
|
{
|
{
|
nnz = predict_nnz(img, i, j);
|
nnz = predict_nnz(img, i, j);
|
}
|
}
|
else
|
else
|
{
|
{
|
nnz = predict_nnz_chroma(img, i, j);
|
nnz = predict_nnz_chroma(img, i, j);
|
}
|
}
|
|
|
if (nnz < 2)
|
if (nnz < 2)
|
{
|
{
|
numcoeff_vlc = 0;
|
numcoeff_vlc = 0;
|
}
|
}
|
else if (nnz < 4)
|
else if (nnz < 4)
|
{
|
{
|
numcoeff_vlc = 1;
|
numcoeff_vlc = 1;
|
}
|
}
|
else if (nnz < 8)
|
else if (nnz < 8)
|
{
|
{
|
numcoeff_vlc = 2;
|
numcoeff_vlc = 2;
|
}
|
}
|
else //
|
else //
|
{
|
{
|
numcoeff_vlc = 3;
|
numcoeff_vlc = 3;
|
}
|
}
|
|
|
currSE.value1 = numcoeff_vlc;
|
currSE.value1 = numcoeff_vlc;
|
|
|
readSyntaxElement_NumCoeffTrailingOnes(&currSE, dP, type);
|
readSyntaxElement_NumCoeffTrailingOnes(&currSE, dP, type);
|
|
|
numcoeff = currSE.value1;
|
numcoeff = currSE.value1;
|
numtrailingones = currSE.value2;
|
numtrailingones = currSE.value2;
|
|
|
img->nz_coeff[img->current_mb_nr][i][j] = numcoeff;
|
img->nz_coeff[img->current_mb_nr][i][j] = numcoeff;
|
}
|
}
|
else
|
else
|
{
|
{
|
// chroma DC
|
// chroma DC
|
readSyntaxElement_NumCoeffTrailingOnesChromaDC(&currSE, dP);
|
readSyntaxElement_NumCoeffTrailingOnesChromaDC(&currSE, dP);
|
|
|
numcoeff = currSE.value1;
|
numcoeff = currSE.value1;
|
numtrailingones = currSE.value2;
|
numtrailingones = currSE.value2;
|
}
|
}
|
|
|
|
|
for (k = 0; k < max_coeff_num; k++)
|
for (k = 0; k < max_coeff_num; k++)
|
{
|
{
|
levarr[k] = 0;
|
levarr[k] = 0;
|
runarr[k] = 0;
|
runarr[k] = 0;
|
}
|
}
|
|
|
numones = numtrailingones;
|
numones = numtrailingones;
|
*number_coefficients = numcoeff;
|
*number_coefficients = numcoeff;
|
|
|
if (numcoeff)
|
if (numcoeff)
|
{
|
{
|
if (numtrailingones)
|
if (numtrailingones)
|
{
|
{
|
|
|
currSE.len = numtrailingones;
|
currSE.len = numtrailingones;
|
|
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring,
|
snprintf(currSE.tracestring,
|
TRACESTRING_SIZE, "%s trailing ones sign (%d,%d)", type, i, j);
|
TRACESTRING_SIZE, "%s trailing ones sign (%d,%d)", type, i, j);
|
#endif
|
#endif
|
|
|
readSyntaxElement_FLC (&currSE, dP->bitstream);
|
readSyntaxElement_FLC (&currSE, dP->bitstream);
|
|
|
code = currSE.inf;
|
code = currSE.inf;
|
ntr = numtrailingones;
|
ntr = numtrailingones;
|
for (k = numcoeff-1; k > numcoeff-1-numtrailingones; k--)
|
for (k = numcoeff-1; k > numcoeff-1-numtrailingones; k--)
|
{
|
{
|
ntr --;
|
ntr --;
|
levarr[k] = (code>>ntr)&1 ? -1 : 1;
|
levarr[k] = (code>>ntr)&1 ? -1 : 1;
|
}
|
}
|
}
|
}
|
|
|
// decode levels
|
// decode levels
|
level_two_or_higher = (numcoeff > 3 && numtrailingones == 3)? 0 : 1;
|
level_two_or_higher = (numcoeff > 3 && numtrailingones == 3)? 0 : 1;
|
vlcnum = (numcoeff > 10 && numtrailingones < 3) ? 1 : 0;
|
vlcnum = (numcoeff > 10 && numtrailingones < 3) ? 1 : 0;
|
|
|
for (k = numcoeff - 1 - numtrailingones; k >= 0; k--)
|
for (k = numcoeff - 1 - numtrailingones; k >= 0; k--)
|
{
|
{
|
|
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring,
|
snprintf(currSE.tracestring,
|
TRACESTRING_SIZE, "%s lev (%d,%d) k=%d vlc=%d ", type,
|
TRACESTRING_SIZE, "%s lev (%d,%d) k=%d vlc=%d ", type,
|
i, j, k, vlcnum);
|
i, j, k, vlcnum);
|
#endif
|
#endif
|
|
|
if (vlcnum == 0)
|
if (vlcnum == 0)
|
readSyntaxElement_Level_VLC0(&currSE, dP);
|
readSyntaxElement_Level_VLC0(&currSE, dP);
|
else
|
else
|
readSyntaxElement_Level_VLCN(&currSE, vlcnum, dP);
|
readSyntaxElement_Level_VLCN(&currSE, vlcnum, dP);
|
|
|
if (level_two_or_higher)
|
if (level_two_or_higher)
|
{
|
{
|
currSE.inf += (currSE.inf > 0) ? 1 : -1;
|
currSE.inf += (currSE.inf > 0) ? 1 : -1;
|
level_two_or_higher = 0;
|
level_two_or_higher = 0;
|
}
|
}
|
|
|
level = levarr[k] = currSE.inf;
|
level = levarr[k] = currSE.inf;
|
if (iabs(level) == 1)
|
if (iabs(level) == 1)
|
numones ++;
|
numones ++;
|
|
|
// update VLC table
|
// update VLC table
|
if (iabs(level)>incVlc[vlcnum])
|
if (iabs(level)>incVlc[vlcnum])
|
vlcnum++;
|
vlcnum++;
|
|
|
if (k == numcoeff - 1 - numtrailingones && iabs(level)>3)
|
if (k == numcoeff - 1 - numtrailingones && iabs(level)>3)
|
vlcnum = 2;
|
vlcnum = 2;
|
|
|
}
|
}
|
|
|
if (numcoeff < max_coeff_num)
|
if (numcoeff < max_coeff_num)
|
{
|
{
|
// decode total run
|
// decode total run
|
vlcnum = numcoeff-1;
|
vlcnum = numcoeff-1;
|
currSE.value1 = vlcnum;
|
currSE.value1 = vlcnum;
|
|
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring,
|
snprintf(currSE.tracestring,
|
TRACESTRING_SIZE, "%s totalrun (%d,%d) vlc=%d ", type, i,j, vlcnum);
|
TRACESTRING_SIZE, "%s totalrun (%d,%d) vlc=%d ", type, i,j, vlcnum);
|
#endif
|
#endif
|
if (cdc)
|
if (cdc)
|
readSyntaxElement_TotalZerosChromaDC(&currSE, dP);
|
readSyntaxElement_TotalZerosChromaDC(&currSE, dP);
|
else
|
else
|
readSyntaxElement_TotalZeros(&currSE, dP);
|
readSyntaxElement_TotalZeros(&currSE, dP);
|
|
|
totzeros = currSE.value1;
|
totzeros = currSE.value1;
|
}
|
}
|
else
|
else
|
{
|
{
|
totzeros = 0;
|
totzeros = 0;
|
}
|
}
|
|
|
// decode run before each coefficient
|
// decode run before each coefficient
|
zerosleft = totzeros;
|
zerosleft = totzeros;
|
i = numcoeff - 1;
|
i = numcoeff - 1;
|
if (zerosleft > 0 && i > 0)
|
if (zerosleft > 0 && i > 0)
|
{
|
{
|
do
|
do
|
{
|
{
|
// select VLC for runbefore
|
// select VLC for runbefore
|
vlcnum = zerosleft - 1;
|
vlcnum = zerosleft - 1;
|
if (vlcnum > RUNBEFORE_NUM - 1)
|
if (vlcnum > RUNBEFORE_NUM - 1)
|
vlcnum = RUNBEFORE_NUM - 1;
|
vlcnum = RUNBEFORE_NUM - 1;
|
|
|
currSE.value1 = vlcnum;
|
currSE.value1 = vlcnum;
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring,
|
snprintf(currSE.tracestring,
|
TRACESTRING_SIZE, "%s run (%d,%d) k=%d vlc=%d ",
|
TRACESTRING_SIZE, "%s run (%d,%d) k=%d vlc=%d ",
|
type, i, j, i, vlcnum);
|
type, i, j, i, vlcnum);
|
#endif
|
#endif
|
|
|
readSyntaxElement_Run(&currSE, dP);
|
readSyntaxElement_Run(&currSE, dP);
|
runarr[i] = currSE.value1;
|
runarr[i] = currSE.value1;
|
|
|
zerosleft -= runarr[i];
|
zerosleft -= runarr[i];
|
i --;
|
i --;
|
} while (zerosleft != 0 && i != 0);
|
} while (zerosleft != 0 && i != 0);
|
}
|
}
|
runarr[i] = zerosleft;
|
runarr[i] = zerosleft;
|
|
|
} // if numcoeff
|
} // if numcoeff
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Calculate the quantisation and inverse quantisation parameters
|
* Calculate the quantisation and inverse quantisation parameters
|
*
|
*
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void CalculateQuant8Param()
|
void CalculateQuant8Param()
|
{
|
{
|
int i, j, k, temp;
|
int i, j, k, temp;
|
|
|
for(k=0; k<6; k++)
|
for(k=0; k<6; k++)
|
for(j=0; j<8; j++)
|
for(j=0; j<8; j++)
|
{
|
{
|
for(i=0; i<8; i++)
|
for(i=0; i<8; i++)
|
{
|
{
|
temp = (i<<3)+j;
|
temp = (i<<3)+j;
|
InvLevelScale8x8Luma_Intra[k][i][j] = dequant_coef8[k][j][i]*qmatrix[6][temp];
|
InvLevelScale8x8Luma_Intra[k][i][j] = dequant_coef8[k][j][i]*qmatrix[6][temp];
|
InvLevelScale8x8Luma_Inter[k][i][j] = dequant_coef8[k][j][i]*qmatrix[7][temp];
|
InvLevelScale8x8Luma_Inter[k][i][j] = dequant_coef8[k][j][i]*qmatrix[7][temp];
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Get coefficients (run/level) of one 8x8 block
|
* Get coefficients (run/level) of one 8x8 block
|
* from the NAL (CABAC Mode)
|
* from the NAL (CABAC Mode)
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void readLumaCoeff8x8_CABAC (struct img_par *img,struct inp_par *inp, int b8)
|
void readLumaCoeff8x8_CABAC (struct img_par *img,struct inp_par *inp, int b8)
|
{
|
{
|
int i,j,k;
|
int i,j,k;
|
int level = 1;
|
int level = 1;
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
Macroblock *currMB = &img->mb_data[mb_nr];
|
Macroblock *currMB = &img->mb_data[mb_nr];
|
int cbp = currMB->cbp;
|
int cbp = currMB->cbp;
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
Slice *currSlice = img->currentSlice;
|
Slice *currSlice = img->currentSlice;
|
DataPartition *dP;
|
DataPartition *dP;
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int start_scan = 0; // take all coeffs
|
int start_scan = 0; // take all coeffs
|
int coef_ctr = start_scan - 1;// i0, j0;
|
int coef_ctr = start_scan - 1;// i0, j0;
|
int boff_x, boff_y;
|
int boff_x, boff_y;
|
|
|
int run, len;
|
int run, len;
|
|
|
int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
|
int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
|
int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
|
int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
|
Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
|
Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
|
int (*InvLevelScale8x8)[8] = IS_INTRA(currMB)? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem];
|
int (*InvLevelScale8x8)[8] = IS_INTRA(currMB)? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem];
|
// select scan type
|
// select scan type
|
const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8;
|
const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8;
|
|
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_intra_block = IS_INTRA(currMB);
|
|
|
if (cbp & (1<<b8)) // are there any coeff in current block at all
|
if (cbp & (1<<b8)) // are there any coeff in current block at all
|
{
|
{
|
// === set offset in current macroblock ===
|
// === set offset in current macroblock ===
|
boff_x = (b8&0x01) << 3;
|
boff_x = (b8&0x01) << 3;
|
boff_y = (b8 >> 1) << 3;
|
boff_y = (b8 >> 1) << 3;
|
|
|
img->subblock_x = boff_x >> 2; // position for coeff_count ctx
|
img->subblock_x = boff_x >> 2; // position for coeff_count ctx
|
img->subblock_y = boff_y >> 2; // position for coeff_count ctx
|
img->subblock_y = boff_y >> 2; // position for coeff_count ctx
|
|
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
{
|
{
|
for(k=start_scan;(k < 65) && (level != 0);k++)
|
for(k=start_scan;(k < 65) && (level != 0);k++)
|
{
|
{
|
//============ read =============
|
//============ read =============
|
/*
|
/*
|
* make distinction between INTRA and INTER coded
|
* make distinction between INTRA and INTER coded
|
* luminance coefficients
|
* luminance coefficients
|
*/
|
*/
|
currSE.context = LUMA_8x8;
|
currSE.context = LUMA_8x8;
|
currSE.type = ((img->is_intra_block == 1)
|
currSE.type = ((img->is_intra_block == 1)
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
|
|
#if TRACE
|
#if TRACE
|
sprintf(currSE.tracestring, "Luma8x8 sng ");
|
sprintf(currSE.tracestring, "Luma8x8 sng ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
//============ decode =============
|
//============ decode =============
|
if (level != 0) /* leave if len=1 */
|
if (level != 0) /* leave if len=1 */
|
{
|
{
|
coef_ctr += run + 1;
|
coef_ctr += run + 1;
|
|
|
i=pos_scan8x8[coef_ctr][0];
|
i=pos_scan8x8[coef_ctr][0];
|
j=pos_scan8x8[coef_ctr][1];
|
j=pos_scan8x8[coef_ctr][1];
|
|
|
currMB->cbp_blk |= 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
|
currMB->cbp_blk |= 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
|
img->m7[boff_y + j][boff_x + i] = rshift_rnd_sf((level * InvLevelScale8x8[j][i]) << qp_per, 6); // dequantization
|
img->m7[boff_y + j][boff_x + i] = rshift_rnd_sf((level * InvLevelScale8x8[j][i]) << qp_per, 6); // dequantization
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for(k=start_scan;(k < 65) && (level != 0);k++)
|
for(k=start_scan;(k < 65) && (level != 0);k++)
|
{
|
{
|
//============ read =============
|
//============ read =============
|
/*
|
/*
|
* make distinction between INTRA and INTER coded
|
* make distinction between INTRA and INTER coded
|
* luminance coefficients
|
* luminance coefficients
|
*/
|
*/
|
currSE.context = LUMA_8x8;
|
currSE.context = LUMA_8x8;
|
currSE.type = ((img->is_intra_block == 1)
|
currSE.type = ((img->is_intra_block == 1)
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
|
|
#if TRACE
|
#if TRACE
|
sprintf(currSE.tracestring, "Luma8x8 sng ");
|
sprintf(currSE.tracestring, "Luma8x8 sng ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
//============ decode =============
|
//============ decode =============
|
if (level != 0) /* leave if len=1 */
|
if (level != 0) /* leave if len=1 */
|
{
|
{
|
coef_ctr += run+1;
|
coef_ctr += run+1;
|
|
|
i=pos_scan8x8[coef_ctr][0];
|
i=pos_scan8x8[coef_ctr][0];
|
j=pos_scan8x8[coef_ctr][1];
|
j=pos_scan8x8[coef_ctr][1];
|
|
|
currMB->cbp_blk |= 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
|
currMB->cbp_blk |= 51 << (4 * b8 - 2 * (b8 & 0x01)); // corresponds to 110011, as if all four 4x4 blocks contain coeff, shifted to block position
|
img->m7[boff_y + j][boff_x + i] = level;
|
img->m7[boff_y + j][boff_x + i] = level;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Get coded block pattern and coefficients (run/level)
|
* Get coded block pattern and coefficients (run/level)
|
* from the NAL
|
* from the NAL
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp)
|
void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp)
|
{
|
{
|
int i,j,k;
|
int i,j,k;
|
int level;
|
int level;
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
int ii,jj;
|
int ii,jj;
|
int m2,jg2;// i1,j1;
|
int m2,jg2;// i1,j1;
|
Macroblock *currMB = &img->mb_data[mb_nr];
|
Macroblock *currMB = &img->mb_data[mb_nr];
|
int cbp;
|
int cbp;
|
SyntaxElement currSE;
|
SyntaxElement currSE;
|
Slice *currSlice = img->currentSlice;
|
Slice *currSlice = img->currentSlice;
|
DataPartition *dP;
|
DataPartition *dP;
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int *partMap = assignSE2partition[currSlice->dp_mode];
|
int coef_ctr, i0, j0, b8;
|
int coef_ctr, i0, j0, b8;
|
int ll;
|
int ll;
|
int block_x,block_y;
|
int block_x,block_y;
|
int start_scan;
|
int start_scan;
|
int run, len;
|
int run, len;
|
int levarr[16], runarr[16], numcoeff;
|
int levarr[16], runarr[16], numcoeff;
|
|
|
int qp_const;
|
int qp_const;
|
int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
|
int qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
|
int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
|
int qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
|
int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB);
|
int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB);
|
|
|
int uv;
|
int uv;
|
int qp_const_uv[2];
|
int qp_const_uv[2];
|
int qp_per_uv[2];
|
int qp_per_uv[2];
|
int qp_rem_uv[2];
|
int qp_rem_uv[2];
|
|
|
int intra = IS_INTRA (currMB);
|
int intra = IS_INTRA (currMB);
|
int temp[4];
|
int temp[4];
|
|
|
int b4;
|
int b4;
|
int yuv = dec_picture->chroma_format_idc-1;
|
int yuv = dec_picture->chroma_format_idc-1;
|
int m5[4];
|
int m5[4];
|
int m6[4];
|
int m6[4];
|
|
|
int need_transform_size_flag;
|
int need_transform_size_flag;
|
Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
|
Boolean lossless_qpprime = (Boolean) ((img->qp + img->bitdepth_luma_qp_scale)==0 && img->lossless_qpprime_flag==1);
|
|
|
int (*InvLevelScale4x4)[4] = NULL;
|
int (*InvLevelScale4x4)[4] = NULL;
|
int (*InvLevelScale8x8)[8] = NULL;
|
int (*InvLevelScale8x8)[8] = NULL;
|
// select scan type
|
// select scan type
|
const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8;
|
const byte (*pos_scan8x8)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN8x8 : FIELD_SCAN8x8;
|
const byte (*pos_scan4x4)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN : FIELD_SCAN;
|
const byte (*pos_scan4x4)[2] = ((img->structure == FRAME) && (!currMB->mb_field)) ? SNGL_SCAN : FIELD_SCAN;
|
|
|
if(img->type==SP_SLICE && currMB->mb_type!=I16MB )
|
if(img->type==SP_SLICE && currMB->mb_type!=I16MB )
|
smb=1;
|
smb=1;
|
|
|
// QPI
|
// QPI
|
//init constants for every chroma qp offset
|
//init constants for every chroma qp offset
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
for (i=0; i<2; i++)
|
for (i=0; i<2; i++)
|
{
|
{
|
qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6;
|
qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6;
|
qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6;
|
qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6;
|
}
|
}
|
}
|
}
|
|
|
// read CBP if not new intra mode
|
// read CBP if not new intra mode
|
if (!IS_NEWINTRA (currMB))
|
if (!IS_NEWINTRA (currMB))
|
{
|
{
|
//===== C B P =====
|
//===== C B P =====
|
//---------------------
|
//---------------------
|
currSE.type = (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
|
currSE.type = (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
|
? SE_CBP_INTRA
|
? SE_CBP_INTRA
|
: SE_CBP_INTER;
|
: SE_CBP_INTER;
|
|
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.mapping = (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
|
currSE.mapping = (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
|
? linfo_cbp_intra
|
? linfo_cbp_intra
|
: linfo_cbp_inter;
|
: linfo_cbp_inter;
|
}
|
}
|
else
|
else
|
{
|
{
|
currSE.reading = readCBP_CABAC;
|
currSE.reading = readCBP_CABAC;
|
}
|
}
|
|
|
TRACE_STRING("coded_block_pattern");
|
TRACE_STRING("coded_block_pattern");
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
currMB->cbp = cbp = currSE.value1;
|
currMB->cbp = cbp = currSE.value1;
|
|
|
|
|
//============= Transform size flag for INTER MBs =============
|
//============= Transform size flag for INTER MBs =============
|
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
need_transform_size_flag = (((currMB->mb_type >= 1 && currMB->mb_type <= 3)||
|
need_transform_size_flag = (((currMB->mb_type >= 1 && currMB->mb_type <= 3)||
|
(IS_DIRECT(currMB) && active_sps->direct_8x8_inference_flag) ||
|
(IS_DIRECT(currMB) && active_sps->direct_8x8_inference_flag) ||
|
(currMB->NoMbPartLessThan8x8Flag))
|
(currMB->NoMbPartLessThan8x8Flag))
|
&& currMB->mb_type != I8MB && currMB->mb_type != I4MB
|
&& currMB->mb_type != I8MB && currMB->mb_type != I4MB
|
&& (currMB->cbp&15)
|
&& (currMB->cbp&15)
|
&& img->Transform8x8Mode);
|
&& img->Transform8x8Mode);
|
|
|
if (need_transform_size_flag)
|
if (need_transform_size_flag)
|
{
|
{
|
currSE.type = SE_HEADER;
|
currSE.type = SE_HEADER;
|
dP = &(currSlice->partArr[partMap[SE_HEADER]]);
|
dP = &(currSlice->partArr[partMap[SE_HEADER]]);
|
currSE.reading = readMB_transform_size_flag_CABAC;
|
currSE.reading = readMB_transform_size_flag_CABAC;
|
TRACE_STRING("transform_size_8x8_flag");
|
TRACE_STRING("transform_size_8x8_flag");
|
|
|
// read UVLC transform_size_8x8_flag
|
// read UVLC transform_size_8x8_flag
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.len = 1;
|
currSE.len = 1;
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
readSyntaxElement_FLC(&currSE, dP->bitstream);
|
}
|
}
|
else
|
else
|
{
|
{
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
}
|
}
|
currMB->luma_transform_size_8x8_flag = currSE.value1;
|
currMB->luma_transform_size_8x8_flag = currSE.value1;
|
}
|
}
|
|
|
//===== DQUANT =====
|
//===== DQUANT =====
|
//----------------------
|
//----------------------
|
// Delta quant only if nonzero coeffs
|
// Delta quant only if nonzero coeffs
|
if (cbp !=0)
|
if (cbp !=0)
|
{
|
{
|
currSE.type = (IS_INTER (currMB)) ? SE_DELTA_QUANT_INTER : SE_DELTA_QUANT_INTRA;
|
currSE.type = (IS_INTER (currMB)) ? SE_DELTA_QUANT_INTER : SE_DELTA_QUANT_INTRA;
|
|
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.mapping = linfo_se;
|
currSE.mapping = linfo_se;
|
}
|
}
|
else
|
else
|
currSE.reading= readDquant_CABAC; //gabi
|
currSE.reading= readDquant_CABAC; //gabi
|
|
|
TRACE_STRING("mb_qp_delta");
|
TRACE_STRING("mb_qp_delta");
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
currMB->delta_quant = currSE.value1;
|
currMB->delta_quant = currSE.value1;
|
if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
|
if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
|
error ("mb_qp_delta is out of range", 500);
|
error ("mb_qp_delta is out of range", 500);
|
|
|
img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
|
img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
|
img->bitdepth_luma_qp_scale;
|
img->bitdepth_luma_qp_scale;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
cbp = currMB->cbp;
|
cbp = currMB->cbp;
|
}
|
}
|
|
|
for (i=0;i<BLOCK_SIZE;i++)
|
for (i=0;i<BLOCK_SIZE;i++)
|
for (j=0;j<BLOCK_SIZE;j++)
|
for (j=0;j<BLOCK_SIZE;j++)
|
memset(&img->cof[i][j][0][0], 0, BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); // reset luma coeffs
|
memset(&img->cof[i][j][0][0], 0, BLOCK_SIZE * BLOCK_SIZE * sizeof(int)); // reset luma coeffs
|
|
|
|
|
if (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes
|
if (IS_NEWINTRA (currMB)) // read DC coeffs for new intra modes
|
{
|
{
|
currSE.type = SE_DELTA_QUANT_INTRA;
|
currSE.type = SE_DELTA_QUANT_INTRA;
|
|
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.mapping = linfo_se;
|
currSE.mapping = linfo_se;
|
}
|
}
|
else
|
else
|
{
|
{
|
currSE.reading= readDquant_CABAC;
|
currSE.reading= readDquant_CABAC;
|
}
|
}
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "Delta quant ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "Delta quant ");
|
#endif
|
#endif
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
currMB->delta_quant = currSE.value1;
|
currMB->delta_quant = currSE.value1;
|
if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
|
if ((currMB->delta_quant < -(26 + img->bitdepth_luma_qp_scale/2)) || (currMB->delta_quant > (25 + img->bitdepth_luma_qp_scale/2)))
|
error ("mb_qp_delta is out of range", 500);
|
error ("mb_qp_delta is out of range", 500);
|
|
|
img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
|
img->qp= ((img->qp + currMB->delta_quant + 52 + 2*img->bitdepth_luma_qp_scale)%(52+img->bitdepth_luma_qp_scale)) -
|
img->bitdepth_luma_qp_scale;
|
img->bitdepth_luma_qp_scale;
|
|
|
for (i=0;i<BLOCK_SIZE;i++)
|
for (i=0;i<BLOCK_SIZE;i++)
|
for (j=0;j<BLOCK_SIZE;j++)
|
for (j=0;j<BLOCK_SIZE;j++)
|
img->ipredmode[img->block_y+j][img->block_x+i]=DC_PRED;
|
img->ipredmode[img->block_y+j][img->block_x+i]=DC_PRED;
|
|
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
{
|
{
|
readCoeff4x4_CAVLC(img, inp, LUMA_INTRA16x16DC, 0, 0,
|
readCoeff4x4_CAVLC(img, inp, LUMA_INTRA16x16DC, 0, 0,
|
levarr, runarr, &numcoeff);
|
levarr, runarr, &numcoeff);
|
|
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level = 1; // just to get inside the loop
|
level = 1; // just to get inside the loop
|
for(k = 0; k < numcoeff; k++)
|
for(k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0) // leave if len=1
|
if (levarr[k] != 0) // leave if len=1
|
{
|
{
|
coef_ctr=coef_ctr+runarr[k]+1;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
img->cof[i0][j0][0][0]=levarr[k];// add new intra DC coeff
|
img->cof[i0][j0][0][0]=levarr[k];// add new intra DC coeff
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
|
|
currSE.type = SE_LUM_DC_INTRA;
|
currSE.type = SE_LUM_DC_INTRA;
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
currSE.context = LUMA_16DC;
|
currSE.context = LUMA_16DC;
|
currSE.type = SE_LUM_DC_INTRA;
|
currSE.type = SE_LUM_DC_INTRA;
|
img->is_intra_block = 1;
|
img->is_intra_block = 1;
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
{
|
{
|
currSE.mapping = linfo_levrun_inter;
|
currSE.mapping = linfo_levrun_inter;
|
}
|
}
|
else
|
else
|
{
|
{
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
}
|
}
|
|
|
coef_ctr = -1;
|
coef_ctr = -1;
|
level = 1; // just to get inside the loop
|
level = 1; // just to get inside the loop
|
|
|
for(k=0;(k<17) && (level!=0);k++)
|
for(k=0;(k<17) && (level!=0);k++)
|
{
|
{
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC luma 16x16 ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC luma 16x16 ");
|
#endif
|
#endif
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
if (level != 0) // leave if len=1
|
if (level != 0) // leave if len=1
|
{
|
{
|
coef_ctr=coef_ctr+run+1;
|
coef_ctr=coef_ctr+run+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
img->cof[i0][j0][0][0]=level;// add new intra DC coeff
|
img->cof[i0][j0][0][0]=level;// add new intra DC coeff
|
}
|
}
|
}
|
}
|
}
|
}
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
itrans_2(img);// transform new intra DC
|
itrans_2(img);// transform new intra DC
|
}
|
}
|
|
|
currMB->qp = img->qp;
|
currMB->qp = img->qp;
|
|
|
set_chroma_qp(currMB);
|
set_chroma_qp(currMB);
|
|
|
qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
|
qp_per = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)/6;
|
qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
|
qp_rem = (img->qp + img->bitdepth_luma_qp_scale - MIN_QP)%6;
|
qp_const = 1<<(3-qp_per);
|
qp_const = 1<<(3-qp_per);
|
|
|
InvLevelScale4x4 = intra? InvLevelScale4x4Luma_Intra[qp_rem] : InvLevelScale4x4Luma_Inter[qp_rem];
|
InvLevelScale4x4 = intra? InvLevelScale4x4Luma_Intra[qp_rem] : InvLevelScale4x4Luma_Inter[qp_rem];
|
InvLevelScale8x8 = intra? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem];
|
InvLevelScale8x8 = intra? InvLevelScale8x8Luma_Intra[qp_rem] : InvLevelScale8x8Luma_Inter[qp_rem];
|
|
|
//init constants for every chroma qp offset
|
//init constants for every chroma qp offset
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
for(i=0; i < 2; i++)
|
for(i=0; i < 2; i++)
|
{
|
{
|
qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6;
|
qp_per_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)/6;
|
qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6;
|
qp_rem_uv[i] = (currMB->qpc[i] + img->bitdepth_chroma_qp_scale)%6;
|
}
|
}
|
}
|
}
|
|
|
|
|
// luma coefficients
|
// luma coefficients
|
for (block_y=0; block_y < 4; block_y += 2) /* all modes */
|
for (block_y=0; block_y < 4; block_y += 2) /* all modes */
|
{
|
{
|
for (block_x=0; block_x < 4; block_x += 2)
|
for (block_x=0; block_x < 4; block_x += 2)
|
{
|
{
|
|
|
b8 = 2*(block_y>>1) + (block_x>>1);
|
b8 = 2*(block_y>>1) + (block_x>>1);
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
{
|
{
|
for (j=block_y; j < block_y+2; j++)
|
for (j=block_y; j < block_y+2; j++)
|
{
|
{
|
for (i=block_x; i < block_x+2; i++)
|
for (i=block_x; i < block_x+2; i++)
|
{
|
{
|
ii = block_x >> 1;
|
ii = block_x >> 1;
|
jj = block_y >> 1;
|
jj = block_y >> 1;
|
b8 = 2 * jj + ii;
|
b8 = 2 * jj + ii;
|
|
|
if (cbp & (1<<b8)) /* are there any coeff in current block at all */
|
if (cbp & (1<<b8)) /* are there any coeff in current block at all */
|
{
|
{
|
readCoeff4x4_CAVLC(img, inp, (IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA), i, j, levarr, runarr, &numcoeff);
|
readCoeff4x4_CAVLC(img, inp, (IS_NEWINTRA(currMB) ? LUMA_INTRA16x16AC : LUMA), i, j, levarr, runarr, &numcoeff);
|
|
|
start_scan = IS_NEWINTRA(currMB) ? 1 : 0;
|
start_scan = IS_NEWINTRA(currMB) ? 1 : 0;
|
coef_ctr = start_scan - 1;
|
coef_ctr = start_scan - 1;
|
|
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
{
|
{
|
if (!currMB->luma_transform_size_8x8_flag) // 4x4 transform
|
if (!currMB->luma_transform_size_8x8_flag) // 4x4 transform
|
{
|
{
|
for (k = 0; k < numcoeff; k++)
|
for (k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
coef_ctr += runarr[k]+1;
|
coef_ctr += runarr[k]+1;
|
|
|
i0 = pos_scan4x4[coef_ctr][0];
|
i0 = pos_scan4x4[coef_ctr][0];
|
j0 = pos_scan4x4[coef_ctr][1];
|
j0 = pos_scan4x4[coef_ctr][1];
|
|
|
// inverse quant for 4x4 transform only
|
// inverse quant for 4x4 transform only
|
currMB->cbp_blk |= (int64) 1 << ((j<<2) + i);
|
currMB->cbp_blk |= (int64) 1 << ((j<<2) + i);
|
img->cof[i][j][j0][i0]= rshift_rnd_sf((levarr[k]*InvLevelScale4x4[j0][i0])<<qp_per, 4);
|
img->cof[i][j][j0][i0]= rshift_rnd_sf((levarr[k]*InvLevelScale4x4[j0][i0])<<qp_per, 4);
|
}
|
}
|
}
|
}
|
}
|
}
|
else // 8x8 transform
|
else // 8x8 transform
|
{
|
{
|
int b4, iz, jz;
|
int b4, iz, jz;
|
for (k = 0; k < numcoeff; k++)
|
for (k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
coef_ctr += runarr[k]+1;
|
coef_ctr += runarr[k]+1;
|
|
|
// do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s
|
// do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s
|
//as containing coefficients
|
//as containing coefficients
|
currMB->cbp_blk |= 51 << ((block_y<<2) + block_x);
|
currMB->cbp_blk |= 51 << ((block_y<<2) + block_x);
|
|
|
b4 = 2*(j - block_y)+(i - block_x);
|
b4 = 2*(j - block_y)+(i - block_x);
|
|
|
iz = pos_scan8x8[(coef_ctr << 2) + b4][0];
|
iz = pos_scan8x8[(coef_ctr << 2) + b4][0];
|
jz = pos_scan8x8[(coef_ctr << 2) + b4][1];
|
jz = pos_scan8x8[(coef_ctr << 2) + b4][1];
|
|
|
img->m7[block_y*4 +jz][block_x*4 +iz] = rshift_rnd_sf((levarr[k]*InvLevelScale8x8[jz][iz])<<qp_per, 6); // dequantization
|
img->m7[block_y*4 +jz][block_x*4 +iz] = rshift_rnd_sf((levarr[k]*InvLevelScale8x8[jz][iz])<<qp_per, 6); // dequantization
|
}
|
}
|
}//else (!currMB->luma_transform_size_8x8_flag)
|
}//else (!currMB->luma_transform_size_8x8_flag)
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (!currMB->luma_transform_size_8x8_flag) // inverse quant for 4x4 transform
|
if (!currMB->luma_transform_size_8x8_flag) // inverse quant for 4x4 transform
|
{
|
{
|
for (k = 0; k < numcoeff; k++)
|
for (k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
coef_ctr += runarr[k]+1;
|
coef_ctr += runarr[k]+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
currMB->cbp_blk |= (int64) 1 << ((j<<2) + i);
|
currMB->cbp_blk |= (int64) 1 << ((j<<2) + i);
|
img->cof[i][j][j0][i0]= levarr[k];
|
img->cof[i][j][j0][i0]= levarr[k];
|
}
|
}
|
}
|
}
|
}
|
}
|
else // inverse quant for 8x8 transform
|
else // inverse quant for 8x8 transform
|
{
|
{
|
int b4, iz, jz;
|
int b4, iz, jz;
|
for (k = 0; k < numcoeff; k++)
|
for (k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
coef_ctr += runarr[k]+1;
|
coef_ctr += runarr[k]+1;
|
|
|
// do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s
|
// do same as CABAC for deblocking: any coeff in the 8x8 marks all the 4x4s
|
//as containing coefficients
|
//as containing coefficients
|
currMB->cbp_blk |= 51 << ((block_y<<2) + block_x);
|
currMB->cbp_blk |= 51 << ((block_y<<2) + block_x);
|
|
|
b4 = 2*(j-block_y)+(i-block_x);
|
b4 = 2*(j-block_y)+(i-block_x);
|
|
|
iz=pos_scan8x8[coef_ctr*4+b4][0];
|
iz=pos_scan8x8[coef_ctr*4+b4][0];
|
jz=pos_scan8x8[coef_ctr*4+b4][1];
|
jz=pos_scan8x8[coef_ctr*4+b4][1];
|
|
|
img->m7[block_y*4 +jz][block_x*4 +iz] = levarr[k];
|
img->m7[block_y*4 +jz][block_x*4 +iz] = levarr[k];
|
}
|
}
|
}
|
}
|
}//else (!currMB->luma_transform_size_8x8_flag)
|
}//else (!currMB->luma_transform_size_8x8_flag)
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
img->nz_coeff[img->current_mb_nr][i][j] = 0;
|
img->nz_coeff[img->current_mb_nr][i][j] = 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
} // VLC
|
} // VLC
|
else
|
else
|
{
|
{
|
if(currMB->luma_transform_size_8x8_flag)
|
if(currMB->luma_transform_size_8x8_flag)
|
readLumaCoeff8x8_CABAC(img, inp, b8); //======= 8x8 trannsform size & CABAC ========
|
readLumaCoeff8x8_CABAC(img, inp, b8); //======= 8x8 trannsform size & CABAC ========
|
else
|
else
|
{
|
{
|
//======= Other Modes & CABAC ========
|
//======= Other Modes & CABAC ========
|
//------------------------------------
|
//------------------------------------
|
for (j=block_y; j < block_y+2; j++)
|
for (j=block_y; j < block_y+2; j++)
|
{
|
{
|
for (i=block_x; i < block_x+2; i++)
|
for (i=block_x; i < block_x+2; i++)
|
{
|
{
|
start_scan = IS_NEWINTRA (currMB)? 1 : 0;
|
start_scan = IS_NEWINTRA (currMB)? 1 : 0;
|
|
|
img->subblock_x = i; // position for coeff_count ctx
|
img->subblock_x = i; // position for coeff_count ctx
|
img->subblock_y = j; // position for coeff_count ctx
|
img->subblock_y = j; // position for coeff_count ctx
|
|
|
if (cbp & (1<<b8)) // are there any coeff in current block at all
|
if (cbp & (1<<b8)) // are there any coeff in current block at all
|
{
|
{
|
coef_ctr = start_scan - 1;
|
coef_ctr = start_scan - 1;
|
level = 1;
|
level = 1;
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_intra_block = IS_INTRA(currMB);
|
|
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
{
|
{
|
for(k=start_scan;(k<17) && (level!=0);k++)
|
for(k=start_scan;(k<17) && (level!=0);k++)
|
{
|
{
|
/*
|
/*
|
* make distinction between INTRA and INTER coded
|
* make distinction between INTRA and INTER coded
|
* luminance coefficients
|
* luminance coefficients
|
*/
|
*/
|
currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4);
|
currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4);
|
currSE.type = (img->is_intra_block
|
currSE.type = (img->is_intra_block
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
|
|
#if TRACE
|
#if TRACE
|
sprintf(currSE.tracestring, "Luma sng ");
|
sprintf(currSE.tracestring, "Luma sng ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_inter;
|
currSE.mapping = linfo_levrun_inter;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
if (level != 0) /* leave if len=1 */
|
if (level != 0) /* leave if len=1 */
|
{
|
{
|
coef_ctr += run+1;
|
coef_ctr += run+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ;
|
currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ;
|
img->cof[i][j][j0][i0]= rshift_rnd_sf((level*InvLevelScale4x4[j0][i0]) << qp_per, 4);
|
img->cof[i][j][j0][i0]= rshift_rnd_sf((level*InvLevelScale4x4[j0][i0]) << qp_per, 4);
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for(k=start_scan;(k<17) && (level!=0);k++)
|
for(k=start_scan;(k<17) && (level!=0);k++)
|
{
|
{
|
/*
|
/*
|
* make distinction between INTRA and INTER coded
|
* make distinction between INTRA and INTER coded
|
* luminance coefficients
|
* luminance coefficients
|
*/
|
*/
|
currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4);
|
currSE.context = (IS_NEWINTRA(currMB) ? LUMA_16AC : LUMA_4x4);
|
currSE.type = (img->is_intra_block
|
currSE.type = (img->is_intra_block
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
? (k==0 ? SE_LUM_DC_INTRA : SE_LUM_AC_INTRA)
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
: (k==0 ? SE_LUM_DC_INTER : SE_LUM_AC_INTER));
|
|
|
#if TRACE
|
#if TRACE
|
sprintf(currSE.tracestring, "Luma sng ");
|
sprintf(currSE.tracestring, "Luma sng ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_inter;
|
currSE.mapping = linfo_levrun_inter;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
if (level != 0) /* leave if len=1 */
|
if (level != 0) /* leave if len=1 */
|
{
|
{
|
coef_ctr += run+1;
|
coef_ctr += run+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ;
|
currMB->cbp_blk |= (int64)1 << ((j<<2) + i) ;
|
|
|
img->cof[i][j][j0][i0]= level;
|
img->cof[i][j][j0][i0]= level;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
|
|
for (j=4;j<(4+img->num_blk8x8_uv);j++) // reset all chroma coeffs before read
|
for (j=4;j<(4+img->num_blk8x8_uv);j++) // reset all chroma coeffs before read
|
for (i=0;i<4;i++)
|
for (i=0;i<4;i++)
|
memset(&img->cof[i][j][0][0], 0, 16 * sizeof(int));
|
memset(&img->cof[i][j][0][0], 0, 16 * sizeof(int));
|
|
|
m2 = img->mb_x * 2;
|
m2 = img->mb_x * 2;
|
jg2 = img->mb_y * 2;
|
jg2 = img->mb_y * 2;
|
|
|
qp_const_uv[0] = 1<<(3-qp_per_uv[0]);
|
qp_const_uv[0] = 1<<(3-qp_per_uv[0]);
|
qp_const_uv[1] = 1<<(3-qp_per_uv[1]);
|
qp_const_uv[1] = 1<<(3-qp_per_uv[1]);
|
|
|
|
|
//========================== CHROMA DC ============================
|
//========================== CHROMA DC ============================
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// chroma DC coeff
|
// chroma DC coeff
|
if(cbp>15)
|
if(cbp>15)
|
{
|
{
|
for (ll=0;ll<3;ll+=2)
|
for (ll=0;ll<3;ll+=2)
|
{
|
{
|
uv = ll>>1;
|
uv = ll>>1;
|
|
|
if (dec_picture->chroma_format_idc == YUV420)
|
if (dec_picture->chroma_format_idc == YUV420)
|
{
|
{
|
int (*InvLevelScale4x4Chroma)[4] = intra
|
int (*InvLevelScale4x4Chroma)[4] = intra
|
? InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]]
|
? InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]]
|
: InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]];
|
: InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]];
|
|
|
//===================== CHROMA DC YUV420 ======================
|
//===================== CHROMA DC YUV420 ======================
|
memset(&img->cofu[0], 0, 4 *sizeof(int));
|
memset(&img->cofu[0], 0, 4 *sizeof(int));
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
{
|
{
|
readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
|
readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
|
levarr, runarr, &numcoeff);
|
levarr, runarr, &numcoeff);
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level=1;
|
level=1;
|
for(k = 0; k < numcoeff; k++)
|
for(k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
|
currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
img->cofu[coef_ctr]=levarr[k];
|
img->cofu[coef_ctr]=levarr[k];
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level=1;
|
level=1;
|
for(k=0;(k<(img->num_cdc_coeff+1))&&(level!=0);k++)
|
for(k=0;(k<(img->num_cdc_coeff+1))&&(level!=0);k++)
|
{
|
{
|
currSE.context = CHROMA_DC;
|
currSE.context = CHROMA_DC;
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_v_block = ll;
|
img->is_v_block = ll;
|
|
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x2 DC Chroma ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x2 DC Chroma ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_c2x2;
|
currSE.mapping = linfo_levrun_c2x2;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
if (level != 0)
|
if (level != 0)
|
{
|
{
|
currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
|
currMB->cbp_blk |= 0xf0000 << (ll<<1) ;
|
coef_ctr=coef_ctr+run+1;
|
coef_ctr=coef_ctr+run+1;
|
// Bug: img->cofu has only 4 entries, hence coef_ctr MUST be <4 (which is
|
// Bug: img->cofu has only 4 entries, hence coef_ctr MUST be <4 (which is
|
// caught by the assert(). If it is bigger than 4, it starts patching the
|
// caught by the assert(). If it is bigger than 4, it starts patching the
|
// img->predmode pointer, which leads to bugs later on.
|
// img->predmode pointer, which leads to bugs later on.
|
//
|
//
|
// This assert() should be left in the code, because it captures a very likely
|
// This assert() should be left in the code, because it captures a very likely
|
// bug early when testing in error prone environments (or when testing NAL
|
// bug early when testing in error prone environments (or when testing NAL
|
// functionality).
|
// functionality).
|
assert (coef_ctr < img->num_cdc_coeff);
|
assert (coef_ctr < img->num_cdc_coeff);
|
img->cofu[coef_ctr]=level;
|
img->cofu[coef_ctr]=level;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (smb // check to see if MB type is SPred or SIntra4x4
|
if (smb // check to see if MB type is SPred or SIntra4x4
|
|| lossless_qpprime)
|
|| lossless_qpprime)
|
{
|
{
|
img->cof[0+ll][4][0][0]=img->cofu[0];
|
img->cof[0+ll][4][0][0]=img->cofu[0];
|
img->cof[1+ll][4][0][0]=img->cofu[1];
|
img->cof[1+ll][4][0][0]=img->cofu[1];
|
img->cof[0+ll][5][0][0]=img->cofu[2];
|
img->cof[0+ll][5][0][0]=img->cofu[2];
|
img->cof[1+ll][5][0][0]=img->cofu[3];
|
img->cof[1+ll][5][0][0]=img->cofu[3];
|
}
|
}
|
else
|
else
|
{
|
{
|
temp[0]=(img->cofu[0]+img->cofu[1]+img->cofu[2]+img->cofu[3]);
|
temp[0]=(img->cofu[0]+img->cofu[1]+img->cofu[2]+img->cofu[3]);
|
temp[1]=(img->cofu[0]-img->cofu[1]+img->cofu[2]-img->cofu[3]);
|
temp[1]=(img->cofu[0]-img->cofu[1]+img->cofu[2]-img->cofu[3]);
|
temp[2]=(img->cofu[0]+img->cofu[1]-img->cofu[2]-img->cofu[3]);
|
temp[2]=(img->cofu[0]+img->cofu[1]-img->cofu[2]-img->cofu[3]);
|
temp[3]=(img->cofu[0]-img->cofu[1]-img->cofu[2]+img->cofu[3]);
|
temp[3]=(img->cofu[0]-img->cofu[1]-img->cofu[2]+img->cofu[3]);
|
|
|
for (i=0;i<img->num_cdc_coeff;i++)
|
for (i=0;i<img->num_cdc_coeff;i++)
|
{
|
{
|
if(qp_per_uv[uv]<5)
|
if(qp_per_uv[uv]<5)
|
{
|
{
|
temp[i]=(temp[i]*InvLevelScale4x4Chroma[0][0])>>(5-qp_per_uv[uv]);
|
temp[i]=(temp[i]*InvLevelScale4x4Chroma[0][0])>>(5-qp_per_uv[uv]);
|
}
|
}
|
else
|
else
|
{
|
{
|
temp[i]=(temp[i]*InvLevelScale4x4Chroma[0][0])<<(qp_per_uv[uv]-5);
|
temp[i]=(temp[i]*InvLevelScale4x4Chroma[0][0])<<(qp_per_uv[uv]-5);
|
}
|
}
|
}
|
}
|
img->cof[0+ll][4][0][0]=temp[0];
|
img->cof[0+ll][4][0][0]=temp[0];
|
img->cof[1+ll][4][0][0]=temp[1];
|
img->cof[1+ll][4][0][0]=temp[1];
|
img->cof[0+ll][5][0][0]=temp[2];
|
img->cof[0+ll][5][0][0]=temp[2];
|
img->cof[1+ll][5][0][0]=temp[3];
|
img->cof[1+ll][5][0][0]=temp[3];
|
}
|
}
|
}
|
}
|
else if (dec_picture->chroma_format_idc == YUV422)
|
else if (dec_picture->chroma_format_idc == YUV422)
|
{
|
{
|
int i,j,j1;
|
int i,j,j1;
|
int uv_idx = ll;
|
int uv_idx = ll;
|
int m3[2][4] = {{0,0,0,0},{0,0,0,0}};
|
int m3[2][4] = {{0,0,0,0},{0,0,0,0}};
|
int m4[2][4] = {{0,0,0,0},{0,0,0,0}};
|
int m4[2][4] = {{0,0,0,0},{0,0,0,0}};
|
int qp_per_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)/6; //for YUV422 only
|
int qp_per_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)/6; //for YUV422 only
|
int qp_rem_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)%6; //for YUV422 only
|
int qp_rem_uv_dc = (currMB->qpc[uv] + 3 + img->bitdepth_chroma_qp_scale)%6; //for YUV422 only
|
|
|
//===================== CHROMA DC YUV422 ======================
|
//===================== CHROMA DC YUV422 ======================
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
{
|
{
|
readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
|
readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
|
levarr, runarr, &numcoeff);
|
levarr, runarr, &numcoeff);
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level=1;
|
level=1;
|
for(k = 0; k < numcoeff; k++)
|
for(k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2);
|
currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2);
|
coef_ctr=coef_ctr+runarr[k]+1;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
i0 = SCAN_YUV422[coef_ctr][0];
|
i0 = SCAN_YUV422[coef_ctr][0];
|
j0 = SCAN_YUV422[coef_ctr][1];
|
j0 = SCAN_YUV422[coef_ctr][1];
|
|
|
m3[i0][j0]=levarr[k];
|
m3[i0][j0]=levarr[k];
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level=1;
|
level=1;
|
for(k=0;(k<9)&&(level!=0);k++)
|
for(k=0;(k<9)&&(level!=0);k++)
|
{
|
{
|
currSE.context = CHROMA_DC_2x4;
|
currSE.context = CHROMA_DC_2x4;
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_v_block = ll;
|
img->is_v_block = ll;
|
|
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x4 DC Chroma ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "2x4 DC Chroma ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_c2x2;
|
currSE.mapping = linfo_levrun_c2x2;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
if (level != 0)
|
if (level != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2) ;
|
currMB->cbp_blk |= ((int64)0xff0000) << (ll<<2) ;
|
coef_ctr=coef_ctr+run+1;
|
coef_ctr=coef_ctr+run+1;
|
assert (coef_ctr < img->num_cdc_coeff);
|
assert (coef_ctr < img->num_cdc_coeff);
|
i0=SCAN_YUV422[coef_ctr][0];
|
i0=SCAN_YUV422[coef_ctr][0];
|
j0=SCAN_YUV422[coef_ctr][1];
|
j0=SCAN_YUV422[coef_ctr][1];
|
|
|
m3[i0][j0]=level;
|
m3[i0][j0]=level;
|
}
|
}
|
}
|
}
|
}
|
}
|
// inverse CHROMA DC YUV422 transform
|
// inverse CHROMA DC YUV422 transform
|
// horizontal
|
// horizontal
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
{
|
{
|
m4[0][0] = m3[0][0] + m3[1][0];
|
m4[0][0] = m3[0][0] + m3[1][0];
|
m4[0][1] = m3[0][1] + m3[1][1];
|
m4[0][1] = m3[0][1] + m3[1][1];
|
m4[0][2] = m3[0][2] + m3[1][2];
|
m4[0][2] = m3[0][2] + m3[1][2];
|
m4[0][3] = m3[0][3] + m3[1][3];
|
m4[0][3] = m3[0][3] + m3[1][3];
|
|
|
m4[1][0] = m3[0][0] - m3[1][0];
|
m4[1][0] = m3[0][0] - m3[1][0];
|
m4[1][1] = m3[0][1] - m3[1][1];
|
m4[1][1] = m3[0][1] - m3[1][1];
|
m4[1][2] = m3[0][2] - m3[1][2];
|
m4[1][2] = m3[0][2] - m3[1][2];
|
m4[1][3] = m3[0][3] - m3[1][3];
|
m4[1][3] = m3[0][3] - m3[1][3];
|
}
|
}
|
else
|
else
|
{
|
{
|
for(i=0;i<2;i++)
|
for(i=0;i<2;i++)
|
for(j=0;j<4;j++)
|
for(j=0;j<4;j++)
|
img->cof[i+uv_idx][j+4][0][0]=m3[i][j];
|
img->cof[i+uv_idx][j+4][0][0]=m3[i][j];
|
}
|
}
|
|
|
// vertical
|
// vertical
|
for (i=0;i<2 && !lossless_qpprime;i++)
|
for (i=0;i<2 && !lossless_qpprime;i++)
|
{
|
{
|
int (*imgcof)[4][4] = img->cof[i+uv_idx];
|
int (*imgcof)[4][4] = img->cof[i+uv_idx];
|
for (j=0; j < 4;j++) //TODO: remove m5 with m4
|
for (j=0; j < 4;j++) //TODO: remove m5 with m4
|
m5[j]=m4[i][j];
|
m5[j]=m4[i][j];
|
|
|
m6[0]=m5[0]+m5[2];
|
m6[0]=m5[0]+m5[2];
|
m6[1]=m5[0]-m5[2];
|
m6[1]=m5[0]-m5[2];
|
m6[2]=m5[1]-m5[3];
|
m6[2]=m5[1]-m5[3];
|
m6[3]=m5[1]+m5[3];
|
m6[3]=m5[1]+m5[3];
|
|
|
for (j=0;j<2;j++)
|
for (j=0;j<2;j++)
|
{
|
{
|
j1=3-j;
|
j1=3-j;
|
if(qp_per_uv_dc<4)
|
if(qp_per_uv_dc<4)
|
{
|
{
|
if(intra == 1)
|
if(intra == 1)
|
{
|
{
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
}
|
}
|
else
|
else
|
{
|
{
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0]+(1<<(3-qp_per_uv_dc)))>>(4-qp_per_uv_dc))+2)>>2;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if(intra == 1)
|
if(intra == 1)
|
{
|
{
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
}
|
}
|
else
|
else
|
{
|
{
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
imgcof[j +4][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
imgcof[j1+4][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv_dc][0][0])<<(qp_per_uv_dc-4))+2)>>2;
|
}
|
}
|
}
|
}
|
}//for (j=0;j<2;j++)
|
}//for (j=0;j<2;j++)
|
}//for (i=0;i<2;i++)
|
}//for (i=0;i<2;i++)
|
}//else if (dec_picture->chroma_format_idc == YUV422)
|
}//else if (dec_picture->chroma_format_idc == YUV422)
|
else
|
else
|
{
|
{
|
//===================== CHROMA DC YUV444 ======================
|
//===================== CHROMA DC YUV444 ======================
|
int i,j,i1,j1;
|
int i,j,i1,j1;
|
int uv_idx = 4 + (ll<<1);
|
int uv_idx = 4 + (ll<<1);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
{
|
{
|
readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
|
readCoeff4x4_CAVLC(img, inp, CHROMA_DC, 0, 0,
|
levarr, runarr, &numcoeff);
|
levarr, runarr, &numcoeff);
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level=1;
|
level=1;
|
for(k = 0; k < numcoeff; k++)
|
for(k = 0; k < numcoeff; k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)0xffff0000) << (ll<<3) ;
|
currMB->cbp_blk |= ((int64)0xffff0000) << (ll<<3) ;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
i0=SNGL_SCAN[coef_ctr][0];
|
i0=SNGL_SCAN[coef_ctr][0];
|
j0=SNGL_SCAN[coef_ctr][1];
|
j0=SNGL_SCAN[coef_ctr][1];
|
|
|
img->cof[i0][j0+uv_idx][0][0]=levarr[k];
|
img->cof[i0][j0+uv_idx][0][0]=levarr[k];
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
coef_ctr=-1;
|
coef_ctr=-1;
|
level=1;
|
level=1;
|
for(k=0;(k<17)&&(level!=0);k++)
|
for(k=0;(k<17)&&(level!=0);k++)
|
{
|
{
|
currSE.context = CHROMA_DC_4x4;
|
currSE.context = CHROMA_DC_4x4;
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_v_block = ll;
|
img->is_v_block = ll;
|
|
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC Chroma ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "DC Chroma ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_c2x2;
|
currSE.mapping = linfo_levrun_c2x2;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
if (level != 0)
|
if (level != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)0xffff0000) << (ll<<3) ;
|
currMB->cbp_blk |= ((int64)0xffff0000) << (ll<<3) ;
|
coef_ctr=coef_ctr+run+1;
|
coef_ctr=coef_ctr+run+1;
|
assert (coef_ctr < img->num_cdc_coeff);
|
assert (coef_ctr < img->num_cdc_coeff);
|
i0=SNGL_SCAN[coef_ctr][0];
|
i0=SNGL_SCAN[coef_ctr][0];
|
j0=SNGL_SCAN[coef_ctr][1];
|
j0=SNGL_SCAN[coef_ctr][1];
|
|
|
img->cof[i0][j0+uv_idx][0][0]=level;
|
img->cof[i0][j0+uv_idx][0][0]=level;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// inverse CHROMA DC YUV444 transform
|
// inverse CHROMA DC YUV444 transform
|
// horizontal
|
// horizontal
|
for (j=uv_idx; (j < 4+uv_idx) && !lossless_qpprime;j++)
|
for (j=uv_idx; (j < 4+uv_idx) && !lossless_qpprime;j++)
|
{
|
{
|
for (i=0;i<4;i++)
|
for (i=0;i<4;i++)
|
m5[i]=img->cof[i][j][0][0];
|
m5[i]=img->cof[i][j][0][0];
|
|
|
m6[0]=m5[0]+m5[2];
|
m6[0]=m5[0]+m5[2];
|
m6[1]=m5[0]-m5[2];
|
m6[1]=m5[0]-m5[2];
|
m6[2]=m5[1]-m5[3];
|
m6[2]=m5[1]-m5[3];
|
m6[3]=m5[1]+m5[3];
|
m6[3]=m5[1]+m5[3];
|
|
|
for (i=0;i<2;i++)
|
for (i=0;i<2;i++)
|
{
|
{
|
i1=3-i;
|
i1=3-i;
|
img->cof[i][j][0][0]= m6[i]+m6[i1];
|
img->cof[i][j][0][0]= m6[i]+m6[i1];
|
img->cof[i1][j][0][0]=m6[i]-m6[i1];
|
img->cof[i1][j][0][0]=m6[i]-m6[i1];
|
}
|
}
|
}
|
}
|
|
|
// vertical
|
// vertical
|
for (i=0;i<4 && !lossless_qpprime;i++)
|
for (i=0;i<4 && !lossless_qpprime;i++)
|
{
|
{
|
for (j=0; j < 4;j++)
|
for (j=0; j < 4;j++)
|
m5[j]=img->cof[i][j+uv_idx][0][0];
|
m5[j]=img->cof[i][j+uv_idx][0][0];
|
|
|
m6[0]=m5[0]+m5[2];
|
m6[0]=m5[0]+m5[2];
|
m6[1]=m5[0]-m5[2];
|
m6[1]=m5[0]-m5[2];
|
m6[2]=m5[1]-m5[3];
|
m6[2]=m5[1]-m5[3];
|
m6[3]=m5[1]+m5[3];
|
m6[3]=m5[1]+m5[3];
|
|
|
for (j=0;j<2;j++)
|
for (j=0;j<2;j++)
|
{
|
{
|
j1=3-j;
|
j1=3-j;
|
if(qp_per_uv[uv]<4)
|
if(qp_per_uv[uv]<4)
|
{
|
{
|
if(intra == 1)
|
if(intra == 1)
|
{
|
{
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
}
|
}
|
else
|
else
|
{
|
{
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0]+(1<<(3-qp_per_uv[uv])))>>(4-qp_per_uv[uv]))+2)>>2;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if(intra == 1)
|
if(intra == 1)
|
{
|
{
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Intra[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
}
|
}
|
else
|
else
|
{
|
{
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
img->cof[i][j +uv_idx][0][0]=((((m6[j]+m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
img->cof[i][j1+uv_idx][0][0]=((((m6[j]-m6[j1])*InvLevelScale4x4Chroma_Inter[uv][qp_rem_uv[uv]][0][0])<<(qp_per_uv[uv]-4))+2)>>2;
|
}
|
}
|
}
|
}
|
}
|
}
|
}//for (i=0;i<4;i++)
|
}//for (i=0;i<4;i++)
|
}//else (dec_picture->chroma_format_idc == YUV444)
|
}//else (dec_picture->chroma_format_idc == YUV444)
|
}//for (ll=0;ll<3;ll+=2)
|
}//for (ll=0;ll<3;ll+=2)
|
}
|
}
|
|
|
// chroma AC coeff, all zero fram start_scan
|
// chroma AC coeff, all zero fram start_scan
|
if (cbp<=31)
|
if (cbp<=31)
|
for (i=0; i < 4; i++)
|
for (i=0; i < 4; i++)
|
memset(&img->nz_coeff [img->current_mb_nr ][i][4], 0, img->num_blk8x8_uv * sizeof(int));
|
memset(&img->nz_coeff [img->current_mb_nr ][i][4], 0, img->num_blk8x8_uv * sizeof(int));
|
|
|
|
|
//========================== CHROMA AC ============================
|
//========================== CHROMA AC ============================
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// chroma AC coeff, all zero fram start_scan
|
// chroma AC coeff, all zero fram start_scan
|
if (cbp>31)
|
if (cbp>31)
|
{
|
{
|
for (b8=0; b8 < img->num_blk8x8_uv; b8++)
|
for (b8=0; b8 < img->num_blk8x8_uv; b8++)
|
{
|
{
|
int uvc = (b8 > ((img->num_blk8x8_uv>>1) - 1 ));
|
int uvc = (b8 > ((img->num_blk8x8_uv>>1) - 1 ));
|
int (*InvLevelScale4x4Chroma)[4] = intra
|
int (*InvLevelScale4x4Chroma)[4] = intra
|
? InvLevelScale4x4Chroma_Intra[uvc][qp_rem_uv[uvc]]
|
? InvLevelScale4x4Chroma_Intra[uvc][qp_rem_uv[uvc]]
|
: InvLevelScale4x4Chroma_Inter[uvc][qp_rem_uv[uvc]];
|
: InvLevelScale4x4Chroma_Inter[uvc][qp_rem_uv[uvc]];
|
|
|
img->is_v_block = uv = uvc;
|
img->is_v_block = uv = uvc;
|
|
|
for (b4=0; b4 < 4; b4++)
|
for (b4=0; b4 < 4; b4++)
|
{
|
{
|
i = cofuv_blk_x[yuv][b8][b4];
|
i = cofuv_blk_x[yuv][b8][b4];
|
j = cofuv_blk_y[yuv][b8][b4];
|
j = cofuv_blk_y[yuv][b8][b4];
|
|
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
if (active_pps->entropy_coding_mode_flag == UVLC)
|
{
|
{
|
readCoeff4x4_CAVLC(img, inp, CHROMA_AC, i, j,
|
readCoeff4x4_CAVLC(img, inp, CHROMA_AC, i, j,
|
levarr, runarr, &numcoeff);
|
levarr, runarr, &numcoeff);
|
coef_ctr=0;
|
coef_ctr=0;
|
level=1;
|
level=1;
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
{
|
{
|
for(k = 0; k < numcoeff;k++)
|
for(k = 0; k < numcoeff;k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
coef_ctr=coef_ctr+runarr[k]+1;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
img->cof[i][j][j0][i0] = rshift_rnd_sf((levarr[k]*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4);
|
img->cof[i][j][j0][i0] = rshift_rnd_sf((levarr[k]*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4);
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for(k = 0; k < numcoeff;k++)
|
for(k = 0; k < numcoeff;k++)
|
{
|
{
|
if (levarr[k] != 0)
|
if (levarr[k] != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
coef_ctr=coef_ctr+runarr[k]+1;
|
coef_ctr=coef_ctr+runarr[k]+1;
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
img->cof[i][j][j0][i0]=levarr[k];
|
img->cof[i][j][j0][i0]=levarr[k];
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
coef_ctr=0;
|
coef_ctr=0;
|
level=1;
|
level=1;
|
|
|
img->subblock_y = subblk_offset_y[yuv][b8][b4]>>2;
|
img->subblock_y = subblk_offset_y[yuv][b8][b4]>>2;
|
img->subblock_x = subblk_offset_x[yuv][b8][b4]>>2;
|
img->subblock_x = subblk_offset_x[yuv][b8][b4]>>2;
|
|
|
currSE.context = CHROMA_AC;
|
currSE.context = CHROMA_AC;
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER);
|
currSE.type = (IS_INTRA(currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER);
|
img->is_intra_block = IS_INTRA(currMB);
|
img->is_intra_block = IS_INTRA(currMB);
|
|
|
if(!lossless_qpprime)
|
if(!lossless_qpprime)
|
{
|
{
|
for(k=0;(k<16)&&(level!=0);k++)
|
for(k=0;(k<16)&&(level!=0);k++)
|
{
|
{
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_inter;
|
currSE.mapping = linfo_levrun_inter;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
if (level != 0)
|
if (level != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
coef_ctr += (run + 1);
|
coef_ctr += (run + 1);
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
img->cof[i][j][j0][i0] = rshift_rnd_sf((level*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4);
|
img->cof[i][j][j0][i0] = rshift_rnd_sf((level*InvLevelScale4x4Chroma[j0][i0])<<qp_per_uv[uv], 4);
|
}
|
}
|
} //for(k=0;(k<16)&&(level!=0);k++)
|
} //for(k=0;(k<16)&&(level!=0);k++)
|
}
|
}
|
else
|
else
|
{
|
{
|
for(k=0;(k<16)&&(level!=0);k++)
|
for(k=0;(k<16)&&(level!=0);k++)
|
{
|
{
|
#if TRACE
|
#if TRACE
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma ");
|
snprintf(currSE.tracestring, TRACESTRING_SIZE, "AC Chroma ");
|
#endif
|
#endif
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
dP = &(currSlice->partArr[partMap[currSE.type]]);
|
|
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
|
currSE.mapping = linfo_levrun_inter;
|
currSE.mapping = linfo_levrun_inter;
|
else
|
else
|
currSE.reading = readRunLevel_CABAC;
|
currSE.reading = readRunLevel_CABAC;
|
|
|
dP->readSyntaxElement(&currSE,img,dP);
|
dP->readSyntaxElement(&currSE,img,dP);
|
level = currSE.value1;
|
level = currSE.value1;
|
run = currSE.value2;
|
run = currSE.value2;
|
len = currSE.len;
|
len = currSE.len;
|
|
|
if (level != 0)
|
if (level != 0)
|
{
|
{
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
currMB->cbp_blk |= ((int64)1) << cbp_blk_chroma[b8][b4];
|
coef_ctr += (run + 1);
|
coef_ctr += (run + 1);
|
|
|
i0=pos_scan4x4[coef_ctr][0];
|
i0=pos_scan4x4[coef_ctr][0];
|
j0=pos_scan4x4[coef_ctr][1];
|
j0=pos_scan4x4[coef_ctr][1];
|
|
|
img->cof[i][j][j0][i0]=level;
|
img->cof[i][j][j0][i0]=level;
|
}
|
}
|
} //for(k=0;(k<16)&&(level!=0);k++)
|
} //for(k=0;(k<16)&&(level!=0);k++)
|
}
|
}
|
} //else / if (active_pps->entropy_coding_mode_flag == UVLC)
|
} //else / if (active_pps->entropy_coding_mode_flag == UVLC)
|
} //for (b4=0; b4 < 4; b4++)
|
} //for (b4=0; b4 < 4; b4++)
|
} //for (b8=0; b8 < img->num_blk8x8_uv; b8++)
|
} //for (b8=0; b8 < img->num_blk8x8_uv; b8++)
|
} //if (cbp>31)
|
} //if (cbp>31)
|
} //if (dec_picture->chroma_format_idc != YUV400)
|
} //if (dec_picture->chroma_format_idc != YUV400)
|
}
|
}
|
|
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* Copy IPCM coefficients to decoded picture buffer and set parameters for this MB
|
* Copy IPCM coefficients to decoded picture buffer and set parameters for this MB
|
* (for IPCM CABAC and IPCM CAVLC 28/11/2003)
|
* (for IPCM CABAC and IPCM CAVLC 28/11/2003)
|
*
|
*
|
* \author
|
* \author
|
* Dong Wang <Dong.Wang@bristol.ac.uk>
|
* Dong Wang <Dong.Wang@bristol.ac.uk>
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
|
|
void decode_ipcm_mb(struct img_par *img)
|
void decode_ipcm_mb(struct img_par *img)
|
{
|
{
|
int i,j;
|
int i,j;
|
|
|
Macroblock *currMb = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMb = &img->mb_data[img->current_mb_nr];
|
|
|
//Copy coefficients to decoded picture buffer
|
//Copy coefficients to decoded picture buffer
|
//IPCM coefficients are stored in img->cof which is set in function readIPCMcoeffsFromNAL()
|
//IPCM coefficients are stored in img->cof which is set in function readIPCMcoeffsFromNAL()
|
|
|
for(i=0;i<16;i++)
|
for(i=0;i<16;i++)
|
for(j=0;j<16;j++)
|
for(j=0;j<16;j++)
|
dec_picture->imgY[img->pix_y+i][img->pix_x+j]=img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03];
|
dec_picture->imgY[img->pix_y+i][img->pix_x+j]=img->cof[(i>>2)][(j>>2)][i & 0x03][j & 0x03];
|
|
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
dec_picture->imgUV[0][img->pix_c_y+i][img->pix_c_x+j]=img->cof[(i>>2) ][(j>>2)+4][i & 0x03][j & 0x03];
|
dec_picture->imgUV[0][img->pix_c_y+i][img->pix_c_x+j]=img->cof[(i>>2) ][(j>>2)+4][i & 0x03][j & 0x03];
|
|
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(i=0;i<img->mb_cr_size_y;i++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
for(j=0;j<img->mb_cr_size_x;j++)
|
dec_picture->imgUV[1][img->pix_c_y+i][img->pix_c_x+j]=img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03];
|
dec_picture->imgUV[1][img->pix_c_y+i][img->pix_c_x+j]=img->cof[(i>>2)+2][(j>>2)+4][i & 0x03][j & 0x03];
|
}
|
}
|
|
|
// for deblocking filter
|
// for deblocking filter
|
currMb->qp=0;
|
currMb->qp=0;
|
set_chroma_qp(currMb);
|
set_chroma_qp(currMb);
|
|
|
// for CAVLC: Set the nz_coeff to 16.
|
// for CAVLC: Set the nz_coeff to 16.
|
// These parameters are to be used in CAVLC decoding of neighbour blocks
|
// These parameters are to be used in CAVLC decoding of neighbour blocks
|
for(i=0;i<4;i++)
|
for(i=0;i<4;i++)
|
for (j=0;j<(4 + img->num_blk8x8_uv);j++)
|
for (j=0;j<(4 + img->num_blk8x8_uv);j++)
|
img->nz_coeff[img->current_mb_nr][i][j]=16;
|
img->nz_coeff[img->current_mb_nr][i][j]=16;
|
|
|
|
|
// for CABAC decoding of MB skip flag
|
// for CABAC decoding of MB skip flag
|
currMb->skip_flag = 0;
|
currMb->skip_flag = 0;
|
|
|
//for deblocking filter CABAC
|
//for deblocking filter CABAC
|
currMb->cbp_blk=0xFFFF;
|
currMb->cbp_blk=0xFFFF;
|
|
|
//For CABAC decoding of Dquant
|
//For CABAC decoding of Dquant
|
last_dquant=0;
|
last_dquant=0;
|
}
|
}
|
|
|
/*!
|
/*!
|
************************************************************************
|
************************************************************************
|
* \brief
|
* \brief
|
* decode one macroblock
|
* decode one macroblock
|
************************************************************************
|
************************************************************************
|
*/
|
*/
|
|
|
int decode_one_macroblock(struct img_par *img,struct inp_par *inp)
|
int decode_one_macroblock(struct img_par *img,struct inp_par *inp)
|
{
|
{
|
int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
|
int tmp_block[BLOCK_SIZE][BLOCK_SIZE];
|
int tmp_blockbw[BLOCK_SIZE][BLOCK_SIZE];
|
int tmp_blockbw[BLOCK_SIZE][BLOCK_SIZE];
|
int i=0,j=0,k,l,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
|
int i=0,j=0,k,l,ii=0,jj=0,i1=0,j1=0,j4=0,i4=0;
|
int uv, hv;
|
int uv, hv;
|
int vec1_x=0,vec1_y=0,vec2_x=0,vec2_y=0;
|
int vec1_x=0,vec1_y=0,vec2_x=0,vec2_y=0;
|
int ioff,joff;
|
int ioff,joff;
|
int block8x8; // needed for ABT
|
int block8x8; // needed for ABT
|
|
|
int bw_pred=0, fw_pred=0, pred, ifx;
|
int bw_pred=0, fw_pred=0, pred, ifx;
|
int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
|
int ii0,jj0,ii1,jj1,if1,jf1,if0,jf0;
|
int mv_mul, f1_x, f1_y, f2_x, f2_y, f3, f4;
|
int mv_mul, f1_x, f1_y, f2_x, f2_y, f3, f4;
|
|
|
static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
|
static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
|
|
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
|
short ref_idx, l0_refframe=-1, l1_refframe=-1;
|
short ref_idx, l0_refframe=-1, l1_refframe=-1;
|
int mv_mode, pred_dir, intra_prediction; // = currMB->ref_frame;
|
int mv_mode, pred_dir, intra_prediction; // = currMB->ref_frame;
|
short l0_ref_idx=-1, l1_ref_idx=-1;
|
short l0_ref_idx=-1, l1_ref_idx=-1;
|
int alpha_l0, alpha_l1, wp_offset;
|
int alpha_l0, alpha_l1, wp_offset;
|
|
|
short *** mv_array, ***l0_mv_array, ***l1_mv_array;
|
short *** mv_array, ***l0_mv_array, ***l1_mv_array;
|
|
|
int mv_scale;
|
int mv_scale;
|
|
|
int mb_nr = img->current_mb_nr;
|
int mb_nr = img->current_mb_nr;
|
int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB);
|
int smb = ((img->type==SP_SLICE) && IS_INTER (currMB)) || (img->type == SI_SLICE && currMB->mb_type == SI4MB);
|
int list_offset;
|
int list_offset;
|
int max_y_cr;
|
int max_y_cr;
|
|
|
StorablePicture **list;
|
StorablePicture **list;
|
|
|
int jf;
|
int jf;
|
|
|
char l0_rFrame = -1, l1_rFrame = -1;
|
char l0_rFrame = -1, l1_rFrame = -1;
|
|
|
short pmvl0[2]={0,0},
|
short pmvl0[2]={0,0},
|
pmvl1[2]={0,0};
|
pmvl1[2]={0,0};
|
|
|
int direct_pdir=-1;
|
int direct_pdir=-1;
|
|
|
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
|
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
|
|
|
byte ** moving_block;
|
byte ** moving_block;
|
short **** co_located_mv;
|
short **** co_located_mv;
|
char *** co_located_ref_idx;
|
char *** co_located_ref_idx;
|
int64 *** co_located_ref_id;
|
int64 *** co_located_ref_id;
|
|
|
int need_4x4_transform = (!currMB->luma_transform_size_8x8_flag);
|
int need_4x4_transform = (!currMB->luma_transform_size_8x8_flag);
|
|
|
int b8, b4;
|
int b8, b4;
|
int uv_shift;
|
int uv_shift;
|
int yuv = dec_picture->chroma_format_idc - 1;
|
int yuv = dec_picture->chroma_format_idc - 1;
|
|
|
if(img->type==SP_SLICE && currMB->mb_type!=I16MB)
|
if(img->type==SP_SLICE && currMB->mb_type!=I16MB)
|
smb=1;// modif ES added
|
smb=1;// modif ES added
|
|
|
if(currMB->mb_type==IPCM)
|
if(currMB->mb_type==IPCM)
|
{
|
{
|
//copy readed data into imgY and set parameters
|
//copy readed data into imgY and set parameters
|
decode_ipcm_mb(img);
|
decode_ipcm_mb(img);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
//////////////////////////
|
//////////////////////////
|
|
|
// find out the correct list offsets
|
// find out the correct list offsets
|
if (curr_mb_field)
|
if (curr_mb_field)
|
{
|
{
|
if(mb_nr&0x01)
|
if(mb_nr&0x01)
|
{
|
{
|
list_offset = 4; // top field mb
|
list_offset = 4; // top field mb
|
moving_block = Co_located->bottom_moving_block;
|
moving_block = Co_located->bottom_moving_block;
|
co_located_mv = Co_located->bottom_mv;
|
co_located_mv = Co_located->bottom_mv;
|
co_located_ref_idx = Co_located->bottom_ref_idx;
|
co_located_ref_idx = Co_located->bottom_ref_idx;
|
co_located_ref_id = Co_located->bottom_ref_pic_id;
|
co_located_ref_id = Co_located->bottom_ref_pic_id;
|
}
|
}
|
else
|
else
|
{
|
{
|
list_offset = 2; // bottom field mb
|
list_offset = 2; // bottom field mb
|
moving_block = Co_located->top_moving_block;
|
moving_block = Co_located->top_moving_block;
|
co_located_mv = Co_located->top_mv;
|
co_located_mv = Co_located->top_mv;
|
co_located_ref_idx = Co_located->top_ref_idx;
|
co_located_ref_idx = Co_located->top_ref_idx;
|
co_located_ref_id = Co_located->top_ref_pic_id;
|
co_located_ref_id = Co_located->top_ref_pic_id;
|
}
|
}
|
max_y_cr = (dec_picture->size_y_cr>>1)-1;
|
max_y_cr = (dec_picture->size_y_cr>>1)-1;
|
}
|
}
|
else
|
else
|
{
|
{
|
list_offset = 0; // no mb aff or frame mb
|
list_offset = 0; // no mb aff or frame mb
|
moving_block = Co_located->moving_block;
|
moving_block = Co_located->moving_block;
|
co_located_mv = Co_located->mv;
|
co_located_mv = Co_located->mv;
|
co_located_ref_idx = Co_located->ref_idx;
|
co_located_ref_idx = Co_located->ref_idx;
|
co_located_ref_id = Co_located->ref_pic_id;
|
co_located_ref_id = Co_located->ref_pic_id;
|
max_y_cr = dec_picture->size_y_cr-1;
|
max_y_cr = dec_picture->size_y_cr-1;
|
}
|
}
|
|
|
if (!img->MbaffFrameFlag)
|
if (!img->MbaffFrameFlag)
|
{
|
{
|
for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
|
for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
|
{
|
{
|
for(k = 0; k < listXsize[l]; k++)
|
for(k = 0; k < listXsize[l]; k++)
|
{
|
{
|
listX[l][k]->chroma_vector_adjustment= 0;
|
listX[l][k]->chroma_vector_adjustment= 0;
|
if(img->structure == TOP_FIELD && img->structure != listX[l][k]->structure)
|
if(img->structure == TOP_FIELD && img->structure != listX[l][k]->structure)
|
listX[l][k]->chroma_vector_adjustment = -2;
|
listX[l][k]->chroma_vector_adjustment = -2;
|
if(img->structure == BOTTOM_FIELD && img->structure != listX[l][k]->structure)
|
if(img->structure == BOTTOM_FIELD && img->structure != listX[l][k]->structure)
|
listX[l][k]->chroma_vector_adjustment = 2;
|
listX[l][k]->chroma_vector_adjustment = 2;
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (curr_mb_field)
|
if (curr_mb_field)
|
{
|
{
|
for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
|
for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
|
{
|
{
|
for(k = 0; k < listXsize[l]; k++)
|
for(k = 0; k < listXsize[l]; k++)
|
{
|
{
|
listX[l][k]->chroma_vector_adjustment= 0;
|
listX[l][k]->chroma_vector_adjustment= 0;
|
if(img->current_mb_nr % 2 == 0 && listX[l][k]->structure == BOTTOM_FIELD)
|
if(img->current_mb_nr % 2 == 0 && listX[l][k]->structure == BOTTOM_FIELD)
|
listX[l][k]->chroma_vector_adjustment = -2;
|
listX[l][k]->chroma_vector_adjustment = -2;
|
if(img->current_mb_nr % 2 == 1 && listX[l][k]->structure == TOP_FIELD)
|
if(img->current_mb_nr % 2 == 1 && listX[l][k]->structure == TOP_FIELD)
|
listX[l][k]->chroma_vector_adjustment = 2;
|
listX[l][k]->chroma_vector_adjustment = 2;
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
|
for (l = LIST_0 + list_offset; l <= (LIST_1 + list_offset); l++)
|
{
|
{
|
for(k = 0; k < listXsize[l]; k++)
|
for(k = 0; k < listXsize[l]; k++)
|
{
|
{
|
listX[l][k]->chroma_vector_adjustment= 0;
|
listX[l][k]->chroma_vector_adjustment= 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
mv_mul=4;
|
mv_mul=4;
|
|
|
// luma decoding **************************************************
|
// luma decoding **************************************************
|
|
|
// get prediction for INTRA_MB_16x16
|
// get prediction for INTRA_MB_16x16
|
if (IS_NEWINTRA (currMB))
|
if (IS_NEWINTRA (currMB))
|
{
|
{
|
intrapred_luma_16x16(img, currMB->i16mode);
|
intrapred_luma_16x16(img, currMB->i16mode);
|
}
|
}
|
|
|
if (img->type==B_SLICE && img->direct_spatial_mv_pred_flag && (IS_DIRECT (currMB) ||
|
if (img->type==B_SLICE && img->direct_spatial_mv_pred_flag && (IS_DIRECT (currMB) ||
|
(IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3]))))
|
(IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3]))))
|
{
|
{
|
char l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR;
|
char l0_rFrameL, l0_rFrameU, l0_rFrameUL, l0_rFrameUR;
|
char l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR;
|
char l1_rFrameL, l1_rFrameU, l1_rFrameUL, l1_rFrameUR;
|
|
|
PixelPos mb_left, mb_up, mb_upleft, mb_upright;
|
PixelPos mb_left, mb_up, mb_upleft, mb_upright;
|
|
|
getLuma4x4Neighbour(img->current_mb_nr, -1, 0, &mb_left);
|
getLuma4x4Neighbour(img->current_mb_nr, -1, 0, &mb_left);
|
getLuma4x4Neighbour(img->current_mb_nr, 0, -1, &mb_up);
|
getLuma4x4Neighbour(img->current_mb_nr, 0, -1, &mb_up);
|
getLuma4x4Neighbour(img->current_mb_nr, 16, -1, &mb_upright);
|
getLuma4x4Neighbour(img->current_mb_nr, 16, -1, &mb_upright);
|
getLuma4x4Neighbour(img->current_mb_nr, -1, -1, &mb_upleft);
|
getLuma4x4Neighbour(img->current_mb_nr, -1, -1, &mb_upleft);
|
|
|
if (!img->MbaffFrameFlag)
|
if (!img->MbaffFrameFlag)
|
{
|
{
|
l0_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1;
|
l0_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] : -1;
|
l0_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
l0_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
l0_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l0_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l0_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
l0_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
|
|
l1_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
l1_rFrameL = mb_left.available ? dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
l1_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
l1_rFrameU = mb_up.available ? dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
l1_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l1_rFrameUL = mb_upleft.available ? dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
l1_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
l1_rFrameUR = mb_upright.available ? dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
}
|
}
|
else
|
else
|
{
|
{
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
if (img->mb_data[img->current_mb_nr].mb_field)
|
{
|
{
|
l0_rFrameL = mb_left.available ?
|
l0_rFrameL = mb_left.available ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0?
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
|
|
l0_rFrameU = mb_up.available ?
|
l0_rFrameU = mb_up.available ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0?
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
|
|
l0_rFrameUL = mb_upleft.available ?
|
l0_rFrameUL = mb_upleft.available ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0?
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
|
|
|
l0_rFrameUR = mb_upright.available ?
|
l0_rFrameUR = mb_upright.available ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0?
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] :
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL;
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] * 2: l0_rFrameUL;
|
|
|
l1_rFrameL = mb_left.available ?
|
l1_rFrameL = mb_left.available ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0?
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] * 2: -1;
|
|
|
l1_rFrameU = mb_up.available ?
|
l1_rFrameU = mb_up.available ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0?
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] * 2: -1;
|
|
|
l1_rFrameUL = mb_upleft.available ?
|
l1_rFrameUL = mb_upleft.available ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0?
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] *2: -1;
|
|
|
l1_rFrameUR = mb_upright.available ?
|
l1_rFrameUR = mb_upright.available ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0?
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] :
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL;
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] * 2: l1_rFrameUL;
|
}
|
}
|
else
|
else
|
{
|
{
|
l0_rFrameL = mb_left.available ?
|
l0_rFrameL = mb_left.available ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1;
|
dec_picture->ref_idx[LIST_0][mb_left.pos_y][mb_left.pos_x]: -1;
|
|
|
l0_rFrameU = mb_up.available ?
|
l0_rFrameU = mb_up.available ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
dec_picture->ref_idx[LIST_0][mb_up.pos_y][mb_up.pos_x] : -1;
|
|
|
l0_rFrameUL = mb_upleft.available ?
|
l0_rFrameUL = mb_upleft.available ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x]>> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
dec_picture->ref_idx[LIST_0][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
|
|
l0_rFrameUR = mb_upright.available ?
|
l0_rFrameUR = mb_upright.available ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
dec_picture->ref_idx[LIST_0][mb_upright.pos_y][mb_upright.pos_x] : l0_rFrameUL;
|
|
|
l1_rFrameL = mb_left.available ?
|
l1_rFrameL = mb_left.available ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
img->mb_data[mb_left.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
dec_picture->ref_idx[LIST_1][mb_left.pos_y][mb_left.pos_x] : -1;
|
|
|
l1_rFrameU = mb_up.available ?
|
l1_rFrameU = mb_up.available ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
img->mb_data[mb_up.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
dec_picture->ref_idx[LIST_1][mb_up.pos_y][mb_up.pos_x] : -1;
|
|
|
l1_rFrameUL = mb_upleft.available ?
|
l1_rFrameUL = mb_upleft.available ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
img->mb_data[mb_upleft.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] >> 1 :
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
dec_picture->ref_idx[LIST_1][mb_upleft.pos_y][mb_upleft.pos_x] : -1;
|
|
|
l1_rFrameUR = mb_upright.available ?
|
l1_rFrameUR = mb_upright.available ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
img->mb_data[mb_upright.mb_addr].mb_field || dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] < 0 ?
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1:
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] >> 1:
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
dec_picture->ref_idx[LIST_1][mb_upright.pos_y][mb_upright.pos_x] : l1_rFrameUL;
|
}
|
}
|
}
|
}
|
|
|
l0_rFrame = (l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU): imax(l0_rFrameL,l0_rFrameU);
|
l0_rFrame = (l0_rFrameL >= 0 && l0_rFrameU >= 0) ? imin(l0_rFrameL,l0_rFrameU): imax(l0_rFrameL,l0_rFrameU);
|
l0_rFrame = (l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(l0_rFrame,l0_rFrameUR): imax(l0_rFrame,l0_rFrameUR);
|
l0_rFrame = (l0_rFrame >= 0 && l0_rFrameUR >= 0) ? imin(l0_rFrame,l0_rFrameUR): imax(l0_rFrame,l0_rFrameUR);
|
|
|
l1_rFrame = (l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU): imax(l1_rFrameL,l1_rFrameU);
|
l1_rFrame = (l1_rFrameL >= 0 && l1_rFrameU >= 0) ? imin(l1_rFrameL,l1_rFrameU): imax(l1_rFrameL,l1_rFrameU);
|
l1_rFrame = (l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(l1_rFrame,l1_rFrameUR): imax(l1_rFrame,l1_rFrameUR);
|
l1_rFrame = (l1_rFrame >= 0 && l1_rFrameUR >= 0) ? imin(l1_rFrame,l1_rFrameUR): imax(l1_rFrame,l1_rFrameUR);
|
|
|
if (l0_rFrame >=0)
|
if (l0_rFrame >=0)
|
SetMotionVectorPredictor (img, pmvl0, l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
SetMotionVectorPredictor (img, pmvl0, l0_rFrame, LIST_0, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
|
|
if (l1_rFrame >=0)
|
if (l1_rFrame >=0)
|
SetMotionVectorPredictor (img, pmvl1, l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
SetMotionVectorPredictor (img, pmvl1, l1_rFrame, LIST_1, dec_picture->ref_idx, dec_picture->mv, 0, 0, 16, 16);
|
}
|
}
|
|
|
for (block8x8=0; block8x8<4; block8x8++)
|
for (block8x8=0; block8x8<4; block8x8++)
|
{
|
{
|
if (currMB->b8mode[block8x8] == I8MB)
|
if (currMB->b8mode[block8x8] == I8MB)
|
{
|
{
|
//=========== 8x8 BLOCK TYPE ============
|
//=========== 8x8 BLOCK TYPE ============
|
ioff = 8*(block8x8&0x01);
|
ioff = 8*(block8x8&0x01);
|
joff = 8*(block8x8>>1);
|
joff = 8*(block8x8>>1);
|
|
|
//PREDICTION
|
//PREDICTION
|
intrapred8x8(img, block8x8);
|
intrapred8x8(img, block8x8);
|
itrans8x8(img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
|
itrans8x8(img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
|
|
|
for(jj=joff;jj<joff + 8;jj++)
|
for(jj=joff;jj<joff + 8;jj++)
|
{
|
{
|
for(ii=ioff;ii<ioff + 8;ii++)
|
for(ii=ioff;ii<ioff + 8;ii++)
|
{
|
{
|
dec_picture->imgY[img->pix_y + jj][img->pix_x + ii] = img->m7[jj][ii]; // construct picture from 4x4 blocks
|
dec_picture->imgY[img->pix_y + jj][img->pix_x + ii] = img->m7[jj][ii]; // construct picture from 4x4 blocks
|
}
|
}
|
}
|
}
|
continue;
|
continue;
|
}
|
}
|
|
|
for (k = block8x8*4; k < block8x8*4+4; k ++)
|
for (k = block8x8*4; k < block8x8*4+4; k ++)
|
{
|
{
|
i = (decode_block_scan[k] & 3);
|
i = (decode_block_scan[k] & 3);
|
j = ((decode_block_scan[k] >> 2) & 3);
|
j = ((decode_block_scan[k] >> 2) & 3);
|
|
|
ioff = (i << 2);
|
ioff = (i << 2);
|
i4 = img->block_x + i;
|
i4 = img->block_x + i;
|
|
|
joff = (j << 2);
|
joff = (j << 2);
|
j4 = img->block_y + j;
|
j4 = img->block_y + j;
|
|
|
mv_mode = currMB->b8mode[2*(j>>1)+(i>>1)];
|
mv_mode = currMB->b8mode[2*(j>>1)+(i>>1)];
|
pred_dir = currMB->b8pdir[2*(j>>1)+(i>>1)];
|
pred_dir = currMB->b8pdir[2*(j>>1)+(i>>1)];
|
|
|
assert (pred_dir<=2);
|
assert (pred_dir<=2);
|
|
|
// PREDICTION
|
// PREDICTION
|
if (mv_mode==IBLOCK)
|
if (mv_mode==IBLOCK)
|
{
|
{
|
//===== INTRA PREDICTION =====
|
//===== INTRA PREDICTION =====
|
if (intrapred(img,ioff,joff,i4,j4)==SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */
|
if (intrapred(img,ioff,joff,i4,j4)==SEARCH_SYNC) /* make 4x4 prediction block mpr from given prediction img->mb_mode */
|
return SEARCH_SYNC; /* bit error */
|
return SEARCH_SYNC; /* bit error */
|
}
|
}
|
else if (!IS_NEWINTRA (currMB))
|
else if (!IS_NEWINTRA (currMB))
|
{
|
{
|
if (pred_dir != 2)
|
if (pred_dir != 2)
|
{
|
{
|
//===== FORWARD/BACKWARD PREDICTION =====
|
//===== FORWARD/BACKWARD PREDICTION =====
|
l0_refframe = ref_idx = dec_picture->ref_idx[LIST_0 + pred_dir][j4][i4];
|
l0_refframe = ref_idx = dec_picture->ref_idx[LIST_0 + pred_dir][j4][i4];
|
mv_array = dec_picture->mv[LIST_0 + pred_dir];
|
mv_array = dec_picture->mv[LIST_0 + pred_dir];
|
list = listX[0+list_offset+ pred_dir];
|
list = listX[0+list_offset+ pred_dir];
|
vec1_x = i4*4*mv_mul + mv_array[j4][i4][0];
|
vec1_x = i4*4*mv_mul + mv_array[j4][i4][0];
|
|
|
if (!curr_mb_field)
|
if (!curr_mb_field)
|
{
|
{
|
vec1_y = j4 * 4 * mv_mul + mv_array[j4][i4][1];
|
vec1_y = j4 * 4 * mv_mul + mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
if ((mb_nr&0x01) == 0)
|
if ((mb_nr&0x01) == 0)
|
vec1_y = (img->block_y * 2 + joff) * mv_mul + mv_array[j4][i4][1];
|
vec1_y = (img->block_y * 2 + joff) * mv_mul + mv_array[j4][i4][1];
|
else
|
else
|
vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + mv_array[j4][i4][1];
|
vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + mv_array[j4][i4][1];
|
}
|
}
|
|
|
get_block (ref_idx, list, vec1_x, vec1_y, img, tmp_block);
|
get_block (ref_idx, list, vec1_x, vec1_y, img, tmp_block);
|
|
|
if (img->apply_weights)
|
if (img->apply_weights)
|
{
|
{
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
{
|
{
|
ref_idx >>=1;
|
ref_idx >>=1;
|
}
|
}
|
|
|
alpha_l0 = img->wp_weight[pred_dir][ref_idx][0];
|
alpha_l0 = img->wp_weight[pred_dir][ref_idx][0];
|
wp_offset = img->wp_offset[pred_dir][l0_refframe>>curr_mb_field][0];
|
wp_offset = img->wp_offset[pred_dir][l0_refframe>>curr_mb_field][0];
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
{
|
{
|
int jpos = jj+joff;
|
int jpos = jj+joff;
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jpos][ii+ioff] = iClip1(img->max_imgpel_value,
|
img->mpr[jpos][ii+ioff] = iClip1(img->max_imgpel_value,
|
(rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii]), img->luma_log2_weight_denom) + wp_offset ));
|
(rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii]), img->luma_log2_weight_denom) + wp_offset ));
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
{
|
{
|
int jpos = jj+joff;
|
int jpos = jj+joff;
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jpos][ii+ioff] = tmp_block[jj][ii];
|
img->mpr[jpos][ii+ioff] = tmp_block[jj][ii];
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (mv_mode != 0)
|
if (mv_mode != 0)
|
{
|
{
|
//===== BI-DIRECTIONAL PREDICTION =====
|
//===== BI-DIRECTIONAL PREDICTION =====
|
l0_mv_array = dec_picture->mv[LIST_0];
|
l0_mv_array = dec_picture->mv[LIST_0];
|
l1_mv_array = dec_picture->mv[LIST_1];
|
l1_mv_array = dec_picture->mv[LIST_1];
|
|
|
l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4];
|
l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4];
|
l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4];
|
l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4];
|
l0_ref_idx = l0_refframe;
|
l0_ref_idx = l0_refframe;
|
l1_ref_idx = l1_refframe;
|
l1_ref_idx = l1_refframe;
|
}
|
}
|
else
|
else
|
{
|
{
|
//===== DIRECT PREDICTION =====
|
//===== DIRECT PREDICTION =====
|
l0_mv_array = dec_picture->mv[LIST_0];
|
l0_mv_array = dec_picture->mv[LIST_0];
|
l1_mv_array = dec_picture->mv[LIST_1];
|
l1_mv_array = dec_picture->mv[LIST_1];
|
l1_refframe = 0;
|
l1_refframe = 0;
|
|
|
if (img->direct_spatial_mv_pred_flag )
|
if (img->direct_spatial_mv_pred_flag )
|
{
|
{
|
int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
|
int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
|
int j6 = imgblock_y + j;
|
int j6 = imgblock_y + j;
|
|
|
if (l0_rFrame >=0)
|
if (l0_rFrame >=0)
|
{
|
{
|
if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
|
if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
|
dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
|
dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
|
dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
|
dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
|
dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->ref_idx[LIST_0][j4][i4] = -1;
|
dec_picture->ref_idx[LIST_0][j4][i4] = -1;
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][0] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
dec_picture->mv [LIST_0][j4][i4][1] = 0;
|
}
|
}
|
|
|
if (l1_rFrame >=0)
|
if (l1_rFrame >=0)
|
{
|
{
|
if (l1_rFrame==0 && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
|
if (l1_rFrame==0 && ((!moving_block[j6][i4]) && (!listX[1+list_offset][0]->is_long_term)))
|
{
|
{
|
|
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
|
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
|
dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
|
dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
|
dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
|
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
|
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][0] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->mv [LIST_1][j4][i4][1] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = -1;
|
dec_picture->ref_idx[LIST_1][j4][i4] = -1;
|
}
|
}
|
|
|
if (l0_rFrame < 0 && l1_rFrame < 0)
|
if (l0_rFrame < 0 && l1_rFrame < 0)
|
{
|
{
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
}
|
}
|
|
|
l0_refframe = (dec_picture->ref_idx[LIST_0][j4][i4]!=-1) ? dec_picture->ref_idx[LIST_0][j4][i4] : 0;
|
l0_refframe = (dec_picture->ref_idx[LIST_0][j4][i4]!=-1) ? dec_picture->ref_idx[LIST_0][j4][i4] : 0;
|
l1_refframe = (dec_picture->ref_idx[LIST_1][j4][i4]!=-1) ? dec_picture->ref_idx[LIST_1][j4][i4] : 0;
|
l1_refframe = (dec_picture->ref_idx[LIST_1][j4][i4]!=-1) ? dec_picture->ref_idx[LIST_1][j4][i4] : 0;
|
|
|
l0_ref_idx = l0_refframe;
|
l0_ref_idx = l0_refframe;
|
l1_ref_idx = l1_refframe;
|
l1_ref_idx = l1_refframe;
|
|
|
if (dec_picture->ref_idx[LIST_1][j4][i4]==-1)
|
if (dec_picture->ref_idx[LIST_1][j4][i4]==-1)
|
direct_pdir = 0;
|
direct_pdir = 0;
|
else if (dec_picture->ref_idx[LIST_0][j4][i4]==-1)
|
else if (dec_picture->ref_idx[LIST_0][j4][i4]==-1)
|
direct_pdir = 1;
|
direct_pdir = 1;
|
else
|
else
|
direct_pdir = 2;
|
direct_pdir = 2;
|
|
|
}
|
}
|
else // Temporal Mode
|
else // Temporal Mode
|
{
|
{
|
|
|
int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
|
int imgblock_y= ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr&0x01) ? (img->block_y-4)>>1:img->block_y>>1: img->block_y;
|
int j6= imgblock_y + j;
|
int j6= imgblock_y + j;
|
|
|
int refList = (co_located_ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0);
|
int refList = (co_located_ref_idx[LIST_0][j6][i4]== -1 ? LIST_1 : LIST_0);
|
int ref_idx = co_located_ref_idx[refList][j6][i4];
|
int ref_idx = co_located_ref_idx[refList][j6][i4];
|
|
|
|
|
if(ref_idx==-1) // co-located is intra mode
|
if(ref_idx==-1) // co-located is intra mode
|
{
|
{
|
for(hv=0; hv<2; hv++)
|
for(hv=0; hv<2; hv++)
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][hv]=0;
|
dec_picture->mv [LIST_0][j4][i4][hv]=0;
|
dec_picture->mv [LIST_1][j4][i4][hv]=0;
|
dec_picture->mv [LIST_1][j4][i4][hv]=0;
|
}
|
}
|
|
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
|
|
l0_refframe = 0;
|
l0_refframe = 0;
|
l0_ref_idx = 0;
|
l0_ref_idx = 0;
|
}
|
}
|
else // co-located skip or inter mode
|
else // co-located skip or inter mode
|
{
|
{
|
int mapped_idx=0;
|
int mapped_idx=0;
|
int iref;
|
int iref;
|
|
|
{
|
{
|
for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
|
for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
|
{
|
{
|
if(img->structure==0 && curr_mb_field==0)
|
if(img->structure==0 && curr_mb_field==0)
|
{
|
{
|
// If the current MB is a frame MB and the colocated is from a field picture,
|
// If the current MB is a frame MB and the colocated is from a field picture,
|
// then the co_located_ref_id may have been generated from the wrong value of
|
// then the co_located_ref_id may have been generated from the wrong value of
|
// frame_poc if it references it's complementary field, so test both POC values
|
// frame_poc if it references it's complementary field, so test both POC values
|
if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][j6][i4])
|
if(listX[0][iref]->top_poc*2 == co_located_ref_id[refList][j6][i4] || listX[0][iref]->bottom_poc*2 == co_located_ref_id[refList][j6][i4])
|
{
|
{
|
mapped_idx=iref;
|
mapped_idx=iref;
|
break;
|
break;
|
}
|
}
|
else //! invalid index. Default to zero even though this case should not happen
|
else //! invalid index. Default to zero even though this case should not happen
|
mapped_idx=INVALIDINDEX;
|
mapped_idx=INVALIDINDEX;
|
continue;
|
continue;
|
}
|
}
|
|
|
if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][j6][i4])
|
if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==co_located_ref_id[refList][j6][i4])
|
{
|
{
|
mapped_idx=iref;
|
mapped_idx=iref;
|
break;
|
break;
|
}
|
}
|
else //! invalid index. Default to zero even though this case should not happen
|
else //! invalid index. Default to zero even though this case should not happen
|
{
|
{
|
mapped_idx=INVALIDINDEX;
|
mapped_idx=INVALIDINDEX;
|
}
|
}
|
}
|
}
|
if (INVALIDINDEX == mapped_idx)
|
if (INVALIDINDEX == mapped_idx)
|
{
|
{
|
error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
|
error("temporal direct error\ncolocated block has ref that is unavailable",-1111);
|
}
|
}
|
}
|
}
|
|
|
l0_ref_idx = mapped_idx;
|
l0_ref_idx = mapped_idx;
|
mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
|
mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
|
|
|
//! In such case, an array is needed for each different reference.
|
//! In such case, an array is needed for each different reference.
|
if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
|
if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0]=co_located_mv[refList][j6][i4][0];
|
dec_picture->mv [LIST_0][j4][i4][0]=co_located_mv[refList][j6][i4][0];
|
dec_picture->mv [LIST_0][j4][i4][1]=co_located_mv[refList][j6][i4][1];
|
dec_picture->mv [LIST_0][j4][i4][1]=co_located_mv[refList][j6][i4][1];
|
|
|
dec_picture->mv [LIST_1][j4][i4][0]=0;
|
dec_picture->mv [LIST_1][j4][i4][0]=0;
|
dec_picture->mv [LIST_1][j4][i4][1]=0;
|
dec_picture->mv [LIST_1][j4][i4][1]=0;
|
}
|
}
|
else
|
else
|
{
|
{
|
dec_picture->mv [LIST_0][j4][i4][0]=(mv_scale * co_located_mv[refList][j6][i4][0] + 128 ) >> 8;
|
dec_picture->mv [LIST_0][j4][i4][0]=(mv_scale * co_located_mv[refList][j6][i4][0] + 128 ) >> 8;
|
dec_picture->mv [LIST_0][j4][i4][1]=(mv_scale * co_located_mv[refList][j6][i4][1] + 128 ) >> 8;
|
dec_picture->mv [LIST_0][j4][i4][1]=(mv_scale * co_located_mv[refList][j6][i4][1] + 128 ) >> 8;
|
|
|
dec_picture->mv [LIST_1][j4][i4][0]=dec_picture->mv[LIST_0][j4][i4][0] - co_located_mv[refList][j6][i4][0] ;
|
dec_picture->mv [LIST_1][j4][i4][0]=dec_picture->mv[LIST_0][j4][i4][0] - co_located_mv[refList][j6][i4][0] ;
|
dec_picture->mv [LIST_1][j4][i4][1]=dec_picture->mv[LIST_0][j4][i4][1] - co_located_mv[refList][j6][i4][1] ;
|
dec_picture->mv [LIST_1][j4][i4][1]=dec_picture->mv[LIST_0][j4][i4][1] - co_located_mv[refList][j6][i4][1] ;
|
}
|
}
|
|
|
l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4] = mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4];
|
l0_refframe = dec_picture->ref_idx[LIST_0][j4][i4] = mapped_idx; //listX[1][0]->ref_idx[refList][j4][i4];
|
l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
l1_refframe = dec_picture->ref_idx[LIST_1][j4][i4] = 0;
|
|
|
l0_ref_idx = l0_refframe;
|
l0_ref_idx = l0_refframe;
|
l1_ref_idx = l1_refframe;
|
l1_ref_idx = l1_refframe;
|
}
|
}
|
}
|
}
|
// store reference picture ID determined by direct mode
|
// store reference picture ID determined by direct mode
|
dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]];
|
dec_picture->ref_pic_id[LIST_0][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->ref_idx[LIST_0][j4][i4]];
|
dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]];
|
dec_picture->ref_pic_id[LIST_1][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][LIST_1 + list_offset][(short)dec_picture->ref_idx[LIST_1][j4][i4]];
|
}
|
}
|
|
|
if (mv_mode==0 && img->direct_spatial_mv_pred_flag )
|
if (mv_mode==0 && img->direct_spatial_mv_pred_flag )
|
{
|
{
|
if (dec_picture->ref_idx[LIST_0][j4][i4] >= 0)
|
if (dec_picture->ref_idx[LIST_0][j4][i4] >= 0)
|
{
|
{
|
|
|
vec1_x = i4*4*mv_mul + l0_mv_array[j4][i4][0];
|
vec1_x = i4*4*mv_mul + l0_mv_array[j4][i4][0];
|
if (!curr_mb_field)
|
if (!curr_mb_field)
|
{
|
{
|
vec1_y = j4*4*mv_mul + l0_mv_array[j4][i4][1];
|
vec1_y = j4*4*mv_mul + l0_mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
if ((mb_nr&0x01) == 0)
|
if ((mb_nr&0x01) == 0)
|
{
|
{
|
vec1_y = (img->block_y * 2 + joff) * mv_mul + l0_mv_array[j4][i4][1];
|
vec1_y = (img->block_y * 2 + joff) * mv_mul + l0_mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + l0_mv_array[j4][i4][1];
|
vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + l0_mv_array[j4][i4][1];
|
}
|
}
|
}
|
}
|
get_block(l0_refframe, listX[0+list_offset], vec1_x, vec1_y, img, tmp_block);
|
get_block(l0_refframe, listX[0+list_offset], vec1_x, vec1_y, img, tmp_block);
|
}
|
}
|
|
|
if (dec_picture->ref_idx[LIST_1][j4][i4] >= 0)
|
if (dec_picture->ref_idx[LIST_1][j4][i4] >= 0)
|
{
|
{
|
vec2_x = i4*4*mv_mul + l1_mv_array[j4][i4][0];
|
vec2_x = i4*4*mv_mul + l1_mv_array[j4][i4][0];
|
if (!curr_mb_field)
|
if (!curr_mb_field)
|
{
|
{
|
vec2_y = j4*4*mv_mul + l1_mv_array[j4][i4][1];
|
vec2_y = j4*4*mv_mul + l1_mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
if ((mb_nr&0x01) == 0)
|
if ((mb_nr&0x01) == 0)
|
{
|
{
|
vec2_y = (img->block_y * 2 + joff) * mv_mul + l1_mv_array[j4][i4][1];
|
vec2_y = (img->block_y * 2 + joff) * mv_mul + l1_mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
vec2_y = ((img->block_y-4) * 2 + joff)* mv_mul + l1_mv_array[j4][i4][1];
|
vec2_y = ((img->block_y-4) * 2 + joff)* mv_mul + l1_mv_array[j4][i4][1];
|
}
|
}
|
}
|
}
|
get_block(l1_refframe, listX[1+list_offset], vec2_x, vec2_y, img, tmp_blockbw);
|
get_block(l1_refframe, listX[1+list_offset], vec2_x, vec2_y, img, tmp_blockbw);
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
vec1_x = i4 * 4 * mv_mul + l0_mv_array[j4][i4][0];
|
vec1_x = i4 * 4 * mv_mul + l0_mv_array[j4][i4][0];
|
vec2_x = i4 * 4 * mv_mul + l1_mv_array[j4][i4][0];
|
vec2_x = i4 * 4 * mv_mul + l1_mv_array[j4][i4][0];
|
|
|
if (!curr_mb_field)
|
if (!curr_mb_field)
|
{
|
{
|
vec1_y = j4 * 4 * mv_mul + l0_mv_array[j4][i4][1];
|
vec1_y = j4 * 4 * mv_mul + l0_mv_array[j4][i4][1];
|
vec2_y = j4 * 4 * mv_mul + l1_mv_array[j4][i4][1];
|
vec2_y = j4 * 4 * mv_mul + l1_mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
if ((mb_nr&0x01) == 0)
|
if ((mb_nr&0x01) == 0)
|
{
|
{
|
vec1_y = (img->block_y * 2 + joff) * mv_mul + l0_mv_array[j4][i4][1];
|
vec1_y = (img->block_y * 2 + joff) * mv_mul + l0_mv_array[j4][i4][1];
|
vec2_y = (img->block_y * 2 + joff) * mv_mul + l1_mv_array[j4][i4][1];
|
vec2_y = (img->block_y * 2 + joff) * mv_mul + l1_mv_array[j4][i4][1];
|
}
|
}
|
else
|
else
|
{
|
{
|
vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + l0_mv_array[j4][i4][1];
|
vec1_y = ((img->block_y-4) * 2 + joff)* mv_mul + l0_mv_array[j4][i4][1];
|
vec2_y = ((img->block_y-4) * 2 + joff)* mv_mul + l1_mv_array[j4][i4][1];
|
vec2_y = ((img->block_y-4) * 2 + joff)* mv_mul + l1_mv_array[j4][i4][1];
|
}
|
}
|
}
|
}
|
|
|
get_block(l0_refframe, listX[0+list_offset], vec1_x, vec1_y, img, tmp_block);
|
get_block(l0_refframe, listX[0+list_offset], vec1_x, vec1_y, img, tmp_block);
|
get_block(l1_refframe, listX[1+list_offset], vec2_x, vec2_y, img, tmp_blockbw);
|
get_block(l1_refframe, listX[1+list_offset], vec2_x, vec2_y, img, tmp_blockbw);
|
}
|
}
|
|
|
if (mv_mode==0 && img->direct_spatial_mv_pred_flag && direct_pdir==0)
|
if (mv_mode==0 && img->direct_spatial_mv_pred_flag && direct_pdir==0)
|
{
|
{
|
if (img->apply_weights)
|
if (img->apply_weights)
|
{
|
{
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
{
|
{
|
l0_ref_idx >>=1;
|
l0_ref_idx >>=1;
|
}
|
}
|
|
|
alpha_l0 = img->wp_weight[LIST_0][l0_ref_idx][0];
|
alpha_l0 = img->wp_weight[LIST_0][l0_ref_idx][0];
|
wp_offset = img->wp_offset[LIST_0][l0_refframe>>curr_mb_field][0];
|
wp_offset = img->wp_offset[LIST_0][l0_refframe>>curr_mb_field][0];
|
|
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value,
|
img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value,
|
(rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii]), img->luma_log2_weight_denom) + wp_offset));
|
(rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii]), img->luma_log2_weight_denom) + wp_offset));
|
}
|
}
|
else
|
else
|
{
|
{
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jj+joff][ii+ioff] = tmp_block[jj][ii];
|
img->mpr[jj+joff][ii+ioff] = tmp_block[jj][ii];
|
}
|
}
|
}
|
}
|
else if (mv_mode==0 && img->direct_spatial_mv_pred_flag && direct_pdir==1)
|
else if (mv_mode==0 && img->direct_spatial_mv_pred_flag && direct_pdir==1)
|
{
|
{
|
if (img->apply_weights)
|
if (img->apply_weights)
|
{
|
{
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
{
|
{
|
l1_ref_idx >>=1;
|
l1_ref_idx >>=1;
|
}
|
}
|
alpha_l1 = img->wp_weight[LIST_1][l1_ref_idx][0];
|
alpha_l1 = img->wp_weight[LIST_1][l1_ref_idx][0];
|
wp_offset = img->wp_offset[LIST_1][l1_refframe>>curr_mb_field][0];
|
wp_offset = img->wp_offset[LIST_1][l1_refframe>>curr_mb_field][0];
|
|
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value,
|
img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value,
|
(rshift_rnd_sf((alpha_l1 * tmp_blockbw[jj][ii]), img->luma_log2_weight_denom) + wp_offset));
|
(rshift_rnd_sf((alpha_l1 * tmp_blockbw[jj][ii]), img->luma_log2_weight_denom) + wp_offset));
|
}
|
}
|
else
|
else
|
{
|
{
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jj+joff][ii+ioff] = tmp_blockbw[jj][ii];
|
img->mpr[jj+joff][ii+ioff] = tmp_blockbw[jj][ii];
|
}
|
}
|
}
|
}
|
else if(img->apply_weights)
|
else if(img->apply_weights)
|
{
|
{
|
int wt_list_offset = (active_pps->weighted_bipred_idc==2)?list_offset:0;
|
int wt_list_offset = (active_pps->weighted_bipred_idc==2)?list_offset:0;
|
|
|
if (mv_mode==0 && img->direct_spatial_mv_pred_flag==0 )l1_ref_idx=0; //temporal direct
|
if (mv_mode==0 && img->direct_spatial_mv_pred_flag==0 )l1_ref_idx=0; //temporal direct
|
|
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
{
|
{
|
l0_ref_idx >>=1;
|
l0_ref_idx >>=1;
|
l1_ref_idx >>=1;
|
l1_ref_idx >>=1;
|
}
|
}
|
|
|
alpha_l0 = img->wbp_weight[LIST_0 + wt_list_offset][l0_ref_idx][l1_ref_idx][0];
|
alpha_l0 = img->wbp_weight[LIST_0 + wt_list_offset][l0_ref_idx][l1_ref_idx][0];
|
alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][0];
|
alpha_l1 = img->wbp_weight[LIST_1 + wt_list_offset][l0_ref_idx][l1_ref_idx][0];
|
wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][0] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][0] + 1) >>1);
|
wp_offset = ((img->wp_offset [LIST_0 + wt_list_offset][l0_ref_idx][0] + img->wp_offset[LIST_1 + wt_list_offset][l1_ref_idx][0] + 1) >>1);
|
|
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
img->mpr[jj+joff][ii+ioff] = (int)iClip1(img->max_imgpel_value,
|
img->mpr[jj+joff][ii+ioff] = (int)iClip1(img->max_imgpel_value,
|
(rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii] + alpha_l1 * tmp_blockbw[jj][ii]), (img->luma_log2_weight_denom + 1)) + wp_offset));
|
(rshift_rnd_sf((alpha_l0 * tmp_block[jj][ii] + alpha_l1 * tmp_blockbw[jj][ii]), (img->luma_log2_weight_denom + 1)) + wp_offset));
|
}
|
}
|
else
|
else
|
{
|
{
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
img->mpr[jj+joff][ii+ioff] = (tmp_block[jj][ii]+tmp_blockbw[jj][ii]+1)>>1;
|
img->mpr[jj+joff][ii+ioff] = (tmp_block[jj][ii]+tmp_blockbw[jj][ii]+1)>>1;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
// =============== 4x4 itrans ================
|
// =============== 4x4 itrans ================
|
// -------------------------------------------
|
// -------------------------------------------
|
if (smb && mv_mode!=IBLOCK)
|
if (smb && mv_mode!=IBLOCK)
|
{
|
{
|
if(!IS_NEWINTRA (currMB))// modif ES added
|
if(!IS_NEWINTRA (currMB))// modif ES added
|
itrans_sp(img,ioff,joff,i,j);
|
itrans_sp(img,ioff,joff,i,j);
|
else //modif ES added
|
else //modif ES added
|
itrans(img,ioff,joff,i,j,0); // modif ES added
|
itrans(img,ioff,joff,i,j,0); // modif ES added
|
}
|
}
|
else
|
else
|
{
|
{
|
if(need_4x4_transform)
|
if(need_4x4_transform)
|
{
|
{
|
if(img->type==SP_SLICE && currMB->mb_type != I16MB) // ES added
|
if(img->type==SP_SLICE && currMB->mb_type != I16MB) // ES added
|
itrans_sp(img,ioff,joff,i,j);//ES added
|
itrans_sp(img,ioff,joff,i,j);//ES added
|
else
|
else
|
itrans (img,ioff,joff,i,j, 0); // use DCT transform and make 4x4 block m7 from prediction block mpr
|
itrans (img,ioff,joff,i,j, 0); // use DCT transform and make 4x4 block m7 from prediction block mpr
|
}
|
}
|
}
|
}
|
if(need_4x4_transform)
|
if(need_4x4_transform)
|
{
|
{
|
int j_pos = j4 * BLOCK_SIZE;
|
int j_pos = j4 * BLOCK_SIZE;
|
int i_pos = i4 * BLOCK_SIZE;
|
int i_pos = i4 * BLOCK_SIZE;
|
|
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
for(jj=0;jj<BLOCK_SIZE;jj++)
|
{
|
{
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
for(ii=0;ii<BLOCK_SIZE;ii++)
|
{
|
{
|
dec_picture->imgY[j_pos + jj][i_pos + ii]=img->m7[jj][ii]; // construct picture from 4x4 blocks
|
dec_picture->imgY[j_pos + jj][i_pos + ii]=img->m7[jj][ii]; // construct picture from 4x4 blocks
|
}
|
}
|
}
|
}
|
}// if(need_4x4_transform)
|
}// if(need_4x4_transform)
|
}
|
}
|
|
|
if(!need_4x4_transform)
|
if(!need_4x4_transform)
|
{
|
{
|
// =============== 8x8 itrans ================
|
// =============== 8x8 itrans ================
|
// -------------------------------------------
|
// -------------------------------------------
|
ioff = 8*(block8x8&0x01);
|
ioff = 8*(block8x8&0x01);
|
joff = 8*(block8x8>>1);
|
joff = 8*(block8x8>>1);
|
|
|
itrans8x8(img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
|
itrans8x8(img,ioff,joff); // use DCT transform and make 8x8 block m7 from prediction block mpr
|
|
|
for(jj=joff;jj<joff + 8;jj++)
|
for(jj=joff;jj<joff + 8;jj++)
|
{
|
{
|
for(ii=ioff;ii<ioff + 8;ii++)
|
for(ii=ioff;ii<ioff + 8;ii++)
|
{
|
{
|
dec_picture->imgY[img->pix_y + jj][img->pix_x + ii]=img->m7[jj][ii]; // construct picture from 4x4 blocks
|
dec_picture->imgY[img->pix_y + jj][img->pix_x + ii]=img->m7[jj][ii]; // construct picture from 4x4 blocks
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (dec_picture->chroma_format_idc != YUV400)
|
if (dec_picture->chroma_format_idc != YUV400)
|
{
|
{
|
// chroma decoding *******************************************************
|
// chroma decoding *******************************************************
|
f1_x = 64/img->mb_cr_size_x;
|
f1_x = 64/img->mb_cr_size_x;
|
f2_x = f1_x-1;
|
f2_x = f1_x-1;
|
|
|
f1_y = 64/img->mb_cr_size_y;
|
f1_y = 64/img->mb_cr_size_y;
|
f2_y = f1_y-1;
|
f2_y = f1_y-1;
|
|
|
f3 = f1_x*f1_y;
|
f3 = f1_x*f1_y;
|
f4 = f3>>1;
|
f4 = f3>>1;
|
|
|
for(uv=0;uv<2;uv++)
|
for(uv=0;uv<2;uv++)
|
{
|
{
|
uv_shift = uv*(img->num_blk8x8_uv>>1);
|
uv_shift = uv*(img->num_blk8x8_uv>>1);
|
intra_prediction = IS_INTRA (currMB);
|
intra_prediction = IS_INTRA (currMB);
|
|
|
if (intra_prediction)
|
if (intra_prediction)
|
{
|
{
|
intrapred_chroma(img, uv);
|
intrapred_chroma(img, uv);
|
}
|
}
|
|
|
for (b8=0;b8<(img->num_blk8x8_uv>>1);b8++)
|
for (b8=0;b8<(img->num_blk8x8_uv>>1);b8++)
|
{
|
{
|
for(b4=0;b4<4;b4++)
|
for(b4=0;b4<4;b4++)
|
{
|
{
|
joff = subblk_offset_y[yuv][b8][b4];
|
joff = subblk_offset_y[yuv][b8][b4];
|
j4 = img->pix_c_y+joff;
|
j4 = img->pix_c_y+joff;
|
ioff = subblk_offset_x[yuv][b8][b4];
|
ioff = subblk_offset_x[yuv][b8][b4];
|
i4 = img->pix_c_x+ioff;
|
i4 = img->pix_c_x+ioff;
|
|
|
mv_mode = currMB->b8mode[block8x8_idx[yuv][b8][b4]];
|
mv_mode = currMB->b8mode[block8x8_idx[yuv][b8][b4]];
|
pred_dir = currMB->b8pdir[block8x8_idx[yuv][b8][b4]];
|
pred_dir = currMB->b8pdir[block8x8_idx[yuv][b8][b4]];
|
assert (pred_dir<=2);
|
assert (pred_dir<=2);
|
|
|
|
|
if (!intra_prediction)
|
if (!intra_prediction)
|
{
|
{
|
if (pred_dir != 2)
|
if (pred_dir != 2)
|
{
|
{
|
int jpos;
|
int jpos;
|
//--- FORWARD/BACKWARD PREDICTION ---
|
//--- FORWARD/BACKWARD PREDICTION ---
|
mv_array = dec_picture->mv[LIST_0 + pred_dir];
|
mv_array = dec_picture->mv[LIST_0 + pred_dir];
|
list = listX[0+list_offset+pred_dir];
|
list = listX[0+list_offset+pred_dir];
|
|
|
for(jj=0;jj<4;jj++)
|
for(jj=0;jj<4;jj++)
|
{
|
{
|
jf=(j4+jj)/(img->mb_size_blk[1][1]); // jf = Subblock_y-coordinate
|
jf=(j4+jj)/(img->mb_size_blk[1][1]); // jf = Subblock_y-coordinate
|
|
|
if (!curr_mb_field)
|
if (!curr_mb_field)
|
jpos=(j4+jj)*f1_y;
|
jpos=(j4+jj)*f1_y;
|
else
|
else
|
{
|
{
|
if ((mb_nr&0x01) == 0)
|
if ((mb_nr&0x01) == 0)
|
jpos=(((img->pix_c_y)>>1) + jj + joff)*f1_y;
|
jpos=(((img->pix_c_y)>>1) + jj + joff)*f1_y;
|
else
|
else
|
jpos=(((img->pix_c_y-img->mb_cr_size_y)>>1) + jj + joff)*f1_y;
|
jpos=(((img->pix_c_y-img->mb_cr_size_y)>>1) + jj + joff)*f1_y;
|
}
|
}
|
|
|
for(ii=0;ii<4;ii++)
|
for(ii=0;ii<4;ii++)
|
{
|
{
|
ifx=(i4+ii)/(img->mb_size_blk[1][0]); // ifx = Subblock_x-coordinate
|
ifx=(i4+ii)/(img->mb_size_blk[1][0]); // ifx = Subblock_x-coordinate
|
l0_refframe = ref_idx = dec_picture->ref_idx[LIST_0+pred_dir][jf][ifx];
|
l0_refframe = ref_idx = dec_picture->ref_idx[LIST_0+pred_dir][jf][ifx];
|
i1=(i4+ii)*f1_x+mv_array[jf][ifx][0];
|
i1=(i4+ii)*f1_x+mv_array[jf][ifx][0];
|
|
|
j1 = jpos+mv_array[jf][ifx][1];
|
j1 = jpos+mv_array[jf][ifx][1];
|
if (active_sps->chroma_format_idc == 1)
|
if (active_sps->chroma_format_idc == 1)
|
j1 += list[ref_idx]->chroma_vector_adjustment;
|
j1 += list[ref_idx]->chroma_vector_adjustment;
|
|
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
|
|
if1=(i1 & f2_x);
|
if1=(i1 & f2_x);
|
jf1=(j1 & f2_y);
|
jf1=(j1 & f2_y);
|
if0=f1_x-if1;
|
if0=f1_x-if1;
|
jf0=f1_y-jf1;
|
jf0=f1_y-jf1;
|
|
|
if (img->apply_weights)
|
if (img->apply_weights)
|
{
|
{
|
imgpel **curUV = list[ref_idx]->imgUV[uv];
|
imgpel **curUV = list[ref_idx]->imgUV[uv];
|
pred = (if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
|
pred = (if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
|
if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
|
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
{
|
{
|
ref_idx >>=1;
|
ref_idx >>=1;
|
}
|
}
|
|
|
img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value_uv, (((img->wp_weight[pred_dir][ref_idx][uv+1] * pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[pred_dir][ref_idx][uv+1]));
|
img->mpr[jj+joff][ii+ioff] = iClip1(img->max_imgpel_value_uv, (((img->wp_weight[pred_dir][ref_idx][uv+1] * pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[pred_dir][ref_idx][uv+1]));
|
}
|
}
|
else
|
else
|
{
|
{
|
imgpel **curUV = list[ref_idx]->imgUV[uv];
|
imgpel **curUV = list[ref_idx]->imgUV[uv];
|
img->mpr[jj+joff][ii+ioff]=(
|
img->mpr[jj+joff][ii+ioff]=(
|
if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
|
if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
|
if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
l0_mv_array = dec_picture->mv[LIST_0];
|
l0_mv_array = dec_picture->mv[LIST_0];
|
l1_mv_array = dec_picture->mv[LIST_1];
|
l1_mv_array = dec_picture->mv[LIST_1];
|
|
|
for(jj=0;jj<4;jj++)
|
for(jj=0;jj<4;jj++)
|
{
|
{
|
int jpos;
|
int jpos;
|
jf=(j4+jj)/(img->mb_size_blk[1][1]); // jf = Subblock_y-coordinate
|
jf=(j4+jj)/(img->mb_size_blk[1][1]); // jf = Subblock_y-coordinate
|
|
|
if (!curr_mb_field)
|
if (!curr_mb_field)
|
{
|
{
|
jpos=(j4+jj)*f1_y;
|
jpos=(j4+jj)*f1_y;
|
}
|
}
|
else
|
else
|
{
|
{
|
if ((mb_nr&0x01) == 0)
|
if ((mb_nr&0x01) == 0)
|
jpos=(((img->pix_c_y)>>1) + jj + joff)*f1_y;
|
jpos=(((img->pix_c_y)>>1) + jj + joff)*f1_y;
|
else
|
else
|
jpos=(((img->pix_c_y-img->mb_cr_size_y)>>1) + jj + joff)*f1_y;
|
jpos=(((img->pix_c_y-img->mb_cr_size_y)>>1) + jj + joff)*f1_y;
|
}
|
}
|
|
|
for(ii=0;ii<4;ii++)
|
for(ii=0;ii<4;ii++)
|
{
|
{
|
ifx=(i4+ii)/(img->mb_size_blk[1][0]); // ifx = Subblock_x-coordinate
|
ifx=(i4+ii)/(img->mb_size_blk[1][0]); // ifx = Subblock_x-coordinate
|
direct_pdir = 2;
|
direct_pdir = 2;
|
|
|
if (mv_mode == 0 && img->direct_spatial_mv_pred_flag)
|
if (mv_mode == 0 && img->direct_spatial_mv_pred_flag)
|
{
|
{
|
//===== DIRECT PREDICTION =====
|
//===== DIRECT PREDICTION =====
|
if (dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2]!=-1)
|
if (dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2]!=-1)
|
{
|
{
|
l0_refframe = dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2];
|
l0_refframe = dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2];
|
l0_ref_idx = l0_refframe;
|
l0_ref_idx = l0_refframe;
|
}
|
}
|
if (dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2]!=-1)
|
if (dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2]!=-1)
|
{
|
{
|
l1_refframe = dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2];
|
l1_refframe = dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2];
|
l1_ref_idx = l1_refframe;
|
l1_ref_idx = l1_refframe;
|
}
|
}
|
|
|
if (dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2]==-1) direct_pdir = 0;
|
if (dec_picture->ref_idx[LIST_1][2*(jf>>1)][(ifx>>1)*2]==-1) direct_pdir = 0;
|
else if (dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2]==-1) direct_pdir = 1;
|
else if (dec_picture->ref_idx[LIST_0][2*(jf>>1)][(ifx>>1)*2]==-1) direct_pdir = 1;
|
|
|
if (direct_pdir == 0 || direct_pdir == 2)
|
if (direct_pdir == 0 || direct_pdir == 2)
|
{
|
{
|
i1=(i4+ii)*f1_x+l0_mv_array[jf][ifx][0];
|
i1=(i4+ii)*f1_x+l0_mv_array[jf][ifx][0];
|
|
|
j1=jpos+l0_mv_array[jf][ifx][1];
|
j1=jpos+l0_mv_array[jf][ifx][1];
|
if (active_sps->chroma_format_idc == 1)
|
if (active_sps->chroma_format_idc == 1)
|
j1 += listX[0+list_offset][l0_refframe]->chroma_vector_adjustment;
|
j1 += listX[0+list_offset][l0_refframe]->chroma_vector_adjustment;
|
|
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
|
|
|
|
if1=(i1 & f2_x);
|
if1=(i1 & f2_x);
|
jf1=(j1 & f2_y);
|
jf1=(j1 & f2_y);
|
if0=f1_x-if1;
|
if0=f1_x-if1;
|
jf0=f1_y-jf1;
|
jf0=f1_y-jf1;
|
|
|
{
|
{
|
imgpel **curUV = listX[LIST_0 + list_offset][l0_refframe]->imgUV[uv];
|
imgpel **curUV = listX[LIST_0 + list_offset][l0_refframe]->imgUV[uv];
|
fw_pred=(if0*jf0 * curUV[jj0][ii0]+
|
fw_pred=(if0*jf0 * curUV[jj0][ii0]+
|
if1*jf0 * curUV[jj0][ii1]+
|
if1*jf0 * curUV[jj0][ii1]+
|
if0*jf1 * curUV[jj1][ii0]+
|
if0*jf1 * curUV[jj1][ii0]+
|
if1*jf1 * curUV[jj1][ii1]+f4)/f3;
|
if1*jf1 * curUV[jj1][ii1]+f4)/f3;
|
}
|
}
|
}
|
}
|
if (direct_pdir == 1 || direct_pdir == 2)
|
if (direct_pdir == 1 || direct_pdir == 2)
|
{
|
{
|
i1=(i4+ii)*f1_x+l1_mv_array[jf][ifx][0];
|
i1=(i4+ii)*f1_x+l1_mv_array[jf][ifx][0];
|
|
|
j1=jpos+l1_mv_array[jf][ifx][1];
|
j1=jpos+l1_mv_array[jf][ifx][1];
|
if (active_sps->chroma_format_idc == 1)
|
if (active_sps->chroma_format_idc == 1)
|
j1 += listX[1+list_offset][l1_refframe]->chroma_vector_adjustment;
|
j1 += listX[1+list_offset][l1_refframe]->chroma_vector_adjustment;
|
|
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
|
|
if1=(i1 & f2_x);
|
if1=(i1 & f2_x);
|
jf1=(j1 & f2_y);
|
jf1=(j1 & f2_y);
|
if0=f1_x-if1;
|
if0=f1_x-if1;
|
jf0=f1_y-jf1;
|
jf0=f1_y-jf1;
|
|
|
{
|
{
|
imgpel **curUV = listX[1+list_offset][l1_refframe]->imgUV[uv];
|
imgpel **curUV = listX[1+list_offset][l1_refframe]->imgUV[uv];
|
bw_pred=(if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
|
bw_pred=(if0*jf0*curUV[jj0][ii0] + if1*jf0*curUV[jj0][ii1]+
|
if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
if0*jf1*curUV[jj1][ii0] + if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
}
|
}
|
}
|
}
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
//===== BI-DIRECTIONAL PREDICTION =====
|
//===== BI-DIRECTIONAL PREDICTION =====
|
l0_refframe = dec_picture->ref_idx[LIST_0][jf][ifx];
|
l0_refframe = dec_picture->ref_idx[LIST_0][jf][ifx];
|
l1_refframe = dec_picture->ref_idx[LIST_1][jf][ifx];
|
l1_refframe = dec_picture->ref_idx[LIST_1][jf][ifx];
|
|
|
l0_ref_idx = l0_refframe;
|
l0_ref_idx = l0_refframe;
|
l1_ref_idx = l1_refframe;
|
l1_ref_idx = l1_refframe;
|
|
|
i1=(i4+ii)*f1_x+l0_mv_array[jf][ifx][0];
|
i1=(i4+ii)*f1_x+l0_mv_array[jf][ifx][0];
|
|
|
j1=jpos+l0_mv_array[jf][ifx][1];
|
j1=jpos+l0_mv_array[jf][ifx][1];
|
if (active_sps->chroma_format_idc == 1)
|
if (active_sps->chroma_format_idc == 1)
|
j1 += listX[0+list_offset][l0_refframe]->chroma_vector_adjustment;
|
j1 += listX[0+list_offset][l0_refframe]->chroma_vector_adjustment;
|
|
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
|
|
if1=(i1 & f2_x);
|
if1=(i1 & f2_x);
|
jf1=(j1 & f2_y);
|
jf1=(j1 & f2_y);
|
if0=f1_x-if1;
|
if0=f1_x-if1;
|
jf0=f1_y-jf1;
|
jf0=f1_y-jf1;
|
{
|
{
|
imgpel **curUV = listX[0+list_offset][l0_refframe]->imgUV[uv];
|
imgpel **curUV = listX[0+list_offset][l0_refframe]->imgUV[uv];
|
|
|
fw_pred=(if0*jf0*curUV[jj0][ii0]+
|
fw_pred=(if0*jf0*curUV[jj0][ii0]+
|
if1*jf0*curUV[jj0][ii1]+
|
if1*jf0*curUV[jj0][ii1]+
|
if0*jf1*curUV[jj1][ii0]+
|
if0*jf1*curUV[jj1][ii0]+
|
if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
}
|
}
|
i1=(i4+ii)*f1_x+l1_mv_array[jf][ifx][0];
|
i1=(i4+ii)*f1_x+l1_mv_array[jf][ifx][0];
|
|
|
j1=jpos+l1_mv_array[jf][ifx][1];
|
j1=jpos+l1_mv_array[jf][ifx][1];
|
if (active_sps->chroma_format_idc == 1)
|
if (active_sps->chroma_format_idc == 1)
|
j1 += listX[1+list_offset][l1_refframe]->chroma_vector_adjustment;
|
j1 += listX[1+list_offset][l1_refframe]->chroma_vector_adjustment;
|
|
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
ii0 = iClip3 (0, img->width_cr_m1, i1/f1_x);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
jj0 = iClip3 (0, max_y_cr, j1/f1_y);
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
ii1 = iClip3 (0, img->width_cr_m1, ((i1+f2_x)/f1_x));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
jj1 = iClip3 (0, max_y_cr, ((j1+f2_y)/f1_y));
|
|
|
|
|
if1=(i1 & f2_x);
|
if1=(i1 & f2_x);
|
jf1=(j1 & f2_y);
|
jf1=(j1 & f2_y);
|
if0=f1_x-if1;
|
if0=f1_x-if1;
|
jf0=f1_y-jf1;
|
jf0=f1_y-jf1;
|
|
|
{
|
{
|
imgpel **curUV = listX[1+list_offset][l1_refframe]->imgUV[uv];
|
imgpel **curUV = listX[1+list_offset][l1_refframe]->imgUV[uv];
|
bw_pred=(if0*jf0*curUV[jj0][ii0]+ if1*jf0*curUV[jj0][ii1]+
|
bw_pred=(if0*jf0*curUV[jj0][ii0]+ if1*jf0*curUV[jj0][ii1]+
|
if0*jf1*curUV[jj1][ii0]+if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
if0*jf1*curUV[jj1][ii0]+if1*jf1*curUV[jj1][ii1]+f4)/f3;
|
}
|
}
|
|
|
}
|
}
|
|
|
if (img->apply_weights)
|
if (img->apply_weights)
|
{
|
{
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
if (((active_pps->weighted_pred_flag&&(img->type==P_SLICE|| img->type == SP_SLICE))||
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
(active_pps->weighted_bipred_idc==1 && (img->type==B_SLICE))) && curr_mb_field)
|
{
|
{
|
l0_ref_idx >>=1;
|
l0_ref_idx >>=1;
|
l1_ref_idx >>=1;
|
l1_ref_idx >>=1;
|
}
|
}
|
|
|
if (img->direct_spatial_mv_pred_flag && direct_pdir==1)
|
if (img->direct_spatial_mv_pred_flag && direct_pdir==1)
|
{
|
{
|
img->mpr[jj+joff][ii+ioff]= iClip1(img->max_imgpel_value_uv,
|
img->mpr[jj+joff][ii+ioff]= iClip1(img->max_imgpel_value_uv,
|
(((img->wp_weight[1][l1_ref_idx][uv+1] * bw_pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[1][l1_refframe>>curr_mb_field][uv+1])); // Replaced with integer only operations
|
(((img->wp_weight[1][l1_ref_idx][uv+1] * bw_pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[1][l1_refframe>>curr_mb_field][uv+1])); // Replaced with integer only operations
|
}
|
}
|
else if (img->direct_spatial_mv_pred_flag && direct_pdir==0)
|
else if (img->direct_spatial_mv_pred_flag && direct_pdir==0)
|
{
|
{
|
img->mpr[jj+joff][ii+ioff]=iClip1(img->max_imgpel_value_uv, (((img->wp_weight[0][l0_ref_idx][uv+1] * fw_pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[0][l0_refframe>>curr_mb_field][uv+1])); // Replaced with integer only operations
|
img->mpr[jj+joff][ii+ioff]=iClip1(img->max_imgpel_value_uv, (((img->wp_weight[0][l0_ref_idx][uv+1] * fw_pred + img->wp_round_chroma)>>img->chroma_log2_weight_denom) + img->wp_offset[0][l0_refframe>>curr_mb_field][uv+1])); // Replaced with integer only operations
|
}
|
}
|
else
|
else
|
{
|
{
|
int wt_list_offset = (active_pps->weighted_bipred_idc==2)?list_offset:0;
|
int wt_list_offset = (active_pps->weighted_bipred_idc==2)?list_offset:0;
|
|
|
alpha_l0 = img->wbp_weight[0+wt_list_offset][l0_ref_idx][l1_ref_idx][uv+1];
|
alpha_l0 = img->wbp_weight[0+wt_list_offset][l0_ref_idx][l1_ref_idx][uv+1];
|
alpha_l1 = img->wbp_weight[1+wt_list_offset][l0_ref_idx][l1_ref_idx][uv+1];
|
alpha_l1 = img->wbp_weight[1+wt_list_offset][l0_ref_idx][l1_ref_idx][uv+1];
|
|
|
img->mpr[jj+joff][ii+ioff]= iClip1(img->max_imgpel_value_uv, (((alpha_l0 * fw_pred + alpha_l1 * bw_pred + (1<<img->chroma_log2_weight_denom)) >> (img->chroma_log2_weight_denom + 1))+ ((img->wp_offset[wt_list_offset + 0][l0_ref_idx][uv+1] + img->wp_offset[wt_list_offset + 1][l1_ref_idx][uv+1] + 1)>>1)));
|
img->mpr[jj+joff][ii+ioff]= iClip1(img->max_imgpel_value_uv, (((alpha_l0 * fw_pred + alpha_l1 * bw_pred + (1<<img->chroma_log2_weight_denom)) >> (img->chroma_log2_weight_denom + 1))+ ((img->wp_offset[wt_list_offset + 0][l0_ref_idx][uv+1] + img->wp_offset[wt_list_offset + 1][l1_ref_idx][uv+1] + 1)>>1)));
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
if (img->direct_spatial_mv_pred_flag && direct_pdir==1)
|
if (img->direct_spatial_mv_pred_flag && direct_pdir==1)
|
{
|
{
|
img->mpr[jj+joff][ii+ioff]=bw_pred;
|
img->mpr[jj+joff][ii+ioff]=bw_pred;
|
}
|
}
|
else if (img->direct_spatial_mv_pred_flag && direct_pdir==0)
|
else if (img->direct_spatial_mv_pred_flag && direct_pdir==0)
|
{
|
{
|
img->mpr[jj+joff][ii+ioff]=fw_pred;
|
img->mpr[jj+joff][ii+ioff]=fw_pred;
|
}
|
}
|
else
|
else
|
{
|
{
|
img->mpr[jj+joff][ii+ioff]=(fw_pred + bw_pred + 1 )>>1;
|
img->mpr[jj+joff][ii+ioff]=(fw_pred + bw_pred + 1 )>>1;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
} //if (!intra_prediction)
|
} //if (!intra_prediction)
|
|
|
if (!smb)
|
if (!smb)
|
{
|
{
|
imgpel **curUV = dec_picture->imgUV[uv];
|
imgpel **curUV = dec_picture->imgUV[uv];
|
itrans(img,ioff,joff, cofuv_blk_x[yuv][b8+uv_shift][b4], cofuv_blk_y[yuv][b8+uv_shift][b4], 1);
|
itrans(img,ioff,joff, cofuv_blk_x[yuv][b8+uv_shift][b4], cofuv_blk_y[yuv][b8+uv_shift][b4], 1);
|
|
|
for(jj=0;jj<4;jj++)
|
for(jj=0;jj<4;jj++)
|
for(ii=0;ii<4;ii++)
|
for(ii=0;ii<4;ii++)
|
{
|
{
|
curUV[j4+jj][i4+ii]=img->m7[jj][ii];
|
curUV[j4+jj][i4+ii]=img->m7[jj][ii];
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if(smb)
|
if(smb)
|
{
|
{
|
imgpel **curUV = dec_picture->imgUV[uv];
|
imgpel **curUV = dec_picture->imgUV[uv];
|
itrans_sp_chroma(img,2*uv);
|
itrans_sp_chroma(img,2*uv);
|
|
|
for (j=4;j<6;j++)
|
for (j=4;j<6;j++)
|
{
|
{
|
joff=(j-4)*4;
|
joff=(j-4)*4;
|
j4=img->pix_c_y+joff;
|
j4=img->pix_c_y+joff;
|
for(i=0;i<2;i++)
|
for(i=0;i<2;i++)
|
{
|
{
|
ioff=i*4;
|
ioff=i*4;
|
i4=img->pix_c_x+ioff;
|
i4=img->pix_c_x+ioff;
|
itrans(img,ioff,joff,2*uv+i,j, 1);
|
itrans(img,ioff,joff,2*uv+i,j, 1);
|
|
|
for(jj=0;jj<4;jj++)
|
for(jj=0;jj<4;jj++)
|
for(ii=0;ii<4;ii++)
|
for(ii=0;ii<4;ii++)
|
{
|
{
|
curUV[j4+jj][i4+ii]=img->m7[jj][ii];
|
curUV[j4+jj][i4+ii]=img->m7[jj][ii];
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|