⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dv.c

📁 tcpmp播放器的flv插件
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	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 + -