📄 huffyuv.c.svn-base
字号:
for(i=0; i<count; i++){ READ_2PIX(s->temp[0][2*i ], s->temp[1][i], 1); READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); }}static void decode_gray_bitstream(HYuvContext *s, int count){ int i; count/=2; for(i=0; i<count; i++){ READ_2PIX(s->temp[0][2*i ], s->temp[0][2*i+1], 0); }}#ifdef CONFIG_ENCODERSstatic int encode_422_bitstream(HYuvContext *s, int count){ int i; if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; }#define LOAD4\ int y0 = s->temp[0][2*i];\ int y1 = s->temp[0][2*i+1];\ int u0 = s->temp[1][i];\ int v0 = s->temp[2][i]; count/=2; if(s->flags&CODEC_FLAG_PASS1){ for(i=0; i<count; i++){ LOAD4; s->stats[0][y0]++; s->stats[1][u0]++; s->stats[0][y1]++; s->stats[2][v0]++; } } if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) return 0; if(s->context){ for(i=0; i<count; i++){ LOAD4; s->stats[0][y0]++; put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); s->stats[1][u0]++; put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); s->stats[0][y1]++; put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); s->stats[2][v0]++; put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); } }else{ for(i=0; i<count; i++){ LOAD4; put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); } } return 0;}static int encode_gray_bitstream(HYuvContext *s, int count){ int i; if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*count){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; }#define LOAD2\ int y0 = s->temp[0][2*i];\ int y1 = s->temp[0][2*i+1];#define STAT2\ s->stats[0][y0]++;\ s->stats[0][y1]++;#define WRITE2\ put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\ put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); count/=2; if(s->flags&CODEC_FLAG_PASS1){ for(i=0; i<count; i++){ LOAD2; STAT2; } } if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) return 0; if(s->context){ for(i=0; i<count; i++){ LOAD2; STAT2; WRITE2; } }else{ for(i=0; i<count; i++){ LOAD2; WRITE2; } } return 0;}#endif /* CONFIG_ENCODERS */static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){ int i; for(i=0; i<count; i++){ int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1); if(code != -1){ *(uint32_t*)&s->temp[0][4*i] = s->pix_bgr_map[code]; }else if(decorrelate){ s->temp[0][4*i+G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); s->temp[0][4*i+B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G]; s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G]; }else{ s->temp[0][4*i+B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); s->temp[0][4*i+G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); } if(alpha) get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! }}static void decode_bgr_bitstream(HYuvContext *s, int count){ if(s->decorrelate){ if(s->bitstream_bpp==24) decode_bgr_1(s, count, 1, 0); else decode_bgr_1(s, count, 1, 1); }else{ if(s->bitstream_bpp==24) decode_bgr_1(s, count, 0, 0); else decode_bgr_1(s, count, 0, 1); }}static int encode_bgr_bitstream(HYuvContext *s, int count){ int i; if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3*4*count){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; }#define LOAD3\ int g= s->temp[0][4*i+G];\ int b= (s->temp[0][4*i+B] - g) & 0xff;\ int r= (s->temp[0][4*i+R] - g) & 0xff;#define STAT3\ s->stats[0][b]++;\ s->stats[1][g]++;\ s->stats[2][r]++;#define WRITE3\ put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\ put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\ put_bits(&s->pb, s->len[2][r], s->bits[2][r]); if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){ for(i=0; i<count; i++){ LOAD3; STAT3; } }else if(s->context || (s->flags&CODEC_FLAG_PASS1)){ for(i=0; i<count; i++){ LOAD3; STAT3; WRITE3; } }else{ for(i=0; i<count; i++){ LOAD3; WRITE3; } } return 0;}#ifdef CONFIG_DECODERSstatic void draw_slice(HYuvContext *s, int y){ int h, cy; int offset[4]; if(s->avctx->draw_horiz_band==NULL) return; h= y - s->last_slice_end; y -= h; if(s->bitstream_bpp==12){ cy= y>>1; }else{ cy= y; } offset[0] = s->picture.linesize[0]*y; offset[1] = s->picture.linesize[1]*cy; offset[2] = s->picture.linesize[2]*cy; offset[3] = 0; emms_c(); s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h); s->last_slice_end= y + h;}static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){ HYuvContext *s = avctx->priv_data; const int width= s->width; const int width2= s->width>>1; const int height= s->height; int fake_ystride, fake_ustride, fake_vstride; AVFrame * const p= &s->picture; int table_size= 0; AVFrame *picture = data; s->bitstream_buffer= av_fast_realloc(s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size/4); if(p->data[0]) avctx->release_buffer(avctx, p); p->reference= 0; if(avctx->get_buffer(avctx, p) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } if(s->context){ table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); if(table_size < 0) return -1; } if((unsigned)(buf_size-table_size) >= INT_MAX/8) return -1; init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8); fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2]; s->last_slice_end= 0; if(s->bitstream_bpp<24){ int y, cy; int lefty, leftu, leftv; int lefttopy, lefttopu, lefttopv; if(s->yuy2){ p->data[0][3]= get_bits(&s->gb, 8); p->data[0][2]= get_bits(&s->gb, 8); p->data[0][1]= get_bits(&s->gb, 8); p->data[0][0]= get_bits(&s->gb, 8); av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n"); return -1; }else{ leftv= p->data[2][0]= get_bits(&s->gb, 8); lefty= p->data[0][1]= get_bits(&s->gb, 8); leftu= p->data[1][0]= get_bits(&s->gb, 8); p->data[0][0]= get_bits(&s->gb, 8); switch(s->predictor){ case LEFT: case PLANE: decode_422_bitstream(s, width-2); lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); if(!(s->flags&CODEC_FLAG_GRAY)){ leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); } for(cy=y=1; y<s->height; y++,cy++){ uint8_t *ydst, *udst, *vdst; if(s->bitstream_bpp==12){ decode_gray_bitstream(s, width); ydst= p->data[0] + p->linesize[0]*y; lefty= add_left_prediction(ydst, s->temp[0], width, lefty); if(s->predictor == PLANE){ if(y>s->interlaced) s->dsp.add_bytes(ydst, ydst - fake_ystride, width); } y++; if(y>=s->height) break; } draw_slice(s, y); ydst= p->data[0] + p->linesize[0]*y; udst= p->data[1] + p->linesize[1]*cy; vdst= p->data[2] + p->linesize[2]*cy; decode_422_bitstream(s, width); lefty= add_left_prediction(ydst, s->temp[0], width, lefty); if(!(s->flags&CODEC_FLAG_GRAY)){ leftu= add_left_prediction(udst, s->temp[1], width2, leftu); leftv= add_left_prediction(vdst, s->temp[2], width2, leftv); } if(s->predictor == PLANE){ if(cy>s->interlaced){ s->dsp.add_bytes(ydst, ydst - fake_ystride, width); if(!(s->flags&CODEC_FLAG_GRAY)){ s->dsp.add_bytes(udst, udst - fake_ustride, width2); s->dsp.add_bytes(vdst, vdst - fake_vstride, width2); } } } } draw_slice(s, height); break; case MEDIAN: /* first line except first 2 pixels is left predicted */ decode_422_bitstream(s, width-2); lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); if(!(s->flags&CODEC_FLAG_GRAY)){ leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); } cy=y=1; /* second line is left predicted for interlaced case */ if(s->interlaced){ decode_422_bitstream(s, width); lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); if(!(s->flags&CODEC_FLAG_GRAY)){ leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); } y++; cy++; } /* next 4 pixels are left predicted too */ decode_422_bitstream(s, 4); lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); if(!(s->flags&CODEC_FLAG_GRAY)){ leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); } /* next line except the first 4 pixels is median predicted */ lefttopy= p->data[0][3]; decode_422_bitstream(s, width-4); add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy); if(!(s->flags&CODEC_FLAG_GRAY)){ lefttopu= p->data[1][1]; lefttopv= p->data[2][1]; add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); } y++; cy++; for(; y<height; y++,cy++){ uint8_t *ydst, *udst, *vdst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -