📄 dv.c
字号:
} re_index += vlc_len;#ifdef VLC_DEBUG printf("run=%d level=%d\n", run, level);#endif pos += run; if (pos >= 64) break; assert(level); pos1 = scan_table[pos]; block[pos1] = level << shift_table[pos1]; UPDATE_CACHE(re, gb); } CLOSE_READER(re, gb); mb->pos = pos;}static inline void bit_copy(PutBitContext *pb, GetBitContext *gb){ int bits_left = get_bits_left(gb); while (bits_left >= MIN_CACHE_BITS) { put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); bits_left -= MIN_CACHE_BITS; } if (bits_left > 0) { put_bits(pb, bits_left, get_bits(gb, bits_left)); }}/* mb_x and mb_y are in units of 8 pixels */static inline void dv_decode_video_segment(DVVideoContext *s, uint8_t *buf_ptr1, const uint16_t *mb_pos_ptr){ int quant, dc, dct_mode, class1, j; int mb_index, mb_x, mb_y, v, last_index; DCTELEM *block, *block1; int c_offset; uint8_t *y_ptr; void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); uint8_t *buf_ptr; PutBitContext pb, vs_pb; GetBitContext gb; BlockInfo mb_data[5 * 6], *mb, *mb1; DCTELEM sblock[5*6][64] __align8; uint8_t mb_bit_buffer[80 + 4] __align8; /* allow some slack */ uint8_t vs_bit_buffer[5 * 80 + 4] __align8; /* allow some slack */ const int log2_blocksize= 3-s->avctx->lowres; assert((((int)mb_bit_buffer)&7)==0); assert((((int)vs_bit_buffer)&7)==0); memset(sblock, 0, sizeof(sblock)); /* pass 1 : read DC and AC coefficients in blocks */ buf_ptr = buf_ptr1; block1 = &sblock[0][0]; mb1 = mb_data; init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80); for(mb_index = 0; mb_index < 5; mb_index++, mb1 += 6, block1 += 6 * 64) { /* skip header */ quant = buf_ptr[3] & 0x0f; buf_ptr += 4; init_put_bits(&pb, mb_bit_buffer, 80); mb = mb1; block = block1; for(j = 0;j < 6; j++) { last_index = block_sizes[j]; init_get_bits(&gb, buf_ptr, last_index); /* get the dc */ dc = get_sbits(&gb, 9); dct_mode = get_bits1(&gb); mb->dct_mode = dct_mode; mb->scan_table = s->dv_zigzag[dct_mode]; class1 = get_bits(&gb, 2); mb->shift_table = s->dv_idct_shift[class1 == 3][dct_mode] [quant + dv_quant_offset[class1]]; dc = dc << 2; /* convert to unsigned because 128 is not added in the standard IDCT */ dc += 1024; block[0] = dc; buf_ptr += last_index >> 3; mb->pos = 0; mb->partial_bit_count = 0;#ifdef VLC_DEBUG printf("MB block: %d, %d ", mb_index, j);#endif dv_decode_ac(&gb, mb, block); /* write the remaining bits in a new buffer only if the block is finished */ if (mb->pos >= 64) bit_copy(&pb, &gb); block += 64; mb++; } /* pass 2 : we can do it just after */#ifdef VLC_DEBUG printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);#endif block = block1; mb = mb1; init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb)); flush_put_bits(&pb); for(j = 0;j < 6; j++, block += 64, mb++) { if (mb->pos < 64 && get_bits_left(&gb) > 0) { dv_decode_ac(&gb, mb, block); /* if still not finished, no need to parse other blocks */ if (mb->pos < 64) break; } } /* all blocks are finished, so the extra bytes can be used at the video segment level */ if (j >= 6) bit_copy(&vs_pb, &gb); } /* we need a pass other the whole video segment */#ifdef VLC_DEBUG printf("***pass 3 size=%d\n", put_bits_count(&vs_pb));#endif block = &sblock[0][0]; mb = mb_data; init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb)); flush_put_bits(&vs_pb); for(mb_index = 0; mb_index < 5; mb_index++) { for(j = 0;j < 6; j++) { if (mb->pos < 64) {#ifdef VLC_DEBUG printf("start %d:%d\n", mb_index, j);#endif dv_decode_ac(&gb, mb, block); } if (mb->pos >= 64 && mb->pos < 127) av_log(NULL, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos); block += 64; mb++; } } /* compute idct and place blocks */ block = &sblock[0][0]; mb = mb_data; for(mb_index = 0; mb_index < 5; mb_index++) { v = *mb_pos_ptr++; mb_x = v & 0xff; mb_y = v >> 8; y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize); if (s->sys->pix_fmt == PIX_FMT_YUV411P) c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize); else c_offset = (((mb_y >> 1) * s->picture.linesize[1] + (mb_x >> 1))<<log2_blocksize); for(j = 0;j < 6; j++) { idct_put = s->idct_put[mb->dct_mode && log2_blocksize==3]; if (j < 4) { if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { /* NOTE: at end of line, the macroblock is handled as 420 */ idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block); } else { idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize), s->picture.linesize[0], block); } } else { if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { uint64_t aligned_pixels[64/8]; uint8_t *pixels= (uint8_t*)aligned_pixels; uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1; int x, y, linesize; /* NOTE: at end of line, the macroblock is handled as 420 */ idct_put(pixels, 8, block); linesize = s->picture.linesize[6 - j]; c_ptr = s->picture.data[6 - j] + c_offset; ptr = pixels; for(y = 0;y < (1<<log2_blocksize); y++) { ptr1= ptr + (1<<(log2_blocksize-1)); c_ptr1 = c_ptr + (linesize<<log2_blocksize); for(x=0; x < (1<<(log2_blocksize-1)); x++){ c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x]; } c_ptr += linesize; ptr += 8; } } else { /* don't ask me why they inverted Cb and Cr ! */ idct_put(s->picture.data[6 - j] + c_offset, s->picture.linesize[6 - j], block); } } block += 64; mb++; } }}#ifdef DV_CODEC_TINY_TARGET/* Converts run and level (where level != 0) pair into vlc, returning bit size */static always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc){ int size; if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { *vlc = dv_vlc_map[run][level].vlc | sign; size = dv_vlc_map[run][level].size; } else { if (level < DV_VLC_MAP_LEV_SIZE) { *vlc = dv_vlc_map[0][level].vlc | sign; size = dv_vlc_map[0][level].size; } else { *vlc = 0xfe00 | (level << 1) | sign; size = 16; } if (run) { *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : (0x1f80 | (run - 1))) << size; size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; } } return size;}static always_inline int dv_rl2vlc_size(int run, int level){ int size; if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { size = dv_vlc_map[run][level].size; } else { size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; if (run) { size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; } } return size;}#elsestatic always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc){ *vlc = dv_vlc_map[run][l].vlc | sign; return dv_vlc_map[run][l].size;}static always_inline int dv_rl2vlc_size(int run, int l){ return dv_vlc_map[run][l].size;}#endiftypedef struct EncBlockInfo { int area_q[4]; int bit_size[4]; int prev[5]; int cur_ac; int cno; int dct_mode; DCTELEM mb[64]; uint8_t next[64]; uint8_t sign[64]; uint8_t partial_bit_count; uint32_t partial_bit_buffer; /* we can't use uint16_t here */} EncBlockInfo;static always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, PutBitContext* pb_end){ int prev; int bits_left; PutBitContext* pb = pb_pool; int size = bi->partial_bit_count; uint32_t vlc = bi->partial_bit_buffer; bi->partial_bit_count = bi->partial_bit_buffer = 0; for(;;){ /* Find suitable storage space */ for (; size > (bits_left = put_bits_left(pb)); pb++) { if (bits_left) { size -= bits_left; put_bits(pb, bits_left, vlc >> size); vlc = vlc & ((1<<size)-1); } if (pb + 1 >= pb_end) { bi->partial_bit_count = size; bi->partial_bit_buffer = vlc; return pb; } } /* Store VLC */ put_bits(pb, size, vlc); if(bi->cur_ac>=64) break; /* Construct the next VLC */ prev= bi->cur_ac; bi->cur_ac = bi->next[prev]; if(bi->cur_ac < 64){ size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc); } else { size = 4; vlc = 6; /* End Of Block stamp */ } } return pb;}static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, const uint8_t* zigzag_scan, int bias){ int i, area; static const int classes[] = {12, 24, 36, 0xffff}; int max=12; int prev=0; bi->mb[0] = blk[0]; for (area = 0; area < 4; area++) { bi->prev[area] = prev; bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) for (i=mb_area_start[area]; i<mb_area_start[area+1]; i++) { int level = blk[zigzag_scan[i]]; if (level+15 > 30U) { bi->sign[i] = (level>>31)&1; bi->mb[i] = level= ABS(level)>>4; if(level>max) max= level;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -