📄 msmpeg4.c
字号:
if (n == 0) return 0; else return get_bits1(gb) + 1;}int msmpeg4_decode_picture_header(MpegEncContext * s){ int code;#if 0{int i;for(i=0; i<s->gb.size_in_bits; i++) printf("%d", get_bits1(&s->gb));// get_bits1(&s->gb);printf("END\n");return -1;}#endif if(s->msmpeg4_version==1){ int start_code, num; start_code = (get_bits(&s->gb, 16)<<16) | get_bits(&s->gb, 16); if(start_code!=0x00000100){ av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n"); return -1; } num= get_bits(&s->gb, 5); // frame number */ } s->pict_type = get_bits(&s->gb, 2) + 1; if (s->pict_type != I_TYPE && s->pict_type != P_TYPE){ av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n"); return -1; }#if 0{ static int had_i=0; if(s->pict_type == I_TYPE) had_i=1; if(!had_i) return -1;}#endif s->qscale = get_bits(&s->gb, 5); if(s->qscale==0){ av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n"); return -1; } if (s->pict_type == I_TYPE) { code = get_bits(&s->gb, 5); if(s->msmpeg4_version==1){ if(code==0 || code>s->mb_height){ av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code); return -1; } s->slice_height = code; }else{ /* 0x17: one slice, 0x18: two slices, ... */ if (code < 0x17){ av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code); return -1; } s->slice_height = s->mb_height / (code - 0x16); } switch(s->msmpeg4_version){ case 1: case 2: s->rl_chroma_table_index = 2; s->rl_table_index = 2; s->dc_table_index = 0; //not used break; case 3: s->rl_chroma_table_index = decode012(&s->gb); s->rl_table_index = decode012(&s->gb); s->dc_table_index = get_bits1(&s->gb); break; case 4: msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8); if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb); else s->per_mb_rl_table= 0; if(!s->per_mb_rl_table){ s->rl_chroma_table_index = decode012(&s->gb); s->rl_table_index = decode012(&s->gb); } s->dc_table_index = get_bits1(&s->gb); s->inter_intra_pred= 0; break; } s->no_rounding = 1; if(s->avctx->debug&FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n", s->qscale, s->rl_chroma_table_index, s->rl_table_index, s->dc_table_index, s->per_mb_rl_table, s->slice_height); } else { switch(s->msmpeg4_version){ case 1: case 2: if(s->msmpeg4_version==1) s->use_skip_mb_code = 1; else s->use_skip_mb_code = get_bits1(&s->gb); s->rl_table_index = 2; s->rl_chroma_table_index = s->rl_table_index; s->dc_table_index = 0; //not used s->mv_table_index = 0; break; case 3: s->use_skip_mb_code = get_bits1(&s->gb); s->rl_table_index = decode012(&s->gb); s->rl_chroma_table_index = s->rl_table_index; s->dc_table_index = get_bits1(&s->gb); s->mv_table_index = get_bits1(&s->gb); break; case 4: s->use_skip_mb_code = get_bits1(&s->gb); if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb); else s->per_mb_rl_table= 0; if(!s->per_mb_rl_table){ s->rl_table_index = decode012(&s->gb); s->rl_chroma_table_index = s->rl_table_index; } s->dc_table_index = get_bits1(&s->gb); s->mv_table_index = get_bits1(&s->gb); s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); break; } if(s->avctx->debug&FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n", s->use_skip_mb_code, s->rl_table_index, s->rl_chroma_table_index, s->dc_table_index, s->mv_table_index, s->per_mb_rl_table, s->qscale); if(s->flipflop_rounding){ s->no_rounding ^= 1; }else{ s->no_rounding = 0; } }//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); s->esc3_level_length= 0; s->esc3_run_length= 0;#ifdef DEBUG printf("*****frame %d:\n", frame_count++);#endif return 0;}int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size){ int left= buf_size*8 - get_bits_count(&s->gb); int length= s->msmpeg4_version>=3 ? 17 : 16; /* the alt_bitstream reader could read over the end so we need to check it */ if(left>=length && left<length+8) { int fps; fps= get_bits(&s->gb, 5); s->bit_rate= get_bits(&s->gb, 11)*1024; if(s->msmpeg4_version>=3) s->flipflop_rounding= get_bits1(&s->gb); else s->flipflop_rounding= 0;// printf("fps:%2d bps:%2d roundingType:%1d\n", fps, s->bit_rate/1024, s->flipflop_rounding); } else if(left<length+8) { s->flipflop_rounding= 0; if(s->msmpeg4_version != 2) av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left); } else { av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n"); } return 0;}static inline void msmpeg4_memsetw(short *tab, int val, int n){ int i; for(i=0;i<n;i++) tab[i] = val;}static void msmpeg4v2_encode_motion(MpegEncContext * s, int val){ int range, bit_size, sign, code, bits; if (val == 0) { /* zero vector */ code = 0; put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); } else { bit_size = s->f_code - 1; range = 1 << bit_size; if (val <= -64) val += 64; else if (val >= 64) val -= 64; if (val >= 0) { sign = 0; } else { val = -val; sign = 1; } val--; code = (val >> bit_size) + 1; bits = val & (range - 1); put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); } }}/* this is identical to h263 except that its range is multiplied by 2 */static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code){ int code, val, sign, shift; code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2);// printf("MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred); if (code < 0) return 0xffff; if (code == 0) return pred; sign = get_bits1(&s->gb); shift = f_code - 1; val = code; if (shift) { val = (val - 1) << shift; val |= get_bits(&s->gb, shift); val++; } if (sign) val = -val; val += pred; if (val <= -64) val += 64; else if (val >= 64) val -= 64; return val;}static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]){ int cbp, code, i; if (s->pict_type == P_TYPE) { if (s->use_skip_mb_code) { if (get_bits1(&s->gb)) { /* skip mb */ s->mb_intra = 0; for(i=0;i<6;i++) s->block_last_index[i] = -1; s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; s->mb_skiped = 1; return 0; } } if(s->msmpeg4_version==2) code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1); else code = get_vlc2(&s->gb, v1_inter_cbpc_vlc.table, V1_INTER_CBPC_VLC_BITS, 3); if(code<0 || code>7){ av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y); return -1; } s->mb_intra = code >>2; cbp = code & 0x3; } else { s->mb_intra = 1; if(s->msmpeg4_version==2) cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1); else cbp= get_vlc2(&s->gb, v1_intra_cbpc_vlc.table, V1_INTRA_CBPC_VLC_BITS, 1); if(cbp<0 || cbp>3){ av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); return -1; } } if (!s->mb_intra) { int mx, my, cbpy; cbpy= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); if(cbpy<0){ av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); return -1; } cbp|= cbpy<<2; if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; h263_pred_motion(s, 0, &mx, &my); mx= msmpeg4v2_decode_motion(s, mx, 1); my= msmpeg4v2_decode_motion(s, my, 1); s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; s->mv[0][0][0] = mx; s->mv[0][0][1] = my; } else { if(s->msmpeg4_version==2){ s->ac_pred = get_bits1(&s->gb); cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors } else{ s->ac_pred = 0; cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors if(s->pict_type==P_TYPE) cbp^=0x3C; } } for (i = 0; i < 6; i++) { if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) { av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); return -1; } } return 0;}static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]){ int cbp, code, i; uint8_t *coded_val; uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]; if (s->pict_type == P_TYPE) { set_stat(ST_INTER_MB); if (s->use_skip_mb_code) { if (get_bits1(&s->gb)) { /* skip mb */ s->mb_intra = 0; for(i=0;i<6;i++) s->block_last_index[i] = -1; s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; s->mb_skiped = 1; *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; return 0; } } code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); if (code < 0) return -1; //s->mb_intra = (code & 0x40) ? 0 : 1; s->mb_intra = (~code & 0x40) >> 6; cbp = code & 0x3f; } else { set_stat(ST_INTRA_MB); s->mb_intra = 1; code = get_vlc2(&s->gb, mb_intra_vlc.table, MB_INTRA_VLC_BITS, 2); if (code < 0) return -1; /* predict coded block pattern */ cbp = 0; for(i=0;i<6;i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -