macroblock.c
资源名称:chapter15.rar [点击查看]
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:173k
源码类别:
Audio
开发平台:
Visual C++
- /*!
- ***********************************************************************
- * file macroblock.c
- *
- * brief
- * Decode a Macroblock
- *
- * author
- * Main contributors (see contributors.h for copyright, address and affiliation details)
- * - Inge Lille-Lang鴜 <inge.lille-langoy@telenor.com>
- * - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
- * - Jani Lainema <jani.lainema@nokia.com>
- * - Sebastian Purreiter <sebastian.purreiter@mch.siemens.de>
- * - Thomas Wedi <wedi@tnt.uni-hannover.de>
- * - Detlev Marpe <marpe@hhi.de>
- * - Gabi Blaettermann
- * - Ye-Kui Wang <wyk@ieee.org>
- * - Lowell Winger <lwinger@lsil.com>
- * - Alexis Michael Tourapis <alexismt@ieee.org>
- ***********************************************************************
- */
- #include "contributors.h"
- #include <math.h>
- #include "global.h"
- #include "mbuffer.h"
- #include "elements.h"
- #include "errorconcealment.h"
- #include "macroblock.h"
- #include "fmo.h"
- #include "cabac.h"
- #include "vlc.h"
- #include "image.h"
- #include "mb_access.h"
- #include "biaridecod.h"
- #include "block.h"
- #include "transform8x8.h"
- #include "transform.h"
- #include "mc_prediction.h"
- #include "quant.h"
- #if TRACE
- #define TRACE_STRING(s) strncpy(currSE.tracestring, s, TRACESTRING_SIZE)
- #define TRACE_DECBITS(i) dectracebitcnt(1)
- #define TRACE_PRINTF(s) sprintf(type, "%s", s);
- #define TRACE_STRING_P(s) strncpy(currSE->tracestring, s, TRACESTRING_SIZE)
- #else
- #define TRACE_STRING(s)
- #define TRACE_DECBITS(i)
- #define TRACE_PRINTF(s)
- #define TRACE_STRING_P(s)
- #endif
- //! single scan pattern
- static const byte SNGL_SCAN[16][2] =
- {
- {0,0},{1,0},{0,1},{0,2},
- {1,1},{2,0},{3,0},{2,1},
- {1,2},{0,3},{1,3},{2,2},
- {3,1},{3,2},{2,3},{3,3}
- };
- //! field scan pattern
- static const byte FIELD_SCAN[16][2] =
- {
- {0,0},{0,1},{1,0},{0,2},
- {0,3},{1,1},{1,2},{1,3},
- {2,0},{2,1},{2,2},{2,3},
- {3,0},{3,1},{3,2},{3,3}
- };
- //! used to control block sizes : Not used/16x16/16x8/8x16/8x8/8x4/4x8/4x4
- static const int BLOCK_STEP[8][2]=
- {
- {0,0},{4,4},{4,2},{2,4},{2,2},{2,1},{1,2},{1,1}
- };
- const byte QP_SCALE_CR[52]=
- {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
- 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
- 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37,
- 37,38,38,38,39,39,39,39
- };
- //! single scan pattern
- const byte SNGL_SCAN8x8[64][2] = {
- {0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1}, {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0},
- {4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4}, {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3},
- {3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4}, {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6},
- {2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5}, {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7}
- };
- //! field scan pattern
- const byte FIELD_SCAN8x8[64][2] = { // 8x8
- {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2}, {2,0}, {1,3}, {0,5}, {0,6}, {0,7}, {1,4}, {2,1}, {3,0},
- {2,2}, {1,5}, {1,6}, {1,7}, {2,3}, {3,1}, {4,0}, {3,2}, {2,4}, {2,5}, {2,6}, {2,7}, {3,3}, {4,1}, {5,0}, {4,2},
- {3,4}, {3,5}, {3,6}, {3,7}, {4,3}, {5,1}, {6,0}, {5,2}, {4,4}, {4,5}, {4,6}, {4,7}, {5,3}, {6,1}, {6,2}, {5,4},
- {5,5}, {5,6}, {5,7}, {6,3}, {7,0}, {7,1}, {6,4}, {6,5}, {6,6}, {6,7}, {7,2}, {7,3}, {7,4}, {7,5}, {7,6}, {7,7}
- };
- //! single scan pattern
- const byte SCAN_YUV422[8][2] =
- {
- {0,0},{0,1},
- {1,0},{0,2},
- {0,3},{1,1},
- {1,2},{1,3}
- };
- static unsigned char cbp_blk_chroma[8][4] =
- { {16, 17, 18, 19},
- {20, 21, 22, 23},
- {24, 25, 26, 27},
- {28, 29, 30, 31},
- {32, 33, 34, 35},
- {36, 37, 38, 39},
- {40, 41, 42, 43},
- {44, 45, 46, 47} };
- //! look up tables for FRExt_chroma support
- const unsigned char subblk_offset_x[3][8][4] =
- {
- { {0, 4, 0, 4},
- {0, 4, 0, 4},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0}, },
- { {0, 4, 0, 4},
- {0, 4, 0, 4},
- {0, 4, 0, 4},
- {0, 4, 0, 4},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0}, },
- { {0, 4, 0, 4},
- {8,12, 8,12},
- {0, 4, 0, 4},
- {8,12, 8,12},
- {0, 4, 0, 4},
- {8,12, 8,12},
- {0, 4, 0, 4},
- {8,12, 8,12} }
- };
- const unsigned char subblk_offset_y[3][8][4] =
- { { {0, 0, 4, 4},
- {0, 0, 4, 4},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0}, },
- { {0, 0, 4, 4},
- {8, 8,12,12},
- {0, 0, 4, 4},
- {8, 8,12,12},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0} },
- { {0, 0, 4, 4},
- {0, 0, 4, 4},
- {8, 8,12,12},
- {8, 8,12,12},
- {0, 0, 4, 4},
- {0, 0, 4, 4},
- {8, 8,12,12},
- {8, 8,12,12} }
- };
- const unsigned char cofuv_blk_x[3][8][4] =
- { { {0, 1, 0, 1},
- {0, 1, 0, 1},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0} },
- { {0, 1, 0, 1},
- {0, 1, 0, 1},
- {0, 1, 0, 1},
- {0, 1, 0, 1},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0},
- {0, 0, 0, 0} },
- { {0, 1, 0, 1},
- {2, 3, 2, 3},
- {0, 1, 0, 1},
- {2, 3, 2, 3},
- {0, 1, 0, 1},
- {2, 3, 2, 3},
- {0, 1, 0, 1},
- {2, 3, 2, 3} }
- };
- static const unsigned char cofuv_blk_y[3][8][4] =
- {
- { { 0, 0, 1, 1},
- { 0, 0, 1, 1},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0} },
- { { 0, 0, 1, 1},
- { 2, 2, 3, 3},
- { 0, 0, 1, 1},
- { 2, 2, 3, 3},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0},
- { 0, 0, 0, 0} },
- { { 0, 0, 1, 1},
- { 0, 0, 1, 1},
- { 2, 2, 3, 3},
- { 2, 2, 3, 3},
- { 0, 0, 1, 1},
- { 0, 0, 1, 1},
- { 2, 2, 3, 3},
- { 2, 2, 3, 3}}
- };
- void dectracebitcnt(int count);
- extern int last_dquant;
- extern ColocatedParams *Co_located;
- extern ColocatedParams *Co_located_JV[MAX_PLANE]; //!< Co_located to be used during 4:4:4 independent mode decoding
- static void readMotionInfoFromNAL (ImageParameters *img, Macroblock *currMB);
- static void read_ipred_modes (ImageParameters *img, Macroblock *currMB);
- static void readCBPandCoeffsFromNAL(ImageParameters *img, Macroblock *currMB);
- static void readIPCMcoeffsFromNAL (ImageParameters *img, struct datapartition *dP);
- // Interpret MB mode
- static void (*interpret_mb_mode)(Macroblock *currMB);
- /*!
- ************************************************************************
- * brief
- * Set context for reference frames
- ************************************************************************
- */
- int BType2CtxRef (int btype)
- {
- return (btype >= 4);
- }
- /*!
- ************************************************************************
- * brief
- * Function pointer for reading the reference picture indices
- ************************************************************************
- */
- static char (*readRefPictureIdx) (SyntaxElement *currSE, DataPartition *dP, char b8mode, int list);
- /*!
- ************************************************************************
- * brief
- * Function for reading the reference picture indices using VLC
- ************************************************************************
- */
- static char readRefPictureIdx_VLC(SyntaxElement *currSE, DataPartition *dP, char b8mode, int list)
- {
- #if TRACE
- static char tstring[20];
- sprintf( tstring, "ref_idx_l%d", list);
- strncpy(currSE->tracestring, tstring, TRACESTRING_SIZE);
- #endif
- currSE->context = BType2CtxRef (b8mode);
- currSE->value2 = list;
- dP->readSyntaxElement (currSE,img,dP);
- return (char) currSE->value1;
- }
- /*!
- ************************************************************************
- * brief
- * Function for reading the reference picture indices using FLC
- ************************************************************************
- */
- static char readRefPictureIdx_FLC(SyntaxElement *currSE, DataPartition *dP, char b8mode, int list)
- {
- #if TRACE
- static char tstring[20];
- sprintf( tstring, "ref_idx_l%d", list);
- strncpy(currSE->tracestring, tstring, TRACESTRING_SIZE);
- #endif
- currSE->context = BType2CtxRef (b8mode);
- currSE->len = 1;
- readSyntaxElement_FLC(currSE, dP->bitstream);
- currSE->value1 = 1 - currSE->value1;
- return (char) currSE->value1;
- }
- /*!
- ************************************************************************
- * brief
- * Dummy Function for reading the reference picture indices
- ************************************************************************
- */
- static char readRefPictureIdx_Null(SyntaxElement *currSE, DataPartition *dP, char b8mode, int list)
- {
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * Function to prepare reference picture indice function pointer
- ************************************************************************
- */
- static inline void prepareListforRefIdx ( SyntaxElement *currSE, DataPartition *dP, int num_ref_idx_active, int refidx_present)
- {
- readRefPictureIdx = readRefPictureIdx_Null; // Initialize readRefPictureIdx
- if(num_ref_idx_active > 1)
- {
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- {
- currSE->mapping = linfo_ue;
- if (refidx_present)
- {
- if (num_ref_idx_active == 2)
- readRefPictureIdx = readRefPictureIdx_FLC;
- else
- readRefPictureIdx = readRefPictureIdx_VLC;
- }
- }
- else
- {
- currSE->reading = readRefFrame_CABAC;
- if (refidx_present)
- readRefPictureIdx = readRefPictureIdx_VLC;
- }
- }
- }
- void set_chroma_qp(ImageParameters *img, Macroblock* currMB)
- {
- int 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] = currMB->qpc[i] < 0 ? currMB->qpc[i] : QP_SCALE_CR[currMB->qpc[i]];
- currMB->qp_scaled[i + 1] = currMB->qpc[i] + img->bitdepth_chroma_qp_scale;
- }
- }
- /*!
- ************************************************************************
- * brief
- * updates chroma QP according to luma QP and bit depth
- ************************************************************************
- */
- void update_qp(ImageParameters *img, Macroblock *currMB, int qp)
- {
- currMB->qp = qp;
- currMB->qp_scaled[0] = qp + img->bitdepth_luma_qp_scale;
- set_chroma_qp(img, currMB);
- }
- static void read_delta_quant(SyntaxElement *currSE, DataPartition *dP, Slice *currSlice, ImageParameters *img, Macroblock *currMB, int *partMap, int type)
- {
- currSE->type = type;
- dP = &(currSlice->partArr[partMap[currSE->type]]);
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- {
- currSE->mapping = linfo_se;
- }
- else
- currSE->reading= readDquant_CABAC;
- TRACE_STRING_P("mb_qp_delta");
- dP->readSyntaxElement(currSE,img,dP);
- 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)))
- 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->bitdepth_luma_qp_scale;
- update_qp(img, currMB, img->qp);
- }
- /*!
- ************************************************************************
- * brief
- * Function to read reference picture indice values
- ************************************************************************
- */
- static inline void readMBRefPictureIdx (SyntaxElement *currSE, DataPartition *dP, Macroblock *currMB, ImageParameters *img, char **cur_ref_idx, int list, int step_v0, int step_h0)
- {
- static int k, j, j0, i0;
- static char refframe;
- for (j0 = 0; j0 < 4; j0 += step_v0)
- {
- img->subblock_y = j0;
- for (i0 = 0; i0 < 4; i0 += step_h0)
- {
- img->subblock_x = i0;
- k = 2 * (j0 >> 1) + (i0 >> 1);
- if ((currMB->b8pdir[k] == list || currMB->b8pdir[k] == BI_PRED) && currMB->b8mode[k] != 0)
- {
- refframe = readRefPictureIdx(currSE, dP, currMB->b8mode[k], list);
- for (j = j0; j < j0 + step_v0; j++)
- memset(&cur_ref_idx[j][img->block_x + i0], refframe, step_h0 * sizeof(char));
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Function to read reference picture indice values
- ************************************************************************
- */
- static inline void readMBMotionVectors (SyntaxElement *currSE, DataPartition *dP, Macroblock *currMB, ImageParameters *img, int list, int step_h0, int step_v0)
- {
- static int i, j, k, i4, j4, ii, jj, kk, i0, j0;
- static short curr_mvd[2], curr_mv[2], pred_mv[2];
- static short (*mvd)[4][2];
- static short ***mv;
- static int mv_mode, step_h, step_v;
- static char cur_ref_idx;
- for (j0=0; j0<4; j0+=step_v0)
- {
- for (i0=0; i0<4; i0+=step_h0)
- {
- kk = 2 * (j0 >> 1) + (i0 >> 1);
- if ((currMB->b8pdir[kk]== list || currMB->b8pdir[kk]== BI_PRED) && (currMB->b8mode[kk] !=0))//has forward vector
- {
- cur_ref_idx = dec_picture->motion.ref_idx[list][img->block_y+j0][img->block_x+i0];
- mv_mode = currMB->b8mode[kk];
- step_h = BLOCK_STEP [mv_mode][0];
- step_v = BLOCK_STEP [mv_mode][1];
- for (j = j0; j < j0 + step_v0; j += step_v)
- {
- img->subblock_y = j; // position used for context determination
- j4 = img->block_y + j;
- mv = &dec_picture->motion.mv [list][j4];
- mvd = &currMB->mvd [list][j];
- for (i = i0; i < i0 + step_h0; i += step_h)
- {
- img->subblock_x = i; // position used for context determination
- i4 = img->block_x + i;
- // first make mv-prediction
- SetMotionVectorPredictor (img, currMB, pred_mv, cur_ref_idx, (byte) list, dec_picture->motion.ref_idx, dec_picture->motion.mv, BLOCK_SIZE * i, BLOCK_SIZE * j, 4*step_h, 4*step_v);
- for (k=0; k < 2; k++)
- {
- #if TRACE
- static char tstring[20];
- sprintf( tstring, "mvd_l%d", list);
- strncpy(currSE->tracestring, tstring, TRACESTRING_SIZE);
- #endif
- currSE->value2 = (k << 1) + list; // identifies the component; only used for context determination
- dP->readSyntaxElement(currSE,img,dP);
- curr_mvd[k] = (short) currSE->value1;
- curr_mv [k] = (short)(curr_mvd[k] + pred_mv[k]); // compute motion vector
- }
- // Init first line (mv)
- for(ii = i4; ii < i4 + step_h; ii++)
- {
- memcpy(&mv[0][ii][0], curr_mv, 2 * sizeof(short));
- }
- // now copy all other lines
- for(jj = 1; jj < step_v; jj++)
- {
- memcpy(&mv[jj][i4][0], &mv[0][i4][0], 2 * step_h * sizeof(short));
- }
- // Init first line (mvd)
- for(ii = i; ii < i + step_h; ii++)
- {
- memcpy(&mvd[0][ii][0], curr_mvd, 2 * sizeof(short));
- }
- // now copy all other lines
- for(jj = 1; jj < step_v; jj++)
- {
- memcpy(&mvd[jj][i][0], &mvd[0][i][0], 2 * step_h * sizeof(short));
- }
- }
- }
- }
- }
- }
- }
- void invScaleCoeff(ImageParameters *img, Macroblock *currMB, int level, int run, int qp_per, int i, int j, int i0, int j0, int coef_ctr, const byte (*pos_scan4x4)[2], int (*InvLevelScale4x4)[4])
- {
- if (level != 0) /* leave if len=1 */
- {
- coef_ctr += run + 1;
- i0=pos_scan4x4[coef_ctr][0];
- j0=pos_scan4x4[coef_ctr][1];
- currMB->cbp_blk |= (int64)1 << ((j << 2) + i) ;
- img->cof[0][(j<<2) + j0][(i<<2) + i0]= rshift_rnd_sf((level * InvLevelScale4x4[j0][i0]) << qp_per, 4);
- }
- }
- /*!
- ************************************************************************
- * brief
- * initializes the current macroblock
- ************************************************************************
- */
- void start_macroblock(ImageParameters *img, Macroblock **currMB)
- {
- int mb_nr = img->current_mb_nr;
- *currMB = &img->mb_data[mb_nr]; // intialization code deleted, see below, StW
- (*currMB)->mbAddrX = mb_nr;
- assert (mb_nr < (int) img->PicSizeInMbs);
- /* Update coordinates of the current macroblock */
- if (img->MbaffFrameFlag)
- {
- img->mb_x = (mb_nr) % ((2*img->width) / MB_BLOCK_SIZE);
- img->mb_y = 2*((mb_nr) / ((2*img->width) / MB_BLOCK_SIZE));
- img->mb_y += (img->mb_x & 0x01);
- img->mb_x >>= 1;
- }
- else
- {
- img->mb_x = PicPos[mb_nr][0];
- img->mb_y = PicPos[mb_nr][1];
- }
- /* Define vertical positions */
- img->block_y = img->mb_y * BLOCK_SIZE; /* luma block position */
- img->block_y_aff = img->block_y;
- 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 */
- /* Define horizontal positions */
- 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_c_x = img->mb_x * img->mb_cr_size_x; /* chroma pixel position */
- // 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
- (*currMB)->slice_nr = img->current_slice_nr;
- if (img->current_slice_nr >= MAX_NUM_SLICES)
- {
- error ("Maximum number of supported slices exceeded. nPlease recompile with increased value for MAX_NUM_SLICES", 200);
- }
- dec_picture->slice_id[img->mb_y][img->mb_x] = (short) img->current_slice_nr;
- dec_picture->max_slice_id = (short) imax(img->current_slice_nr, dec_picture->max_slice_id);
- CheckAvailabilityOfNeighbors(*currMB);
- // Reset syntax element entries in MB struct
- (*currMB)->qp = img->qp ;
- (*currMB)->mb_type = 0;
- (*currMB)->delta_quant = 0;
- (*currMB)->cbp = 0;
- (*currMB)->cbp_blk = 0;
- (*currMB)->cbp_blk_CbCr[0] = 0;
- (*currMB)->cbp_blk_CbCr[1] = 0;
- (*currMB)->c_ipred_mode = DC_PRED_8; //GB
- memset(&((*currMB)->mvd[0][0][0][0]),0, 2 * BLOCK_MULTIPLE * BLOCK_MULTIPLE * 2 * sizeof(short));
- memset((*currMB)->cbp_bits, 0, 3 * sizeof(int64));
- memset((*currMB)->cbp_bits_8x8, 0, 3 * sizeof(int64));
- // initialize img->mb_rres
- memset(&(img->mb_rres[0][0][0]), 0, 3 * MB_PIXELS * sizeof(int));
- // store filtering parameters for this MB
- (*currMB)->DFDisableIdc = img->currentSlice->DFDisableIdc;
- (*currMB)->DFAlphaC0Offset = img->currentSlice->DFAlphaC0Offset;
- (*currMB)->DFBetaOffset = img->currentSlice->DFBetaOffset;
- }
- /*!
- ************************************************************************
- * brief
- * set coordinates of the next macroblock
- * check end_of_slice condition
- ************************************************************************
- */
- Boolean exit_macroblock(ImageParameters *img,int eos_bit)
- {
- //! The if() statement below resembles the original code, which tested
- //! 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
- //! picture by checking the tr of the next slice header!
- // printf ("exit_macroblock: FmoGetLastMBOfPicture %d, img->current_mb_nr %dn", FmoGetLastMBOfPicture(), img->current_mb_nr);
- img->num_dec_mb++;
- if (img->num_dec_mb == img->PicSizeInMbs)
- {
- return TRUE;
- }
- // ask for last mb in the slice UVLC
- else
- {
- img->current_mb_nr = FmoGetNextMBNr (img->current_mb_nr);
- if (img->current_mb_nr == -1) // End of Slice group, MUST be end of slice
- {
- assert (nal_startcode_follows (img->currentSlice, eos_bit) == TRUE);
- return TRUE;
- }
- if(nal_startcode_follows(img->currentSlice, eos_bit) == FALSE)
- return FALSE;
- if(img->type == I_SLICE || img->type == SI_SLICE || active_pps->entropy_coding_mode_flag == CABAC)
- return TRUE;
- if(img->cod_counter <= 0)
- return TRUE;
- return FALSE;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Interpret the mb mode for P-Frames
- ************************************************************************
- */
- static void interpret_mb_mode_P(Macroblock *currMB)
- {
- const int ICBPTAB[6] = {0,16,32,15,31,47};
- int mbmode = currMB->mb_type;
- #define ZERO_P8x8 (mbmode==5)
- #define MODE_IS_P8x8 (mbmode==4 || mbmode==5)
- #define MODE_IS_I4x4 (mbmode==6)
- #define I16OFFSET (mbmode-7)
- #define MODE_IS_IPCM (mbmode==31)
- if(mbmode <4)
- {
- currMB->mb_type = mbmode;
- memset(&currMB->b8mode[0],mbmode,4 * sizeof(char));
- memset(&currMB->b8pdir[0], 0, 4 * sizeof(char));
- }
- else if(MODE_IS_P8x8)
- {
- currMB->mb_type = P8x8;
- img->allrefzero = ZERO_P8x8;
- }
- else if(MODE_IS_I4x4)
- {
- currMB->mb_type = I4MB;
- memset(&currMB->b8mode[0],IBLOCK, 4 * sizeof(char));
- memset(&currMB->b8pdir[0], -1, 4 * sizeof(char));
- }
- else if(MODE_IS_IPCM)
- {
- currMB->mb_type = IPCM;
- currMB->cbp = -1;
- currMB->i16mode = 0;
- memset(&currMB->b8mode[0], 0, 4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1, 4 * sizeof(char));
- }
- else
- {
- currMB->mb_type = I16MB;
- currMB->cbp = ICBPTAB[(I16OFFSET)>>2];
- currMB->i16mode = (I16OFFSET) & 0x03;
- memset(&currMB->b8mode[0], 0, 4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1, 4 * sizeof(char));
- }
- }
- /*!
- ************************************************************************
- * brief
- * Interpret the mb mode for I-Frames
- ************************************************************************
- */
- static void interpret_mb_mode_I(Macroblock *currMB)
- {
- static const int ICBPTAB[6] = {0,16,32,15,31,47};
- int mbmode = currMB->mb_type;
- if (mbmode==0)
- {
- currMB->mb_type = I4MB;
- memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- }
- else if(mbmode==25)
- {
- currMB->mb_type=IPCM;
- currMB->cbp= -1;
- currMB->i16mode = 0;
- memset(&currMB->b8mode[0],0,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- }
- else
- {
- currMB->mb_type = I16MB;
- currMB->cbp= ICBPTAB[(mbmode-1)>>2];
- currMB->i16mode = (mbmode-1) & 0x03;
- memset(&currMB->b8mode[0], 0, 4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1, 4 * sizeof(char));
- }
- }
- /*!
- ************************************************************************
- * brief
- * Interpret the mb mode for B-Frames
- ************************************************************************
- */
- static void interpret_mb_mode_B(Macroblock *currMB)
- {
- 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},
- {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},
- {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};
- int i, mbmode;
- int mbtype = currMB->mb_type;
- //--- set mbtype, b8type, and b8pdir ---
- if (mbtype==0) // direct
- {
- mbmode=0;
- memset(&currMB->b8mode[0],0,4 * sizeof(char));
- memset(&currMB->b8pdir[0],2,4 * sizeof(char));
- }
- else if (mbtype==23) // intra4x4
- {
- mbmode=I4MB;
- memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- }
- else if ((mbtype>23) && (mbtype<48) ) // intra16x16
- {
- mbmode=I16MB;
- memset(&currMB->b8mode[0],0,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- currMB->cbp = ICBPTAB[(mbtype-24)>>2];
- currMB->i16mode = (mbtype-24) & 0x03;
- }
- else if (mbtype==22) // 8x8(+split)
- {
- mbmode=P8x8; // b8mode and pdir is transmitted in additional codewords
- }
- else if (mbtype<4) // 16x16
- {
- mbmode=1;
- memset(&currMB->b8mode[0], 1,4 * sizeof(char));
- memset(&currMB->b8pdir[0],offset2pdir16x16[mbtype],4 * sizeof(char));
- }
- else if(mbtype==48)
- {
- mbmode=IPCM;
- memset(&currMB->b8mode[0], 0,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- currMB->cbp= -1;
- currMB->i16mode = 0;
- }
- else if ((mbtype&0x01)==0) // 16x8
- {
- mbmode=2;
- memset(&currMB->b8mode[0], 2,4 * sizeof(char));
- for(i=0;i<4;i++)
- {
- currMB->b8pdir[i] = (char) offset2pdir16x8 [mbtype][i>>1];
- }
- }
- else
- {
- mbmode=3;
- memset(&currMB->b8mode[0], 3,4 * sizeof(char));
- for(i=0;i<4;i++)
- {
- currMB->b8pdir[i] = (char) offset2pdir8x16 [mbtype][i&0x01];
- }
- }
- currMB->mb_type = mbmode;
- }
- /*!
- ************************************************************************
- * brief
- * Interpret the mb mode for SI-Frames
- ************************************************************************
- */
- static void interpret_mb_mode_SI(Macroblock *currMB)
- {
- const int ICBPTAB[6] = {0,16,32,15,31,47};
- int mbmode = currMB->mb_type;
- if (mbmode==0)
- {
- currMB->mb_type = SI4MB;
- memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- img->siblock[img->mb_y][img->mb_x]=1;
- }
- else if (mbmode==1)
- {
- currMB->mb_type = I4MB;
- memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- }
- else if(mbmode==26)
- {
- currMB->mb_type=IPCM;
- currMB->cbp= -1;
- currMB->i16mode = 0;
- memset(&currMB->b8mode[0],0,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- }
- else
- {
- currMB->mb_type = I16MB;
- currMB->cbp= ICBPTAB[(mbmode-1)>>2];
- currMB->i16mode = (mbmode-2) & 0x03;
- memset(&currMB->b8mode[0],0,4 * sizeof(char));
- memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
- }
- }
- /*!
- ************************************************************************
- * brief
- * Set mode interpretation based on slice type
- ************************************************************************
- */
- void set_interpret_mb_mode(int slice_type)
- {
- switch (slice_type)
- {
- case P_SLICE: case SP_SLICE:
- interpret_mb_mode = interpret_mb_mode_P;
- break;
- case B_SLICE:
- interpret_mb_mode = interpret_mb_mode_B;
- break;
- case I_SLICE:
- interpret_mb_mode = interpret_mb_mode_I;
- break;
- case SI_SLICE:
- interpret_mb_mode = interpret_mb_mode_SI;
- break;
- default:
- printf("Unsupported slice typen");
- break;
- }
- }
- /*!
- ************************************************************************
- * brief
- * init macroblock I and P frames
- ************************************************************************
- */
- static void init_macroblock(ImageParameters *img)
- {
- int i, j, k;
- for (k = LIST_0; k <= LIST_1; k++)
- {
- for(j = img->block_y; j < img->block_y + BLOCK_SIZE; j++)
- memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(char));
- for(j = img->block_y; j < img->block_y + BLOCK_SIZE; j++)
- { // reset vectors and pred. modes
- memset(&dec_picture->motion.mv[k][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
- memset(&dec_picture->motion.ref_idx[k][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
- for (i = img->block_x; i < img->block_x + BLOCK_SIZE;i++)
- {
- dec_picture->motion.ref_pic_id[k][j][i] = INT64_MIN;
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Sets mode for 8x8 block
- ************************************************************************
- */
- void SetB8Mode (ImageParameters* img, Macroblock* currMB, int value, int i)
- {
- 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 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};
- if (img->type==B_SLICE)
- {
- currMB->b8mode[i] = (char) b_v2b8[value];
- currMB->b8pdir[i] = (char) b_v2pd[value];
- }
- else
- {
- currMB->b8mode[i] = (char) p_v2b8[value];
- currMB->b8pdir[i] = (char) p_v2pd[value];
- }
- }
- void reset_coeffs(void)
- {
- // reset all coeffs
- memset(&img->fcf[0][0][0], 0, 3 * MB_PIXELS * sizeof(int));
- memset(&img->cof[0][0][0], 0, 3 * MB_PIXELS * sizeof(int));
- // CAVLC
- if (active_pps->entropy_coding_mode_flag == UVLC)
- memset(&img->nz_coeff[img->current_mb_nr][0][0][0], 0, 3 * BLOCK_SIZE * BLOCK_SIZE * sizeof(int));
- }
- void field_flag_inference(Macroblock *currMB)
- {
- if (currMB->mbAvailA)
- {
- currMB->mb_field = img->mb_data[currMB->mbAddrA].mb_field;
- }
- else
- {
- // check top macroblock pair
- currMB->mb_field = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0;
- }
- }
- void copy_macroblock(ImageParameters *img, Macroblock *currMB)
- {
- short pred_mv[2];
- int zeroMotionAbove;
- int zeroMotionLeft;
- PixelPos mb_a, mb_b;
- int i, j;
- int a_mv_y = 0;
- int a_ref_idx = 0;
- int b_mv_y = 0;
- int b_ref_idx = 0;
- int img_block_y = img->block_y;
- int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0;
- short ***cur_mv = dec_picture->motion.mv[LIST_0];
- get4x4Neighbour(currMB,-1, 0, img->mb_size[IS_LUMA], &mb_a);
- get4x4Neighbour(currMB, 0,-1, img->mb_size[IS_LUMA], &mb_b);
- if (mb_a.available)
- {
- a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1];
- a_ref_idx = dec_picture->motion.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)
- {
- a_mv_y /=2;
- a_ref_idx *=2;
- }
- if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
- {
- a_mv_y *=2;
- a_ref_idx >>=1;
- }
- }
- if (mb_b.available)
- {
- b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1];
- b_ref_idx = dec_picture->motion.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)
- {
- b_mv_y /=2;
- b_ref_idx *=2;
- }
- if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
- {
- b_mv_y *=2;
- 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;
- 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;
- reset_coeffs();
- if (zeroMotionAbove || zeroMotionLeft)
- {
- 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));
- }
- }
- else
- {
- SetMotionVectorPredictor (img, currMB, pred_mv, 0, LIST_0, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16);
- for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
- {
- for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
- memcpy(&cur_mv[j][i][0], &pred_mv[0], 2 * sizeof(short));
- }
- }
- for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++)
- {
- memset(&dec_picture->motion.ref_idx[LIST_0][j][img->block_x], 0, BLOCK_SIZE * sizeof(char));
- for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
- {
- dec_picture->motion.ref_pic_id[LIST_0][j][i] =
- dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->motion.ref_idx[LIST_0][j][i]];
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Get the syntax elements from the NAL
- ************************************************************************
- */
- void read_one_macroblock(ImageParameters *img, Macroblock *currMB)
- {
- int i;
- SyntaxElement currSE;
- int mb_nr = img->current_mb_nr;
- Slice *currSlice = img->currentSlice;
- DataPartition *dP;
- int *partMap = assignSE2partition[currSlice->dp_mode];
- Macroblock *topMB = NULL;
- int prevMbSkipped = 0;
- int check_bottom, read_bottom, read_top;
- if (img->MbaffFrameFlag)
- {
- if (mb_nr&0x01)
- {
- topMB= &img->mb_data[mb_nr-1];
- if(!(img->type == B_SLICE))
- prevMbSkipped = (topMB->mb_type == 0);
- else
- prevMbSkipped = topMB->skip_flag;
- }
- else
- prevMbSkipped = 0;
- }
- currMB->mb_field = ((mb_nr&0x01) == 0)? 0 : img->mb_data[mb_nr-1].mb_field;
- update_qp(img, currMB, img->qp);
- currSE.type = SE_MBTYPE;
- // read MB mode *****************************************************************
- dP = &(currSlice->partArr[partMap[currSE.type]]);
- 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)
- {
- // read MB aff
- if (img->MbaffFrameFlag && (mb_nr&0x01)==0)
- {
- TRACE_STRING("mb_field_decoding_flag");
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- {
- currSE.len = (int64) 1;
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- }
- else
- {
- currSE.reading = readFieldModeInfo_CABAC;
- dP->readSyntaxElement(&currSE,img,dP);
- }
- currMB->mb_field = currSE.value1;
- }
- if(active_pps->entropy_coding_mode_flag == CABAC)
- CheckAvailabilityOfNeighborsCABAC(currMB);
- // read MB type
- TRACE_STRING("mb_type");
- currSE.reading = readMB_typeInfo_CABAC;
- dP->readSyntaxElement(&currSE,img,dP);
- currMB->mb_type = currSE.value1;
- if(!dP->bitstream->ei_flag)
- currMB->ei_flag = 0;
- }
- // non I/SI-slice CABAC
- else if (active_pps->entropy_coding_mode_flag == CABAC)
- {
- // read MB skip_flag
- if (img->MbaffFrameFlag && ((mb_nr&0x01) == 0||prevMbSkipped))
- field_flag_inference(currMB);
- CheckAvailabilityOfNeighborsCABAC(currMB);
- TRACE_STRING("mb_skip_flag");
- currSE.reading = readMB_skip_flagInfo_CABAC;
- dP->readSyntaxElement(&currSE,img,dP);
- currMB->mb_type = currSE.value1;
- currMB->skip_flag = !(currSE.value1);
- if (img->type==B_SLICE)
- currMB->cbp = currSE.value2;
- if (!dP->bitstream->ei_flag)
- currMB->ei_flag = 0;
- if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0)
- img->cod_counter=0;
- // read MB AFF
- if (img->MbaffFrameFlag)
- {
- check_bottom=read_bottom=read_top=0;
- if ((mb_nr&0x01)==0)
- {
- check_bottom = currMB->skip_flag;
- read_top = !check_bottom;
- }
- else
- {
- read_bottom = (topMB->skip_flag && (!currMB->skip_flag));
- }
- if (read_bottom || read_top)
- {
- TRACE_STRING("mb_field_decoding_flag");
- currSE.reading = readFieldModeInfo_CABAC;
- dP->readSyntaxElement(&currSE,img,dP);
- currMB->mb_field = currSE.value1;
- }
- if (check_bottom)
- check_next_mb_and_get_field_mode_CABAC(&currSE,img,dP);
- }
- CheckAvailabilityOfNeighborsCABAC(currMB);
- // read MB type
- if (currMB->mb_type != 0 )
- {
- currSE.reading = readMB_typeInfo_CABAC;
- TRACE_STRING("mb_type");
- dP->readSyntaxElement(&currSE,img,dP);
- currMB->mb_type = currSE.value1;
- if(!dP->bitstream->ei_flag)
- currMB->ei_flag = 0;
- }
- }
- // VLC Non-Intra
- else
- {
- if(img->cod_counter == -1)
- {
- TRACE_STRING("mb_skip_run");
- dP->readSyntaxElement(&currSE,img,dP);
- img->cod_counter = currSE.value1;
- }
- if (img->cod_counter==0)
- {
- // read MB aff
- if ((img->MbaffFrameFlag) && (((mb_nr&0x01)==0) || ((mb_nr&0x01) && prevMbSkipped)))
- {
- TRACE_STRING("mb_field_decoding_flag");
- currSE.len = (int64) 1;
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- currMB->mb_field = currSE.value1;
- }
- // read MB type
- TRACE_STRING("mb_type");
- dP->readSyntaxElement(&currSE,img,dP);
- if(img->type == P_SLICE || img->type == SP_SLICE)
- currSE.value1++;
- currMB->mb_type = currSE.value1;
- if(!dP->bitstream->ei_flag)
- currMB->ei_flag = 0;
- img->cod_counter--;
- currMB->skip_flag = 0;
- }
- else
- {
- img->cod_counter--;
- currMB->mb_type = 0;
- currMB->ei_flag = 0;
- currMB->skip_flag = 1;
- // read field flag of bottom block
- if(img->MbaffFrameFlag)
- {
- if(img->cod_counter == 0 && ((mb_nr&0x01) == 0))
- {
- TRACE_STRING("mb_field_decoding_flag (of coded bottom mb)");
- currSE.len = (int64) 1;
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- dP->bitstream->frame_bitoffset--;
- TRACE_DECBITS(1);
- currMB->mb_field = currSE.value1;
- }
- else if(img->cod_counter > 0 && ((mb_nr&0x01) == 0))
- {
- // check left macroblock pair first
- if (mb_is_available(mb_nr-2, currMB)&&((mb_nr%(img->PicWidthInMbs*2))!=0))
- {
- currMB->mb_field = img->mb_data[mb_nr-2].mb_field;
- }
- else
- {
- // check top macroblock pair
- if (mb_is_available(mb_nr - 2*img->PicWidthInMbs, currMB))
- {
- currMB->mb_field = img->mb_data[mb_nr-2*img->PicWidthInMbs].mb_field;
- }
- else
- currMB->mb_field = 0;
- }
- }
- }
- }
- }
- dec_picture->motion.mb_field[mb_nr] = (byte) currMB->mb_field;
- img->block_y_aff = ((img->MbaffFrameFlag) && (currMB->mb_field)) ? (mb_nr&0x01) ? (img->block_y - 4)>>1 : img->block_y >> 1 : img->block_y;
- img->siblock[img->mb_y][img->mb_x]=0;
- interpret_mb_mode(currMB);
- if(img->MbaffFrameFlag)
- {
- if(currMB->mb_field)
- {
- img->num_ref_idx_l0_active <<=1;
- img->num_ref_idx_l1_active <<=1;
- }
- }
- //init NoMbPartLessThan8x8Flag
- 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 ======
- if (IS_P8x8 (currMB))
- {
- currSE.type = SE_MBTYPE;
- dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
- if (active_pps->entropy_coding_mode_flag ==UVLC || dP->bitstream->ei_flag)
- currSE.mapping = linfo_ue;
- else
- currSE.reading = readB8_typeInfo_CABAC;
- for (i=0; i<4; i++)
- {
- TRACE_STRING("sub_mb_type");
- dP->readSyntaxElement (&currSE, img, dP);
- SetB8Mode (img, currMB, currSE.value1, i);
- //set NoMbPartLessThan8x8Flag for P8x8 mode
- currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && active_sps->direct_8x8_inference_flag) ||
- (currMB->b8mode[i]==4);
- }
- //--- init macroblock data ---
- init_macroblock (img);
- readMotionInfoFromNAL (img, currMB);
- }
- //============= Transform Size Flag for INTRA MBs =============
- //-------------------------------------------------------------
- //transform size flag for INTRA_4x4 and INTRA_8x8 modes
- if (currMB->mb_type == I4MB && img->Transform8x8Mode)
- {
- currSE.type = SE_HEADER;
- dP = &(currSlice->partArr[partMap[SE_HEADER]]);
- currSE.reading = readMB_transform_size_flag_CABAC;
- TRACE_STRING("transform_size_8x8_flag");
- // read UVLC transform_size_8x8_flag
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- {
- currSE.len = (int64) 1;
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- }
- else
- {
- dP->readSyntaxElement(&currSE,img,dP);
- }
- currMB->luma_transform_size_8x8_flag = currSE.value1;
- if (currMB->luma_transform_size_8x8_flag)
- {
- currMB->mb_type = I8MB;
- for (i=0;i<4;i++)
- {
- currMB->b8mode[i]=I8MB;
- currMB->b8pdir[i]=-1;
- }
- }
- }
- else
- {
- 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( !IS_INTRA(currMB) )
- {
- img->intra_block[mb_nr] = 0;
- }
- }
- //! TO for error concealment
- //! If we have an INTRA Macroblock and we lost the partition
- //! which contains the intra coefficients Copy MB would be better
- //! than just a gray block.
- //! 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.
- /*
- !!!KS
- dP = &(currSlice->partArr[partMap[SE_CBP_INTRA]]);
- if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)
- {
- currMB->mb_type = 0;
- currMB->ei_flag = 1;
- for (i=0;i<4;i++) {currMB->b8mode[i]=currMB->b8pdir[i]=0; }
- }
- dP = &(currSlice->partArr[partMap[currSE.type]]);
- //! End TO
- */
- //--- init macroblock data ---
- if (!IS_P8x8 (currMB))
- init_macroblock(img);
- if (IS_DIRECT (currMB) && img->cod_counter >= 0)
- {
- currMB->cbp = 0;
- reset_coeffs();
- if (active_pps->entropy_coding_mode_flag ==CABAC)
- img->cod_counter=-1;
- }
- else if (IS_COPY (currMB)) //keep last macroblock
- {
- copy_macroblock(img, currMB);
- }
- else if(currMB->mb_type != IPCM)
- {
- // intra prediction modes for a macroblock 4x4 **********************************************
- if (IS_INTRA(currMB))
- read_ipred_modes(img, currMB);
- // read inter frame vector data *********************************************************
- if (IS_INTERMV (currMB) && (!IS_P8x8(currMB)))
- {
- readMotionInfoFromNAL (img, currMB);
- }
- // read CBP and Coeffs ***************************************************************
- readCBPandCoeffsFromNAL (img, currMB);
- }
- else
- {
- //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
- // same category as MBTYPE
- if ( currSlice->dp_mode && currSlice->dpB_NotPresent )
- {
- concealIPCMcoeffs(img);
- }
- else
- {
- dP = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
- readIPCMcoeffsFromNAL(img, dP);
- }
- }
- return;
- }
- /*!
- ************************************************************************
- * brief
- * Initialize decoding engine after decoding an IPCM macroblock
- * (for IPCM CABAC 28/11/2003)
- *
- * author
- * Dong Wang <Dong.Wang@bristol.ac.uk>
- ************************************************************************
- */
- void init_decoding_engine_IPCM(ImageParameters *img)
- {
- Slice *currSlice = img->currentSlice;
- Bitstream *currStream;
- int ByteStartPosition;
- int PartitionNumber;
- int i;
- if(currSlice->dp_mode==PAR_DP_1)
- PartitionNumber=1;
- else if(currSlice->dp_mode==PAR_DP_3)
- PartitionNumber=3;
- else
- {
- printf("Partition Mode is not supportedn");
- exit(1);
- }
- for(i=0;i<PartitionNumber;i++)
- {
- currStream = currSlice->partArr[i].bitstream;
- ByteStartPosition = currStream->read_len;
- arideco_start_decoding (&currSlice->partArr[i].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len);
- }
- }
- /*!
- ************************************************************************
- * brief
- * Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
- * (for IPCM CABAC and IPCM CAVLC)
- *
- * author
- * Dong Wang <Dong.Wang@bristol.ac.uk>
- ************************************************************************
- */
- static void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP)
- {
- SyntaxElement currSE;
- int i,j;
- //For CABAC, we don't need to read bits to let stream byte aligned
- // because we have variable for integer bytes position
- if(active_pps->entropy_coding_mode_flag == CABAC)
- {
- readIPCM_CABAC(dP);
- init_decoding_engine_IPCM(img);
- }
- else
- {
- //read bits to let stream byte aligned
- if(((dP->bitstream->frame_bitoffset) & 0x07) != 0)
- {
- TRACE_STRING("pcm_alignment_zero_bit");
- currSE.len = (8 - ((dP->bitstream->frame_bitoffset) & 0x07));
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- }
- //read luma and chroma IPCM coefficients
- currSE.len=img->bitdepth_luma;
- TRACE_STRING("pcm_sample_luma");
- for(i=0;i<MB_BLOCK_SIZE;i++)
- {
- for(j=0;j<MB_BLOCK_SIZE;j++)
- {
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- img->cof[0][i][j] = currSE.value1;
- img->fcf[0][i][j] = currSE.value1;
- }
- }
- currSE.len=img->bitdepth_chroma;
- if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(img))
- {
- TRACE_STRING("pcm_sample_chroma (u)");
- for(i=0;i<img->mb_cr_size_y;i++)
- {
- for(j=0;j<img->mb_cr_size_x;j++)
- {
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- img->cof[1][i][j] = currSE.value1;
- img->fcf[1][i][j] = currSE.value1;
- }
- }
- TRACE_STRING("pcm_sample_chroma (v)");
- for(i=0;i<img->mb_cr_size_y;i++)
- {
- for(j=0;j<img->mb_cr_size_x;j++)
- {
- readSyntaxElement_FLC(&currSE, dP->bitstream);
- img->cof[2][i][j] = currSE.value1;
- img->fcf[2][i][j] = currSE.value1;
- }
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * If data partition B is lost, conceal PCM sample values with DC.
- *
- ************************************************************************
- */
- void concealIPCMcoeffs(ImageParameters *img)
- {
- int i, j, k;
- for(i=0;i<MB_BLOCK_SIZE;i++)
- {
- for(j=0;j<MB_BLOCK_SIZE;j++)
- {
- img->cof[0][i][j] = img->dc_pred_value_comp[0];
- img->fcf[0][i][j] = img->dc_pred_value_comp[0];
- }
- }
- if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(img))
- {
- for (k = 0; k < 2; k++)
- {
- for(i=0;i<img->mb_cr_size_y;i++)
- {
- for(j=0;j<img->mb_cr_size_x;j++)
- {
- img->cof[k][i][j] = img->dc_pred_value_comp[k];
- img->fcf[k][i][j] = img->dc_pred_value_comp[k];
- }
- }
- }
- }
- }
- static void read_ipred_modes(ImageParameters *img, Macroblock *currMB)
- {
- int b8,i,j,bi,bj,bx,by,dec;
- SyntaxElement currSE;
- DataPartition *dP;
- Slice *currSlice = img->currentSlice;
- int *partMap = assignSE2partition[currSlice->dp_mode];
- int ts, ls;
- int mostProbableIntraPredMode;
- int upIntraPredMode;
- int leftIntraPredMode;
- char IntraChromaPredModeFlag = IS_INTRA(currMB);
- int bs_x, bs_y;
- int ii,jj;
- PixelPos left_block, top_block;
- currSE.type = SE_INTRAPREDMODE;
- TRACE_STRING("intra4x4_pred_mode");
- dP = &(currSlice->partArr[partMap[currSE.type]]);
- if (!(active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag))
- currSE.reading = readIntraPredMode_CABAC;
- for(b8 = 0; b8 < 4; b8++) //loop 8x8 blocks
- {
- if((currMB->b8mode[b8]==IBLOCK )||(currMB->b8mode[b8]==I8MB))
- {
- bs_x = bs_y = (currMB->b8mode[b8] == I8MB)?8:4;
- IntraChromaPredModeFlag = 1;
- ii = (bs_x>>2);
- jj = (bs_y>>2);
- for(j=0;j<2;j+=jj) //loop subblocks
- {
- by = (b8&2) + j;
- bj = img->block_y + by;
- for(i=0;i<2;i+=ii)
- {
- bx = ((b8&1)<<1) + i;
- bi = img->block_x + bx;
- //get from stream
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- readSyntaxElement_Intra4x4PredictionMode(&currSE,img,dP->bitstream);
- else
- {
- currSE.context=(b8<<2)+(j<<1) +i;
- dP->readSyntaxElement(&currSE,img,dP);
- }
- get4x4Neighbour(currMB, (bx<<2) - 1, (by<<2), img->mb_size[IS_LUMA], &left_block);
- get4x4Neighbour(currMB, (bx<<2), (by<<2) - 1, img->mb_size[IS_LUMA], &top_block );
- //get from array and decode
- if (active_pps->constrained_intra_pred_flag)
- {
- 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;
- }
- // !! KS: not sure if the following is still correct...
- 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 (left_block.available)
- if (img->siblock [left_block.pos_y][left_block.pos_x])
- ls=1;
- if (top_block.available)
- if (img->siblock [top_block.pos_y][top_block.pos_x])
- ts=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;
- mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;
- dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);
- //set
- 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));
- }
- }
- }
- }
- }
- if (IntraChromaPredModeFlag && (dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444))
- {
- currSE.type = SE_INTRAPREDMODE;
- TRACE_STRING("intra_chroma_pred_mode");
- dP = &(currSlice->partArr[partMap[currSE.type]]);
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- currSE.mapping = linfo_ue;
- else
- currSE.reading = readCIPredMode_CABAC;
- dP->readSyntaxElement(&currSE,img,dP);
- currMB->c_ipred_mode = currSE.value1;
- if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
- {
- error("illegal chroma intra pred mode!n", 600);
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Set motion vector predictor
- ************************************************************************
- */
- void SetMotionVectorPredictor (ImageParameters *img,
- Macroblock *currMB,
- short pred_mv[2],
- char ref_frame,
- byte list,
- char ***refPic,
- short ****tmp_mv,
- int mb_x,
- int mb_y,
- int blockshape_x,
- int blockshape_y)
- {
- int mv_a, mv_b, mv_c, pred_vec=0;
- int mvPredType, rFrameL, rFrameU, rFrameUR;
- int hv;
- PixelPos block_a, block_b, block_c, block_d;
- get4x4Neighbour(currMB, mb_x - 1, mb_y, img->mb_size[IS_LUMA], &block_a);
- get4x4Neighbour(currMB, mb_x, mb_y - 1, img->mb_size[IS_LUMA], &block_b);
- get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, img->mb_size[IS_LUMA], &block_c);
- get4x4Neighbour(currMB, mb_x - 1, mb_y - 1, img->mb_size[IS_LUMA], &block_d);
- if (mb_y > 0)
- {
- if (mb_x < 8) // first column of 8x8 blocks
- {
- if (mb_y==8)
- {
- if (blockshape_x == 16)
- block_c.available = 0;
- }
- else
- {
- if (mb_x + blockshape_x == 8)
- block_c.available = 0;
- }
- }
- else
- {
- if (mb_x + blockshape_x == 16)
- block_c.available = 0;
- }
- }
- if (!block_c.available)
- {
- block_c = block_d;
- }
- mvPredType = MVPRED_MEDIAN;
- if (!img->MbaffFrameFlag)
- {
- 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;
- rFrameUR = block_c.available ? refPic[list][block_c.pos_y][block_c.pos_x] : -1;
- }
- else
- {
- if (img->mb_data[img->current_mb_nr].mb_field)
- {
- rFrameL = block_a.available ?
- 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] * 2:
- -1;
- rFrameU = block_b.available ?
- 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] * 2:
- -1;
- rFrameUR = block_c.available ?
- 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] * 2:
- -1;
- }
- else
- {
- rFrameL = block_a.available ?
- 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;
- rFrameU = block_b.available ?
- 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;
- rFrameUR = block_c.available ?
- 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;
- }
- }
- /* Prediction if only one of the neighbors uses the reference frame
- * we are checking
- */
- 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_UR;
- // Directional predictions
- if(blockshape_x == 8 && blockshape_y == 16)
- {
- if(mb_x == 0)
- {
- if(rFrameL == ref_frame)
- mvPredType = MVPRED_L;
- }
- else
- {
- if( rFrameUR == ref_frame)
- mvPredType = MVPRED_UR;
- }
- }
- else if(blockshape_x == 16 && blockshape_y == 8)
- {
- if(mb_y == 0)
- {
- if(rFrameU == ref_frame)
- mvPredType = MVPRED_U;
- }
- else
- {
- if(rFrameL == ref_frame)
- mvPredType = MVPRED_L;
- }
- }
- for (hv=0; hv < 2; hv++)
- {
- if (!img->MbaffFrameFlag || 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_c = block_c.available ? tmp_mv[list][block_c.pos_y][block_c.pos_x][hv] : 0;
- }
- else
- {
- if (img->mb_data[img->current_mb_nr].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] / 2:
- 0;
- 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] / 2:
- 0;
- 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] / 2:
- 0;
- }
- else
- {
- 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]:
- 0;
- 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]:
- 0;
- 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]:
- 0;
- }
- }
- switch (mvPredType)
- {
- case MVPRED_MEDIAN:
- if(!(block_b.available || block_c.available))
- pred_vec = mv_a;
- 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));
- break;
- case MVPRED_L:
- pred_vec = mv_a;
- break;
- case MVPRED_U:
- pred_vec = mv_b;
- break;
- case MVPRED_UR:
- pred_vec = mv_c;
- break;
- default:
- break;
- }
- pred_mv[hv] = (short) pred_vec;
- }
- }
- /*!
- ************************************************************************
- * brief
- * Read motion info
- ************************************************************************
- */
- static void readMotionInfoFromNAL (ImageParameters *img, Macroblock *currMB)
- {
- int i,j,k;
- int mb_nr = img->current_mb_nr;
- SyntaxElement currSE;
- Slice *currSlice = img->currentSlice;
- DataPartition *dP = NULL;
- int *partMap = assignSE2partition[currSlice->dp_mode];
- int bslice = (img->type==B_SLICE);
- int partmode = (IS_P8x8(currMB)?4:currMB->mb_type);
- int step_h0 = BLOCK_STEP [partmode][0];
- int step_v0 = BLOCK_STEP [partmode][1];
- int i0, j0, j6;
- int j4, i4, ii;
- MotionParams *colocated;
- int mv_scale = 0;
- int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0;
- if (bslice)
- {
- if ((img->MbaffFrameFlag) && (currMB->mb_field))
- {
- if(mb_nr&0x01)
- {
- colocated = &Co_located->bottom;
- }
- else
- {
- colocated = &Co_located->top;
- }
- }
- else
- {
- colocated = &Co_located->frame;
- }
- if (IS_P8x8 (currMB))
- {
- if (img->direct_spatial_mv_pred_flag)
- {
- char l0_rFrame, l1_rFrame;
- short pmvl0[2]={0,0}, pmvl1[2]={0,0};
- prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame);
- for (k = 0; k < 4; k++)
- {
- if (currMB->b8mode[k] == 0)
- {
- i = img->block_x + 2 * (k & 0x01);
- for(j = 2 * (k >> 1); j < 2 * (k >> 1)+2;j++)
- {
- j6 = img->block_y_aff + j;
- j4 = img->block_y + j;
- for(i4 = i; i4 < i + 2; i4++)
- {
- if (l0_rFrame >= 0)
- {
- if (!l0_rFrame && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term)))
- {
- dec_picture->motion.mv [LIST_0][j4][i4][0] = 0;
- dec_picture->motion.mv [LIST_0][j4][i4][1] = 0;
- dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0;
- }
- else
- {
- dec_picture->motion.mv [LIST_0][j4][i4][0] = pmvl0[0];
- dec_picture->motion.mv [LIST_0][j4][i4][1] = pmvl0[1];
- dec_picture->motion.ref_idx[LIST_0][j4][i4] = l0_rFrame;
- }
- }
- else
- {
- dec_picture->motion.mv [LIST_0][j4][i4][0] = 0;
- dec_picture->motion.mv [LIST_0][j4][i4][1] = 0;
- dec_picture->motion.ref_idx[LIST_0][j4][i4] = -1;
- }
- if (l1_rFrame >= 0)
- {
- if (l1_rFrame==0 && ((!colocated->moving_block[j6][i4])&& (!listX[LIST_1 + list_offset][0]->is_long_term)))
- {
- dec_picture->motion.mv [LIST_1][j4][i4][0] = 0;
- dec_picture->motion.mv [LIST_1][j4][i4][1] = 0;
- dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0;
- }
- else
- {
- dec_picture->motion.mv [LIST_1][j4][i4][0] = pmvl1[0];
- dec_picture->motion.mv [LIST_1][j4][i4][1] = pmvl1[1];
- dec_picture->motion.ref_idx[LIST_1][j4][i4] = l1_rFrame;
- }
- }
- else
- {
- dec_picture->motion.mv [LIST_1][j4][i4][0] = 0;
- dec_picture->motion.mv [LIST_1][j4][i4][1] = 0;
- dec_picture->motion.ref_idx[LIST_1][j4][i4] = -1;
- }
- if (l0_rFrame <0 && l1_rFrame <0)
- {
- dec_picture->motion.ref_idx[LIST_0][j4][i4] = 0;
- dec_picture->motion.ref_idx[LIST_1][j4][i4] = 0;
- }
- }
- }
- }
- }
- }
- else
- {
- for (k = 0; k < 4; k++) // Scan all blocks
- {
- if (currMB->b8mode[k] == 0)
- {
- for(j0 = 2 * (k >> 1); j0 < 2 * (k >> 1) + 2; j0 += step_v0)
- {
- for(i0 = img->block_x + 2*(k & 0x01); i0 < img->block_x + 2 * (k & 0x01)+2; i0 += step_h0)
- {
- int refList = colocated->ref_idx[LIST_0 ][img->block_y_aff + j0][i0]== -1 ? LIST_1 : LIST_0;
- int ref_idx = colocated->ref_idx[refList][img->block_y_aff + j0][i0];
- int mapped_idx = -1, iref;
- if (ref_idx == -1)
- {
- for (j4 = img->block_y + j0; j4 < img->block_y + j0 + step_v0; j4++)
- {
- memset(&dec_picture->motion.ref_idx [LIST_0][j4][i0], 0, step_h0 * sizeof(char));
- memset(&dec_picture->motion.ref_idx [LIST_1][j4][i0], 0, step_h0 * sizeof(char));
- memset(&dec_picture->motion.mv [LIST_0][j4][i0][0], 0, 2 * step_h0 * sizeof(short));
- memset(&dec_picture->motion.mv [LIST_1][j4][i0][0], 0, 2 * step_h0 * sizeof(short));
- }
- }
- else
- {
- 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));
- if(img->structure==0 && curr_mb_field==0)
- {
- // If the current MB is a frame MB and the colocated is from a field picture,
- // then the colocated->ref_pic_id may have been generated from the wrong value of
- // frame_poc if it references it's complementary field, so test both POC values
- if(listX[0][iref]->top_poc * 2 == colocated->ref_pic_id[refList][img->block_y_aff + j0][i0]
- || listX[0][iref]->bottom_poc * 2 == colocated->ref_pic_id[refList][img->block_y_aff + j0][i0])
- {
- mapped_idx=iref;
- break;
- }
- else //! invalid index. Default to zero even though this case should not happen
- mapped_idx=INVALIDINDEX;
- continue;
- }
- if (dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][iref]==colocated->ref_pic_id[refList][img->block_y_aff + j0][i0])
- {
- mapped_idx=iref;
- break;
- }
- else //! invalid index. Default to zero even though this case should not happen
- mapped_idx=INVALIDINDEX;
- }
- if (INVALIDINDEX == mapped_idx)
- {
- error("temporal direct errorncolocated block has ref that is unavailable",-1111);
- }
- for (j = j0; j < j0 + step_v0; j++)
- {
- j4 = img->block_y + j;
- j6 = img->block_y_aff + j;
- for (i4 = i0; i4 < i0 + step_h0; i4++)
- {
- mv_scale = img->mvscale[LIST_0 + list_offset][mapped_idx];
- dec_picture->motion.ref_idx [LIST_0][j4][i4] = (char) mapped_idx;
- dec_picture->motion.ref_idx [LIST_1][j4][i4] = 0;
- for (ii=0; ii < 2; ii++)
- {
- if (mv_scale == 9999 || listX[LIST_0+list_offset][mapped_idx]->is_long_term)
- {
- dec_picture->motion.mv [LIST_0][j4][i4][ii] = colocated->mv[refList][j6][i4][ii];
- dec_picture->motion.mv [LIST_1][j4][i4][ii] = 0;
- }
- else
- {
- dec_picture->motion.mv [LIST_0][j4][i4][ii] = (short) ((mv_scale * colocated->mv[refList][j6][i4][ii] + 128 ) >> 8);
- dec_picture->motion.mv [LIST_1][j4][i4][ii] = (short) (dec_picture->motion.mv[LIST_0][j4][i4][ii] - colocated->mv[refList][j6][i4][ii]);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- //===== READ REFERENCE PICTURE INDICES =====
- currSE.type = SE_REFFRAME;
- dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
- // For LIST_0, if multiple ref. pictures, read LIST_0 reference picture indices for the MB ***********
- prepareListforRefIdx (&currSE, dP, img->num_ref_idx_l0_active, !IS_P8x8 (currMB) || bslice || (!img->allrefzero));
- readMBRefPictureIdx (&currSE, dP, currMB, img, &dec_picture->motion.ref_idx[LIST_0][img->block_y], LIST_0, step_v0, step_h0);
- // For LIST_1, if multiple ref. pictures, read LIST_1 reference picture indices for the MB ***********
- prepareListforRefIdx (&currSE, dP, img->num_ref_idx_l1_active, !IS_P8x8 (currMB) || bslice || (!img->allrefzero));
- readMBRefPictureIdx (&currSE, dP, currMB, img, &dec_picture->motion.ref_idx[LIST_1][img->block_y], LIST_1, step_v0, step_h0);
- //===== READ MOTION VECTORS =====
- currSE.type = SE_MVD;
- dP = &(currSlice->partArr[partMap[SE_MVD]]);
- if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
- currSE.mapping = linfo_se;
- else
- currSE.reading = readMVD_CABAC;
- // LIST_0 Motion vectors
- readMBMotionVectors (&currSE, dP, currMB, img, LIST_0, step_h0, step_v0);
- // LIST_1 Motion vectors
- if (bslice)
- readMBMotionVectors (&currSE, dP, currMB, img, LIST_1, step_h0, step_v0);
- // record reference picture Ids for deblocking decisions
- for (k = LIST_0; k <= (bslice ? LIST_1: LIST_0); k++)
- {
- for(j4 = img->block_y; j4 < (img->block_y +4);j4++)
- {
- for(i4 = img->block_x; i4 < (img->block_x + 4);i4++)
- {
- if (dec_picture->motion.ref_idx[k][j4][i4]>=0)
- dec_picture->motion.ref_pic_id[k][j4][i4] = dec_picture->ref_pic_num[img->current_slice_nr][k + list_offset][(short)dec_picture->motion.ref_idx[k][j4][i4]];
- else
- dec_picture->motion.ref_pic_id[k][j4][i4] = INT64_MIN;
- }
- }
- }
- }
- /*!
- ************************************************************************
- * brief
- * Get the Prediction from the Neighboring Blocks for Number of
- * Nonzero Coefficients
- *
- * Luma Blocks
- ************************************************************************
- */
- int predict_nnz(Macroblock *currMB, int block_type, ImageParameters *img, int i,int j)
- {
- PixelPos pix;
- int pred_nnz = 0;
- int cnt = 0;
- // left block
- get4x4Neighbour(currMB, i - 1, j, img->mb_size[IS_LUMA], &pix);
- 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];
- if (!pix.available)
- cnt++;
- }
- if (pix.available)
- {
- switch (block_type)
- {
- case LUMA:
- pred_nnz = img->nz_coeff [pix.mb_addr ][0][pix.y][pix.x];
- cnt++;
- break;
- case CB:
- pred_nnz = img->nz_coeff [pix.mb_addr ][1][pix.y][pix.x];
- cnt++;
- break;
- case CR:
- pred_nnz = img->nz_coeff [pix.mb_addr ][2][pix.y][pix.x];
- cnt++;
- break;
- default:
- error("writeCoeff4x4_CAVLC: Invalid block type", 600);
- break;
- }
- }
- // top block
- get4x4Neighbour(currMB, i, j - 1, img->mb_size[IS_LUMA], &pix);
- 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];
- if (!pix.available)
- cnt++;
- }
- if (pix.available)
- {
- switch (block_type)
- {
- case LUMA:
- pred_nnz += img->nz_coeff [pix.mb_addr ][0][pix.y][pix.x];
- cnt++;
- break;
- case CB:
- pred_nnz += img->nz_coeff [pix.mb_addr ][1][pix.y][pix.x];
- cnt++;
- break;
- case CR:
- pred_nnz += img->nz_coeff [pix.mb_addr ][2][pix.y][pix.x];
- cnt++;
- break;
- default:
- error("writeCoeff4x4_CAVLC: Invalid block type", 600);
- break;
- }
- }
- if (cnt==2)
- {
- pred_nnz++;
- pred_nnz>>=1;
- }
- return pred_nnz;
- }
- /*!
- ************************************************************************
- * brief
- * Get the Prediction from the Neighboring Blocks for Number of
- * Nonzero Coefficients
- *
- * Chroma Blocks
- ************************************************************************
- */
- int predict_nnz_chroma(Macroblock *currMB, ImageParameters *img, int i,int j)
- {
- PixelPos pix;
- int pred_nnz = 0;
- int cnt = 0;
- if (dec_picture->chroma_format_idc != YUV444)
- {
- //YUV420 and YUV422
- // left block
- get4x4Neighbour(currMB, ((i&0x01)<<2) - 1, j, img->mb_size[IS_CHROMA], &pix);
- 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];
- if (!pix.available)
- cnt++;
- }
- if (pix.available)
- {
- pred_nnz = img->nz_coeff [pix.mb_addr ][1][pix.y][2 * (i>>1) + pix.x];
- cnt++;
- }
- // top block
- get4x4Neighbour(currMB, ((i&0x01)<<2), j - 1, img->mb_size[IS_CHROMA], &pix);
- 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];
- if (!pix.available)
- cnt++;
- }
- if (pix.available)
- {
- pred_nnz += img->nz_coeff [pix.mb_addr ][1][pix.y][2 * (i>>1) + pix.x];
- cnt++;
- }
- if (cnt==2)
- {
- pred_nnz++;
- pred_nnz >>= 1;
- }
- }
- return pred_nnz;
- }
- /*!
- ************************************************************************
- * brief
- * Reads coeff of an 4x4 block (CAVLC)
- *
- * author
- * Karl Lillevold <karll@real.com>
- * contributions by James Au <james@ubvideo.com>
- ************************************************************************
- */
- void readCoeff4x4_CAVLC (Macroblock *currMB, ImageParameters *img,
- int block_type,
- int i, int j, int levarr[16], int runarr[16],
- int *number_coefficients)
- {
- int mb_nr = img->current_mb_nr;
- SyntaxElement currSE;
- Slice *currSlice = img->currentSlice;
- DataPartition *dP;
- int *partMap = assignSE2partition[currSlice->dp_mode];
- static Bitstream *currStream;
- int k, code, vlcnum;
- static int numcoeff, numtrailingones, numcoeff_vlc;
- static int level_two_or_higher;
- int numones, totzeros, abslevel, cdc=0, cac=0;
- int zerosleft, ntr, dptype = 0;
- int max_coeff_num = 0, nnz;
- static char type[15];
- static int incVlc[] = {0,3,6,12,24,48,32768}; // maximum vlc = 6
- numcoeff = 0;
- switch (block_type)
- {
- case LUMA:
- max_coeff_num = 16;
- TRACE_PRINTF("Luma");
- dptype = IS_INTRA (currMB) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER;
- img->nz_coeff[mb_nr][0][j][i] = 0;
- break;
- case LUMA_INTRA16x16DC:
- max_coeff_num = 16;
- TRACE_PRINTF("Lum16DC");
- dptype = SE_LUM_DC_INTRA;
- img->nz_coeff[mb_nr][0][j][i] = 0;
- break;
- case LUMA_INTRA16x16AC:
- max_coeff_num = 15;
- TRACE_PRINTF("Lum16AC");
- dptype = SE_LUM_AC_INTRA;
- img->nz_coeff[mb_nr][0][j][i] = 0;
- break;
- case CB:
- max_coeff_num = 16;
- TRACE_PRINTF("Luma_add1");
- dptype = (IS_INTRA (currMB)) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER;
- img->nz_coeff[mb_nr][1][j][i] = 0;
- break;
- case CB_INTRA16x16DC:
- max_coeff_num = 16;
- TRACE_PRINTF("Luma_add1_16DC");
- dptype = SE_LUM_DC_INTRA;
- img->nz_coeff[mb_nr][1][j][i] = 0;
- break;
- case CB_INTRA16x16AC:
- max_coeff_num = 15;
- TRACE_PRINTF("Luma_add1_16AC");
- dptype = SE_LUM_AC_INTRA;
- img->nz_coeff[mb_nr][1][j][i] = 0;
- break;
- case CR:
- max_coeff_num = 16;
- TRACE_PRINTF("Luma_add2");
- dptype = (IS_INTRA (currMB)) ? SE_LUM_AC_INTRA : SE_LUM_AC_INTER;
- img->nz_coeff[mb_nr][2][j][i] = 0;
- break;
- case CR_INTRA16x16DC:
- max_coeff_num = 16;
- TRACE_PRINTF("Luma_add2_16DC");
- dptype = SE_LUM_DC_INTRA;
- img->nz_coeff[mb_nr][2][j][i] = 0;
- break;
- case CR_INTRA16x16AC:
- max_coeff_num = 15;
- TRACE_PRINTF("Luma_add1_16AC");
- dptype = SE_LUM_AC_INTRA;
- img->nz_coeff[mb_nr][2][j][i] = 0;
- break;
- case CHROMA_DC:
- max_coeff_num = img->num_cdc_coeff;
- cdc = 1;
- TRACE_PRINTF("ChrDC");
- dptype = IS_INTRA (currMB) ? SE_CHR_DC_INTRA : SE_CHR_DC_INTER;
- img->nz_coeff[mb_nr][0][j][i] = 0;
- break;
- case CHROMA_AC:
- max_coeff_num = 15;
- cac = 1;
- TRACE_PRINTF("ChrDC");
- dptype = IS_INTRA (currMB) ? SE_CHR_AC_INTRA : SE_CHR_AC_INTER;
- img->nz_coeff[mb_nr][0][j][i] = 0;
- break;
- default:
- error ("readCoeff4x4_CAVLC: invalid block type", 600);
- img->nz_coeff[mb_nr][0][j][i] = 0;
- break;
- }
- currSE.type = dptype;
- dP = &(currSlice->partArr[partMap[dptype]]);
- currStream = dP->bitstream;
- if (!cdc)
- {
- // luma or chroma AC
- if(block_type==LUMA || block_type==LUMA_INTRA16x16DC || block_type==LUMA_INTRA16x16AC ||block_type==CHROMA_AC)
- {
- nnz = (!cac) ? predict_nnz(currMB, LUMA, img, i<<2, j<<2) : predict_nnz_chroma(currMB, img, i, ((j-4)<<2));
- }
- else if (block_type==CB || block_type==CB_INTRA16x16DC || block_type==CB_INTRA16x16AC)
- {
- nnz = predict_nnz(currMB, CB, img, i<<2, j<<2);
- }
- else
- {
- nnz = predict_nnz(currMB, CR, img, i<<2, j<<2);
- }
- if (nnz < 2)
- {
- numcoeff_vlc = 0;
- }
- else if (nnz < 4)
- {
- numcoeff_vlc = 1;
- }
- else if (nnz < 8)
- {
- numcoeff_vlc = 2;
- }
- else //
- {
- numcoeff_vlc = 3;
- }
- currSE.value1 = numcoeff_vlc;
- readSyntaxElement_NumCoeffTrailingOnes(&currSE, currStream, type);
- numcoeff = currSE.value1;
- numtrailingones = currSE.value2;
- if(block_type==LUMA || block_type==LUMA_INTRA16x16DC || block_type==LUMA_INTRA16x16AC ||block_type==CHROMA_AC)
- img->nz_coeff[mb_nr][0][j][i] = numcoeff;
- else if (block_type==CB || block_type==CB_INTRA16x16DC || block_type==CB_INTRA16x16AC)
- img->nz_coeff[mb_nr][1][j][i] = numcoeff;
- else
- img->nz_coeff[mb_nr][2][j][i] = numcoeff;
- }
- else
- {
- // chroma DC
- readSyntaxElement_NumCoeffTrailingOnesChromaDC(&currSE, currStream);
- numcoeff = currSE.value1;
- numtrailingones = currSE.value2;
- }
- memset(levarr, 0, max_coeff_num * sizeof(int));
- memset(runarr, 0, max_coeff_num * sizeof(int));
- numones = numtrailingones;
- *number_coefficients = numcoeff;
- if (numcoeff)
- {
- if (numtrailingones)
- {
- currSE.len = numtrailingones;
- #if TRACE
- snprintf(currSE.tracestring,
- TRACESTRING_SIZE, "%s trailing ones sign (%d,%d)", type, i, j);
- #endif
- readSyntaxElement_FLC (&currSE, currStream);
- code = currSE.inf;
- ntr = numtrailingones;
- for (k = numcoeff - 1; k > numcoeff - 1 - numtrailingones; k--)
- {
- ntr --;
- levarr[k] = (code>>ntr)&1 ? -1 : 1;
- }
- }
- // decode levels
- level_two_or_higher = (numcoeff > 3 && numtrailingones == 3)? 0 : 1;
- vlcnum = (numcoeff > 10 && numtrailingones < 3) ? 1 : 0;
- for (k = numcoeff - 1 - numtrailingones; k >= 0; k--)
- {
- #if TRACE
- snprintf(currSE.tracestring,
- TRACESTRING_SIZE, "%s lev (%d,%d) k=%d vlc=%d ", type, i, j, k, vlcnum);
- #endif
- if (vlcnum == 0)
- readSyntaxElement_Level_VLC0(&currSE, currStream);
- else
- readSyntaxElement_Level_VLCN(&currSE, vlcnum, currStream);
- if (level_two_or_higher)
- {
- currSE.inf += (currSE.inf > 0) ? 1 : -1;
- level_two_or_higher = 0;
- }
- levarr[k] = currSE.inf;
- abslevel = iabs(levarr[k]);
- if (abslevel == 1)
- numones ++;
- // update VLC table
- if (abslevel > incVlc[vlcnum])
- vlcnum++;
- if (k == numcoeff - 1 - numtrailingones && abslevel >3)
- vlcnum = 2;
- }
- if (numcoeff < max_coeff_num)
- {
- // decode total run
- vlcnum = numcoeff - 1;
- currSE.value1 = vlcnum;
- #if TRACE
- snprintf(currSE.tracestring,
- TRACESTRING_SIZE, "%s totalrun (%d,%d) vlc=%d ", type, i,j, vlcnum);
- #endif
- if (cdc)
- readSyntaxElement_TotalZerosChromaDC(&currSE, currStream);
- else
- readSyntaxElement_TotalZeros(&currSE, currStream);
- totzeros = currSE.value1;
- }
- else
- {
- totzeros = 0;
- }
- // decode run before each coefficient
- zerosleft = totzeros;
- i = numcoeff - 1;
- if (zerosleft > 0 && i > 0)
- {
- do
- {
- // select VLC for runbefore
- vlcnum = imin(zerosleft - 1, RUNBEFORE_NUM_M1);
- currSE.value1 = vlcnum;
- #if TRACE
- snprintf(currSE.tracestring,
- TRACESTRING_SIZE, "%s run (%d,%d) k=%d vlc=%d ",
- type, i, j, i, vlcnum);
- #endif
- readSyntaxElement_Run(&currSE, currStream);
- runarr[i] = currSE.value1;
- zerosleft -= runarr[i];
- i --;
- } while (zerosleft != 0 && i != 0);
- }
- runarr[i] = zerosleft;
- } // if numcoeff
- }
- /*!
- ************************************************************************
- * brief
- * Get coefficients (run/level) of one 8x8 block
- * from the NAL (CABAC Mode)
- ************************************************************************
- */
- static void readLumaCoeff8x8_CABAC (ImageParameters *img, Macroblock *currMB, ColorPlane pl, int b8)
- {
- static int (*tcoeffs)[16];
- int i,j,k;