📄 svq3.c
字号:
for (i=0; i < 4; i++) { *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = 0; } } if (s->mb_y > 0) { memcpy (h->mv_cache[m][scan8[0] - 1*8], s->current_picture.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t)); memset (&h->ref_cache[m][scan8[0] - 1*8], (h->intra4x4_pred_mode[mb_xy - s->mb_stride][4] == -1) ? PART_NOT_AVAILABLE : 1, 4); if (s->mb_x < (s->mb_width - 1)) { *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride + 4]; h->ref_cache[m][scan8[0] + 4 - 1*8] = (h->intra4x4_pred_mode[mb_xy - s->mb_stride + 1][0] == -1 || h->intra4x4_pred_mode[mb_xy - s->mb_stride][4] == -1) ? PART_NOT_AVAILABLE : 1; }else h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE; if (s->mb_x > 0) { *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride - 1]; h->ref_cache[m][scan8[0] - 1 - 1*8] = (h->intra4x4_pred_mode[mb_xy - s->mb_stride - 1][3] == -1) ? PART_NOT_AVAILABLE : 1; }else h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE; }else memset (&h->ref_cache[m][scan8[0] - 1*8 - 1], PART_NOT_AVAILABLE, 8); if (s->pict_type != B_TYPE) break; } /* decode motion vector(s) and form prediction(s) */ if (s->pict_type == P_TYPE) { svq3_mc_dir (h, (mb_type - 1), mode, 0, 0); } else { /* B_TYPE */ if (mb_type != 2) { svq3_mc_dir (h, 0, mode, 0, 0); } else { for (i=0; i < 4; i++) { memset (s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } } if (mb_type != 1) { svq3_mc_dir (h, 0, mode, 1, (mb_type == 3)); } else { for (i=0; i < 4; i++) { memset (s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } } } mb_type = MB_TYPE_16x16; } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */ memset (h->intra4x4_pred_mode_cache, -1, 8*5*sizeof(int8_t)); if (mb_type == 8) { if (s->mb_x > 0) { for (i=0; i < 4; i++) { h->intra4x4_pred_mode_cache[scan8[0] - 1 + i*8] = h->intra4x4_pred_mode[mb_xy - 1][i]; } if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1) { h->left_samples_available = 0x5F5F; } } if (s->mb_y > 0) { h->intra4x4_pred_mode_cache[4+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][4]; h->intra4x4_pred_mode_cache[5+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][5]; h->intra4x4_pred_mode_cache[6+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][6]; h->intra4x4_pred_mode_cache[7+8*0] = h->intra4x4_pred_mode[mb_xy - s->mb_stride][3]; if (h->intra4x4_pred_mode_cache[4+8*0] == -1) { h->top_samples_available = 0x33FF; } } /* decode prediction codes for luma blocks */ for (i=0; i < 16; i+=2) { vlc = svq3_get_ue_golomb (&s->gb); if (vlc >= 25) return -1; left = &h->intra4x4_pred_mode_cache[scan8[i] - 1]; top = &h->intra4x4_pred_mode_cache[scan8[i] - 8]; left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]]; left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]]; if (left[1] == -1 || left[2] == -1) return -1; } } else { /* mb_type == 33, DC_128_PRED block type */ for (i=0; i < 4; i++) { memset (&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_PRED, 4); } } write_back_intra_pred_mode (h); if (mb_type == 8) { check_intra4x4_pred_mode (h); h->top_samples_available = (s->mb_y == 0) ? 0x33FF : 0xFFFF; h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF; } else { for (i=0; i < 4; i++) { memset (&h->intra4x4_pred_mode_cache[scan8[0] + 8*i], DC_128_PRED, 4); } h->top_samples_available = 0x33FF; h->left_samples_available = 0x5F5F; } mb_type = MB_TYPE_INTRA4x4; } else { /* INTRA16x16 */ dir = i_mb_type_info[mb_type - 8].pred_mode; dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; if ((h->intra16x16_pred_mode = check_intra_pred_mode (h, dir)) == -1) return -1; cbp = i_mb_type_info[mb_type - 8].cbp; mb_type = MB_TYPE_INTRA16x16; } if (!IS_INTER(mb_type) && s->pict_type != I_TYPE) { for (i=0; i < 4; i++) { memset (s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } if (s->pict_type == B_TYPE) { for (i=0; i < 4; i++) { memset (s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } } } if (!IS_INTRA4x4(mb_type)) { memset (h->intra4x4_pred_mode[mb_xy], DC_PRED, 8); } if (!IS_SKIP(mb_type) || s->pict_type == B_TYPE) { memset (h->non_zero_count_cache + 8, 0, 4*9*sizeof(uint8_t)); s->dsp.clear_blocks(h->mb); } if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == B_TYPE)) { if ((vlc = svq3_get_ue_golomb (&s->gb)) >= 48) return -1; cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc] : golomb_to_inter_cbp[vlc]; } if (IS_INTRA16x16(mb_type) || (s->pict_type != I_TYPE && s->adaptive_quant && cbp)) { s->qscale += svq3_get_se_golomb (&s->gb); if (s->qscale > 31) return -1; } if (IS_INTRA16x16(mb_type)) { if (svq3_decode_block (&s->gb, h->mb, 0, 0)) return -1; } if (cbp) { const int index = IS_INTRA16x16(mb_type) ? 1 : 0; const int type = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1); for (i=0; i < 4; i++) { if ((cbp & (1 << i))) { for (j=0; j < 4; j++) { k = index ? ((j&1) + 2*(i&1) + 2*(j&2) + 4*(i&2)) : (4*i + j); h->non_zero_count_cache[ scan8[k] ] = 1; if (svq3_decode_block (&s->gb, &h->mb[16*k], index, type)) return -1; } } } if ((cbp & 0x30)) { for (i=0; i < 2; ++i) { if (svq3_decode_block (&s->gb, &h->mb[16*(16 + 4*i)], 0, 3)) return -1; } if ((cbp & 0x20)) { for (i=0; i < 8; i++) { h->non_zero_count_cache[ scan8[16+i] ] = 1; if (svq3_decode_block (&s->gb, &h->mb[16*(16 + i)], 1, 1)) return -1; } } } } s->current_picture.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) { h->chroma_pred_mode = check_intra_pred_mode (h, DC_PRED8x8); } return 0;}static int svq3_decode_slice_header (H264Context *h) { MpegEncContext *const s = (MpegEncContext *) h; const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; int i, header; header = get_bits (&s->gb, 8); if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { /* TODO: what? */ av_log(h->s.avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); return -1; } else { int length = (header >> 5) & 3; h->next_slice_index = s->gb.index + 8*show_bits (&s->gb, 8*length) + 8*length; if (h->next_slice_index > s->gb.size_in_bits) return -1; s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); s->gb.index += 8; if (length > 0) { memcpy ((uint8_t *) &s->gb.buffer[s->gb.index >> 3], &s->gb.buffer[s->gb.size_in_bits >> 3], (length - 1)); } } if ((i = svq3_get_ue_golomb (&s->gb)) == INVALID_VLC || i >= 3) return -1; h->slice_type = golomb_to_pict_type[i]; if ((header & 0x9F) == 2) { i = (s->mb_num < 64) ? 6 : (1 + av_log2 (s->mb_num - 1)); s->mb_skip_run = get_bits (&s->gb, i) - (s->mb_x + (s->mb_y * s->mb_width)); } else { get_bits1 (&s->gb); s->mb_skip_run = 0; } h->slice_num = get_bits (&s->gb, 8); s->qscale = get_bits (&s->gb, 5); s->adaptive_quant = get_bits1 (&s->gb); /* unknown fields */ get_bits1 (&s->gb); if (h->unknown_svq3_flag) { get_bits1 (&s->gb); } get_bits1 (&s->gb); get_bits (&s->gb, 2); while (get_bits1 (&s->gb)) { get_bits (&s->gb, 8); } /* reset intra predictors and invalidate motion vector references */ if (s->mb_x > 0) { memset (h->intra4x4_pred_mode[mb_xy - 1], -1, 4*sizeof(int8_t)); memset (h->intra4x4_pred_mode[mb_xy - s->mb_x], -1, 8*sizeof(int8_t)*s->mb_x); } if (s->mb_y > 0) { memset (h->intra4x4_pred_mode[mb_xy - s->mb_stride], -1, 8*sizeof(int8_t)*(s->mb_width - s->mb_x)); if (s->mb_x > 0) { h->intra4x4_pred_mode[mb_xy - s->mb_stride - 1][3] = -1; } } return 0;}static int svq3_decode_frame (AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { MpegEncContext *const s = avctx->priv_data; H264Context *const h = avctx->priv_data; int m, mb_type; *data_size = 0; s->flags = avctx->flags; if (!s->context_initialized) { s->width = avctx->width; s->height = avctx->height; h->pred4x4[DIAG_DOWN_LEFT_PRED] = pred4x4_down_left_svq3_c; h->pred16x16[PLANE_PRED8x8] = pred16x16_plane_svq3_c; h->halfpel_flag = 1; h->thirdpel_flag = 1; h->unknown_svq3_flag = 0; h->chroma_qp = 4; if (MPV_common_init (s) < 0) return -1; h->b_stride = 4*s->mb_width; alloc_tables (h); if (avctx->extradata && avctx->extradata_size >= 0x64 && !memcmp (avctx->extradata, "SVQ3", 4)) { GetBitContext gb; init_get_bits (&gb, (uint8_t *) avctx->extradata + 0x62, 8*(avctx->extradata_size - 0x62)); /* 'frame size code' and optional 'width, height' */ if (get_bits (&gb, 3) == 7) { get_bits (&gb, 12); get_bits (&gb, 12); } h->halfpel_flag = get_bits1 (&gb); h->thirdpel_flag = get_bits1 (&gb); /* unknown fields */ get_bits1 (&gb); get_bits1 (&gb); get_bits1 (&gb); get_bits1 (&gb); s->low_delay = get_bits1 (&gb); /* unknown field */ get_bits1 (&gb); while (get_bits1 (&gb)) { get_bits (&gb, 8); } h->unknown_svq3_flag = get_bits1 (&gb); avctx->has_b_frames = !s->low_delay; } } /* special case for last picture */ if (buf_size == 0) { if (s->next_picture_ptr && !s->low_delay) { *(AVFrame *) data = *(AVFrame *) &s->next_picture; *data_size = sizeof(AVFrame); } return 0; } init_get_bits (&s->gb, buf, 8*buf_size); s->mb_x = s->mb_y = 0; if (svq3_decode_slice_header (h)) return -1; s->pict_type = h->slice_type; s->picture_number = h->slice_num; if(avctx->debug&FF_DEBUG_PICT_INFO){ av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d\n", av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag, s->adaptive_quant, s->qscale ); } /* for hurry_up==5 */ s->current_picture.pict_type = s->pict_type; s->current_picture.key_frame = (s->pict_type == I_TYPE); /* skip b frames if we dont have reference frames */ if (s->last_picture_ptr == NULL && s->pict_type == B_TYPE) return 0; /* skip b frames if we are in a hurry */ if (avctx->hurry_up && s->pict_type == B_TYPE) return 0; /* skip everything if we are in a hurry >= 5 */ if (avctx->hurry_up >= 5) return 0; if (s->next_p_frame_damaged) { if (s->pict_type == B_TYPE) return 0; else s->next_p_frame_damaged = 0; } frame_start (h); if (s->pict_type == B_TYPE) { h->frame_num_offset = (h->slice_num - h->prev_frame_num); if (h->frame_num_offset < 0) { h->frame_num_offset += 256; } if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) { av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n"); return -1; } } else { h->prev_frame_num = h->frame_num; h->frame_num = h->slice_num; h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num); if (h->prev_frame_num_offset < 0) { h->prev_frame_num_offset += 256; } } for(m=0; m<2; m++){ int i; for(i=0; i<4; i++){ int j; for(j=-1; j<4; j++) h->ref_cache[m][scan8[0] + 8*i + j]= 1; h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE; } } for (s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) { for (s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { if ( (s->gb.index + 7) >= s->gb.size_in_bits && ((s->gb.index & 7) == 0 || show_bits (&s->gb, (-s->gb.index & 7)) == 0)) { s->gb.index = h->next_slice_index; s->gb.size_in_bits = 8*buf_size; if (svq3_decode_slice_header (h)) return -1; /* TODO: support s->mb_skip_run */ } mb_type = svq3_get_ue_golomb (&s->gb); if (s->pict_type == I_TYPE) { mb_type += 8; } else if (s->pict_type == B_TYPE && mb_type >= 4) { mb_type += 4; } if (mb_type > 33 || svq3_decode_mb (h, mb_type)) { av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); return -1; } if (mb_type != 0) { hl_decode_mb (h); } if (s->pict_type != B_TYPE && !s->low_delay) { s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = (s->pict_type == P_TYPE && mb_type < 8) ? (mb_type - 1) : -1; } } ff_draw_horiz_band(s, 16*s->mb_y, 16); } MPV_frame_end(s); if (s->pict_type == B_TYPE || s->low_delay) { *(AVFrame *) data = *(AVFrame *) &s->current_picture; } else { *(AVFrame *) data = *(AVFrame *) &s->last_picture; } avctx->frame_number = s->picture_number - 1; /* dont output the last pic after seeking */ if (s->last_picture_ptr || s->low_delay) { *data_size = sizeof(AVFrame); } return buf_size;}AVCodec svq3_decoder = { "svq3", CODEC_TYPE_VIDEO, CODEC_ID_SVQ3, sizeof(H264Context), decode_init, NULL, decode_end, svq3_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -