📄 mpeg12.c
字号:
if (s->pict_type == P_TYPE && !(mb_type & MB_FOR)) { s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; s->last_mv[0][1][0] = 0; s->last_mv[0][1][1] = 0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; } else if (mb_type & (MB_FOR | MB_BACK)) { /* motion vectors */ s->mv_dir = 0; for(i=0;i<2;i++) { if (mb_type & (MB_FOR >> i)) { s->mv_dir |= (MV_DIR_FORWARD >> i); dprintf("motion_type=%d\n", motion_type); switch(motion_type) { case MT_FRAME: /* or MT_16X8 */ if (s->picture_structure == PICT_FRAME) { /* MT_FRAME */ s->mv_type = MV_TYPE_16X16; for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], s->last_mv[i][0][k]); s->last_mv[i][0][k] = val; s->last_mv[i][1][k] = val; /* full_pel: only for mpeg1 */ if (s->full_pel[i]) val = val << 1; s->mv[i][0][k] = val; dprintf("mv%d: %d\n", k, val); } } else { /* MT_16X8 */ s->mv_type = MV_TYPE_16X8; for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], s->last_mv[i][j][k]); s->last_mv[i][j][k] = val; s->mv[i][j][k] = val; } } } break; case MT_FIELD: if (s->picture_structure == PICT_FRAME) { s->mv_type = MV_TYPE_FIELD; for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][j][0]); s->last_mv[i][j][0] = val; s->mv[i][j][0] = val; dprintf("fmx=%d\n", val); val = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][j][1] >> 1); s->last_mv[i][j][1] = val << 1; s->mv[i][j][1] = val; dprintf("fmy=%d\n", val); } } else { s->mv_type = MV_TYPE_16X16; s->field_select[i][0] = get_bits1(&s->gb); for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], s->last_mv[i][0][k]); s->last_mv[i][0][k] = val; s->last_mv[i][1][k] = val; s->mv[i][0][k] = val; } } break; case MT_DMV: { int dmx, dmy, mx, my, m; mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); s->last_mv[i][0][0] = mx; s->last_mv[i][1][0] = mx; dmx = get_dmv(s); my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1] >> 1); dmy = get_dmv(s); s->mv_type = MV_TYPE_DMV; /* XXX: totally broken */ if (s->picture_structure == PICT_FRAME) { s->last_mv[i][0][1] = my << 1; s->last_mv[i][1][1] = my << 1; m = s->top_field_first ? 1 : 3; /* top -> top pred */ s->mv[i][0][0] = mx; s->mv[i][0][1] = my << 1; s->mv[i][1][0] = ((mx * m + (mx > 0)) >> 1) + dmx; s->mv[i][1][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; m = 4 - m; s->mv[i][2][0] = mx; s->mv[i][2][1] = my << 1; s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; } else { s->last_mv[i][0][1] = my; s->last_mv[i][1][1] = my; s->mv[i][0][0] = mx; s->mv[i][0][1] = my; s->mv[i][1][0] = ((mx + (mx > 0)) >> 1) + dmx; s->mv[i][1][1] = ((my + (my > 0)) >> 1) + dmy - 1 /* + 2 * cur_field */; } } break; } } } } if ((mb_type & MB_INTRA) && s->concealment_motion_vectors) { skip_bits1(&s->gb); /* marker */ } if (mb_type & MB_PAT) { cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); if (cbp < 0){ fprintf(stderr, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); return -1; } cbp++; } dprintf("cbp=%x\n", cbp); if (s->mpeg2) { if (s->mb_intra) { for(i=0;i<6;i++) { if (mpeg2_decode_block_intra(s, block[i], i) < 0) return -1; } } else { for(i=0;i<6;i++) { if (cbp & 32) { if (mpeg2_decode_block_non_intra(s, block[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; } cbp+=cbp; } } } else { if (s->mb_intra) { for(i=0;i<6;i++) { if (mpeg1_decode_block_intra(s, block[i], i) < 0) return -1; } }else{ for(i=0;i<6;i++) { if (cbp & 32) { if (mpeg1_decode_block_inter(s, block[i], i) < 0) return -1; } else { s->block_last_index[i] = -1; } cbp+=cbp; } } } return 0;}/* as h263, but only 17 codes */static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred){ int code, sign, val, m, l, shift; code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); if (code < 0) { return 0xffff; } if (code == 0) { return pred; } sign = get_bits1(&s->gb); shift = fcode - 1; val = (code - 1) << shift; if (shift > 0) val |= get_bits(&s->gb, shift); val++; if (sign) val = -val; val += pred; /* modulo decoding */ l = (1 << shift) * 16; m = 2 * l; if (val < -l) { val += m; } else if (val >= l) { val -= m; } return val;}static inline int decode_dc(MpegEncContext *s, int component){ int code, diff; if (component == 0) { code = get_vlc2(&s->gb, dc_lum_vlc.table, DC_VLC_BITS, 2); } else { code = get_vlc2(&s->gb, dc_chroma_vlc.table, DC_VLC_BITS, 2); } if (code < 0){ fprintf(stderr, "invalid dc code at %d %d\n", s->mb_x, s->mb_y); return 0xffff; } if (code == 0) { diff = 0; } else { diff = get_bits(&s->gb, code); if ((diff & (1 << (code - 1))) == 0) diff = (-1 << code) | (diff + 1); } return diff;}static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n){ int level, dc, diff, i, j, run; int component; RLTable *rl = &rl_mpeg1; UINT8 * const scantable= s->intra_scantable.permutated; const UINT16 *quant_matrix= s->intra_matrix; const int qscale= s->qscale; /* DC coef */ component = (n <= 3 ? 0 : n - 4 + 1); diff = decode_dc(s, component); if (diff >= 0xffff) return -1; dc = s->last_dc[component]; dc += diff; s->last_dc[component] = dc; block[0] = dc<<3; dprintf("dc=%d diff=%d\n", dc, diff); i = 0; { OPEN_READER(re, &s->gb); /* now quantify & encode AC coefs */ for(;;) { UPDATE_CACHE(re, &s->gb); GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2); if(level == 127){ break; } else if(level != 0) { i += run; j = scantable[i]; level= (level*qscale*quant_matrix[j])>>3; level= (level-1)|1; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); } else { /* escape */ run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); UPDATE_CACHE(re, &s->gb); level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); if (level == -128) { level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8); } else if (level == 0) { level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); } i += run; j = scantable[i]; if(level<0){ level= -level; level= (level*qscale*quant_matrix[j])>>3; level= (level-1)|1; level= -level; }else{ level= (level*qscale*quant_matrix[j])>>3; level= (level-1)|1; } } if (i > 63){ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); return -1; } block[j] = level; } CLOSE_READER(re, &s->gb); } s->block_last_index[n] = i; return 0;}static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n){ int level, i, j, run; RLTable *rl = &rl_mpeg1; UINT8 * const scantable= s->intra_scantable.permutated; const UINT16 *quant_matrix= s->inter_matrix; const int qscale= s->qscale; { int v; OPEN_READER(re, &s->gb); i = -1; /* special case for the first coef. no need to add a second vlc table */ UPDATE_CACHE(re, &s->gb); v= SHOW_UBITS(re, &s->gb, 2); if (v & 2) { LAST_SKIP_BITS(re, &s->gb, 2); level= (3*qscale*quant_matrix[0])>>4; level= (level-1)|1; if(v&1) level= -level; block[0] = level; i++; } /* now quantify & encode AC coefs */ for(;;) { UPDATE_CACHE(re, &s->gb); GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2); if(level == 127){ break; } else if(level != 0) { i += run; j = scantable[i]; level= ((level*2+1)*qscale*quant_matrix[j])>>4; level= (level-1)|1; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); } else { /* escape */ run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); UPDATE_CACHE(re, &s->gb); level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8); if (level == -128) { level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8); } else if (level == 0) { level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); } i += run; j = scantable[i]; if(level<0){ level= -level; level= ((level*2+1)*qscale*quant_matrix[j])>>4; level= (level-1)|1; level= -level; }else{ level= ((level*2+1)*qscale*quant_matrix[j])>>4; level= (level-1)|1; } } if (i > 63){ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); return -1; } block[j] = level; } CLOSE_READER(re, &s->gb); } s->block_last_index[n] = i; return 0;}/* Also does unquantization here, since I will never support mpeg2 encoding */static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n){ int level, i, j, run; RLTable *rl = &rl_mpeg1; UINT8 * const scantable= s->intra_scantable.permutated; const UINT16 *quant_matrix; const int qscale= s->qscale; int mismatch; mismatch = 1; { int v; OPEN_READER(re, &s->gb); i = -1; if (n < 4) quant_matrix = s->inter_matrix;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -