1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavutil/intmath.h" 22cabdff1aSopenharmony_ci#include "libavutil/libm.h" 23cabdff1aSopenharmony_ci#include "libavutil/log.h" 24cabdff1aSopenharmony_ci#include "libavutil/opt.h" 25cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 26cabdff1aSopenharmony_ci#include "avcodec.h" 27cabdff1aSopenharmony_ci#include "codec_internal.h" 28cabdff1aSopenharmony_ci#include "encode.h" 29cabdff1aSopenharmony_ci#include "packet_internal.h" 30cabdff1aSopenharmony_ci#include "snow_dwt.h" 31cabdff1aSopenharmony_ci#include "snow.h" 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "rangecoder.h" 34cabdff1aSopenharmony_ci#include "mathops.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci#include "mpegvideo.h" 37cabdff1aSopenharmony_ci#include "h263enc.h" 38cabdff1aSopenharmony_ci 39cabdff1aSopenharmony_cistatic av_cold int encode_init(AVCodecContext *avctx) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci SnowContext *s = avctx->priv_data; 42cabdff1aSopenharmony_ci int plane_index, ret; 43cabdff1aSopenharmony_ci int i; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci if(s->pred == DWT_97 46cabdff1aSopenharmony_ci && (avctx->flags & AV_CODEC_FLAG_QSCALE) 47cabdff1aSopenharmony_ci && avctx->global_quality == 0){ 48cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n"); 49cabdff1aSopenharmony_ci return AVERROR(EINVAL); 50cabdff1aSopenharmony_ci } 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci s->spatial_decomposition_type= s->pred; //FIXME add decorrelator type r transform_type 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci s->mv_scale = (avctx->flags & AV_CODEC_FLAG_QPEL) ? 2 : 4; 55cabdff1aSopenharmony_ci s->block_max_depth= (avctx->flags & AV_CODEC_FLAG_4MV ) ? 1 : 0; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci for(plane_index=0; plane_index<3; plane_index++){ 58cabdff1aSopenharmony_ci s->plane[plane_index].diag_mc= 1; 59cabdff1aSopenharmony_ci s->plane[plane_index].htaps= 6; 60cabdff1aSopenharmony_ci s->plane[plane_index].hcoeff[0]= 40; 61cabdff1aSopenharmony_ci s->plane[plane_index].hcoeff[1]= -10; 62cabdff1aSopenharmony_ci s->plane[plane_index].hcoeff[2]= 2; 63cabdff1aSopenharmony_ci s->plane[plane_index].fast_mc= 1; 64cabdff1aSopenharmony_ci } 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci if ((ret = ff_snow_common_init(avctx)) < 0) { 67cabdff1aSopenharmony_ci return ret; 68cabdff1aSopenharmony_ci } 69cabdff1aSopenharmony_ci ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx); 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci ff_snow_alloc_blocks(s); 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci s->version=0; 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci s->m.avctx = avctx; 76cabdff1aSopenharmony_ci s->m.bit_rate= avctx->bit_rate; 77cabdff1aSopenharmony_ci s->m.lmin = avctx->mb_lmin; 78cabdff1aSopenharmony_ci s->m.lmax = avctx->mb_lmax; 79cabdff1aSopenharmony_ci s->m.mb_num = (avctx->width * avctx->height + 255) / 256; // For ratecontrol 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci s->m.me.temp = 82cabdff1aSopenharmony_ci s->m.me.scratchpad = av_calloc(avctx->width + 64, 2*16*2*sizeof(uint8_t)); 83cabdff1aSopenharmony_ci s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); 84cabdff1aSopenharmony_ci s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); 85cabdff1aSopenharmony_ci s->m.sc.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t)); 86cabdff1aSopenharmony_ci if (!s->m.me.scratchpad || !s->m.me.map || !s->m.me.score_map || !s->m.sc.obmc_scratchpad) 87cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci ff_h263_encode_init(&s->m); //mv_penalty 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci s->max_ref_frames = av_clip(avctx->refs, 1, MAX_REF_FRAMES); 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci if(avctx->flags&AV_CODEC_FLAG_PASS1){ 94cabdff1aSopenharmony_ci if(!avctx->stats_out) 95cabdff1aSopenharmony_ci avctx->stats_out = av_mallocz(256); 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci if (!avctx->stats_out) 98cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 99cabdff1aSopenharmony_ci } 100cabdff1aSopenharmony_ci if((avctx->flags&AV_CODEC_FLAG_PASS2) || !(avctx->flags&AV_CODEC_FLAG_QSCALE)){ 101cabdff1aSopenharmony_ci ret = ff_rate_control_init(&s->m); 102cabdff1aSopenharmony_ci if(ret < 0) 103cabdff1aSopenharmony_ci return ret; 104cabdff1aSopenharmony_ci } 105cabdff1aSopenharmony_ci s->pass1_rc= !(avctx->flags & (AV_CODEC_FLAG_QSCALE|AV_CODEC_FLAG_PASS2)); 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci switch(avctx->pix_fmt){ 108cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P: 109cabdff1aSopenharmony_ci// case AV_PIX_FMT_YUV422P: 110cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P: 111cabdff1aSopenharmony_ci// case AV_PIX_FMT_YUV411P: 112cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV410P: 113cabdff1aSopenharmony_ci s->nb_planes = 3; 114cabdff1aSopenharmony_ci s->colorspace_type= 0; 115cabdff1aSopenharmony_ci break; 116cabdff1aSopenharmony_ci case AV_PIX_FMT_GRAY8: 117cabdff1aSopenharmony_ci s->nb_planes = 1; 118cabdff1aSopenharmony_ci s->colorspace_type = 1; 119cabdff1aSopenharmony_ci break; 120cabdff1aSopenharmony_ci/* case AV_PIX_FMT_RGB32: 121cabdff1aSopenharmony_ci s->colorspace= 1; 122cabdff1aSopenharmony_ci break;*/ 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, 126cabdff1aSopenharmony_ci &s->chroma_v_shift); 127cabdff1aSopenharmony_ci if (ret) 128cabdff1aSopenharmony_ci return ret; 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci ret = ff_set_cmp(&s->mecc, s->mecc.me_cmp, s->avctx->me_cmp); 131cabdff1aSopenharmony_ci ret |= ff_set_cmp(&s->mecc, s->mecc.me_sub_cmp, s->avctx->me_sub_cmp); 132cabdff1aSopenharmony_ci if (ret < 0) 133cabdff1aSopenharmony_ci return AVERROR(EINVAL); 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci s->input_picture = av_frame_alloc(); 136cabdff1aSopenharmony_ci if (!s->input_picture) 137cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci if ((ret = ff_snow_get_buffer(s, s->input_picture)) < 0) 140cabdff1aSopenharmony_ci return ret; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci if(s->motion_est == FF_ME_ITER){ 143cabdff1aSopenharmony_ci int size= s->b_width * s->b_height << 2*s->block_max_depth; 144cabdff1aSopenharmony_ci for(i=0; i<s->max_ref_frames; i++){ 145cabdff1aSopenharmony_ci s->ref_mvs[i] = av_calloc(size, sizeof(*s->ref_mvs[i])); 146cabdff1aSopenharmony_ci s->ref_scores[i] = av_calloc(size, sizeof(*s->ref_scores[i])); 147cabdff1aSopenharmony_ci if (!s->ref_mvs[i] || !s->ref_scores[i]) 148cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci return 0; 153cabdff1aSopenharmony_ci} 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci//near copy & paste from dsputil, FIXME 156cabdff1aSopenharmony_cistatic int pix_sum(uint8_t * pix, int line_size, int w, int h) 157cabdff1aSopenharmony_ci{ 158cabdff1aSopenharmony_ci int s, i, j; 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci s = 0; 161cabdff1aSopenharmony_ci for (i = 0; i < h; i++) { 162cabdff1aSopenharmony_ci for (j = 0; j < w; j++) { 163cabdff1aSopenharmony_ci s += pix[0]; 164cabdff1aSopenharmony_ci pix ++; 165cabdff1aSopenharmony_ci } 166cabdff1aSopenharmony_ci pix += line_size - w; 167cabdff1aSopenharmony_ci } 168cabdff1aSopenharmony_ci return s; 169cabdff1aSopenharmony_ci} 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci//near copy & paste from dsputil, FIXME 172cabdff1aSopenharmony_cistatic int pix_norm1(uint8_t * pix, int line_size, int w) 173cabdff1aSopenharmony_ci{ 174cabdff1aSopenharmony_ci int s, i, j; 175cabdff1aSopenharmony_ci const uint32_t *sq = ff_square_tab + 256; 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci s = 0; 178cabdff1aSopenharmony_ci for (i = 0; i < w; i++) { 179cabdff1aSopenharmony_ci for (j = 0; j < w; j ++) { 180cabdff1aSopenharmony_ci s += sq[pix[0]]; 181cabdff1aSopenharmony_ci pix ++; 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci pix += line_size - w; 184cabdff1aSopenharmony_ci } 185cabdff1aSopenharmony_ci return s; 186cabdff1aSopenharmony_ci} 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_cistatic inline int get_penalty_factor(int lambda, int lambda2, int type){ 189cabdff1aSopenharmony_ci switch(type&0xFF){ 190cabdff1aSopenharmony_ci default: 191cabdff1aSopenharmony_ci case FF_CMP_SAD: 192cabdff1aSopenharmony_ci return lambda>>FF_LAMBDA_SHIFT; 193cabdff1aSopenharmony_ci case FF_CMP_DCT: 194cabdff1aSopenharmony_ci return (3*lambda)>>(FF_LAMBDA_SHIFT+1); 195cabdff1aSopenharmony_ci case FF_CMP_W53: 196cabdff1aSopenharmony_ci return (4*lambda)>>(FF_LAMBDA_SHIFT); 197cabdff1aSopenharmony_ci case FF_CMP_W97: 198cabdff1aSopenharmony_ci return (2*lambda)>>(FF_LAMBDA_SHIFT); 199cabdff1aSopenharmony_ci case FF_CMP_SATD: 200cabdff1aSopenharmony_ci case FF_CMP_DCT264: 201cabdff1aSopenharmony_ci return (2*lambda)>>FF_LAMBDA_SHIFT; 202cabdff1aSopenharmony_ci case FF_CMP_RD: 203cabdff1aSopenharmony_ci case FF_CMP_PSNR: 204cabdff1aSopenharmony_ci case FF_CMP_SSE: 205cabdff1aSopenharmony_ci case FF_CMP_NSSE: 206cabdff1aSopenharmony_ci return lambda2>>FF_LAMBDA_SHIFT; 207cabdff1aSopenharmony_ci case FF_CMP_BIT: 208cabdff1aSopenharmony_ci return 1; 209cabdff1aSopenharmony_ci } 210cabdff1aSopenharmony_ci} 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci//FIXME copy&paste 213cabdff1aSopenharmony_ci#define P_LEFT P[1] 214cabdff1aSopenharmony_ci#define P_TOP P[2] 215cabdff1aSopenharmony_ci#define P_TOPRIGHT P[3] 216cabdff1aSopenharmony_ci#define P_MEDIAN P[4] 217cabdff1aSopenharmony_ci#define P_MV1 P[9] 218cabdff1aSopenharmony_ci#define FLAG_QPEL 1 //must be 1 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_cistatic int encode_q_branch(SnowContext *s, int level, int x, int y){ 221cabdff1aSopenharmony_ci uint8_t p_buffer[1024]; 222cabdff1aSopenharmony_ci uint8_t i_buffer[1024]; 223cabdff1aSopenharmony_ci uint8_t p_state[sizeof(s->block_state)]; 224cabdff1aSopenharmony_ci uint8_t i_state[sizeof(s->block_state)]; 225cabdff1aSopenharmony_ci RangeCoder pc, ic; 226cabdff1aSopenharmony_ci uint8_t *pbbak= s->c.bytestream; 227cabdff1aSopenharmony_ci uint8_t *pbbak_start= s->c.bytestream_start; 228cabdff1aSopenharmony_ci int score, score2, iscore, i_len, p_len, block_s, sum, base_bits; 229cabdff1aSopenharmony_ci const int w= s->b_width << s->block_max_depth; 230cabdff1aSopenharmony_ci const int h= s->b_height << s->block_max_depth; 231cabdff1aSopenharmony_ci const int rem_depth= s->block_max_depth - level; 232cabdff1aSopenharmony_ci const int index= (x + y*w) << rem_depth; 233cabdff1aSopenharmony_ci const int block_w= 1<<(LOG2_MB_SIZE - level); 234cabdff1aSopenharmony_ci int trx= (x+1)<<rem_depth; 235cabdff1aSopenharmony_ci int try= (y+1)<<rem_depth; 236cabdff1aSopenharmony_ci const BlockNode *left = x ? &s->block[index-1] : &null_block; 237cabdff1aSopenharmony_ci const BlockNode *top = y ? &s->block[index-w] : &null_block; 238cabdff1aSopenharmony_ci const BlockNode *right = trx<w ? &s->block[index+1] : &null_block; 239cabdff1aSopenharmony_ci const BlockNode *bottom= try<h ? &s->block[index+w] : &null_block; 240cabdff1aSopenharmony_ci const BlockNode *tl = y && x ? &s->block[index-w-1] : left; 241cabdff1aSopenharmony_ci const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt 242cabdff1aSopenharmony_ci int pl = left->color[0]; 243cabdff1aSopenharmony_ci int pcb= left->color[1]; 244cabdff1aSopenharmony_ci int pcr= left->color[2]; 245cabdff1aSopenharmony_ci int pmx, pmy; 246cabdff1aSopenharmony_ci int mx=0, my=0; 247cabdff1aSopenharmony_ci int l,cr,cb; 248cabdff1aSopenharmony_ci const int stride= s->current_picture->linesize[0]; 249cabdff1aSopenharmony_ci const int uvstride= s->current_picture->linesize[1]; 250cabdff1aSopenharmony_ci uint8_t *current_data[3]= { s->input_picture->data[0] + (x + y* stride)*block_w, 251cabdff1aSopenharmony_ci s->input_picture->data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift), 252cabdff1aSopenharmony_ci s->input_picture->data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)}; 253cabdff1aSopenharmony_ci int P[10][2]; 254cabdff1aSopenharmony_ci int16_t last_mv[3][2]; 255cabdff1aSopenharmony_ci int qpel= !!(s->avctx->flags & AV_CODEC_FLAG_QPEL); //unused 256cabdff1aSopenharmony_ci const int shift= 1+qpel; 257cabdff1aSopenharmony_ci MotionEstContext *c= &s->m.me; 258cabdff1aSopenharmony_ci int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); 259cabdff1aSopenharmony_ci int mx_context= av_log2(2*FFABS(left->mx - top->mx)); 260cabdff1aSopenharmony_ci int my_context= av_log2(2*FFABS(left->my - top->my)); 261cabdff1aSopenharmony_ci int s_context= 2*left->level + 2*top->level + tl->level + tr->level; 262cabdff1aSopenharmony_ci int ref, best_ref, ref_score, ref_mx, ref_my; 263cabdff1aSopenharmony_ci int range = MAX_MV >> (1 + qpel); 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci av_assert0(sizeof(s->block_state) >= 256); 266cabdff1aSopenharmony_ci if(s->keyframe){ 267cabdff1aSopenharmony_ci set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); 268cabdff1aSopenharmony_ci return 0; 269cabdff1aSopenharmony_ci } 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci// clip predictors / edge ? 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci P_LEFT[0]= left->mx; 274cabdff1aSopenharmony_ci P_LEFT[1]= left->my; 275cabdff1aSopenharmony_ci P_TOP [0]= top->mx; 276cabdff1aSopenharmony_ci P_TOP [1]= top->my; 277cabdff1aSopenharmony_ci P_TOPRIGHT[0]= tr->mx; 278cabdff1aSopenharmony_ci P_TOPRIGHT[1]= tr->my; 279cabdff1aSopenharmony_ci 280cabdff1aSopenharmony_ci last_mv[0][0]= s->block[index].mx; 281cabdff1aSopenharmony_ci last_mv[0][1]= s->block[index].my; 282cabdff1aSopenharmony_ci last_mv[1][0]= right->mx; 283cabdff1aSopenharmony_ci last_mv[1][1]= right->my; 284cabdff1aSopenharmony_ci last_mv[2][0]= bottom->mx; 285cabdff1aSopenharmony_ci last_mv[2][1]= bottom->my; 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci s->m.mb_stride=2; 288cabdff1aSopenharmony_ci s->m.mb_x= 289cabdff1aSopenharmony_ci s->m.mb_y= 0; 290cabdff1aSopenharmony_ci c->skip= 0; 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci av_assert1(c-> stride == stride); 293cabdff1aSopenharmony_ci av_assert1(c->uvstride == uvstride); 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); 296cabdff1aSopenharmony_ci c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); 297cabdff1aSopenharmony_ci c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); 298cabdff1aSopenharmony_ci c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_DMV; 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_ci c->xmin = - x*block_w - 16+3; 301cabdff1aSopenharmony_ci c->ymin = - y*block_w - 16+3; 302cabdff1aSopenharmony_ci c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3; 303cabdff1aSopenharmony_ci c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3; 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci c->xmin = FFMAX(c->xmin, -range); 306cabdff1aSopenharmony_ci c->xmax = FFMIN(c->xmax, range); 307cabdff1aSopenharmony_ci c->ymin = FFMAX(c->ymin, -range); 308cabdff1aSopenharmony_ci c->ymax = FFMIN(c->ymax, range); 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift); 311cabdff1aSopenharmony_ci if(P_LEFT[1] > (c->ymax<<shift)) P_LEFT[1] = (c->ymax<<shift); 312cabdff1aSopenharmony_ci if(P_TOP[0] > (c->xmax<<shift)) P_TOP[0] = (c->xmax<<shift); 313cabdff1aSopenharmony_ci if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1] = (c->ymax<<shift); 314cabdff1aSopenharmony_ci if(P_TOPRIGHT[0] < (c->xmin * (1<<shift))) P_TOPRIGHT[0]= (c->xmin * (1<<shift)); 315cabdff1aSopenharmony_ci if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip 316cabdff1aSopenharmony_ci if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift); 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); 319cabdff1aSopenharmony_ci P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_ci if (!y) { 322cabdff1aSopenharmony_ci c->pred_x= P_LEFT[0]; 323cabdff1aSopenharmony_ci c->pred_y= P_LEFT[1]; 324cabdff1aSopenharmony_ci } else { 325cabdff1aSopenharmony_ci c->pred_x = P_MEDIAN[0]; 326cabdff1aSopenharmony_ci c->pred_y = P_MEDIAN[1]; 327cabdff1aSopenharmony_ci } 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci score= INT_MAX; 330cabdff1aSopenharmony_ci best_ref= 0; 331cabdff1aSopenharmony_ci for(ref=0; ref<s->ref_frames; ref++){ 332cabdff1aSopenharmony_ci init_ref(c, current_data, s->last_picture[ref]->data, NULL, block_w*x, block_w*y, 0); 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_ci ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv, 335cabdff1aSopenharmony_ci (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w); 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci av_assert2(ref_mx >= c->xmin); 338cabdff1aSopenharmony_ci av_assert2(ref_mx <= c->xmax); 339cabdff1aSopenharmony_ci av_assert2(ref_my >= c->ymin); 340cabdff1aSopenharmony_ci av_assert2(ref_my <= c->ymax); 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w); 343cabdff1aSopenharmony_ci ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0); 344cabdff1aSopenharmony_ci ref_score+= 2*av_log2(2*ref)*c->penalty_factor; 345cabdff1aSopenharmony_ci if(s->ref_mvs[ref]){ 346cabdff1aSopenharmony_ci s->ref_mvs[ref][index][0]= ref_mx; 347cabdff1aSopenharmony_ci s->ref_mvs[ref][index][1]= ref_my; 348cabdff1aSopenharmony_ci s->ref_scores[ref][index]= ref_score; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci if(score > ref_score){ 351cabdff1aSopenharmony_ci score= ref_score; 352cabdff1aSopenharmony_ci best_ref= ref; 353cabdff1aSopenharmony_ci mx= ref_mx; 354cabdff1aSopenharmony_ci my= ref_my; 355cabdff1aSopenharmony_ci } 356cabdff1aSopenharmony_ci } 357cabdff1aSopenharmony_ci //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2 358cabdff1aSopenharmony_ci 359cabdff1aSopenharmony_ci // subpel search 360cabdff1aSopenharmony_ci base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start); 361cabdff1aSopenharmony_ci pc= s->c; 362cabdff1aSopenharmony_ci pc.bytestream_start= 363cabdff1aSopenharmony_ci pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo 364cabdff1aSopenharmony_ci memcpy(p_state, s->block_state, sizeof(s->block_state)); 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci if(level!=s->block_max_depth) 367cabdff1aSopenharmony_ci put_rac(&pc, &p_state[4 + s_context], 1); 368cabdff1aSopenharmony_ci put_rac(&pc, &p_state[1 + left->type + top->type], 0); 369cabdff1aSopenharmony_ci if(s->ref_frames > 1) 370cabdff1aSopenharmony_ci put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0); 371cabdff1aSopenharmony_ci pred_mv(s, &pmx, &pmy, best_ref, left, top, tr); 372cabdff1aSopenharmony_ci put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1); 373cabdff1aSopenharmony_ci put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1); 374cabdff1aSopenharmony_ci p_len= pc.bytestream - pc.bytestream_start; 375cabdff1aSopenharmony_ci score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT; 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_ci block_s= block_w*block_w; 378cabdff1aSopenharmony_ci sum = pix_sum(current_data[0], stride, block_w, block_w); 379cabdff1aSopenharmony_ci l= (sum + block_s/2)/block_s; 380cabdff1aSopenharmony_ci iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s; 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci if (s->nb_planes > 2) { 383cabdff1aSopenharmony_ci block_s= block_w*block_w>>(s->chroma_h_shift + s->chroma_v_shift); 384cabdff1aSopenharmony_ci sum = pix_sum(current_data[1], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); 385cabdff1aSopenharmony_ci cb= (sum + block_s/2)/block_s; 386cabdff1aSopenharmony_ci // iscore += pix_norm1(¤t_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s; 387cabdff1aSopenharmony_ci sum = pix_sum(current_data[2], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift); 388cabdff1aSopenharmony_ci cr= (sum + block_s/2)/block_s; 389cabdff1aSopenharmony_ci // iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s; 390cabdff1aSopenharmony_ci }else 391cabdff1aSopenharmony_ci cb = cr = 0; 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_ci ic= s->c; 394cabdff1aSopenharmony_ci ic.bytestream_start= 395cabdff1aSopenharmony_ci ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo 396cabdff1aSopenharmony_ci memcpy(i_state, s->block_state, sizeof(s->block_state)); 397cabdff1aSopenharmony_ci if(level!=s->block_max_depth) 398cabdff1aSopenharmony_ci put_rac(&ic, &i_state[4 + s_context], 1); 399cabdff1aSopenharmony_ci put_rac(&ic, &i_state[1 + left->type + top->type], 1); 400cabdff1aSopenharmony_ci put_symbol(&ic, &i_state[32], l-pl , 1); 401cabdff1aSopenharmony_ci if (s->nb_planes > 2) { 402cabdff1aSopenharmony_ci put_symbol(&ic, &i_state[64], cb-pcb, 1); 403cabdff1aSopenharmony_ci put_symbol(&ic, &i_state[96], cr-pcr, 1); 404cabdff1aSopenharmony_ci } 405cabdff1aSopenharmony_ci i_len= ic.bytestream - ic.bytestream_start; 406cabdff1aSopenharmony_ci iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT; 407cabdff1aSopenharmony_ci 408cabdff1aSopenharmony_ci av_assert1(iscore < 255*255*256 + s->lambda2*10); 409cabdff1aSopenharmony_ci av_assert1(iscore >= 0); 410cabdff1aSopenharmony_ci av_assert1(l>=0 && l<=255); 411cabdff1aSopenharmony_ci av_assert1(pl>=0 && pl<=255); 412cabdff1aSopenharmony_ci 413cabdff1aSopenharmony_ci if(level==0){ 414cabdff1aSopenharmony_ci int varc= iscore >> 8; 415cabdff1aSopenharmony_ci int vard= score >> 8; 416cabdff1aSopenharmony_ci if (vard <= 64 || vard < varc) 417cabdff1aSopenharmony_ci c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); 418cabdff1aSopenharmony_ci else 419cabdff1aSopenharmony_ci c->scene_change_score+= s->m.qscale; 420cabdff1aSopenharmony_ci } 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_ci if(level!=s->block_max_depth){ 423cabdff1aSopenharmony_ci put_rac(&s->c, &s->block_state[4 + s_context], 0); 424cabdff1aSopenharmony_ci score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0); 425cabdff1aSopenharmony_ci score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0); 426cabdff1aSopenharmony_ci score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1); 427cabdff1aSopenharmony_ci score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1); 428cabdff1aSopenharmony_ci score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead 429cabdff1aSopenharmony_ci 430cabdff1aSopenharmony_ci if(score2 < score && score2 < iscore) 431cabdff1aSopenharmony_ci return score2; 432cabdff1aSopenharmony_ci } 433cabdff1aSopenharmony_ci 434cabdff1aSopenharmony_ci if(iscore < score){ 435cabdff1aSopenharmony_ci pred_mv(s, &pmx, &pmy, 0, left, top, tr); 436cabdff1aSopenharmony_ci memcpy(pbbak, i_buffer, i_len); 437cabdff1aSopenharmony_ci s->c= ic; 438cabdff1aSopenharmony_ci s->c.bytestream_start= pbbak_start; 439cabdff1aSopenharmony_ci s->c.bytestream= pbbak + i_len; 440cabdff1aSopenharmony_ci set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA); 441cabdff1aSopenharmony_ci memcpy(s->block_state, i_state, sizeof(s->block_state)); 442cabdff1aSopenharmony_ci return iscore; 443cabdff1aSopenharmony_ci }else{ 444cabdff1aSopenharmony_ci memcpy(pbbak, p_buffer, p_len); 445cabdff1aSopenharmony_ci s->c= pc; 446cabdff1aSopenharmony_ci s->c.bytestream_start= pbbak_start; 447cabdff1aSopenharmony_ci s->c.bytestream= pbbak + p_len; 448cabdff1aSopenharmony_ci set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0); 449cabdff1aSopenharmony_ci memcpy(s->block_state, p_state, sizeof(s->block_state)); 450cabdff1aSopenharmony_ci return score; 451cabdff1aSopenharmony_ci } 452cabdff1aSopenharmony_ci} 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_cistatic void encode_q_branch2(SnowContext *s, int level, int x, int y){ 455cabdff1aSopenharmony_ci const int w= s->b_width << s->block_max_depth; 456cabdff1aSopenharmony_ci const int rem_depth= s->block_max_depth - level; 457cabdff1aSopenharmony_ci const int index= (x + y*w) << rem_depth; 458cabdff1aSopenharmony_ci int trx= (x+1)<<rem_depth; 459cabdff1aSopenharmony_ci BlockNode *b= &s->block[index]; 460cabdff1aSopenharmony_ci const BlockNode *left = x ? &s->block[index-1] : &null_block; 461cabdff1aSopenharmony_ci const BlockNode *top = y ? &s->block[index-w] : &null_block; 462cabdff1aSopenharmony_ci const BlockNode *tl = y && x ? &s->block[index-w-1] : left; 463cabdff1aSopenharmony_ci const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt 464cabdff1aSopenharmony_ci int pl = left->color[0]; 465cabdff1aSopenharmony_ci int pcb= left->color[1]; 466cabdff1aSopenharmony_ci int pcr= left->color[2]; 467cabdff1aSopenharmony_ci int pmx, pmy; 468cabdff1aSopenharmony_ci int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); 469cabdff1aSopenharmony_ci int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref; 470cabdff1aSopenharmony_ci int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref; 471cabdff1aSopenharmony_ci int s_context= 2*left->level + 2*top->level + tl->level + tr->level; 472cabdff1aSopenharmony_ci 473cabdff1aSopenharmony_ci if(s->keyframe){ 474cabdff1aSopenharmony_ci set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); 475cabdff1aSopenharmony_ci return; 476cabdff1aSopenharmony_ci } 477cabdff1aSopenharmony_ci 478cabdff1aSopenharmony_ci if(level!=s->block_max_depth){ 479cabdff1aSopenharmony_ci if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){ 480cabdff1aSopenharmony_ci put_rac(&s->c, &s->block_state[4 + s_context], 1); 481cabdff1aSopenharmony_ci }else{ 482cabdff1aSopenharmony_ci put_rac(&s->c, &s->block_state[4 + s_context], 0); 483cabdff1aSopenharmony_ci encode_q_branch2(s, level+1, 2*x+0, 2*y+0); 484cabdff1aSopenharmony_ci encode_q_branch2(s, level+1, 2*x+1, 2*y+0); 485cabdff1aSopenharmony_ci encode_q_branch2(s, level+1, 2*x+0, 2*y+1); 486cabdff1aSopenharmony_ci encode_q_branch2(s, level+1, 2*x+1, 2*y+1); 487cabdff1aSopenharmony_ci return; 488cabdff1aSopenharmony_ci } 489cabdff1aSopenharmony_ci } 490cabdff1aSopenharmony_ci if(b->type & BLOCK_INTRA){ 491cabdff1aSopenharmony_ci pred_mv(s, &pmx, &pmy, 0, left, top, tr); 492cabdff1aSopenharmony_ci put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1); 493cabdff1aSopenharmony_ci put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1); 494cabdff1aSopenharmony_ci if (s->nb_planes > 2) { 495cabdff1aSopenharmony_ci put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); 496cabdff1aSopenharmony_ci put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); 497cabdff1aSopenharmony_ci } 498cabdff1aSopenharmony_ci set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA); 499cabdff1aSopenharmony_ci }else{ 500cabdff1aSopenharmony_ci pred_mv(s, &pmx, &pmy, b->ref, left, top, tr); 501cabdff1aSopenharmony_ci put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0); 502cabdff1aSopenharmony_ci if(s->ref_frames > 1) 503cabdff1aSopenharmony_ci put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0); 504cabdff1aSopenharmony_ci put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1); 505cabdff1aSopenharmony_ci put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1); 506cabdff1aSopenharmony_ci set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0); 507cabdff1aSopenharmony_ci } 508cabdff1aSopenharmony_ci} 509cabdff1aSopenharmony_ci 510cabdff1aSopenharmony_cistatic int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ 511cabdff1aSopenharmony_ci int i, x2, y2; 512cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 513cabdff1aSopenharmony_ci const int block_size = MB_SIZE >> s->block_max_depth; 514cabdff1aSopenharmony_ci const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; 515cabdff1aSopenharmony_ci const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; 516cabdff1aSopenharmony_ci const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; 517cabdff1aSopenharmony_ci const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; 518cabdff1aSopenharmony_ci const int ref_stride= s->current_picture->linesize[plane_index]; 519cabdff1aSopenharmony_ci uint8_t *src= s-> input_picture->data[plane_index]; 520cabdff1aSopenharmony_ci IDWTELEM *dst= (IDWTELEM*)s->m.sc.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned 521cabdff1aSopenharmony_ci const int b_stride = s->b_width << s->block_max_depth; 522cabdff1aSopenharmony_ci const int w= p->width; 523cabdff1aSopenharmony_ci const int h= p->height; 524cabdff1aSopenharmony_ci int index= mb_x + mb_y*b_stride; 525cabdff1aSopenharmony_ci BlockNode *b= &s->block[index]; 526cabdff1aSopenharmony_ci BlockNode backup= *b; 527cabdff1aSopenharmony_ci int ab=0; 528cabdff1aSopenharmony_ci int aa=0; 529cabdff1aSopenharmony_ci 530cabdff1aSopenharmony_ci av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc stuff above 531cabdff1aSopenharmony_ci 532cabdff1aSopenharmony_ci b->type|= BLOCK_INTRA; 533cabdff1aSopenharmony_ci b->color[plane_index]= 0; 534cabdff1aSopenharmony_ci memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM)); 535cabdff1aSopenharmony_ci 536cabdff1aSopenharmony_ci for(i=0; i<4; i++){ 537cabdff1aSopenharmony_ci int mb_x2= mb_x + (i &1) - 1; 538cabdff1aSopenharmony_ci int mb_y2= mb_y + (i>>1) - 1; 539cabdff1aSopenharmony_ci int x= block_w*mb_x2 + block_w/2; 540cabdff1aSopenharmony_ci int y= block_h*mb_y2 + block_h/2; 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci add_yblock(s, 0, NULL, dst + (i&1)*block_w + (i>>1)*obmc_stride*block_h, NULL, obmc, 543cabdff1aSopenharmony_ci x, y, block_w, block_h, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index); 544cabdff1aSopenharmony_ci 545cabdff1aSopenharmony_ci for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_h); y2++){ 546cabdff1aSopenharmony_ci for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){ 547cabdff1aSopenharmony_ci int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_h*mb_y - block_h/2))*obmc_stride; 548cabdff1aSopenharmony_ci int obmc_v= obmc[index]; 549cabdff1aSopenharmony_ci int d; 550cabdff1aSopenharmony_ci if(y<0) obmc_v += obmc[index + block_h*obmc_stride]; 551cabdff1aSopenharmony_ci if(x<0) obmc_v += obmc[index + block_w]; 552cabdff1aSopenharmony_ci if(y+block_h>h) obmc_v += obmc[index - block_h*obmc_stride]; 553cabdff1aSopenharmony_ci if(x+block_w>w) obmc_v += obmc[index - block_w]; 554cabdff1aSopenharmony_ci //FIXME precalculate this or simplify it somehow else 555cabdff1aSopenharmony_ci 556cabdff1aSopenharmony_ci d = -dst[index] + (1<<(FRAC_BITS-1)); 557cabdff1aSopenharmony_ci dst[index] = d; 558cabdff1aSopenharmony_ci ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v; 559cabdff1aSopenharmony_ci aa += obmc_v * obmc_v; //FIXME precalculate this 560cabdff1aSopenharmony_ci } 561cabdff1aSopenharmony_ci } 562cabdff1aSopenharmony_ci } 563cabdff1aSopenharmony_ci *b= backup; 564cabdff1aSopenharmony_ci 565cabdff1aSopenharmony_ci return av_clip_uint8( ROUNDED_DIV(ab<<LOG2_OBMC_MAX, aa) ); //FIXME we should not need clipping 566cabdff1aSopenharmony_ci} 567cabdff1aSopenharmony_ci 568cabdff1aSopenharmony_cistatic inline int get_block_bits(SnowContext *s, int x, int y, int w){ 569cabdff1aSopenharmony_ci const int b_stride = s->b_width << s->block_max_depth; 570cabdff1aSopenharmony_ci const int b_height = s->b_height<< s->block_max_depth; 571cabdff1aSopenharmony_ci int index= x + y*b_stride; 572cabdff1aSopenharmony_ci const BlockNode *b = &s->block[index]; 573cabdff1aSopenharmony_ci const BlockNode *left = x ? &s->block[index-1] : &null_block; 574cabdff1aSopenharmony_ci const BlockNode *top = y ? &s->block[index-b_stride] : &null_block; 575cabdff1aSopenharmony_ci const BlockNode *tl = y && x ? &s->block[index-b_stride-1] : left; 576cabdff1aSopenharmony_ci const BlockNode *tr = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl; 577cabdff1aSopenharmony_ci int dmx, dmy; 578cabdff1aSopenharmony_ci// int mx_context= av_log2(2*FFABS(left->mx - top->mx)); 579cabdff1aSopenharmony_ci// int my_context= av_log2(2*FFABS(left->my - top->my)); 580cabdff1aSopenharmony_ci 581cabdff1aSopenharmony_ci if(x<0 || x>=b_stride || y>=b_height) 582cabdff1aSopenharmony_ci return 0; 583cabdff1aSopenharmony_ci/* 584cabdff1aSopenharmony_ci1 0 0 585cabdff1aSopenharmony_ci01X 1-2 1 586cabdff1aSopenharmony_ci001XX 3-6 2-3 587cabdff1aSopenharmony_ci0001XXX 7-14 4-7 588cabdff1aSopenharmony_ci00001XXXX 15-30 8-15 589cabdff1aSopenharmony_ci*/ 590cabdff1aSopenharmony_ci//FIXME try accurate rate 591cabdff1aSopenharmony_ci//FIXME intra and inter predictors if surrounding blocks are not the same type 592cabdff1aSopenharmony_ci if(b->type & BLOCK_INTRA){ 593cabdff1aSopenharmony_ci return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0])) 594cabdff1aSopenharmony_ci + av_log2(2*FFABS(left->color[1] - b->color[1])) 595cabdff1aSopenharmony_ci + av_log2(2*FFABS(left->color[2] - b->color[2]))); 596cabdff1aSopenharmony_ci }else{ 597cabdff1aSopenharmony_ci pred_mv(s, &dmx, &dmy, b->ref, left, top, tr); 598cabdff1aSopenharmony_ci dmx-= b->mx; 599cabdff1aSopenharmony_ci dmy-= b->my; 600cabdff1aSopenharmony_ci return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda 601cabdff1aSopenharmony_ci + av_log2(2*FFABS(dmy)) 602cabdff1aSopenharmony_ci + av_log2(2*b->ref)); 603cabdff1aSopenharmony_ci } 604cabdff1aSopenharmony_ci} 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_cistatic int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uint8_t (*obmc_edged)[MB_SIZE * 2]){ 607cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 608cabdff1aSopenharmony_ci const int block_size = MB_SIZE >> s->block_max_depth; 609cabdff1aSopenharmony_ci const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; 610cabdff1aSopenharmony_ci const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; 611cabdff1aSopenharmony_ci const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; 612cabdff1aSopenharmony_ci const int ref_stride= s->current_picture->linesize[plane_index]; 613cabdff1aSopenharmony_ci uint8_t *dst= s->current_picture->data[plane_index]; 614cabdff1aSopenharmony_ci uint8_t *src= s-> input_picture->data[plane_index]; 615cabdff1aSopenharmony_ci IDWTELEM *pred= (IDWTELEM*)s->m.sc.obmc_scratchpad + plane_index*block_size*block_size*4; 616cabdff1aSopenharmony_ci uint8_t *cur = s->scratchbuf; 617cabdff1aSopenharmony_ci uint8_t *tmp = s->emu_edge_buffer; 618cabdff1aSopenharmony_ci const int b_stride = s->b_width << s->block_max_depth; 619cabdff1aSopenharmony_ci const int b_height = s->b_height<< s->block_max_depth; 620cabdff1aSopenharmony_ci const int w= p->width; 621cabdff1aSopenharmony_ci const int h= p->height; 622cabdff1aSopenharmony_ci int distortion; 623cabdff1aSopenharmony_ci int rate= 0; 624cabdff1aSopenharmony_ci const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); 625cabdff1aSopenharmony_ci int sx= block_w*mb_x - block_w/2; 626cabdff1aSopenharmony_ci int sy= block_h*mb_y - block_h/2; 627cabdff1aSopenharmony_ci int x0= FFMAX(0,-sx); 628cabdff1aSopenharmony_ci int y0= FFMAX(0,-sy); 629cabdff1aSopenharmony_ci int x1= FFMIN(block_w*2, w-sx); 630cabdff1aSopenharmony_ci int y1= FFMIN(block_h*2, h-sy); 631cabdff1aSopenharmony_ci int i,x,y; 632cabdff1aSopenharmony_ci 633cabdff1aSopenharmony_ci av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below chckinhg only block_w 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_ci ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_h*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h); 636cabdff1aSopenharmony_ci 637cabdff1aSopenharmony_ci for(y=y0; y<y1; y++){ 638cabdff1aSopenharmony_ci const uint8_t *obmc1= obmc_edged[y]; 639cabdff1aSopenharmony_ci const IDWTELEM *pred1 = pred + y*obmc_stride; 640cabdff1aSopenharmony_ci uint8_t *cur1 = cur + y*ref_stride; 641cabdff1aSopenharmony_ci uint8_t *dst1 = dst + sx + (sy+y)*ref_stride; 642cabdff1aSopenharmony_ci for(x=x0; x<x1; x++){ 643cabdff1aSopenharmony_ci#if FRAC_BITS >= LOG2_OBMC_MAX 644cabdff1aSopenharmony_ci int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX); 645cabdff1aSopenharmony_ci#else 646cabdff1aSopenharmony_ci int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS); 647cabdff1aSopenharmony_ci#endif 648cabdff1aSopenharmony_ci v = (v + pred1[x]) >> FRAC_BITS; 649cabdff1aSopenharmony_ci if(v&(~255)) v= ~(v>>31); 650cabdff1aSopenharmony_ci dst1[x] = v; 651cabdff1aSopenharmony_ci } 652cabdff1aSopenharmony_ci } 653cabdff1aSopenharmony_ci 654cabdff1aSopenharmony_ci /* copy the regions where obmc[] = (uint8_t)256 */ 655cabdff1aSopenharmony_ci if(LOG2_OBMC_MAX == 8 656cabdff1aSopenharmony_ci && (mb_x == 0 || mb_x == b_stride-1) 657cabdff1aSopenharmony_ci && (mb_y == 0 || mb_y == b_height-1)){ 658cabdff1aSopenharmony_ci if(mb_x == 0) 659cabdff1aSopenharmony_ci x1 = block_w; 660cabdff1aSopenharmony_ci else 661cabdff1aSopenharmony_ci x0 = block_w; 662cabdff1aSopenharmony_ci if(mb_y == 0) 663cabdff1aSopenharmony_ci y1 = block_h; 664cabdff1aSopenharmony_ci else 665cabdff1aSopenharmony_ci y0 = block_h; 666cabdff1aSopenharmony_ci for(y=y0; y<y1; y++) 667cabdff1aSopenharmony_ci memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0); 668cabdff1aSopenharmony_ci } 669cabdff1aSopenharmony_ci 670cabdff1aSopenharmony_ci if(block_w==16){ 671cabdff1aSopenharmony_ci /* FIXME rearrange dsputil to fit 32x32 cmp functions */ 672cabdff1aSopenharmony_ci /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */ 673cabdff1aSopenharmony_ci /* FIXME cmps overlap but do not cover the wavelet's whole support. 674cabdff1aSopenharmony_ci * So improving the score of one block is not strictly guaranteed 675cabdff1aSopenharmony_ci * to improve the score of the whole frame, thus iterative motion 676cabdff1aSopenharmony_ci * estimation does not always converge. */ 677cabdff1aSopenharmony_ci if(s->avctx->me_cmp == FF_CMP_W97) 678cabdff1aSopenharmony_ci distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32); 679cabdff1aSopenharmony_ci else if(s->avctx->me_cmp == FF_CMP_W53) 680cabdff1aSopenharmony_ci distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32); 681cabdff1aSopenharmony_ci else{ 682cabdff1aSopenharmony_ci distortion = 0; 683cabdff1aSopenharmony_ci for(i=0; i<4; i++){ 684cabdff1aSopenharmony_ci int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride; 685cabdff1aSopenharmony_ci distortion += s->mecc.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16); 686cabdff1aSopenharmony_ci } 687cabdff1aSopenharmony_ci } 688cabdff1aSopenharmony_ci }else{ 689cabdff1aSopenharmony_ci av_assert2(block_w==8); 690cabdff1aSopenharmony_ci distortion = s->mecc.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2); 691cabdff1aSopenharmony_ci } 692cabdff1aSopenharmony_ci 693cabdff1aSopenharmony_ci if(plane_index==0){ 694cabdff1aSopenharmony_ci for(i=0; i<4; i++){ 695cabdff1aSopenharmony_ci/* ..RRr 696cabdff1aSopenharmony_ci * .RXx. 697cabdff1aSopenharmony_ci * rxx.. 698cabdff1aSopenharmony_ci */ 699cabdff1aSopenharmony_ci rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1); 700cabdff1aSopenharmony_ci } 701cabdff1aSopenharmony_ci if(mb_x == b_stride-2) 702cabdff1aSopenharmony_ci rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1); 703cabdff1aSopenharmony_ci } 704cabdff1aSopenharmony_ci return distortion + rate*penalty_factor; 705cabdff1aSopenharmony_ci} 706cabdff1aSopenharmony_ci 707cabdff1aSopenharmony_cistatic int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ 708cabdff1aSopenharmony_ci int i, y2; 709cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 710cabdff1aSopenharmony_ci const int block_size = MB_SIZE >> s->block_max_depth; 711cabdff1aSopenharmony_ci const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; 712cabdff1aSopenharmony_ci const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; 713cabdff1aSopenharmony_ci const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth]; 714cabdff1aSopenharmony_ci const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; 715cabdff1aSopenharmony_ci const int ref_stride= s->current_picture->linesize[plane_index]; 716cabdff1aSopenharmony_ci uint8_t *dst= s->current_picture->data[plane_index]; 717cabdff1aSopenharmony_ci uint8_t *src= s-> input_picture->data[plane_index]; 718cabdff1aSopenharmony_ci //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst 719cabdff1aSopenharmony_ci // const has only been removed from zero_dst to suppress a warning 720cabdff1aSopenharmony_ci static IDWTELEM zero_dst[4096]; //FIXME 721cabdff1aSopenharmony_ci const int b_stride = s->b_width << s->block_max_depth; 722cabdff1aSopenharmony_ci const int w= p->width; 723cabdff1aSopenharmony_ci const int h= p->height; 724cabdff1aSopenharmony_ci int distortion= 0; 725cabdff1aSopenharmony_ci int rate= 0; 726cabdff1aSopenharmony_ci const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp); 727cabdff1aSopenharmony_ci 728cabdff1aSopenharmony_ci av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below 729cabdff1aSopenharmony_ci 730cabdff1aSopenharmony_ci for(i=0; i<9; i++){ 731cabdff1aSopenharmony_ci int mb_x2= mb_x + (i%3) - 1; 732cabdff1aSopenharmony_ci int mb_y2= mb_y + (i/3) - 1; 733cabdff1aSopenharmony_ci int x= block_w*mb_x2 + block_w/2; 734cabdff1aSopenharmony_ci int y= block_h*mb_y2 + block_h/2; 735cabdff1aSopenharmony_ci 736cabdff1aSopenharmony_ci add_yblock(s, 0, NULL, zero_dst, dst, obmc, 737cabdff1aSopenharmony_ci x, y, block_w, block_h, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index); 738cabdff1aSopenharmony_ci 739cabdff1aSopenharmony_ci //FIXME find a cleaner/simpler way to skip the outside stuff 740cabdff1aSopenharmony_ci for(y2= y; y2<0; y2++) 741cabdff1aSopenharmony_ci memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); 742cabdff1aSopenharmony_ci for(y2= h; y2<y+block_h; y2++) 743cabdff1aSopenharmony_ci memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w); 744cabdff1aSopenharmony_ci if(x<0){ 745cabdff1aSopenharmony_ci for(y2= y; y2<y+block_h; y2++) 746cabdff1aSopenharmony_ci memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x); 747cabdff1aSopenharmony_ci } 748cabdff1aSopenharmony_ci if(x+block_w > w){ 749cabdff1aSopenharmony_ci for(y2= y; y2<y+block_h; y2++) 750cabdff1aSopenharmony_ci memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w); 751cabdff1aSopenharmony_ci } 752cabdff1aSopenharmony_ci 753cabdff1aSopenharmony_ci av_assert1(block_w== 8 || block_w==16); 754cabdff1aSopenharmony_ci distortion += s->mecc.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h); 755cabdff1aSopenharmony_ci } 756cabdff1aSopenharmony_ci 757cabdff1aSopenharmony_ci if(plane_index==0){ 758cabdff1aSopenharmony_ci BlockNode *b= &s->block[mb_x+mb_y*b_stride]; 759cabdff1aSopenharmony_ci int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1); 760cabdff1aSopenharmony_ci 761cabdff1aSopenharmony_ci/* ..RRRr 762cabdff1aSopenharmony_ci * .RXXx. 763cabdff1aSopenharmony_ci * .RXXx. 764cabdff1aSopenharmony_ci * rxxx. 765cabdff1aSopenharmony_ci */ 766cabdff1aSopenharmony_ci if(merged) 767cabdff1aSopenharmony_ci rate = get_block_bits(s, mb_x, mb_y, 2); 768cabdff1aSopenharmony_ci for(i=merged?4:0; i<9; i++){ 769cabdff1aSopenharmony_ci static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}}; 770cabdff1aSopenharmony_ci rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1); 771cabdff1aSopenharmony_ci } 772cabdff1aSopenharmony_ci } 773cabdff1aSopenharmony_ci return distortion + rate*penalty_factor; 774cabdff1aSopenharmony_ci} 775cabdff1aSopenharmony_ci 776cabdff1aSopenharmony_cistatic int encode_subband_c0run(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){ 777cabdff1aSopenharmony_ci const int w= b->width; 778cabdff1aSopenharmony_ci const int h= b->height; 779cabdff1aSopenharmony_ci int x, y; 780cabdff1aSopenharmony_ci 781cabdff1aSopenharmony_ci if(1){ 782cabdff1aSopenharmony_ci int run=0; 783cabdff1aSopenharmony_ci int *runs = s->run_buffer; 784cabdff1aSopenharmony_ci int run_index=0; 785cabdff1aSopenharmony_ci int max_index; 786cabdff1aSopenharmony_ci 787cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 788cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 789cabdff1aSopenharmony_ci int v, p=0; 790cabdff1aSopenharmony_ci int /*ll=0, */l=0, lt=0, t=0, rt=0; 791cabdff1aSopenharmony_ci v= src[x + y*stride]; 792cabdff1aSopenharmony_ci 793cabdff1aSopenharmony_ci if(y){ 794cabdff1aSopenharmony_ci t= src[x + (y-1)*stride]; 795cabdff1aSopenharmony_ci if(x){ 796cabdff1aSopenharmony_ci lt= src[x - 1 + (y-1)*stride]; 797cabdff1aSopenharmony_ci } 798cabdff1aSopenharmony_ci if(x + 1 < w){ 799cabdff1aSopenharmony_ci rt= src[x + 1 + (y-1)*stride]; 800cabdff1aSopenharmony_ci } 801cabdff1aSopenharmony_ci } 802cabdff1aSopenharmony_ci if(x){ 803cabdff1aSopenharmony_ci l= src[x - 1 + y*stride]; 804cabdff1aSopenharmony_ci /*if(x > 1){ 805cabdff1aSopenharmony_ci if(orientation==1) ll= src[y + (x-2)*stride]; 806cabdff1aSopenharmony_ci else ll= src[x - 2 + y*stride]; 807cabdff1aSopenharmony_ci }*/ 808cabdff1aSopenharmony_ci } 809cabdff1aSopenharmony_ci if(parent){ 810cabdff1aSopenharmony_ci int px= x>>1; 811cabdff1aSopenharmony_ci int py= y>>1; 812cabdff1aSopenharmony_ci if(px<b->parent->width && py<b->parent->height) 813cabdff1aSopenharmony_ci p= parent[px + py*2*stride]; 814cabdff1aSopenharmony_ci } 815cabdff1aSopenharmony_ci if(!(/*ll|*/l|lt|t|rt|p)){ 816cabdff1aSopenharmony_ci if(v){ 817cabdff1aSopenharmony_ci runs[run_index++]= run; 818cabdff1aSopenharmony_ci run=0; 819cabdff1aSopenharmony_ci }else{ 820cabdff1aSopenharmony_ci run++; 821cabdff1aSopenharmony_ci } 822cabdff1aSopenharmony_ci } 823cabdff1aSopenharmony_ci } 824cabdff1aSopenharmony_ci } 825cabdff1aSopenharmony_ci max_index= run_index; 826cabdff1aSopenharmony_ci runs[run_index++]= run; 827cabdff1aSopenharmony_ci run_index=0; 828cabdff1aSopenharmony_ci run= runs[run_index++]; 829cabdff1aSopenharmony_ci 830cabdff1aSopenharmony_ci put_symbol2(&s->c, b->state[30], max_index, 0); 831cabdff1aSopenharmony_ci if(run_index <= max_index) 832cabdff1aSopenharmony_ci put_symbol2(&s->c, b->state[1], run, 3); 833cabdff1aSopenharmony_ci 834cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 835cabdff1aSopenharmony_ci if(s->c.bytestream_end - s->c.bytestream < w*40){ 836cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); 837cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 838cabdff1aSopenharmony_ci } 839cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 840cabdff1aSopenharmony_ci int v, p=0; 841cabdff1aSopenharmony_ci int /*ll=0, */l=0, lt=0, t=0, rt=0; 842cabdff1aSopenharmony_ci v= src[x + y*stride]; 843cabdff1aSopenharmony_ci 844cabdff1aSopenharmony_ci if(y){ 845cabdff1aSopenharmony_ci t= src[x + (y-1)*stride]; 846cabdff1aSopenharmony_ci if(x){ 847cabdff1aSopenharmony_ci lt= src[x - 1 + (y-1)*stride]; 848cabdff1aSopenharmony_ci } 849cabdff1aSopenharmony_ci if(x + 1 < w){ 850cabdff1aSopenharmony_ci rt= src[x + 1 + (y-1)*stride]; 851cabdff1aSopenharmony_ci } 852cabdff1aSopenharmony_ci } 853cabdff1aSopenharmony_ci if(x){ 854cabdff1aSopenharmony_ci l= src[x - 1 + y*stride]; 855cabdff1aSopenharmony_ci /*if(x > 1){ 856cabdff1aSopenharmony_ci if(orientation==1) ll= src[y + (x-2)*stride]; 857cabdff1aSopenharmony_ci else ll= src[x - 2 + y*stride]; 858cabdff1aSopenharmony_ci }*/ 859cabdff1aSopenharmony_ci } 860cabdff1aSopenharmony_ci if(parent){ 861cabdff1aSopenharmony_ci int px= x>>1; 862cabdff1aSopenharmony_ci int py= y>>1; 863cabdff1aSopenharmony_ci if(px<b->parent->width && py<b->parent->height) 864cabdff1aSopenharmony_ci p= parent[px + py*2*stride]; 865cabdff1aSopenharmony_ci } 866cabdff1aSopenharmony_ci if(/*ll|*/l|lt|t|rt|p){ 867cabdff1aSopenharmony_ci int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p)); 868cabdff1aSopenharmony_ci 869cabdff1aSopenharmony_ci put_rac(&s->c, &b->state[0][context], !!v); 870cabdff1aSopenharmony_ci }else{ 871cabdff1aSopenharmony_ci if(!run){ 872cabdff1aSopenharmony_ci run= runs[run_index++]; 873cabdff1aSopenharmony_ci 874cabdff1aSopenharmony_ci if(run_index <= max_index) 875cabdff1aSopenharmony_ci put_symbol2(&s->c, b->state[1], run, 3); 876cabdff1aSopenharmony_ci av_assert2(v); 877cabdff1aSopenharmony_ci }else{ 878cabdff1aSopenharmony_ci run--; 879cabdff1aSopenharmony_ci av_assert2(!v); 880cabdff1aSopenharmony_ci } 881cabdff1aSopenharmony_ci } 882cabdff1aSopenharmony_ci if(v){ 883cabdff1aSopenharmony_ci int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p)); 884cabdff1aSopenharmony_ci int l2= 2*FFABS(l) + (l<0); 885cabdff1aSopenharmony_ci int t2= 2*FFABS(t) + (t<0); 886cabdff1aSopenharmony_ci 887cabdff1aSopenharmony_ci put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4); 888cabdff1aSopenharmony_ci put_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l2&0xFF] + 3*ff_quant3bA[t2&0xFF]], v<0); 889cabdff1aSopenharmony_ci } 890cabdff1aSopenharmony_ci } 891cabdff1aSopenharmony_ci } 892cabdff1aSopenharmony_ci } 893cabdff1aSopenharmony_ci return 0; 894cabdff1aSopenharmony_ci} 895cabdff1aSopenharmony_ci 896cabdff1aSopenharmony_cistatic int encode_subband(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){ 897cabdff1aSopenharmony_ci// encode_subband_qtree(s, b, src, parent, stride, orientation); 898cabdff1aSopenharmony_ci// encode_subband_z0run(s, b, src, parent, stride, orientation); 899cabdff1aSopenharmony_ci return encode_subband_c0run(s, b, src, parent, stride, orientation); 900cabdff1aSopenharmony_ci// encode_subband_dzr(s, b, src, parent, stride, orientation); 901cabdff1aSopenharmony_ci} 902cabdff1aSopenharmony_ci 903cabdff1aSopenharmony_cistatic av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){ 904cabdff1aSopenharmony_ci const int b_stride= s->b_width << s->block_max_depth; 905cabdff1aSopenharmony_ci BlockNode *block= &s->block[mb_x + mb_y * b_stride]; 906cabdff1aSopenharmony_ci BlockNode backup= *block; 907cabdff1aSopenharmony_ci unsigned value; 908cabdff1aSopenharmony_ci int rd, index; 909cabdff1aSopenharmony_ci 910cabdff1aSopenharmony_ci av_assert2(mb_x>=0 && mb_y>=0); 911cabdff1aSopenharmony_ci av_assert2(mb_x<b_stride); 912cabdff1aSopenharmony_ci 913cabdff1aSopenharmony_ci if(intra){ 914cabdff1aSopenharmony_ci block->color[0] = p[0]; 915cabdff1aSopenharmony_ci block->color[1] = p[1]; 916cabdff1aSopenharmony_ci block->color[2] = p[2]; 917cabdff1aSopenharmony_ci block->type |= BLOCK_INTRA; 918cabdff1aSopenharmony_ci }else{ 919cabdff1aSopenharmony_ci index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1); 920cabdff1aSopenharmony_ci value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12); 921cabdff1aSopenharmony_ci if(s->me_cache[index] == value) 922cabdff1aSopenharmony_ci return 0; 923cabdff1aSopenharmony_ci s->me_cache[index]= value; 924cabdff1aSopenharmony_ci 925cabdff1aSopenharmony_ci block->mx= p[0]; 926cabdff1aSopenharmony_ci block->my= p[1]; 927cabdff1aSopenharmony_ci block->type &= ~BLOCK_INTRA; 928cabdff1aSopenharmony_ci } 929cabdff1aSopenharmony_ci 930cabdff1aSopenharmony_ci rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged) + s->intra_penalty * !!intra; 931cabdff1aSopenharmony_ci 932cabdff1aSopenharmony_ci//FIXME chroma 933cabdff1aSopenharmony_ci if(rd < *best_rd){ 934cabdff1aSopenharmony_ci *best_rd= rd; 935cabdff1aSopenharmony_ci return 1; 936cabdff1aSopenharmony_ci }else{ 937cabdff1aSopenharmony_ci *block= backup; 938cabdff1aSopenharmony_ci return 0; 939cabdff1aSopenharmony_ci } 940cabdff1aSopenharmony_ci} 941cabdff1aSopenharmony_ci 942cabdff1aSopenharmony_ci/* special case for int[2] args we discard afterwards, 943cabdff1aSopenharmony_ci * fixes compilation problem with gcc 2.95 */ 944cabdff1aSopenharmony_cistatic av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){ 945cabdff1aSopenharmony_ci int p[2] = {p0, p1}; 946cabdff1aSopenharmony_ci return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd); 947cabdff1aSopenharmony_ci} 948cabdff1aSopenharmony_ci 949cabdff1aSopenharmony_cistatic av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){ 950cabdff1aSopenharmony_ci const int b_stride= s->b_width << s->block_max_depth; 951cabdff1aSopenharmony_ci BlockNode *block= &s->block[mb_x + mb_y * b_stride]; 952cabdff1aSopenharmony_ci BlockNode backup[4]; 953cabdff1aSopenharmony_ci unsigned value; 954cabdff1aSopenharmony_ci int rd, index; 955cabdff1aSopenharmony_ci 956cabdff1aSopenharmony_ci /* We don't initialize backup[] during variable declaration, because 957cabdff1aSopenharmony_ci * that fails to compile on MSVC: "cannot convert from 'BlockNode' to 958cabdff1aSopenharmony_ci * 'int16_t'". */ 959cabdff1aSopenharmony_ci backup[0] = block[0]; 960cabdff1aSopenharmony_ci backup[1] = block[1]; 961cabdff1aSopenharmony_ci backup[2] = block[b_stride]; 962cabdff1aSopenharmony_ci backup[3] = block[b_stride + 1]; 963cabdff1aSopenharmony_ci 964cabdff1aSopenharmony_ci av_assert2(mb_x>=0 && mb_y>=0); 965cabdff1aSopenharmony_ci av_assert2(mb_x<b_stride); 966cabdff1aSopenharmony_ci av_assert2(((mb_x|mb_y)&1) == 0); 967cabdff1aSopenharmony_ci 968cabdff1aSopenharmony_ci index= (p0 + 31*p1) & (ME_CACHE_SIZE-1); 969cabdff1aSopenharmony_ci value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12); 970cabdff1aSopenharmony_ci if(s->me_cache[index] == value) 971cabdff1aSopenharmony_ci return 0; 972cabdff1aSopenharmony_ci s->me_cache[index]= value; 973cabdff1aSopenharmony_ci 974cabdff1aSopenharmony_ci block->mx= p0; 975cabdff1aSopenharmony_ci block->my= p1; 976cabdff1aSopenharmony_ci block->ref= ref; 977cabdff1aSopenharmony_ci block->type &= ~BLOCK_INTRA; 978cabdff1aSopenharmony_ci block[1]= block[b_stride]= block[b_stride+1]= *block; 979cabdff1aSopenharmony_ci 980cabdff1aSopenharmony_ci rd= get_4block_rd(s, mb_x, mb_y, 0); 981cabdff1aSopenharmony_ci 982cabdff1aSopenharmony_ci//FIXME chroma 983cabdff1aSopenharmony_ci if(rd < *best_rd){ 984cabdff1aSopenharmony_ci *best_rd= rd; 985cabdff1aSopenharmony_ci return 1; 986cabdff1aSopenharmony_ci }else{ 987cabdff1aSopenharmony_ci block[0]= backup[0]; 988cabdff1aSopenharmony_ci block[1]= backup[1]; 989cabdff1aSopenharmony_ci block[b_stride]= backup[2]; 990cabdff1aSopenharmony_ci block[b_stride+1]= backup[3]; 991cabdff1aSopenharmony_ci return 0; 992cabdff1aSopenharmony_ci } 993cabdff1aSopenharmony_ci} 994cabdff1aSopenharmony_ci 995cabdff1aSopenharmony_cistatic void iterative_me(SnowContext *s){ 996cabdff1aSopenharmony_ci int pass, mb_x, mb_y; 997cabdff1aSopenharmony_ci const int b_width = s->b_width << s->block_max_depth; 998cabdff1aSopenharmony_ci const int b_height= s->b_height << s->block_max_depth; 999cabdff1aSopenharmony_ci const int b_stride= b_width; 1000cabdff1aSopenharmony_ci int color[3]; 1001cabdff1aSopenharmony_ci 1002cabdff1aSopenharmony_ci { 1003cabdff1aSopenharmony_ci RangeCoder r = s->c; 1004cabdff1aSopenharmony_ci uint8_t state[sizeof(s->block_state)]; 1005cabdff1aSopenharmony_ci memcpy(state, s->block_state, sizeof(s->block_state)); 1006cabdff1aSopenharmony_ci for(mb_y= 0; mb_y<s->b_height; mb_y++) 1007cabdff1aSopenharmony_ci for(mb_x= 0; mb_x<s->b_width; mb_x++) 1008cabdff1aSopenharmony_ci encode_q_branch(s, 0, mb_x, mb_y); 1009cabdff1aSopenharmony_ci s->c = r; 1010cabdff1aSopenharmony_ci memcpy(s->block_state, state, sizeof(s->block_state)); 1011cabdff1aSopenharmony_ci } 1012cabdff1aSopenharmony_ci 1013cabdff1aSopenharmony_ci for(pass=0; pass<25; pass++){ 1014cabdff1aSopenharmony_ci int change= 0; 1015cabdff1aSopenharmony_ci 1016cabdff1aSopenharmony_ci for(mb_y= 0; mb_y<b_height; mb_y++){ 1017cabdff1aSopenharmony_ci for(mb_x= 0; mb_x<b_width; mb_x++){ 1018cabdff1aSopenharmony_ci int dia_change, i, j, ref; 1019cabdff1aSopenharmony_ci int best_rd= INT_MAX, ref_rd; 1020cabdff1aSopenharmony_ci BlockNode backup, ref_b; 1021cabdff1aSopenharmony_ci const int index= mb_x + mb_y * b_stride; 1022cabdff1aSopenharmony_ci BlockNode *block= &s->block[index]; 1023cabdff1aSopenharmony_ci BlockNode *tb = mb_y ? &s->block[index-b_stride ] : NULL; 1024cabdff1aSopenharmony_ci BlockNode *lb = mb_x ? &s->block[index -1] : NULL; 1025cabdff1aSopenharmony_ci BlockNode *rb = mb_x+1<b_width ? &s->block[index +1] : NULL; 1026cabdff1aSopenharmony_ci BlockNode *bb = mb_y+1<b_height ? &s->block[index+b_stride ] : NULL; 1027cabdff1aSopenharmony_ci BlockNode *tlb= mb_x && mb_y ? &s->block[index-b_stride-1] : NULL; 1028cabdff1aSopenharmony_ci BlockNode *trb= mb_x+1<b_width && mb_y ? &s->block[index-b_stride+1] : NULL; 1029cabdff1aSopenharmony_ci BlockNode *blb= mb_x && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL; 1030cabdff1aSopenharmony_ci BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL; 1031cabdff1aSopenharmony_ci const int b_w= (MB_SIZE >> s->block_max_depth); 1032cabdff1aSopenharmony_ci uint8_t obmc_edged[MB_SIZE * 2][MB_SIZE * 2]; 1033cabdff1aSopenharmony_ci 1034cabdff1aSopenharmony_ci if(pass && (block->type & BLOCK_OPT)) 1035cabdff1aSopenharmony_ci continue; 1036cabdff1aSopenharmony_ci block->type |= BLOCK_OPT; 1037cabdff1aSopenharmony_ci 1038cabdff1aSopenharmony_ci backup= *block; 1039cabdff1aSopenharmony_ci 1040cabdff1aSopenharmony_ci if(!s->me_cache_generation) 1041cabdff1aSopenharmony_ci memset(s->me_cache, 0, sizeof(s->me_cache)); 1042cabdff1aSopenharmony_ci s->me_cache_generation += 1<<22; 1043cabdff1aSopenharmony_ci 1044cabdff1aSopenharmony_ci //FIXME precalculate 1045cabdff1aSopenharmony_ci { 1046cabdff1aSopenharmony_ci int x, y; 1047cabdff1aSopenharmony_ci for (y = 0; y < b_w * 2; y++) 1048cabdff1aSopenharmony_ci memcpy(obmc_edged[y], ff_obmc_tab[s->block_max_depth] + y * b_w * 2, b_w * 2); 1049cabdff1aSopenharmony_ci if(mb_x==0) 1050cabdff1aSopenharmony_ci for(y=0; y<b_w*2; y++) 1051cabdff1aSopenharmony_ci memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w); 1052cabdff1aSopenharmony_ci if(mb_x==b_stride-1) 1053cabdff1aSopenharmony_ci for(y=0; y<b_w*2; y++) 1054cabdff1aSopenharmony_ci memset(obmc_edged[y]+b_w, obmc_edged[y][b_w] + obmc_edged[y][b_w*2-1], b_w); 1055cabdff1aSopenharmony_ci if(mb_y==0){ 1056cabdff1aSopenharmony_ci for(x=0; x<b_w*2; x++) 1057cabdff1aSopenharmony_ci obmc_edged[0][x] += obmc_edged[b_w-1][x]; 1058cabdff1aSopenharmony_ci for(y=1; y<b_w; y++) 1059cabdff1aSopenharmony_ci memcpy(obmc_edged[y], obmc_edged[0], b_w*2); 1060cabdff1aSopenharmony_ci } 1061cabdff1aSopenharmony_ci if(mb_y==b_height-1){ 1062cabdff1aSopenharmony_ci for(x=0; x<b_w*2; x++) 1063cabdff1aSopenharmony_ci obmc_edged[b_w*2-1][x] += obmc_edged[b_w][x]; 1064cabdff1aSopenharmony_ci for(y=b_w; y<b_w*2-1; y++) 1065cabdff1aSopenharmony_ci memcpy(obmc_edged[y], obmc_edged[b_w*2-1], b_w*2); 1066cabdff1aSopenharmony_ci } 1067cabdff1aSopenharmony_ci } 1068cabdff1aSopenharmony_ci 1069cabdff1aSopenharmony_ci //skip stuff outside the picture 1070cabdff1aSopenharmony_ci if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){ 1071cabdff1aSopenharmony_ci uint8_t *src= s-> input_picture->data[0]; 1072cabdff1aSopenharmony_ci uint8_t *dst= s->current_picture->data[0]; 1073cabdff1aSopenharmony_ci const int stride= s->current_picture->linesize[0]; 1074cabdff1aSopenharmony_ci const int block_w= MB_SIZE >> s->block_max_depth; 1075cabdff1aSopenharmony_ci const int block_h= MB_SIZE >> s->block_max_depth; 1076cabdff1aSopenharmony_ci const int sx= block_w*mb_x - block_w/2; 1077cabdff1aSopenharmony_ci const int sy= block_h*mb_y - block_h/2; 1078cabdff1aSopenharmony_ci const int w= s->plane[0].width; 1079cabdff1aSopenharmony_ci const int h= s->plane[0].height; 1080cabdff1aSopenharmony_ci int y; 1081cabdff1aSopenharmony_ci 1082cabdff1aSopenharmony_ci for(y=sy; y<0; y++) 1083cabdff1aSopenharmony_ci memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); 1084cabdff1aSopenharmony_ci for(y=h; y<sy+block_h*2; y++) 1085cabdff1aSopenharmony_ci memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2); 1086cabdff1aSopenharmony_ci if(sx<0){ 1087cabdff1aSopenharmony_ci for(y=sy; y<sy+block_h*2; y++) 1088cabdff1aSopenharmony_ci memcpy(dst + sx + y*stride, src + sx + y*stride, -sx); 1089cabdff1aSopenharmony_ci } 1090cabdff1aSopenharmony_ci if(sx+block_w*2 > w){ 1091cabdff1aSopenharmony_ci for(y=sy; y<sy+block_h*2; y++) 1092cabdff1aSopenharmony_ci memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w); 1093cabdff1aSopenharmony_ci } 1094cabdff1aSopenharmony_ci } 1095cabdff1aSopenharmony_ci 1096cabdff1aSopenharmony_ci // intra(black) = neighbors' contribution to the current block 1097cabdff1aSopenharmony_ci for(i=0; i < s->nb_planes; i++) 1098cabdff1aSopenharmony_ci color[i]= get_dc(s, mb_x, mb_y, i); 1099cabdff1aSopenharmony_ci 1100cabdff1aSopenharmony_ci // get previous score (cannot be cached due to OBMC) 1101cabdff1aSopenharmony_ci if(pass > 0 && (block->type&BLOCK_INTRA)){ 1102cabdff1aSopenharmony_ci int color0[3]= {block->color[0], block->color[1], block->color[2]}; 1103cabdff1aSopenharmony_ci check_block(s, mb_x, mb_y, color0, 1, obmc_edged, &best_rd); 1104cabdff1aSopenharmony_ci }else 1105cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, block->mx, block->my, obmc_edged, &best_rd); 1106cabdff1aSopenharmony_ci 1107cabdff1aSopenharmony_ci ref_b= *block; 1108cabdff1aSopenharmony_ci ref_rd= best_rd; 1109cabdff1aSopenharmony_ci for(ref=0; ref < s->ref_frames; ref++){ 1110cabdff1aSopenharmony_ci int16_t (*mvr)[2]= &s->ref_mvs[ref][index]; 1111cabdff1aSopenharmony_ci if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold 1112cabdff1aSopenharmony_ci continue; 1113cabdff1aSopenharmony_ci block->ref= ref; 1114cabdff1aSopenharmony_ci best_rd= INT_MAX; 1115cabdff1aSopenharmony_ci 1116cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], obmc_edged, &best_rd); 1117cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, 0, 0, obmc_edged, &best_rd); 1118cabdff1aSopenharmony_ci if(tb) 1119cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], obmc_edged, &best_rd); 1120cabdff1aSopenharmony_ci if(lb) 1121cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], obmc_edged, &best_rd); 1122cabdff1aSopenharmony_ci if(rb) 1123cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], obmc_edged, &best_rd); 1124cabdff1aSopenharmony_ci if(bb) 1125cabdff1aSopenharmony_ci check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], obmc_edged, &best_rd); 1126cabdff1aSopenharmony_ci 1127cabdff1aSopenharmony_ci /* fullpel ME */ 1128cabdff1aSopenharmony_ci //FIXME avoid subpel interpolation / round to nearest integer 1129cabdff1aSopenharmony_ci do{ 1130cabdff1aSopenharmony_ci int newx = block->mx; 1131cabdff1aSopenharmony_ci int newy = block->my; 1132cabdff1aSopenharmony_ci int dia_size = s->iterative_dia_size ? s->iterative_dia_size : FFMAX(s->avctx->dia_size, 1); 1133cabdff1aSopenharmony_ci dia_change=0; 1134cabdff1aSopenharmony_ci for(i=0; i < dia_size; i++){ 1135cabdff1aSopenharmony_ci for(j=0; j<i; j++){ 1136cabdff1aSopenharmony_ci dia_change |= check_block_inter(s, mb_x, mb_y, newx+4*(i-j), newy+(4*j), obmc_edged, &best_rd); 1137cabdff1aSopenharmony_ci dia_change |= check_block_inter(s, mb_x, mb_y, newx-4*(i-j), newy-(4*j), obmc_edged, &best_rd); 1138cabdff1aSopenharmony_ci dia_change |= check_block_inter(s, mb_x, mb_y, newx-(4*j), newy+4*(i-j), obmc_edged, &best_rd); 1139cabdff1aSopenharmony_ci dia_change |= check_block_inter(s, mb_x, mb_y, newx+(4*j), newy-4*(i-j), obmc_edged, &best_rd); 1140cabdff1aSopenharmony_ci } 1141cabdff1aSopenharmony_ci } 1142cabdff1aSopenharmony_ci }while(dia_change); 1143cabdff1aSopenharmony_ci /* subpel ME */ 1144cabdff1aSopenharmony_ci do{ 1145cabdff1aSopenharmony_ci static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},}; 1146cabdff1aSopenharmony_ci dia_change=0; 1147cabdff1aSopenharmony_ci for(i=0; i<8; i++) 1148cabdff1aSopenharmony_ci dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], obmc_edged, &best_rd); 1149cabdff1aSopenharmony_ci }while(dia_change); 1150cabdff1aSopenharmony_ci //FIXME or try the standard 2 pass qpel or similar 1151cabdff1aSopenharmony_ci 1152cabdff1aSopenharmony_ci mvr[0][0]= block->mx; 1153cabdff1aSopenharmony_ci mvr[0][1]= block->my; 1154cabdff1aSopenharmony_ci if(ref_rd > best_rd){ 1155cabdff1aSopenharmony_ci ref_rd= best_rd; 1156cabdff1aSopenharmony_ci ref_b= *block; 1157cabdff1aSopenharmony_ci } 1158cabdff1aSopenharmony_ci } 1159cabdff1aSopenharmony_ci best_rd= ref_rd; 1160cabdff1aSopenharmony_ci *block= ref_b; 1161cabdff1aSopenharmony_ci check_block(s, mb_x, mb_y, color, 1, obmc_edged, &best_rd); 1162cabdff1aSopenharmony_ci //FIXME RD style color selection 1163cabdff1aSopenharmony_ci if(!same_block(block, &backup)){ 1164cabdff1aSopenharmony_ci if(tb ) tb ->type &= ~BLOCK_OPT; 1165cabdff1aSopenharmony_ci if(lb ) lb ->type &= ~BLOCK_OPT; 1166cabdff1aSopenharmony_ci if(rb ) rb ->type &= ~BLOCK_OPT; 1167cabdff1aSopenharmony_ci if(bb ) bb ->type &= ~BLOCK_OPT; 1168cabdff1aSopenharmony_ci if(tlb) tlb->type &= ~BLOCK_OPT; 1169cabdff1aSopenharmony_ci if(trb) trb->type &= ~BLOCK_OPT; 1170cabdff1aSopenharmony_ci if(blb) blb->type &= ~BLOCK_OPT; 1171cabdff1aSopenharmony_ci if(brb) brb->type &= ~BLOCK_OPT; 1172cabdff1aSopenharmony_ci change ++; 1173cabdff1aSopenharmony_ci } 1174cabdff1aSopenharmony_ci } 1175cabdff1aSopenharmony_ci } 1176cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_DEBUG, "pass:%d changed:%d\n", pass, change); 1177cabdff1aSopenharmony_ci if(!change) 1178cabdff1aSopenharmony_ci break; 1179cabdff1aSopenharmony_ci } 1180cabdff1aSopenharmony_ci 1181cabdff1aSopenharmony_ci if(s->block_max_depth == 1){ 1182cabdff1aSopenharmony_ci int change= 0; 1183cabdff1aSopenharmony_ci for(mb_y= 0; mb_y<b_height; mb_y+=2){ 1184cabdff1aSopenharmony_ci for(mb_x= 0; mb_x<b_width; mb_x+=2){ 1185cabdff1aSopenharmony_ci int i; 1186cabdff1aSopenharmony_ci int best_rd, init_rd; 1187cabdff1aSopenharmony_ci const int index= mb_x + mb_y * b_stride; 1188cabdff1aSopenharmony_ci BlockNode *b[4]; 1189cabdff1aSopenharmony_ci 1190cabdff1aSopenharmony_ci b[0]= &s->block[index]; 1191cabdff1aSopenharmony_ci b[1]= b[0]+1; 1192cabdff1aSopenharmony_ci b[2]= b[0]+b_stride; 1193cabdff1aSopenharmony_ci b[3]= b[2]+1; 1194cabdff1aSopenharmony_ci if(same_block(b[0], b[1]) && 1195cabdff1aSopenharmony_ci same_block(b[0], b[2]) && 1196cabdff1aSopenharmony_ci same_block(b[0], b[3])) 1197cabdff1aSopenharmony_ci continue; 1198cabdff1aSopenharmony_ci 1199cabdff1aSopenharmony_ci if(!s->me_cache_generation) 1200cabdff1aSopenharmony_ci memset(s->me_cache, 0, sizeof(s->me_cache)); 1201cabdff1aSopenharmony_ci s->me_cache_generation += 1<<22; 1202cabdff1aSopenharmony_ci 1203cabdff1aSopenharmony_ci init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0); 1204cabdff1aSopenharmony_ci 1205cabdff1aSopenharmony_ci //FIXME more multiref search? 1206cabdff1aSopenharmony_ci check_4block_inter(s, mb_x, mb_y, 1207cabdff1aSopenharmony_ci (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2, 1208cabdff1aSopenharmony_ci (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd); 1209cabdff1aSopenharmony_ci 1210cabdff1aSopenharmony_ci for(i=0; i<4; i++) 1211cabdff1aSopenharmony_ci if(!(b[i]->type&BLOCK_INTRA)) 1212cabdff1aSopenharmony_ci check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd); 1213cabdff1aSopenharmony_ci 1214cabdff1aSopenharmony_ci if(init_rd != best_rd) 1215cabdff1aSopenharmony_ci change++; 1216cabdff1aSopenharmony_ci } 1217cabdff1aSopenharmony_ci } 1218cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4); 1219cabdff1aSopenharmony_ci } 1220cabdff1aSopenharmony_ci} 1221cabdff1aSopenharmony_ci 1222cabdff1aSopenharmony_cistatic void encode_blocks(SnowContext *s, int search){ 1223cabdff1aSopenharmony_ci int x, y; 1224cabdff1aSopenharmony_ci int w= s->b_width; 1225cabdff1aSopenharmony_ci int h= s->b_height; 1226cabdff1aSopenharmony_ci 1227cabdff1aSopenharmony_ci if(s->motion_est == FF_ME_ITER && !s->keyframe && search) 1228cabdff1aSopenharmony_ci iterative_me(s); 1229cabdff1aSopenharmony_ci 1230cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1231cabdff1aSopenharmony_ci if(s->c.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit 1232cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); 1233cabdff1aSopenharmony_ci return; 1234cabdff1aSopenharmony_ci } 1235cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1236cabdff1aSopenharmony_ci if(s->motion_est == FF_ME_ITER || !search) 1237cabdff1aSopenharmony_ci encode_q_branch2(s, 0, x, y); 1238cabdff1aSopenharmony_ci else 1239cabdff1aSopenharmony_ci encode_q_branch (s, 0, x, y); 1240cabdff1aSopenharmony_ci } 1241cabdff1aSopenharmony_ci } 1242cabdff1aSopenharmony_ci} 1243cabdff1aSopenharmony_ci 1244cabdff1aSopenharmony_cistatic void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){ 1245cabdff1aSopenharmony_ci const int w= b->width; 1246cabdff1aSopenharmony_ci const int h= b->height; 1247cabdff1aSopenharmony_ci const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); 1248cabdff1aSopenharmony_ci const int qmul= ff_qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS); 1249cabdff1aSopenharmony_ci int x,y, thres1, thres2; 1250cabdff1aSopenharmony_ci 1251cabdff1aSopenharmony_ci if(s->qlog == LOSSLESS_QLOG){ 1252cabdff1aSopenharmony_ci for(y=0; y<h; y++) 1253cabdff1aSopenharmony_ci for(x=0; x<w; x++) 1254cabdff1aSopenharmony_ci dst[x + y*stride]= src[x + y*stride]; 1255cabdff1aSopenharmony_ci return; 1256cabdff1aSopenharmony_ci } 1257cabdff1aSopenharmony_ci 1258cabdff1aSopenharmony_ci bias= bias ? 0 : (3*qmul)>>3; 1259cabdff1aSopenharmony_ci thres1= ((qmul - bias)>>QEXPSHIFT) - 1; 1260cabdff1aSopenharmony_ci thres2= 2*thres1; 1261cabdff1aSopenharmony_ci 1262cabdff1aSopenharmony_ci if(!bias){ 1263cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1264cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1265cabdff1aSopenharmony_ci int i= src[x + y*stride]; 1266cabdff1aSopenharmony_ci 1267cabdff1aSopenharmony_ci if((unsigned)(i+thres1) > thres2){ 1268cabdff1aSopenharmony_ci if(i>=0){ 1269cabdff1aSopenharmony_ci i<<= QEXPSHIFT; 1270cabdff1aSopenharmony_ci i/= qmul; //FIXME optimize 1271cabdff1aSopenharmony_ci dst[x + y*stride]= i; 1272cabdff1aSopenharmony_ci }else{ 1273cabdff1aSopenharmony_ci i= -i; 1274cabdff1aSopenharmony_ci i<<= QEXPSHIFT; 1275cabdff1aSopenharmony_ci i/= qmul; //FIXME optimize 1276cabdff1aSopenharmony_ci dst[x + y*stride]= -i; 1277cabdff1aSopenharmony_ci } 1278cabdff1aSopenharmony_ci }else 1279cabdff1aSopenharmony_ci dst[x + y*stride]= 0; 1280cabdff1aSopenharmony_ci } 1281cabdff1aSopenharmony_ci } 1282cabdff1aSopenharmony_ci }else{ 1283cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1284cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1285cabdff1aSopenharmony_ci int i= src[x + y*stride]; 1286cabdff1aSopenharmony_ci 1287cabdff1aSopenharmony_ci if((unsigned)(i+thres1) > thres2){ 1288cabdff1aSopenharmony_ci if(i>=0){ 1289cabdff1aSopenharmony_ci i<<= QEXPSHIFT; 1290cabdff1aSopenharmony_ci i= (i + bias) / qmul; //FIXME optimize 1291cabdff1aSopenharmony_ci dst[x + y*stride]= i; 1292cabdff1aSopenharmony_ci }else{ 1293cabdff1aSopenharmony_ci i= -i; 1294cabdff1aSopenharmony_ci i<<= QEXPSHIFT; 1295cabdff1aSopenharmony_ci i= (i + bias) / qmul; //FIXME optimize 1296cabdff1aSopenharmony_ci dst[x + y*stride]= -i; 1297cabdff1aSopenharmony_ci } 1298cabdff1aSopenharmony_ci }else 1299cabdff1aSopenharmony_ci dst[x + y*stride]= 0; 1300cabdff1aSopenharmony_ci } 1301cabdff1aSopenharmony_ci } 1302cabdff1aSopenharmony_ci } 1303cabdff1aSopenharmony_ci} 1304cabdff1aSopenharmony_ci 1305cabdff1aSopenharmony_cistatic void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){ 1306cabdff1aSopenharmony_ci const int w= b->width; 1307cabdff1aSopenharmony_ci const int h= b->height; 1308cabdff1aSopenharmony_ci const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); 1309cabdff1aSopenharmony_ci const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); 1310cabdff1aSopenharmony_ci const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; 1311cabdff1aSopenharmony_ci int x,y; 1312cabdff1aSopenharmony_ci 1313cabdff1aSopenharmony_ci if(s->qlog == LOSSLESS_QLOG) return; 1314cabdff1aSopenharmony_ci 1315cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1316cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1317cabdff1aSopenharmony_ci int i= src[x + y*stride]; 1318cabdff1aSopenharmony_ci if(i<0){ 1319cabdff1aSopenharmony_ci src[x + y*stride]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias 1320cabdff1aSopenharmony_ci }else if(i>0){ 1321cabdff1aSopenharmony_ci src[x + y*stride]= (( i*qmul + qadd)>>(QEXPSHIFT)); 1322cabdff1aSopenharmony_ci } 1323cabdff1aSopenharmony_ci } 1324cabdff1aSopenharmony_ci } 1325cabdff1aSopenharmony_ci} 1326cabdff1aSopenharmony_ci 1327cabdff1aSopenharmony_cistatic void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){ 1328cabdff1aSopenharmony_ci const int w= b->width; 1329cabdff1aSopenharmony_ci const int h= b->height; 1330cabdff1aSopenharmony_ci int x,y; 1331cabdff1aSopenharmony_ci 1332cabdff1aSopenharmony_ci for(y=h-1; y>=0; y--){ 1333cabdff1aSopenharmony_ci for(x=w-1; x>=0; x--){ 1334cabdff1aSopenharmony_ci int i= x + y*stride; 1335cabdff1aSopenharmony_ci 1336cabdff1aSopenharmony_ci if(x){ 1337cabdff1aSopenharmony_ci if(use_median){ 1338cabdff1aSopenharmony_ci if(y && x+1<w) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]); 1339cabdff1aSopenharmony_ci else src[i] -= src[i - 1]; 1340cabdff1aSopenharmony_ci }else{ 1341cabdff1aSopenharmony_ci if(y) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]); 1342cabdff1aSopenharmony_ci else src[i] -= src[i - 1]; 1343cabdff1aSopenharmony_ci } 1344cabdff1aSopenharmony_ci }else{ 1345cabdff1aSopenharmony_ci if(y) src[i] -= src[i - stride]; 1346cabdff1aSopenharmony_ci } 1347cabdff1aSopenharmony_ci } 1348cabdff1aSopenharmony_ci } 1349cabdff1aSopenharmony_ci} 1350cabdff1aSopenharmony_ci 1351cabdff1aSopenharmony_cistatic void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){ 1352cabdff1aSopenharmony_ci const int w= b->width; 1353cabdff1aSopenharmony_ci const int h= b->height; 1354cabdff1aSopenharmony_ci int x,y; 1355cabdff1aSopenharmony_ci 1356cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1357cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1358cabdff1aSopenharmony_ci int i= x + y*stride; 1359cabdff1aSopenharmony_ci 1360cabdff1aSopenharmony_ci if(x){ 1361cabdff1aSopenharmony_ci if(use_median){ 1362cabdff1aSopenharmony_ci if(y && x+1<w) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]); 1363cabdff1aSopenharmony_ci else src[i] += src[i - 1]; 1364cabdff1aSopenharmony_ci }else{ 1365cabdff1aSopenharmony_ci if(y) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]); 1366cabdff1aSopenharmony_ci else src[i] += src[i - 1]; 1367cabdff1aSopenharmony_ci } 1368cabdff1aSopenharmony_ci }else{ 1369cabdff1aSopenharmony_ci if(y) src[i] += src[i - stride]; 1370cabdff1aSopenharmony_ci } 1371cabdff1aSopenharmony_ci } 1372cabdff1aSopenharmony_ci } 1373cabdff1aSopenharmony_ci} 1374cabdff1aSopenharmony_ci 1375cabdff1aSopenharmony_cistatic void encode_qlogs(SnowContext *s){ 1376cabdff1aSopenharmony_ci int plane_index, level, orientation; 1377cabdff1aSopenharmony_ci 1378cabdff1aSopenharmony_ci for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){ 1379cabdff1aSopenharmony_ci for(level=0; level<s->spatial_decomposition_count; level++){ 1380cabdff1aSopenharmony_ci for(orientation=level ? 1:0; orientation<4; orientation++){ 1381cabdff1aSopenharmony_ci if(orientation==2) continue; 1382cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1); 1383cabdff1aSopenharmony_ci } 1384cabdff1aSopenharmony_ci } 1385cabdff1aSopenharmony_ci } 1386cabdff1aSopenharmony_ci} 1387cabdff1aSopenharmony_ci 1388cabdff1aSopenharmony_cistatic void encode_header(SnowContext *s){ 1389cabdff1aSopenharmony_ci int plane_index, i; 1390cabdff1aSopenharmony_ci uint8_t kstate[32]; 1391cabdff1aSopenharmony_ci 1392cabdff1aSopenharmony_ci memset(kstate, MID_STATE, sizeof(kstate)); 1393cabdff1aSopenharmony_ci 1394cabdff1aSopenharmony_ci put_rac(&s->c, kstate, s->keyframe); 1395cabdff1aSopenharmony_ci if(s->keyframe || s->always_reset){ 1396cabdff1aSopenharmony_ci ff_snow_reset_contexts(s); 1397cabdff1aSopenharmony_ci s->last_spatial_decomposition_type= 1398cabdff1aSopenharmony_ci s->last_qlog= 1399cabdff1aSopenharmony_ci s->last_qbias= 1400cabdff1aSopenharmony_ci s->last_mv_scale= 1401cabdff1aSopenharmony_ci s->last_block_max_depth= 0; 1402cabdff1aSopenharmony_ci for(plane_index=0; plane_index<2; plane_index++){ 1403cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 1404cabdff1aSopenharmony_ci p->last_htaps=0; 1405cabdff1aSopenharmony_ci p->last_diag_mc=0; 1406cabdff1aSopenharmony_ci memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff)); 1407cabdff1aSopenharmony_ci } 1408cabdff1aSopenharmony_ci } 1409cabdff1aSopenharmony_ci if(s->keyframe){ 1410cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->version, 0); 1411cabdff1aSopenharmony_ci put_rac(&s->c, s->header_state, s->always_reset); 1412cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0); 1413cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0); 1414cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0); 1415cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->colorspace_type, 0); 1416cabdff1aSopenharmony_ci if (s->nb_planes > 2) { 1417cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0); 1418cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0); 1419cabdff1aSopenharmony_ci } 1420cabdff1aSopenharmony_ci put_rac(&s->c, s->header_state, s->spatial_scalability); 1421cabdff1aSopenharmony_ci// put_rac(&s->c, s->header_state, s->rate_scalability); 1422cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0); 1423cabdff1aSopenharmony_ci 1424cabdff1aSopenharmony_ci encode_qlogs(s); 1425cabdff1aSopenharmony_ci } 1426cabdff1aSopenharmony_ci 1427cabdff1aSopenharmony_ci if(!s->keyframe){ 1428cabdff1aSopenharmony_ci int update_mc=0; 1429cabdff1aSopenharmony_ci for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){ 1430cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 1431cabdff1aSopenharmony_ci update_mc |= p->last_htaps != p->htaps; 1432cabdff1aSopenharmony_ci update_mc |= p->last_diag_mc != p->diag_mc; 1433cabdff1aSopenharmony_ci update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff)); 1434cabdff1aSopenharmony_ci } 1435cabdff1aSopenharmony_ci put_rac(&s->c, s->header_state, update_mc); 1436cabdff1aSopenharmony_ci if(update_mc){ 1437cabdff1aSopenharmony_ci for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){ 1438cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 1439cabdff1aSopenharmony_ci put_rac(&s->c, s->header_state, p->diag_mc); 1440cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, p->htaps/2-1, 0); 1441cabdff1aSopenharmony_ci for(i= p->htaps/2; i; i--) 1442cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0); 1443cabdff1aSopenharmony_ci } 1444cabdff1aSopenharmony_ci } 1445cabdff1aSopenharmony_ci if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ 1446cabdff1aSopenharmony_ci put_rac(&s->c, s->header_state, 1); 1447cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0); 1448cabdff1aSopenharmony_ci encode_qlogs(s); 1449cabdff1aSopenharmony_ci }else 1450cabdff1aSopenharmony_ci put_rac(&s->c, s->header_state, 0); 1451cabdff1aSopenharmony_ci } 1452cabdff1aSopenharmony_ci 1453cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1); 1454cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->qlog - s->last_qlog , 1); 1455cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->mv_scale - s->last_mv_scale, 1); 1456cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->qbias - s->last_qbias , 1); 1457cabdff1aSopenharmony_ci put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1); 1458cabdff1aSopenharmony_ci 1459cabdff1aSopenharmony_ci} 1460cabdff1aSopenharmony_ci 1461cabdff1aSopenharmony_cistatic void update_last_header_values(SnowContext *s){ 1462cabdff1aSopenharmony_ci int plane_index; 1463cabdff1aSopenharmony_ci 1464cabdff1aSopenharmony_ci if(!s->keyframe){ 1465cabdff1aSopenharmony_ci for(plane_index=0; plane_index<2; plane_index++){ 1466cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 1467cabdff1aSopenharmony_ci p->last_diag_mc= p->diag_mc; 1468cabdff1aSopenharmony_ci p->last_htaps = p->htaps; 1469cabdff1aSopenharmony_ci memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff)); 1470cabdff1aSopenharmony_ci } 1471cabdff1aSopenharmony_ci } 1472cabdff1aSopenharmony_ci 1473cabdff1aSopenharmony_ci s->last_spatial_decomposition_type = s->spatial_decomposition_type; 1474cabdff1aSopenharmony_ci s->last_qlog = s->qlog; 1475cabdff1aSopenharmony_ci s->last_qbias = s->qbias; 1476cabdff1aSopenharmony_ci s->last_mv_scale = s->mv_scale; 1477cabdff1aSopenharmony_ci s->last_block_max_depth = s->block_max_depth; 1478cabdff1aSopenharmony_ci s->last_spatial_decomposition_count = s->spatial_decomposition_count; 1479cabdff1aSopenharmony_ci} 1480cabdff1aSopenharmony_ci 1481cabdff1aSopenharmony_cistatic int qscale2qlog(int qscale){ 1482cabdff1aSopenharmony_ci return lrint(QROOT*log2(qscale / (float)FF_QP2LAMBDA)) 1483cabdff1aSopenharmony_ci + 61*QROOT/8; ///< 64 > 60 1484cabdff1aSopenharmony_ci} 1485cabdff1aSopenharmony_ci 1486cabdff1aSopenharmony_cistatic int ratecontrol_1pass(SnowContext *s, AVFrame *pict) 1487cabdff1aSopenharmony_ci{ 1488cabdff1aSopenharmony_ci /* Estimate the frame's complexity as a sum of weighted dwt coefficients. 1489cabdff1aSopenharmony_ci * FIXME we know exact mv bits at this point, 1490cabdff1aSopenharmony_ci * but ratecontrol isn't set up to include them. */ 1491cabdff1aSopenharmony_ci uint32_t coef_sum= 0; 1492cabdff1aSopenharmony_ci int level, orientation, delta_qlog; 1493cabdff1aSopenharmony_ci 1494cabdff1aSopenharmony_ci for(level=0; level<s->spatial_decomposition_count; level++){ 1495cabdff1aSopenharmony_ci for(orientation=level ? 1 : 0; orientation<4; orientation++){ 1496cabdff1aSopenharmony_ci SubBand *b= &s->plane[0].band[level][orientation]; 1497cabdff1aSopenharmony_ci IDWTELEM *buf= b->ibuf; 1498cabdff1aSopenharmony_ci const int w= b->width; 1499cabdff1aSopenharmony_ci const int h= b->height; 1500cabdff1aSopenharmony_ci const int stride= b->stride; 1501cabdff1aSopenharmony_ci const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16); 1502cabdff1aSopenharmony_ci const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); 1503cabdff1aSopenharmony_ci const int qdiv= (1<<16)/qmul; 1504cabdff1aSopenharmony_ci int x, y; 1505cabdff1aSopenharmony_ci //FIXME this is ugly 1506cabdff1aSopenharmony_ci for(y=0; y<h; y++) 1507cabdff1aSopenharmony_ci for(x=0; x<w; x++) 1508cabdff1aSopenharmony_ci buf[x+y*stride]= b->buf[x+y*stride]; 1509cabdff1aSopenharmony_ci if(orientation==0) 1510cabdff1aSopenharmony_ci decorrelate(s, b, buf, stride, 1, 0); 1511cabdff1aSopenharmony_ci for(y=0; y<h; y++) 1512cabdff1aSopenharmony_ci for(x=0; x<w; x++) 1513cabdff1aSopenharmony_ci coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16; 1514cabdff1aSopenharmony_ci } 1515cabdff1aSopenharmony_ci } 1516cabdff1aSopenharmony_ci 1517cabdff1aSopenharmony_ci /* ugly, ratecontrol just takes a sqrt again */ 1518cabdff1aSopenharmony_ci av_assert0(coef_sum < INT_MAX); 1519cabdff1aSopenharmony_ci coef_sum = (uint64_t)coef_sum * coef_sum >> 16; 1520cabdff1aSopenharmony_ci 1521cabdff1aSopenharmony_ci if(pict->pict_type == AV_PICTURE_TYPE_I){ 1522cabdff1aSopenharmony_ci s->m.current_picture.mb_var_sum= coef_sum; 1523cabdff1aSopenharmony_ci s->m.current_picture.mc_mb_var_sum= 0; 1524cabdff1aSopenharmony_ci }else{ 1525cabdff1aSopenharmony_ci s->m.current_picture.mc_mb_var_sum= coef_sum; 1526cabdff1aSopenharmony_ci s->m.current_picture.mb_var_sum= 0; 1527cabdff1aSopenharmony_ci } 1528cabdff1aSopenharmony_ci 1529cabdff1aSopenharmony_ci pict->quality= ff_rate_estimate_qscale(&s->m, 1); 1530cabdff1aSopenharmony_ci if (pict->quality < 0) 1531cabdff1aSopenharmony_ci return INT_MIN; 1532cabdff1aSopenharmony_ci s->lambda= pict->quality * 3/2; 1533cabdff1aSopenharmony_ci delta_qlog= qscale2qlog(pict->quality) - s->qlog; 1534cabdff1aSopenharmony_ci s->qlog+= delta_qlog; 1535cabdff1aSopenharmony_ci return delta_qlog; 1536cabdff1aSopenharmony_ci} 1537cabdff1aSopenharmony_ci 1538cabdff1aSopenharmony_cistatic void calculate_visual_weight(SnowContext *s, Plane *p){ 1539cabdff1aSopenharmony_ci int width = p->width; 1540cabdff1aSopenharmony_ci int height= p->height; 1541cabdff1aSopenharmony_ci int level, orientation, x, y; 1542cabdff1aSopenharmony_ci 1543cabdff1aSopenharmony_ci for(level=0; level<s->spatial_decomposition_count; level++){ 1544cabdff1aSopenharmony_ci int64_t error=0; 1545cabdff1aSopenharmony_ci for(orientation=level ? 1 : 0; orientation<4; orientation++){ 1546cabdff1aSopenharmony_ci SubBand *b= &p->band[level][orientation]; 1547cabdff1aSopenharmony_ci IDWTELEM *ibuf= b->ibuf; 1548cabdff1aSopenharmony_ci 1549cabdff1aSopenharmony_ci memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height); 1550cabdff1aSopenharmony_ci ibuf[b->width/2 + b->height/2*b->stride]= 256*16; 1551cabdff1aSopenharmony_ci ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count); 1552cabdff1aSopenharmony_ci for(y=0; y<height; y++){ 1553cabdff1aSopenharmony_ci for(x=0; x<width; x++){ 1554cabdff1aSopenharmony_ci int64_t d= s->spatial_idwt_buffer[x + y*width]*16; 1555cabdff1aSopenharmony_ci error += d*d; 1556cabdff1aSopenharmony_ci } 1557cabdff1aSopenharmony_ci } 1558cabdff1aSopenharmony_ci if (orientation == 2) 1559cabdff1aSopenharmony_ci error /= 2; 1560cabdff1aSopenharmony_ci b->qlog= (int)(QROOT * log2(352256.0/sqrt(error)) + 0.5); 1561cabdff1aSopenharmony_ci if (orientation != 1) 1562cabdff1aSopenharmony_ci error = 0; 1563cabdff1aSopenharmony_ci } 1564cabdff1aSopenharmony_ci p->band[level][1].qlog = p->band[level][2].qlog; 1565cabdff1aSopenharmony_ci } 1566cabdff1aSopenharmony_ci} 1567cabdff1aSopenharmony_ci 1568cabdff1aSopenharmony_cistatic int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 1569cabdff1aSopenharmony_ci const AVFrame *pict, int *got_packet) 1570cabdff1aSopenharmony_ci{ 1571cabdff1aSopenharmony_ci SnowContext *s = avctx->priv_data; 1572cabdff1aSopenharmony_ci RangeCoder * const c= &s->c; 1573cabdff1aSopenharmony_ci AVFrame *pic; 1574cabdff1aSopenharmony_ci const int width= s->avctx->width; 1575cabdff1aSopenharmony_ci const int height= s->avctx->height; 1576cabdff1aSopenharmony_ci int level, orientation, plane_index, i, y, ret; 1577cabdff1aSopenharmony_ci uint8_t rc_header_bak[sizeof(s->header_state)]; 1578cabdff1aSopenharmony_ci uint8_t rc_block_bak[sizeof(s->block_state)]; 1579cabdff1aSopenharmony_ci 1580cabdff1aSopenharmony_ci if ((ret = ff_alloc_packet(avctx, pkt, s->b_width*s->b_height*MB_SIZE*MB_SIZE*3 + AV_INPUT_BUFFER_MIN_SIZE)) < 0) 1581cabdff1aSopenharmony_ci return ret; 1582cabdff1aSopenharmony_ci 1583cabdff1aSopenharmony_ci ff_init_range_encoder(c, pkt->data, pkt->size); 1584cabdff1aSopenharmony_ci ff_build_rac_states(c, (1LL<<32)/20, 256-8); 1585cabdff1aSopenharmony_ci 1586cabdff1aSopenharmony_ci for(i=0; i < s->nb_planes; i++){ 1587cabdff1aSopenharmony_ci int hshift= i ? s->chroma_h_shift : 0; 1588cabdff1aSopenharmony_ci int vshift= i ? s->chroma_v_shift : 0; 1589cabdff1aSopenharmony_ci for(y=0; y<AV_CEIL_RSHIFT(height, vshift); y++) 1590cabdff1aSopenharmony_ci memcpy(&s->input_picture->data[i][y * s->input_picture->linesize[i]], 1591cabdff1aSopenharmony_ci &pict->data[i][y * pict->linesize[i]], 1592cabdff1aSopenharmony_ci AV_CEIL_RSHIFT(width, hshift)); 1593cabdff1aSopenharmony_ci s->mpvencdsp.draw_edges(s->input_picture->data[i], s->input_picture->linesize[i], 1594cabdff1aSopenharmony_ci AV_CEIL_RSHIFT(width, hshift), AV_CEIL_RSHIFT(height, vshift), 1595cabdff1aSopenharmony_ci EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, 1596cabdff1aSopenharmony_ci EDGE_TOP | EDGE_BOTTOM); 1597cabdff1aSopenharmony_ci 1598cabdff1aSopenharmony_ci } 1599cabdff1aSopenharmony_ci emms_c(); 1600cabdff1aSopenharmony_ci pic = s->input_picture; 1601cabdff1aSopenharmony_ci pic->pict_type = pict->pict_type; 1602cabdff1aSopenharmony_ci pic->quality = pict->quality; 1603cabdff1aSopenharmony_ci 1604cabdff1aSopenharmony_ci s->m.picture_number= avctx->frame_number; 1605cabdff1aSopenharmony_ci if(avctx->flags&AV_CODEC_FLAG_PASS2){ 1606cabdff1aSopenharmony_ci s->m.pict_type = pic->pict_type = s->m.rc_context.entry[avctx->frame_number].new_pict_type; 1607cabdff1aSopenharmony_ci s->keyframe = pic->pict_type == AV_PICTURE_TYPE_I; 1608cabdff1aSopenharmony_ci if(!(avctx->flags&AV_CODEC_FLAG_QSCALE)) { 1609cabdff1aSopenharmony_ci pic->quality = ff_rate_estimate_qscale(&s->m, 0); 1610cabdff1aSopenharmony_ci if (pic->quality < 0) 1611cabdff1aSopenharmony_ci return -1; 1612cabdff1aSopenharmony_ci } 1613cabdff1aSopenharmony_ci }else{ 1614cabdff1aSopenharmony_ci s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0; 1615cabdff1aSopenharmony_ci s->m.pict_type = pic->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; 1616cabdff1aSopenharmony_ci } 1617cabdff1aSopenharmony_ci 1618cabdff1aSopenharmony_ci if(s->pass1_rc && avctx->frame_number == 0) 1619cabdff1aSopenharmony_ci pic->quality = 2*FF_QP2LAMBDA; 1620cabdff1aSopenharmony_ci if (pic->quality) { 1621cabdff1aSopenharmony_ci s->qlog = qscale2qlog(pic->quality); 1622cabdff1aSopenharmony_ci s->lambda = pic->quality * 3/2; 1623cabdff1aSopenharmony_ci } 1624cabdff1aSopenharmony_ci if (s->qlog < 0 || (!pic->quality && (avctx->flags & AV_CODEC_FLAG_QSCALE))) { 1625cabdff1aSopenharmony_ci s->qlog= LOSSLESS_QLOG; 1626cabdff1aSopenharmony_ci s->lambda = 0; 1627cabdff1aSopenharmony_ci }//else keep previous frame's qlog until after motion estimation 1628cabdff1aSopenharmony_ci 1629cabdff1aSopenharmony_ci if (s->current_picture->data[0]) { 1630cabdff1aSopenharmony_ci int w = s->avctx->width; 1631cabdff1aSopenharmony_ci int h = s->avctx->height; 1632cabdff1aSopenharmony_ci 1633cabdff1aSopenharmony_ci s->mpvencdsp.draw_edges(s->current_picture->data[0], 1634cabdff1aSopenharmony_ci s->current_picture->linesize[0], w , h , 1635cabdff1aSopenharmony_ci EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); 1636cabdff1aSopenharmony_ci if (s->current_picture->data[2]) { 1637cabdff1aSopenharmony_ci s->mpvencdsp.draw_edges(s->current_picture->data[1], 1638cabdff1aSopenharmony_ci s->current_picture->linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift, 1639cabdff1aSopenharmony_ci EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); 1640cabdff1aSopenharmony_ci s->mpvencdsp.draw_edges(s->current_picture->data[2], 1641cabdff1aSopenharmony_ci s->current_picture->linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift, 1642cabdff1aSopenharmony_ci EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM); 1643cabdff1aSopenharmony_ci } 1644cabdff1aSopenharmony_ci emms_c(); 1645cabdff1aSopenharmony_ci } 1646cabdff1aSopenharmony_ci 1647cabdff1aSopenharmony_ci ff_snow_frame_start(s); 1648cabdff1aSopenharmony_ci 1649cabdff1aSopenharmony_ci s->m.current_picture_ptr= &s->m.current_picture; 1650cabdff1aSopenharmony_ci s->m.current_picture.f = s->current_picture; 1651cabdff1aSopenharmony_ci s->m.current_picture.f->pts = pict->pts; 1652cabdff1aSopenharmony_ci if(pic->pict_type == AV_PICTURE_TYPE_P){ 1653cabdff1aSopenharmony_ci int block_width = (width +15)>>4; 1654cabdff1aSopenharmony_ci int block_height= (height+15)>>4; 1655cabdff1aSopenharmony_ci int stride= s->current_picture->linesize[0]; 1656cabdff1aSopenharmony_ci 1657cabdff1aSopenharmony_ci av_assert0(s->current_picture->data[0]); 1658cabdff1aSopenharmony_ci av_assert0(s->last_picture[0]->data[0]); 1659cabdff1aSopenharmony_ci 1660cabdff1aSopenharmony_ci s->m.avctx= s->avctx; 1661cabdff1aSopenharmony_ci s->m. last_picture.f = s->last_picture[0]; 1662cabdff1aSopenharmony_ci s->m. new_picture = s->input_picture; 1663cabdff1aSopenharmony_ci s->m. last_picture_ptr= &s->m. last_picture; 1664cabdff1aSopenharmony_ci s->m.linesize = stride; 1665cabdff1aSopenharmony_ci s->m.uvlinesize= s->current_picture->linesize[1]; 1666cabdff1aSopenharmony_ci s->m.width = width; 1667cabdff1aSopenharmony_ci s->m.height= height; 1668cabdff1aSopenharmony_ci s->m.mb_width = block_width; 1669cabdff1aSopenharmony_ci s->m.mb_height= block_height; 1670cabdff1aSopenharmony_ci s->m.mb_stride= s->m.mb_width+1; 1671cabdff1aSopenharmony_ci s->m.b8_stride= 2*s->m.mb_width+1; 1672cabdff1aSopenharmony_ci s->m.f_code=1; 1673cabdff1aSopenharmony_ci s->m.pict_type = pic->pict_type; 1674cabdff1aSopenharmony_ci s->m.motion_est= s->motion_est; 1675cabdff1aSopenharmony_ci s->m.me.scene_change_score=0; 1676cabdff1aSopenharmony_ci s->m.me.dia_size = avctx->dia_size; 1677cabdff1aSopenharmony_ci s->m.quarter_sample= (s->avctx->flags & AV_CODEC_FLAG_QPEL)!=0; 1678cabdff1aSopenharmony_ci s->m.out_format= FMT_H263; 1679cabdff1aSopenharmony_ci s->m.unrestricted_mv= 1; 1680cabdff1aSopenharmony_ci 1681cabdff1aSopenharmony_ci s->m.lambda = s->lambda; 1682cabdff1aSopenharmony_ci s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); 1683cabdff1aSopenharmony_ci s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; 1684cabdff1aSopenharmony_ci 1685cabdff1aSopenharmony_ci s->m.mecc= s->mecc; //move 1686cabdff1aSopenharmony_ci s->m.qdsp= s->qdsp; //move 1687cabdff1aSopenharmony_ci s->m.hdsp = s->hdsp; 1688cabdff1aSopenharmony_ci ff_init_me(&s->m); 1689cabdff1aSopenharmony_ci s->hdsp = s->m.hdsp; 1690cabdff1aSopenharmony_ci s->mecc= s->m.mecc; 1691cabdff1aSopenharmony_ci } 1692cabdff1aSopenharmony_ci 1693cabdff1aSopenharmony_ci if(s->pass1_rc){ 1694cabdff1aSopenharmony_ci memcpy(rc_header_bak, s->header_state, sizeof(s->header_state)); 1695cabdff1aSopenharmony_ci memcpy(rc_block_bak, s->block_state, sizeof(s->block_state)); 1696cabdff1aSopenharmony_ci } 1697cabdff1aSopenharmony_ci 1698cabdff1aSopenharmony_ciredo_frame: 1699cabdff1aSopenharmony_ci 1700cabdff1aSopenharmony_ci s->spatial_decomposition_count= 5; 1701cabdff1aSopenharmony_ci 1702cabdff1aSopenharmony_ci while( !(width >>(s->chroma_h_shift + s->spatial_decomposition_count)) 1703cabdff1aSopenharmony_ci || !(height>>(s->chroma_v_shift + s->spatial_decomposition_count))) 1704cabdff1aSopenharmony_ci s->spatial_decomposition_count--; 1705cabdff1aSopenharmony_ci 1706cabdff1aSopenharmony_ci if (s->spatial_decomposition_count <= 0) { 1707cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Resolution too low\n"); 1708cabdff1aSopenharmony_ci return AVERROR(EINVAL); 1709cabdff1aSopenharmony_ci } 1710cabdff1aSopenharmony_ci 1711cabdff1aSopenharmony_ci s->m.pict_type = pic->pict_type; 1712cabdff1aSopenharmony_ci s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0; 1713cabdff1aSopenharmony_ci 1714cabdff1aSopenharmony_ci ff_snow_common_init_after_header(avctx); 1715cabdff1aSopenharmony_ci 1716cabdff1aSopenharmony_ci if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ 1717cabdff1aSopenharmony_ci for(plane_index=0; plane_index < s->nb_planes; plane_index++){ 1718cabdff1aSopenharmony_ci calculate_visual_weight(s, &s->plane[plane_index]); 1719cabdff1aSopenharmony_ci } 1720cabdff1aSopenharmony_ci } 1721cabdff1aSopenharmony_ci 1722cabdff1aSopenharmony_ci encode_header(s); 1723cabdff1aSopenharmony_ci s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start); 1724cabdff1aSopenharmony_ci encode_blocks(s, 1); 1725cabdff1aSopenharmony_ci s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits; 1726cabdff1aSopenharmony_ci 1727cabdff1aSopenharmony_ci for(plane_index=0; plane_index < s->nb_planes; plane_index++){ 1728cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 1729cabdff1aSopenharmony_ci int w= p->width; 1730cabdff1aSopenharmony_ci int h= p->height; 1731cabdff1aSopenharmony_ci int x, y; 1732cabdff1aSopenharmony_ci// int bits= put_bits_count(&s->c.pb); 1733cabdff1aSopenharmony_ci 1734cabdff1aSopenharmony_ci if (!s->memc_only) { 1735cabdff1aSopenharmony_ci //FIXME optimize 1736cabdff1aSopenharmony_ci if(pict->data[plane_index]) //FIXME gray hack 1737cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1738cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1739cabdff1aSopenharmony_ci s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS; 1740cabdff1aSopenharmony_ci } 1741cabdff1aSopenharmony_ci } 1742cabdff1aSopenharmony_ci predict_plane(s, s->spatial_idwt_buffer, plane_index, 0); 1743cabdff1aSopenharmony_ci 1744cabdff1aSopenharmony_ci if( plane_index==0 1745cabdff1aSopenharmony_ci && pic->pict_type == AV_PICTURE_TYPE_P 1746cabdff1aSopenharmony_ci && !(avctx->flags&AV_CODEC_FLAG_PASS2) 1747cabdff1aSopenharmony_ci && s->m.me.scene_change_score > s->scenechange_threshold){ 1748cabdff1aSopenharmony_ci ff_init_range_encoder(c, pkt->data, pkt->size); 1749cabdff1aSopenharmony_ci ff_build_rac_states(c, (1LL<<32)/20, 256-8); 1750cabdff1aSopenharmony_ci pic->pict_type= AV_PICTURE_TYPE_I; 1751cabdff1aSopenharmony_ci s->keyframe=1; 1752cabdff1aSopenharmony_ci s->current_picture->key_frame=1; 1753cabdff1aSopenharmony_ci goto redo_frame; 1754cabdff1aSopenharmony_ci } 1755cabdff1aSopenharmony_ci 1756cabdff1aSopenharmony_ci if(s->qlog == LOSSLESS_QLOG){ 1757cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1758cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1759cabdff1aSopenharmony_ci s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS; 1760cabdff1aSopenharmony_ci } 1761cabdff1aSopenharmony_ci } 1762cabdff1aSopenharmony_ci }else{ 1763cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1764cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1765cabdff1aSopenharmony_ci s->spatial_dwt_buffer[y*w + x]= s->spatial_idwt_buffer[y*w + x] * (1 << ENCODER_EXTRA_BITS); 1766cabdff1aSopenharmony_ci } 1767cabdff1aSopenharmony_ci } 1768cabdff1aSopenharmony_ci } 1769cabdff1aSopenharmony_ci 1770cabdff1aSopenharmony_ci ff_spatial_dwt(s->spatial_dwt_buffer, s->temp_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); 1771cabdff1aSopenharmony_ci 1772cabdff1aSopenharmony_ci if(s->pass1_rc && plane_index==0){ 1773cabdff1aSopenharmony_ci int delta_qlog = ratecontrol_1pass(s, pic); 1774cabdff1aSopenharmony_ci if (delta_qlog <= INT_MIN) 1775cabdff1aSopenharmony_ci return -1; 1776cabdff1aSopenharmony_ci if(delta_qlog){ 1777cabdff1aSopenharmony_ci //reordering qlog in the bitstream would eliminate this reset 1778cabdff1aSopenharmony_ci ff_init_range_encoder(c, pkt->data, pkt->size); 1779cabdff1aSopenharmony_ci memcpy(s->header_state, rc_header_bak, sizeof(s->header_state)); 1780cabdff1aSopenharmony_ci memcpy(s->block_state, rc_block_bak, sizeof(s->block_state)); 1781cabdff1aSopenharmony_ci encode_header(s); 1782cabdff1aSopenharmony_ci encode_blocks(s, 0); 1783cabdff1aSopenharmony_ci } 1784cabdff1aSopenharmony_ci } 1785cabdff1aSopenharmony_ci 1786cabdff1aSopenharmony_ci for(level=0; level<s->spatial_decomposition_count; level++){ 1787cabdff1aSopenharmony_ci for(orientation=level ? 1 : 0; orientation<4; orientation++){ 1788cabdff1aSopenharmony_ci SubBand *b= &p->band[level][orientation]; 1789cabdff1aSopenharmony_ci 1790cabdff1aSopenharmony_ci quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias); 1791cabdff1aSopenharmony_ci if(orientation==0) 1792cabdff1aSopenharmony_ci decorrelate(s, b, b->ibuf, b->stride, pic->pict_type == AV_PICTURE_TYPE_P, 0); 1793cabdff1aSopenharmony_ci if (!s->no_bitstream) 1794cabdff1aSopenharmony_ci encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation); 1795cabdff1aSopenharmony_ci av_assert0(b->parent==NULL || b->parent->stride == b->stride*2); 1796cabdff1aSopenharmony_ci if(orientation==0) 1797cabdff1aSopenharmony_ci correlate(s, b, b->ibuf, b->stride, 1, 0); 1798cabdff1aSopenharmony_ci } 1799cabdff1aSopenharmony_ci } 1800cabdff1aSopenharmony_ci 1801cabdff1aSopenharmony_ci for(level=0; level<s->spatial_decomposition_count; level++){ 1802cabdff1aSopenharmony_ci for(orientation=level ? 1 : 0; orientation<4; orientation++){ 1803cabdff1aSopenharmony_ci SubBand *b= &p->band[level][orientation]; 1804cabdff1aSopenharmony_ci 1805cabdff1aSopenharmony_ci dequantize(s, b, b->ibuf, b->stride); 1806cabdff1aSopenharmony_ci } 1807cabdff1aSopenharmony_ci } 1808cabdff1aSopenharmony_ci 1809cabdff1aSopenharmony_ci ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); 1810cabdff1aSopenharmony_ci if(s->qlog == LOSSLESS_QLOG){ 1811cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1812cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1813cabdff1aSopenharmony_ci s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS; 1814cabdff1aSopenharmony_ci } 1815cabdff1aSopenharmony_ci } 1816cabdff1aSopenharmony_ci } 1817cabdff1aSopenharmony_ci predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); 1818cabdff1aSopenharmony_ci }else{ 1819cabdff1aSopenharmony_ci //ME/MC only 1820cabdff1aSopenharmony_ci if(pic->pict_type == AV_PICTURE_TYPE_I){ 1821cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1822cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1823cabdff1aSopenharmony_ci s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x]= 1824cabdff1aSopenharmony_ci pict->data[plane_index][y*pict->linesize[plane_index] + x]; 1825cabdff1aSopenharmony_ci } 1826cabdff1aSopenharmony_ci } 1827cabdff1aSopenharmony_ci }else{ 1828cabdff1aSopenharmony_ci memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h); 1829cabdff1aSopenharmony_ci predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); 1830cabdff1aSopenharmony_ci } 1831cabdff1aSopenharmony_ci } 1832cabdff1aSopenharmony_ci if(s->avctx->flags&AV_CODEC_FLAG_PSNR){ 1833cabdff1aSopenharmony_ci int64_t error= 0; 1834cabdff1aSopenharmony_ci 1835cabdff1aSopenharmony_ci if(pict->data[plane_index]) //FIXME gray hack 1836cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 1837cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 1838cabdff1aSopenharmony_ci int d= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x]; 1839cabdff1aSopenharmony_ci error += d*d; 1840cabdff1aSopenharmony_ci } 1841cabdff1aSopenharmony_ci } 1842cabdff1aSopenharmony_ci s->avctx->error[plane_index] += error; 1843cabdff1aSopenharmony_ci s->encoding_error[plane_index] = error; 1844cabdff1aSopenharmony_ci } 1845cabdff1aSopenharmony_ci 1846cabdff1aSopenharmony_ci } 1847cabdff1aSopenharmony_ci emms_c(); 1848cabdff1aSopenharmony_ci 1849cabdff1aSopenharmony_ci update_last_header_values(s); 1850cabdff1aSopenharmony_ci 1851cabdff1aSopenharmony_ci ff_snow_release_buffer(avctx); 1852cabdff1aSopenharmony_ci 1853cabdff1aSopenharmony_ci s->current_picture->coded_picture_number = avctx->frame_number; 1854cabdff1aSopenharmony_ci s->current_picture->pict_type = pic->pict_type; 1855cabdff1aSopenharmony_ci s->current_picture->quality = pic->quality; 1856cabdff1aSopenharmony_ci s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start); 1857cabdff1aSopenharmony_ci s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits; 1858cabdff1aSopenharmony_ci s->m.current_picture.f->display_picture_number = 1859cabdff1aSopenharmony_ci s->m.current_picture.f->coded_picture_number = avctx->frame_number; 1860cabdff1aSopenharmony_ci s->m.current_picture.f->quality = pic->quality; 1861cabdff1aSopenharmony_ci s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start); 1862cabdff1aSopenharmony_ci if(s->pass1_rc) 1863cabdff1aSopenharmony_ci if (ff_rate_estimate_qscale(&s->m, 0) < 0) 1864cabdff1aSopenharmony_ci return -1; 1865cabdff1aSopenharmony_ci if(avctx->flags&AV_CODEC_FLAG_PASS1) 1866cabdff1aSopenharmony_ci ff_write_pass1_stats(&s->m); 1867cabdff1aSopenharmony_ci s->m.last_pict_type = s->m.pict_type; 1868cabdff1aSopenharmony_ci 1869cabdff1aSopenharmony_ci emms_c(); 1870cabdff1aSopenharmony_ci 1871cabdff1aSopenharmony_ci ff_side_data_set_encoder_stats(pkt, s->current_picture->quality, 1872cabdff1aSopenharmony_ci s->encoding_error, 1873cabdff1aSopenharmony_ci (s->avctx->flags&AV_CODEC_FLAG_PSNR) ? SNOW_MAX_PLANES : 0, 1874cabdff1aSopenharmony_ci s->current_picture->pict_type); 1875cabdff1aSopenharmony_ci 1876cabdff1aSopenharmony_ci pkt->size = ff_rac_terminate(c, 0); 1877cabdff1aSopenharmony_ci if (s->current_picture->key_frame) 1878cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 1879cabdff1aSopenharmony_ci *got_packet = 1; 1880cabdff1aSopenharmony_ci 1881cabdff1aSopenharmony_ci return 0; 1882cabdff1aSopenharmony_ci} 1883cabdff1aSopenharmony_ci 1884cabdff1aSopenharmony_cistatic av_cold int encode_end(AVCodecContext *avctx) 1885cabdff1aSopenharmony_ci{ 1886cabdff1aSopenharmony_ci SnowContext *s = avctx->priv_data; 1887cabdff1aSopenharmony_ci 1888cabdff1aSopenharmony_ci ff_snow_common_end(s); 1889cabdff1aSopenharmony_ci ff_rate_control_uninit(&s->m); 1890cabdff1aSopenharmony_ci av_frame_free(&s->input_picture); 1891cabdff1aSopenharmony_ci av_freep(&avctx->stats_out); 1892cabdff1aSopenharmony_ci 1893cabdff1aSopenharmony_ci return 0; 1894cabdff1aSopenharmony_ci} 1895cabdff1aSopenharmony_ci 1896cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(SnowContext, x) 1897cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 1898cabdff1aSopenharmony_cistatic const AVOption options[] = { 1899cabdff1aSopenharmony_ci {"motion_est", "motion estimation algorithm", OFFSET(motion_est), AV_OPT_TYPE_INT, {.i64 = FF_ME_EPZS }, FF_ME_ZERO, FF_ME_ITER, VE, "motion_est" }, 1900cabdff1aSopenharmony_ci { "zero", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ZERO }, 0, 0, VE, "motion_est" }, 1901cabdff1aSopenharmony_ci { "epzs", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_EPZS }, 0, 0, VE, "motion_est" }, 1902cabdff1aSopenharmony_ci { "xone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_XONE }, 0, 0, VE, "motion_est" }, 1903cabdff1aSopenharmony_ci { "iter", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FF_ME_ITER }, 0, 0, VE, "motion_est" }, 1904cabdff1aSopenharmony_ci { "memc_only", "Only do ME/MC (I frames -> ref, P frame -> ME+MC).", OFFSET(memc_only), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, 1905cabdff1aSopenharmony_ci { "no_bitstream", "Skip final bitstream writeout.", OFFSET(no_bitstream), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, 1906cabdff1aSopenharmony_ci { "intra_penalty", "Penalty for intra blocks in block decission", OFFSET(intra_penalty), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, 1907cabdff1aSopenharmony_ci { "iterative_dia_size", "Dia size for the iterative ME", OFFSET(iterative_dia_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, 1908cabdff1aSopenharmony_ci { "sc_threshold", "Scene change threshold", OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE }, 1909cabdff1aSopenharmony_ci { "pred", "Spatial decomposition type", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, DWT_97, DWT_53, VE, "pred" }, 1910cabdff1aSopenharmony_ci { "dwt97", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, 1911cabdff1aSopenharmony_ci { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, 1912cabdff1aSopenharmony_ci { "rc_eq", "Set rate control equation. When computing the expression, besides the standard functions " 1913cabdff1aSopenharmony_ci "defined in the section 'Expression Evaluation', the following functions are available: " 1914cabdff1aSopenharmony_ci "bits2qp(bits), qp2bits(qp). Also the following constants are available: iTex pTex tex mv " 1915cabdff1aSopenharmony_ci "fCode iCount mcVar var isI isP isB avgQP qComp avgIITex avgPITex avgPPTex avgBPTex avgTex.", 1916cabdff1aSopenharmony_ci OFFSET(m.rc_eq), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VE }, 1917cabdff1aSopenharmony_ci { NULL }, 1918cabdff1aSopenharmony_ci}; 1919cabdff1aSopenharmony_ci 1920cabdff1aSopenharmony_cistatic const AVClass snowenc_class = { 1921cabdff1aSopenharmony_ci .class_name = "snow encoder", 1922cabdff1aSopenharmony_ci .item_name = av_default_item_name, 1923cabdff1aSopenharmony_ci .option = options, 1924cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 1925cabdff1aSopenharmony_ci}; 1926cabdff1aSopenharmony_ci 1927cabdff1aSopenharmony_ciconst FFCodec ff_snow_encoder = { 1928cabdff1aSopenharmony_ci .p.name = "snow", 1929cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Snow"), 1930cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1931cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_SNOW, 1932cabdff1aSopenharmony_ci .priv_data_size = sizeof(SnowContext), 1933cabdff1aSopenharmony_ci .init = encode_init, 1934cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(encode_frame), 1935cabdff1aSopenharmony_ci .close = encode_end, 1936cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]){ 1937cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV444P, 1938cabdff1aSopenharmony_ci AV_PIX_FMT_GRAY8, 1939cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 1940cabdff1aSopenharmony_ci }, 1941cabdff1aSopenharmony_ci .p.priv_class = &snowenc_class, 1942cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | 1943cabdff1aSopenharmony_ci FF_CODEC_CAP_INIT_CLEANUP, 1944cabdff1aSopenharmony_ci}; 1945