⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video.c

📁 MPEG2 PLAYER in linux
💻 C
📖 第 1 页 / 共 5 页
字号:
ParseMacroBlock(vid_stream)  VidStream *vid_stream;{  int addr_incr;  unsigned int data;  int mask, i, recon_right_for, recon_down_for, recon_right_back,      recon_down_back;  int zero_block_flag;  BOOLEAN mb_quant = 0, mb_motion_forw = 0, mb_motion_back = 0,       mb_pattern = 0;  int no_dith_flag = 0;  int ditherType = vid_stream->ditherType;#ifdef ANALYSIS  mbSizeCount = bitCountRead();#endif  /*   * Parse off macroblock address increment and add to macroblock address.   */  do {    unsigned int ind;				           show_bits11(ind);				           DecodeMBAddrInc(addr_incr);    if (mb_addr_inc[ind].num_bits==0) {      addr_incr = 1;    }    if (addr_incr == MB_ESCAPE) {      vid_stream->mblock.mb_address += 33;      addr_incr = MB_STUFFING;    }  } while (addr_incr == MB_STUFFING);  vid_stream->mblock.mb_address += addr_incr;  if (vid_stream->mblock.mb_address > (vid_stream->mb_height *				       vid_stream->mb_width - 1))    return SKIP_TO_START_CODE;  /*   * If macroblocks have been skipped, process skipped macroblocks.   */  if (vid_stream->mblock.mb_address - vid_stream->mblock.past_mb_addr > 1) {    if (vid_stream->picture.code_type == P_TYPE)      ProcessSkippedPFrameMBlocks(vid_stream);    else if (vid_stream->picture.code_type == B_TYPE)      ProcessSkippedBFrameMBlocks(vid_stream);  }  /* Set past macroblock address to current macroblock address. */  vid_stream->mblock.past_mb_addr = vid_stream->mblock.mb_address;  /* Based on picture type decode macroblock type. */  switch (vid_stream->picture.code_type) {  case I_TYPE:    DecodeMBTypeI(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,		  vid_stream->mblock.mb_intra);    break;  case P_TYPE:    DecodeMBTypeP(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,		  vid_stream->mblock.mb_intra);    break;  case B_TYPE:    DecodeMBTypeB(mb_quant, mb_motion_forw, mb_motion_back, mb_pattern,		  vid_stream->mblock.mb_intra);    break;  case D_TYPE:    fprintf(stderr, "ERROR:  MPEG-1 Streams with D-frames are not supported\n");    exit(1);  }  /* If quantization flag set, parse off new quantization scale. */  if (mb_quant == TRUE) {    get_bits5(data);    vid_stream->slice.quant_scale = data;  }  /* If forward motion vectors exist... */  if (mb_motion_forw == TRUE) {    /* Parse off and decode horizontal forward motion vector. */    DecodeMotionVectors(vid_stream->mblock.motion_h_forw_code);    /* If horiz. forward r data exists, parse off. */    if ((vid_stream->picture.forw_f != 1) &&	(vid_stream->mblock.motion_h_forw_code != 0)) {      get_bitsn(vid_stream->picture.forw_r_size, data);      vid_stream->mblock.motion_h_forw_r = data;    }    /* Parse off and decode vertical forward motion vector. */    DecodeMotionVectors(vid_stream->mblock.motion_v_forw_code);    /* If vert. forw. r data exists, parse off. */    if ((vid_stream->picture.forw_f != 1) &&	(vid_stream->mblock.motion_v_forw_code != 0)) {      get_bitsn(vid_stream->picture.forw_r_size, data);      vid_stream->mblock.motion_v_forw_r = data;    }  }  /* If back motion vectors exist... */  if (mb_motion_back == TRUE) {    /* Parse off and decode horiz. back motion vector. */    DecodeMotionVectors(vid_stream->mblock.motion_h_back_code);    /* If horiz. back r data exists, parse off. */    if ((vid_stream->picture.back_f != 1) &&	(vid_stream->mblock.motion_h_back_code != 0)) {      get_bitsn(vid_stream->picture.back_r_size, data);      vid_stream->mblock.motion_h_back_r = data;    }    /* Parse off and decode vert. back motion vector. */    DecodeMotionVectors(vid_stream->mblock.motion_v_back_code);    /* If vert. back r data exists, parse off. */    if ((vid_stream->picture.back_f != 1) &&	(vid_stream->mblock.motion_v_back_code != 0)) {      get_bitsn(vid_stream->picture.back_r_size, data);      vid_stream->mblock.motion_v_back_r = data;    }  }#ifdef ANALYSIS  if (vid_stream->mblock.mb_intra) {    stat_a[0].i_mbnum++;    mbCBPPtr = stat_a[0].i_mbcbp;    mbCoeffPtr = stat_a[0].i_mbcoeff;    mbSizePtr = &(stat_a[0].i_mbsize);  } else if (mb_motion_back && mb_motion_forw) {    stat_a[0].bi_mbnum++;    mbCBPPtr = stat_a[0].bi_mbcbp;    mbCoeffPtr = stat_a[0].bi_mbcoeff;    mbSizePtr = &(stat_a[0].bi_mbsize);  } else if (mb_motion_back) {    stat_a[0].b_mbnum++;    mbCBPPtr = stat_a[0].b_mbcbp;    mbCoeffPtr = stat_a[0].b_mbcoeff;    mbSizePtr = &(stat_a[0].b_mbsize);  } else {    stat_a[0].p_mbnum++;    mbCBPPtr = stat_a[0].p_mbcbp;    mbCoeffPtr = stat_a[0].p_mbcoeff;    mbSizePtr = &(stat_a[0].p_mbsize);  }#endif  /* If mblock pattern flag set, parse and decode CBP (code block pattern). */  if (mb_pattern == TRUE) {    DecodeCBP(vid_stream->mblock.cbp);  }  /* Otherwise, set CBP to zero. */  else    vid_stream->mblock.cbp = 0;#ifdef ANALYSIS  mbCBPPtr[vid_stream->mblock.cbp]++;#endif  /* Reconstruct motion vectors depending on picture type. */  if (vid_stream->picture.code_type == P_TYPE) {    /*     * If no forw motion vectors, reset previous and current vectors to 0.     */    if (!mb_motion_forw) {      recon_right_for = 0;      recon_down_for = 0;      vid_stream->mblock.recon_right_for_prev = 0;      vid_stream->mblock.recon_down_for_prev = 0;    }    /*     * Otherwise, compute new forw motion vectors. Reset previous vectors to     * current vectors.     */    else {      ComputeForwVector(&recon_right_for, &recon_down_for, vid_stream);    }  }  if (vid_stream->picture.code_type == B_TYPE) {    /* Reset prev. and current vectors to zero if mblock is intracoded. */    if (vid_stream->mblock.mb_intra) {      vid_stream->mblock.recon_right_for_prev = 0;      vid_stream->mblock.recon_down_for_prev = 0;      vid_stream->mblock.recon_right_back_prev = 0;      vid_stream->mblock.recon_down_back_prev = 0;    } else {            /* If no forw vectors, current vectors equal prev. vectors. */            if (!mb_motion_forw) {	recon_right_for = vid_stream->mblock.recon_right_for_prev;	recon_down_for = vid_stream->mblock.recon_down_for_prev;      }      /*       * Otherwise compute forw. vectors. Reset prev vectors to new values.       */            else {	ComputeForwVector(&recon_right_for, &recon_down_for, vid_stream);      }            /* If no back vectors, set back vectors to prev back vectors. */            if (!mb_motion_back) {        recon_right_back = vid_stream->mblock.recon_right_back_prev;        recon_down_back = vid_stream->mblock.recon_down_back_prev;      }      /* Otherwise compute new vectors and reset prev. back vectors. */      else {        ComputeBackVector(&recon_right_back, &recon_down_back, vid_stream);      }      /*       * Store vector existence flags in structure for possible skipped       * macroblocks to follow.       */      vid_stream->mblock.bpict_past_forw = mb_motion_forw;      vid_stream->mblock.bpict_past_back = mb_motion_back;    }  }#ifndef DISABLE_DITHER  /* For each possible block in macroblock. */  if (ditherType == GRAY_DITHER ||      ditherType == GRAY2_DITHER ||      ditherType == GRAY256_DITHER ||      ditherType == GRAY2562_DITHER ||      ditherType == MONO_DITHER ||      ditherType == MONO_THRESHOLD) {    for (mask = 32, i = 0; i < 4; mask >>= 1, i++) {      /* If block exists... */      if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {        zero_block_flag = 0;        ParseReconBlock(i, vid_stream);      } else {        zero_block_flag = 1;      }      /* If macroblock is intra coded... */      if (vid_stream->mblock.mb_intra) {        ReconIMBlock(vid_stream, i);      } else if (mb_motion_forw && mb_motion_back) {        ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,		    recon_right_back, recon_down_back, zero_block_flag);      } else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {        ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,		    zero_block_flag);      } else if (mb_motion_back) {        ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,		    zero_block_flag);      }    }    /* Kill the Chrominance blocks... */    if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x2)) {        ParseAwayBlock(4, vid_stream);    }    if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x1)) {        ParseAwayBlock(5, vid_stream);    }  } else {    if ((ditherType == MBORDERED_DITHER) &&	(vid_stream->mblock.cbp == 0) &&	(vid_stream->picture.code_type == 3) &&	(!vid_stream->mblock.mb_intra) &&	(!(mb_motion_forw && mb_motion_back))) {      MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address, 		     mb_motion_forw, recon_right_for, recon_down_for, 		     mb_motion_back, recon_right_back, recon_down_back,		     vid_stream->past->display, vid_stream->future->display);      vid_stream->ditherFlags[vid_stream->mblock.mb_address] = 0;      no_dith_flag = 1;    }    else {#endif      for (mask = 32, i = 0; i < 6; mask >>= 1, i++) {		/* If block exists... */	if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & mask)) {	  zero_block_flag = 0;	  ParseReconBlock(i, vid_stream);	} else {	  zero_block_flag = 1;	}		/* If macroblock is intra coded... */	if (vid_stream->mblock.mb_intra) {	  ReconIMBlock(vid_stream, i);	} else if (mb_motion_forw && mb_motion_back) {	  ReconBiMBlock(vid_stream, i, recon_right_for, recon_down_for,			recon_right_back, recon_down_back, zero_block_flag);	} else if (mb_motion_forw || (vid_stream->picture.code_type == P_TYPE)) {	  ReconPMBlock(vid_stream, i, recon_right_for, recon_down_for,		       zero_block_flag);	} else if (mb_motion_back) {	  ReconBMBlock(vid_stream, i, recon_right_back, recon_down_back,		       zero_block_flag);	}      }#ifndef DISABLE_DITHER    }  }#endif#ifndef DISABLE_DITHER  if ((ditherType == MBORDERED_DITHER) && (!no_dith_flag)) {    if ((vid_stream->picture.code_type == 2) &&	(vid_stream->mblock.cbp == 0) &&	(!vid_stream->mblock.mb_intra)) {      MBOrderedDitherDisplayCopy(vid_stream, vid_stream->mblock.mb_address,				 1, recon_right_for, recon_down_for,				 0, 0, 0,				 vid_stream->future->display,				 (unsigned char *) NULL);      vid_stream->ditherFlags[vid_stream->mblock.mb_address] = 0;    }    else {      vid_stream->ditherFlags[vid_stream->mblock.mb_address] = 1;    }  }#endif  /* If D Type picture, flush marker bit. */  if (vid_stream->picture.code_type == 4)    flush_bits(1);  /* If macroblock was intracoded, set macroblock past intra address. */  if (vid_stream->mblock.mb_intra)    vid_stream->mblock.past_intra_addr =      vid_stream->mblock.mb_address;#ifdef ANALYSIS  *mbSizePtr += bitCountRead() - mbSizeCount;#endif  return PARSE_OK;}/* *-------------------------------------------------------------- * * ReconIMBlock -- * *	Reconstructs intra coded macroblock. * * Results: *	None. * * Side effects: *	None. * *-------------------------------------------------------------- */#ifndef NDEBUG/* If people really want to see such things, check 'em */#define myassert(x,expression)\  if (!(expression)) {\  fprintf (stderr,"Bad crop value (%d) at line %d\n", x, __LINE__);\  next_start_code(vid_stream); return;}#define assertCrop(x)	myassert(x,((x) >= -MAX_NEG_CROP) && \				 ((x) <= 2048+MAX_NEG_CROP))#else#define assertCrop(x)#endifstatic voidReconIMBlock(vid_stream, bnum)  VidStream *vid_stream;  int bnum;{  int mb_row, mb_col, row, col, row_size, rr;  unsigned char *dest;  /* Calculate macroblock row and column from address. */  mb_row = vid_stream->mblock.mb_address / vid_stream->mb_width;  mb_col = vid_stream->mblock.mb_address % vid_stream->mb_width;  /* If block is luminance block... */  if (bnum < 4) {    /* Calculate row and col values for upper left pixel of block. */    row = mb_row * 16;    col = mb_col * 16;    if (bnum > 1)      row += 8;    if (bnum % 2)      col += 8;    /* Set dest to luminance plane of current pict image. */    dest = vid_stream->current->luminance;    /* Establish row size. */    row_size = vid_stream->mb_width * 16;  }  /* Otherwise if block is Cr block... */  /* Cr first because of the earlier mixup */  else if (bnum == 5) {    /* Set dest to Cr plane of current pict image. */    dest = vid_stream->current->Cr;    /* Establish row size. */    row_size = vid_stream->mb_width * 8;    /* Calculate row,col for upper left pixel of block. */    row = mb_row * 8;    col = mb_col * 8;  }  /* Otherwise block is Cb block, and ... */  else {    /* Set dest to Cb plane of current pict image. */    dest = vid_stream->current->Cb;    /* Establish row size. */    row_size = vid_stream->mb_width * 8;    /* Calculate row,col for upper left pixel value of block. */    row = mb_row * 8;    col = mb_col * 8;  }  /*   * For each pixel in block, set to cropped reconstructed value from inverse   * dct.   */  {    short *sp = &vid_stream->block.dct_recon[0][0];    unsigned char *cm = cropTbl + MAX_NEG_CROP;    dest += row * row_size + col;    for (rr = 0; rr < 4; rr++, sp += 16, dest += row_size) {      dest[0] = cm[sp[0]];	  assertCrop(sp[0]);      dest[1] = cm[sp[1]];      assertCrop(sp[1]);      dest[2] = cm[sp[2]];      assertCrop(sp[2]);      dest[3] = cm[sp[3]];      assertCrop(sp[3]);      dest[4] = cm[sp[4]];      assertCrop(sp[4]);      dest[5] = cm[sp[5]];      assertCrop(sp[5]);      dest[6] = cm[sp[6]];      assertCrop(sp[6]);      dest[7] = cm[sp[7]];      assertCrop(sp[7]);      dest += row_size;      dest[0] = cm[sp[8]];      assertCrop(sp[8]);      dest[1] = cm[sp[9]];      assertCrop(sp[9]);      dest[2] = cm[sp[10]];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -