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

📄 video.c

📁 mpeng Lib
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If start code is extension start code, parse off extension data. */  if (next_bits(32, EXT_START_CODE)) {    flush_bits32;    if (vid_stream->picture.ext_data != NULL) {      free(vid_stream->picture.ext_data);      vid_stream->picture.ext_data = NULL;    }    vid_stream->picture.ext_data = get_ext_data();  }  /* If start code is user start code, parse off user data. */  if (next_bits(32, USER_START_CODE)) {    flush_bits32;    if (vid_stream->picture.user_data != NULL) {      free(vid_stream->picture.user_data);      vid_stream->picture.user_data = NULL;    }    vid_stream->picture.user_data = get_ext_data();  }  /* Find a pict image structure in ring buffer not currently locked. */  i = 0;  while (vid_stream->ring[i]->locked != 0) {    if (++i >= RING_BUF_SIZE) {      perror("Fatal error. Ring buffer full.");      exit(1);    }  }  /* Set current pict image structure to the one just found in ring. */  vid_stream->current = vid_stream->ring[i];  /* Set time stamp. */  vid_stream->current->show_time = time_stamp;  /* Reset past macroblock address field. */  vid_stream->mblock.past_mb_addr = -1;  return PARSE_OK;}/* *-------------------------------------------------------------- * * ParseSlice -- * *      Parses off slice header. * * Results: *      Values found in slice header put into video stream structure. * * Side effects: *      Bit stream irreversibly parsed. * *-------------------------------------------------------------- */static intParseSlice(vid_stream)  VidStream *vid_stream;{  unsigned int data;  /* Flush slice start code. */  flush_bits(24);  /* Parse off slice vertical position. */  get_bits8(data);  vid_stream->slice.vert_pos = data;  /* Parse off quantization scale. */  get_bits5(data);  vid_stream->slice.quant_scale = data;  /* Parse off extra bit slice info. */  if (vid_stream->slice.extra_info != NULL) {    free(vid_stream->slice.extra_info);    vid_stream->slice.extra_info = NULL;  }  vid_stream->slice.extra_info = get_extra_bit_info();  /* Reset past intrablock address. */  vid_stream->mblock.past_intra_addr = -2;  /* Reset previous recon motion vectors. */  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;  /* Reset macroblock address. */  vid_stream->mblock.mb_address = ((vid_stream->slice.vert_pos - 1) *				   vid_stream->mb_width) - 1;  /* Reset past dct dc y, cr, and cb values. */  vid_stream->block.dct_dc_y_past = 1024;  vid_stream->block.dct_dc_cr_past = 1024;  vid_stream->block.dct_dc_cb_past = 1024;  return PARSE_OK;}/* *-------------------------------------------------------------- * * ParseMacroBlock -- * *      Parseoff macroblock. Reconstructs DCT values. Applies *      inverse DCT, reconstructs motion vectors, calculates and *      set pixel values for macroblock in current pict image *      structure. * * Results: *      Here's where everything really happens. Welcome to the *      heart of darkness. * * Side effects: *      Bit stream irreversibly parsed off. * *-------------------------------------------------------------- */static intParseMacroBlock(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, mb_motion_forw, mb_motion_back, mb_pattern;  int no_dith_flag = 0;  /*   * Parse off macroblock address increment and add to macroblock address.   */  do {    DecodeMBAddrInc(addr_incr);    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;  }  /* 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;    }  }  /* 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;  /* 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);    }  }  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);      }      /* 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);      }      /*       * Store vector existance 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;    }  }  /* For each possible block in macroblock. */  if (ditherType == GRAY_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);      } 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 Chrominace blocks... */    if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x2)) {        ParseAwayBlock(4);    }    if ((vid_stream->mblock.mb_intra) || (vid_stream->mblock.cbp & 0x1)) {        ParseAwayBlock(5);    }  } else {#if (ENABLE_DITHER)    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);      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);	} 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);	}      }    }  }#if (ENABLE_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);      ditherFlags[vid_stream->mblock.mb_address] = 0;    }    else     {      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;  return PARSE_OK;}/* *-------------------------------------------------------------- * * ReconIMBlock -- * *	Reconstructs intra coded macroblock. * * Results: *	None. * * Side effects: *	None. * *-------------------------------------------------------------- */static 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... */  else if (bnum == 4) {

⌨️ 快捷键说明

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