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

📄 video_mpeg1.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
        int r_size = pic.coding_ext.f_code[s][t] - 1;        { // Read and compute the motion vector delta      int motion_code = get_vlc(table_b10, "motion_code[r][s][0] (b10)");            if((pic.coding_ext.f_code[s][t] != 1) && (motion_code != 0)) {	int motion_residual = GETBITS(r_size, "motion_residual[r][s][0]");		delta = ((abs(motion_code) - 1) << r_size) + motion_residual + 1;	if(motion_code < 0)	  delta = - delta;      }      else {	delta = motion_code;      }          }        if(mb.dmv == 1)      mb.dmvector[t] = get_vlc(table_b11, "dmvector[0] (b11)");      // Get the predictor    prediction = pic.PMV[r][s][t];    if((t==1) && (mb.mv_format == MV_FORMAT_FIELD) &&        (pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE))      prediction = prediction >> 1;         /* DIV */        { // Compute the resulting motion vector      int f = 1 << r_size;      int high = (16 * f) - 1;      int low = ((-16) * f);      int range = (32 * f);            vector = prediction + delta;      if(vector < low)	vector = vector + range;      if(vector > high)	vector = vector - range;    }        // Update predictors    if((t==1) && (mb.mv_format == MV_FORMAT_FIELD) &&        (pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE))      pic.PMV[r][s][t] = vector * 2;    else      pic.PMV[r][s][t] = vector;        // Scale the vector so that it is always measured in half pels    if(pic.header.full_pel_vector[s])      mb.vector[r][s][t] = vector << 1;    else      mb.vector[r][s][t] = vector;  }}/* 6.2.5.2 Motion vectors */static inlinevoid motion_vectors(unsigned int s){  DPRINTF(3, "motion_vectors(%u)\n", s);    /* This does not differ from MPEG-2 if:     pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE &&     pic.coding_ext.frame_pred_frame_dct == 1     but these are all constant in MPEG1 so we set the following once     at the start if the video sequence.        mb.prediction_type = PRED_TYPE_FRAME_BASED;     mb.motion_vector_count = 1;     mb.mv_format = MV_FORMAT_FRAME;     mb.dmv = 0;  */  motion_vector(0, s);}/* 6.2.5.1 Macroblock modes */staticint macroblock_modes(void){  DPRINTF(3, "macroblock_modes\n");  if(pic.header.picture_coding_type == PIC_CODING_TYPE_I) {    mb.modes.macroblock_type = get_vlc(table_b2, "macroblock_type (b2)");  } else if(pic.header.picture_coding_type == PIC_CODING_TYPE_P) {    mb.modes.macroblock_type = get_vlc(table_b3, "macroblock_type (b3)");  } else if(pic.header.picture_coding_type == PIC_CODING_TYPE_B) {    mb.modes.macroblock_type = get_vlc(table_b4, "macroblock_type (b4)");  } else {    fprintf(stderr, "*** Unsupported picture type %02x\n", 	    pic.header.picture_coding_type);    return -1;    //exit_program(-1);  }  if(mb.modes.macroblock_type == VLC_FAIL) {    return -1;  }    mb.modes.macroblock_quant = mb.modes.macroblock_type & MACROBLOCK_QUANT;  mb.modes.macroblock_motion_forward =    mb.modes.macroblock_type & MACROBLOCK_MOTION_FORWARD;  mb.modes.macroblock_motion_backward =    mb.modes.macroblock_type & MACROBLOCK_MOTION_BACKWARD;  mb.modes.macroblock_pattern = mb.modes.macroblock_type & MACROBLOCK_PATTERN;  mb.modes.macroblock_intra = mb.modes.macroblock_type & MACROBLOCK_INTRA;#if 0 // MPEG2  mb.modes.spatial_temporal_weight_code_flag =    mb.modes.macroblock_type & SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG;    DPRINTF(5, "spatial_temporal_weight_code_flag: %01x\n", mb.modes.spatial_temporal_weight_code_flag);  if((mb.modes.spatial_temporal_weight_code_flag == 1) &&     ( 1 /*spatial_temporal_weight_code_table_index != 0*/)) {    mb.modes.spatial_temporal_weight_code = GETBITS(2, "spatial_temporal_weight_code");  }  if(mb.modes.macroblock_motion_forward ||     mb.modes.macroblock_motion_backward) {    if(pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) {      if(pic.coding_ext.frame_pred_frame_dct == 0) {	mb.modes.frame_motion_type = GETBITS(2, "frame_motion_type");      } else {	/* frame_motion_type omitted from the bitstream */	mb.modes.frame_motion_type = 0x2;      }    } else {      mb.modes.field_motion_type = GETBITS(2, "field_motion_type");    }  }  /* if(decode_dct_type) */  if((pic.coding_ext.picture_structure == PIC_STRUCT_FRAME_PICTURE) &&     (pic.coding_ext.frame_pred_frame_dct == 0) &&     (mb.modes.macroblock_intra || mb.modes.macroblock_pattern)) {        mb.modes.dct_type = GETBITS(1, "dct_type");  } else {    /* Table 6-19. Value of dct_type if dct_type is not in the bitstream.*/    if(pic.coding_ext.frame_pred_frame_dct == 1) {      mb.modes.dct_type = 0;    }    /* else dct_type is unused, either field picture or mb not coded */  }#endif    return 0;}/* 6.2.5 Macroblock */staticint macroblock(int new_slice){  uint16_t inc_add = 0;    DPRINTF(3, "macroblock()\n");  // MPEG-1 start   (this does not occur in an MPEG-2 stream)  //                 (not a valid macroblock_escape code)  while(nextbits(11) == 0x00F) {    GETBITS(11, "macroblock_stuffing");  }  // MPEG-1 end  while(nextbits(11) == 0x008) {    GETBITS(11, "macroblock_escape");    inc_add += 33;  }  mb.macroblock_address_increment    = get_vlc(table_b1, "macroblock_address_increment");    if(mb.macroblock_address_increment == VLC_FAIL) {    return -1;  }    mb.macroblock_address_increment += inc_add;    seq.macroblock_address += mb.macroblock_address_increment;  seq.mb_column = seq.macroblock_address % seq.mb_width;  seq.mb_row = seq.macroblock_address / seq.mb_width;  if(new_slice) /* There are never any skipped blocks at start of a slice */    mb.macroblock_address_increment = 1;  DPRINTF(2, " Macroblock: %d, row: %d, col: %d\n",	  seq.macroblock_address,	  seq.mb_row,	  seq.mb_column);  #ifdef DEBUG  if(mb.macroblock_address_increment > 1) {    DPRINTF(3, "Skipped %d macroblocks ",	    mb.macroblock_address_increment);  }#endif      /* Process all block that are skipped. (Do motion compensation) */  if(mb.macroblock_address_increment > 1) {        int i;            /* There is plenty of room to optimize this */    switch(pic.header.picture_coding_type) {        case PIC_CODING_TYPE_I:      fprintf(stderr, "*** skipped blocks in I-picture\n");      return -1; // Error parsing bitstream        case PIC_CODING_TYPE_P:      DPRINTF(3,"in P-picture\n");      /* Assume prediction is forward with a zero vector */      mb.modes.macroblock_motion_forward = 1; // Remove Me      mb.modes.macroblock_motion_backward = 0; // Remove Me      mb.modes.macroblock_type |= MACROBLOCK_MOTION_FORWARD;      mb.modes.macroblock_type &= ~MACROBLOCK_MOTION_BACKWARD;	      reset_vectors(); // Instead of explicit set to zero.      break;        case PIC_CODING_TYPE_B:      DPRINTF(3,"in B-frame\n");      /* Use previous macroblock modes and vectors. */      break;    }        /* We only get here for P or B picutes. */    i = mb.macroblock_address_increment;    while( --i > 0 ) {      seq.mb_column = (seq.macroblock_address - i) % seq.mb_width;      seq.mb_row    = (seq.macroblock_address - i) / seq.mb_width;      /* Skipped blocks never have any DCT-coefficients,	 so there is no call to motion_comp_add_coeff */      motion_comp();    }    seq.mb_column = seq.macroblock_address % seq.mb_width;    seq.mb_row    = seq.macroblock_address / seq.mb_width;  }    /* What kind of macroblock is this. */  if(macroblock_modes() == -1) {    return -1; // Error parsing bitstream  }    if(mb.modes.macroblock_quant) {    mb.quantiser_scale = GETBITS(5, "quantiser_scale_code");  }    if(mb.modes.macroblock_intra == 0) {    reset_dc_dct_pred();    DPRINTF(3, "non_intra macroblock\n");  }      /* Decoding of motion vectors. */    // Reset predictors: when a macroblock is skipped in a P-picture. */  if(mb.macroblock_address_increment > 1) {    reset_dc_dct_pred(); // Could be moved but fitts fine here    if(pic.header.picture_coding_type == PIC_CODING_TYPE_P)      reset_PMV();  }    if(mb.modes.macroblock_motion_forward)    motion_vectors(0);  if(mb.modes.macroblock_motion_backward)    motion_vectors(1);    // Update predictors.  if((mb.modes.macroblock_motion_forward == 0) &&     (mb.modes.macroblock_motion_backward == 0)) {  // Is this correct?    reset_PMV();  }   switch (pic.header.picture_coding_type) {  case PIC_CODING_TYPE_I: /* I-picture */    break;  case PIC_CODING_TYPE_P: /* P-picture */    if(mb.modes.macroblock_intra) {      reset_PMV();      reset_vectors();    }    if((!mb.modes.macroblock_intra) && (!mb.modes.macroblock_motion_forward)) {      reset_PMV();      /* Asume prediction is forward with a zero vector */      mb.modes.macroblock_motion_forward = 1; // Remove Me      mb.modes.macroblock_motion_backward = 0; // Remove Me      mb.modes.macroblock_type |= MACROBLOCK_MOTION_FORWARD;      mb.modes.macroblock_type &= ~MACROBLOCK_MOTION_BACKWARD;	      reset_vectors(); // Instead of explicit set to zero.    }    break;  case PIC_CODING_TYPE_B: /* B-picture */    if(mb.modes.macroblock_intra) {      reset_PMV();      reset_vectors();    }    break;  }      /* Pel reconstruction      - motion compensation (if any)     - decode coefficents     - inverse quantisation      - 'oddify' the coefficents     - inverse transform     - combine the data with motion compensated pels */    if(mb.modes.macroblock_intra) {    unsigned int i;        /* Intra blocks always have pattern coded for all sub blocks.        The IDCT function writes directly to the output buffers. */        for(i = 0; i < 6; i++) {        DPRINTF(4, "cbpindex: %d assumed\n", i);      if(block_intra(i) == -1)	return -1; // Error parsing bitstream            /* Shortcut: write the IDCT data directly into the picture buffer */      {	const int x = seq.mb_column;	const int y = seq.mb_row;	const int width = seq.mb_width * 16; //seq.horizontal_size;	int d, stride;	uint8_t *dst;		if (mb.modes.dct_type) {	  d = 1;	  stride = width * 2;	} else {	  d = 8;	  stride = width;	}		if(i < 4) {	  dst = &dst_image->y[x * 16 + y * width * 16];	  dst = (i & 1) ? dst + 8 : dst;	  dst = (i >= 2) ? dst + width * d : dst;	}	else {	  stride = width / 2; // HACK alert !!!	  if(i == 4)	    dst = &dst_image->u[x * 8 + y * width/2 * 8];	  else // i == 5	    dst = &dst_image->v[x * 8 + y * width/2 * 8];	}		mlib_VideoIDCT8x8_U8_S16(dst, (int16_t *)mb.QFS, stride);      }    }  }   else { /* Non-intra block */        motion_comp();    if(mb.modes.macroblock_pattern) {      int i;      if(coded_block_pattern() == -1)	return -1; // Error parsing bitstream            for(i = 0; i < 6; i++) {	if(mb.cbp & (1<<(5-i))) {	  DPRINTF(4, "cbpindex: %d set\n", i);	  if(block_non_intra(i) == -1)	    return -1; // Error parsing bitstream	  	  //mlib_VideoIDCT8x8_S16_S16((int16_t *)mb.QFS, (int16_t *)mb.QFS);	  motion_comp_add_coeff(i); // do idtc and add in here	}      }    }  }    return 0;}/* 6.2.4 Slice */int mpeg1_slice(void){  uint32_t slice_start_code;  int new_slice = 1;    DPRINTF(3, "slice\n");  reset_dc_dct_pred();  reset_PMV();  reset_vectors();  DPRINTF(3, "start of slice\n");  slice_start_code = GETBITS(32, "slice_start_code");  slice_data.slice_vertical_position = slice_start_code & 0xff;    // Do we need to update seq.mb_col ???  seq.mb_row = slice_data.slice_vertical_position - 1;  seq.macroblock_address = (seq.mb_row * seq.mb_width) - 1;  mb.quantiser_scale = GETBITS(5, "quantiser_scale_code");  if(nextbits(1) == 1) {    slice_data.intra_slice_flag = GETBITS(1, "intra_slice_flag");    slice_data.intra_slice = GETBITS(1, "intra_slice");    slice_data.reserved_bits = GETBITS(7, "reserved_bits");    while(nextbits(1) == 1) {      slice_data.extra_bit_slice = GETBITS(1, "extra_bit_slice");      slice_data.extra_information_slice 	= GETBITS(8, "extra_information_slice");    }  }  slice_data.extra_bit_slice = GETBITS(1, "extra_bit_slice");  do {    if( macroblock(new_slice) ) {      //break;      return -1;    }    new_slice = 0;  } while(nextbits(23) != 0);  next_start_code();  return 0;}

⌨️ 快捷键说明

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