📄 huffyuv.c
字号:
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; if(s->bitstream_bpp==12){ while(2*cy > y){ decode_gray_bitstream(s, width); ydst= p->data[0] + p->linesize[0]*y; add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); y++; } if(y>=height) break; } draw_slice(s, y); decode_422_bitstream(s, width); ydst= p->data[0] + p->linesize[0]*y; udst= p->data[1] + p->linesize[1]*cy; vdst= p->data[2] + p->linesize[2]*cy; add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); if(!(s->flags&CODEC_FLAG_GRAY)){ add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); } } draw_slice(s, height); break; } } }else{ int y; int leftr, leftg, leftb; const int last_line= (height-1)*p->linesize[0]; if(s->bitstream_bpp==32){ p->data[0][last_line+3]= get_bits(&s->gb, 8); leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8); }else{ leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8); skip_bits(&s->gb, 8); } if(s->bgr32){ switch(s->predictor){ case LEFT: case PLANE: decode_bgr_bitstream(s, width-1); add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); for(y=s->height-2; y>=0; y--){ //yes its stored upside down decode_bgr_bitstream(s, width); add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); if(s->predictor == PLANE){ if((y&s->interlaced)==0){ s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride); } } } draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order break; default: av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n"); } }else{ av_log(avctx, AV_LOG_ERROR, "BGR24 output isnt implemenetd yet\n"); return -1; } } emms_c(); *picture= *p; *data_size = sizeof(AVFrame); return (get_bits_count(&s->gb)+31)/32*4;}static int decode_end(AVCodecContext *avctx){ HYuvContext *s = avctx->priv_data; int i; for(i=0; i<3; i++){ free_vlc(&s->vlc[i]); } avcodec_default_free_buffers(avctx); return 0;}static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ HYuvContext *s = avctx->priv_data; AVFrame *pict = data; const int width= s->width; const int width2= s->width>>1; const int height= s->height; const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; AVFrame * const p= &s->picture; int i, size; init_put_bits(&s->pb, buf, buf_size); *p = *pict; p->pict_type= FF_I_TYPE; p->key_frame= 1; if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ int lefty, leftu, leftv, y, cy; put_bits(&s->pb, 8, leftv= p->data[2][0]); put_bits(&s->pb, 8, lefty= p->data[0][1]); put_bits(&s->pb, 8, leftu= p->data[1][0]); put_bits(&s->pb, 8, p->data[0][0]); lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty); leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu); leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv); encode_422_bitstream(s, width-2); if(s->predictor==MEDIAN){ int lefttopy, lefttopu, lefttopv; cy=y=1; if(s->interlaced){ lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty); leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu); leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv); encode_422_bitstream(s, width); y++; cy++; } lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty); leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu); leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv); encode_422_bitstream(s, 4); lefttopy= p->data[0][3]; lefttopu= p->data[1][1]; lefttopv= p->data[2][1]; s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); encode_422_bitstream(s, width-4); y++; cy++; for(; y<height; y++,cy++){ uint8_t *ydst, *udst, *vdst; if(s->bitstream_bpp==12){ while(2*cy > y){ ydst= p->data[0] + p->linesize[0]*y; s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); encode_gray_bitstream(s, width); y++; } if(y>=height) break; } ydst= p->data[0] + p->linesize[0]*y; udst= p->data[1] + p->linesize[1]*cy; vdst= p->data[2] + p->linesize[2]*cy; s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv); encode_422_bitstream(s, width); } }else{ for(cy=y=1; y<height; y++,cy++){ uint8_t *ydst, *udst, *vdst; /* encode a luma only line & y++ */ if(s->bitstream_bpp==12){ ydst= p->data[0] + p->linesize[0]*y; if(s->predictor == PLANE && s->interlaced < y){ s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); }else{ lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); } encode_gray_bitstream(s, width); y++; if(y>=height) break; } ydst= p->data[0] + p->linesize[0]*y; udst= p->data[1] + p->linesize[1]*cy; vdst= p->data[2] + p->linesize[2]*cy; if(s->predictor == PLANE && s->interlaced < cy){ s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2); s->dsp.diff_bytes(s->temp[2] + 1250, vdst, vdst - fake_vstride, width2); lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu); leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + 1250, width2, leftv); }else{ lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu); leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv); } encode_422_bitstream(s, width); } } }else{ av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); } emms_c(); size= (get_bit_count(&s->pb)+31)/32; if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){ int j; char *p= avctx->stats_out; for(i=0; i<3; i++){ for(j=0; j<256; j++){ sprintf(p, "%llu ", s->stats[i][j]); p+= strlen(p); s->stats[i][j]= 0; } sprintf(p, "\n"); p++; } }else{ flush_put_bits(&s->pb); s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); } s->picture_number++; return size*4;}static int encode_end(AVCodecContext *avctx){// HYuvContext *s = avctx->priv_data; av_freep(&avctx->extradata); av_freep(&avctx->stats_out); return 0;}static const AVOption huffyuv_options[] ={ AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0), AVOPTION_END()};AVCodec huffyuv_decoder = { "huffyuv", CODEC_TYPE_VIDEO, CODEC_ID_HUFFYUV, sizeof(HYuvContext), decode_init, NULL, decode_end, decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, NULL};#ifdef CONFIG_ENCODERSAVCodec huffyuv_encoder = { "huffyuv", CODEC_TYPE_VIDEO, CODEC_ID_HUFFYUV, sizeof(HYuvContext), encode_init, encode_frame, encode_end, .options = huffyuv_options,};#endif //CONFIG_ENCODERS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -