📄 svq1.c
字号:
dst = current; s->dsp.put_pixels_tab[1][((pmv[i]->y & 1) << 1) | (pmv[i]->x & 1)](dst,src,pitch,8); /* select next block */ if (i & 1) { current += 8*(pitch - 1); previous += 8*(pitch - 1); } else { current += 8; previous += 8; } } return 0;}static int svq1_decode_delta_block (MpegEncContext *s, bit_buffer_t *bitbuf, uint8_t *current, uint8_t *previous, int pitch, svq1_pmv_t *motion, int x, int y) { uint32_t bit_cache; uint32_t block_type; int result = 0; /* get block type */ bit_cache = get_bit_cache (bitbuf); bit_cache >>= (32 - 3); block_type = svq1_block_type_table[bit_cache].value; skip_bits(bitbuf,svq1_block_type_table[bit_cache].length); /* reset motion vectors */ if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { motion[0].x = motion[0].y = motion[(x / 8) + 2].x = motion[(x / 8) + 2].y = motion[(x / 8) + 3].x = motion[(x / 8) + 3].y = 0; } switch (block_type) { case SVQ1_BLOCK_SKIP: svq1_skip_block (current, previous, pitch, x, y); break; case SVQ1_BLOCK_INTER: result = svq1_motion_inter_block (s, bitbuf, current, previous, pitch, motion, x, y); if (result != 0) {#ifdef DEBUG_SVQ1 printf("Error in svq1_motion_inter_block %i\n",result);#endif break; } result = svq1_decode_block_non_intra (bitbuf, current, pitch); break; case SVQ1_BLOCK_INTER_4V: result = svq1_motion_inter_4v_block (s, bitbuf, current, previous, pitch, motion, x, y); if (result != 0) {#ifdef DEBUG_SVQ1 printf("Error in svq1_motion_inter_4v_block %i\n",result);#endif break; } result = svq1_decode_block_non_intra (bitbuf, current, pitch); break; case SVQ1_BLOCK_INTRA: result = svq1_decode_block_intra (bitbuf, current, pitch); break; } return result;}/* standard video sizes */static struct { int width; int height; } svq1_frame_size_table[8] = { { 160, 120 }, { 128, 96 }, { 176, 144 }, { 352, 288 }, { 704, 576 }, { 240, 180 }, { 320, 240 }, { -1, -1 }};static int svq1_decode_frame_header (bit_buffer_t *bitbuf,MpegEncContext *s) { int frame_size_code; /* unknown field */ get_bits (bitbuf, 8); /* frame type */ s->pict_type= get_bits (bitbuf, 2)+1; if(s->pict_type==4) return -1; if (s->pict_type == I_TYPE) { /* unknown fields */ if (s->f_code == 0x50 || s->f_code == 0x60) { get_bits (bitbuf, 16); } if ((s->f_code ^ 0x10) >= 0x50) { skip_bits(bitbuf,8*get_bits (bitbuf, 8)); } get_bits (bitbuf, 2); get_bits (bitbuf, 2); get_bits (bitbuf, 1); /* load frame size */ frame_size_code = get_bits (bitbuf, 3); if (frame_size_code == 7) { /* load width, height (12 bits each) */ s->width = get_bits (bitbuf, 12); s->height = get_bits (bitbuf, 12); if (!s->width || !s->height) return -1; } else { /* get width, height from table */ s->width = svq1_frame_size_table[frame_size_code].width; s->height = svq1_frame_size_table[frame_size_code].height; } } /* unknown fields */ if (get_bits (bitbuf, 1) == 1) { get_bits (bitbuf, 1); get_bits (bitbuf, 1); if (get_bits (bitbuf, 2) != 0) return -1; } if (get_bits (bitbuf, 1) == 1) { get_bits (bitbuf, 1); get_bits (bitbuf, 4); get_bits (bitbuf, 1); get_bits (bitbuf, 2); while (get_bits (bitbuf, 1) == 1) { get_bits (bitbuf, 8); } } return 0;}static int svq1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, UINT8 *buf, int buf_size){ MpegEncContext *s=avctx->priv_data; uint8_t *current, *previous; int result, i, x, y, width, height; AVPicture *pict = data; /* initialize bit buffer */ init_get_bits(&s->gb,buf,buf_size); /* decode frame header */ s->f_code = get_bits (&s->gb, 22); if ((s->f_code & ~0x70) || !(s->f_code & 0x60)) return -1; /* swap some header bytes (why?) */ if (s->f_code != 0x20) { uint32_t *src = (uint32_t *) (buf + 4); for (i=0; i < 4; i++) { src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; } } result = svq1_decode_frame_header (&s->gb, s); if(MPV_frame_start(s, avctx) < 0) return -1; if (result != 0) {#ifdef DEBUG_SVQ1 printf("Error in svq1_decode_frame_header %i\n",result);#endif return result; } if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size; /* decode y, u and v components */ for (i=0; i < 3; i++) { int linesize; if (i == 0) { width = (s->width+15)&~15; height = (s->height+15)&~15; linesize= s->linesize; } else { if(s->flags&CODEC_FLAG_GRAY) break; width = (s->width/4+15)&~15; height = (s->height/4+15)&~15; linesize= s->uvlinesize; } current = s->current_picture[i]; if(s->pict_type==B_TYPE){ previous = s->next_picture[i]; }else{ previous = s->last_picture[i]; } if (s->pict_type == I_TYPE) { /* keyframe */ for (y=0; y < height; y+=16) { for (x=0; x < width; x+=16) { result = svq1_decode_block_intra (&s->gb, ¤t[x], linesize); if (result != 0) {#ifdef DEBUG_SVQ1 printf("Error in svq1_decode_block %i (keyframe)\n",result);#endif return result; } } current += 16*linesize; } } else { svq1_pmv_t pmv[width/8+3]; /* delta frame */ memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv_t)); for (y=0; y < height; y+=16) { for (x=0; x < width; x+=16) { result = svq1_decode_delta_block (s, &s->gb, ¤t[x], previous, linesize, pmv, x, y); if (result != 0) {#ifdef DEBUG_SVQ1 printf("Error in svq1_decode_delta_block %i\n",result);#endif return result; } } pmv[0].x = pmv[0].y = 0; current += 16*linesize; } } pict->data[i] = s->current_picture[i]; pict->linesize[i] = linesize; } *data_size=sizeof(AVPicture); return buf_size;}static int svq1_decode_init(AVCodecContext *avctx){ MpegEncContext *s = avctx->priv_data; s->avctx = avctx; s->width = (avctx->width+3)&~3; s->height = (avctx->height+3)&~3; s->codec_id= avctx->codec->id; avctx->mbskip_table= s->mbskip_table; avctx->pix_fmt = PIX_FMT_YUV410P; avctx->has_b_frames= s->has_b_frames=1; // not true, but DP frames and these behave like unidirectional b frames s->flags= avctx->flags; if (MPV_common_init(s) < 0) return -1; return 0;}static int svq1_decode_end(AVCodecContext *avctx){ MpegEncContext *s = avctx->priv_data; MPV_common_end(s); return 0;}AVCodec svq1_decoder = { "svq1", CODEC_TYPE_VIDEO, CODEC_ID_SVQ1, sizeof(MpegEncContext), svq1_decode_init, NULL, svq1_decode_end, svq1_decode_frame, CODEC_CAP_DR1,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -