1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> 3cabdff1aSopenharmony_ci * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net> 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#ifndef AVCODEC_SNOW_H 23cabdff1aSopenharmony_ci#define AVCODEC_SNOW_H 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#include "libavutil/motion_vector.h" 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "hpeldsp.h" 28cabdff1aSopenharmony_ci#include "me_cmp.h" 29cabdff1aSopenharmony_ci#include "qpeldsp.h" 30cabdff1aSopenharmony_ci#include "snow_dwt.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci#include "rangecoder.h" 33cabdff1aSopenharmony_ci#include "mathops.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci#include "mpegvideo.h" 36cabdff1aSopenharmony_ci#include "h264qpel.h" 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci#define SNOW_MAX_PLANES 4 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci#define FF_ME_ITER 3 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci#define MID_STATE 128 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci#define MAX_PLANES 4 45cabdff1aSopenharmony_ci#define QSHIFT 5 46cabdff1aSopenharmony_ci#define QROOT (1<<QSHIFT) 47cabdff1aSopenharmony_ci#define LOSSLESS_QLOG -128 48cabdff1aSopenharmony_ci#define FRAC_BITS 4 49cabdff1aSopenharmony_ci#define MAX_REF_FRAMES 8 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci#define LOG2_OBMC_MAX 8 52cabdff1aSopenharmony_ci#define OBMC_MAX (1<<(LOG2_OBMC_MAX)) 53cabdff1aSopenharmony_citypedef struct BlockNode{ 54cabdff1aSopenharmony_ci int16_t mx; ///< Motion vector component X, see mv_scale 55cabdff1aSopenharmony_ci int16_t my; ///< Motion vector component Y, see mv_scale 56cabdff1aSopenharmony_ci uint8_t ref; ///< Reference frame index 57cabdff1aSopenharmony_ci uint8_t color[3]; ///< Color for intra 58cabdff1aSopenharmony_ci uint8_t type; ///< Bitfield of BLOCK_* 59cabdff1aSopenharmony_ci//#define TYPE_SPLIT 1 60cabdff1aSopenharmony_ci#define BLOCK_INTRA 1 ///< Intra block, inter otherwise 61cabdff1aSopenharmony_ci#define BLOCK_OPT 2 ///< Block needs no checks in this round of iterative motion estiation 62cabdff1aSopenharmony_ci//#define TYPE_NOCOLOR 4 63cabdff1aSopenharmony_ci uint8_t level; //FIXME merge into type? 64cabdff1aSopenharmony_ci}BlockNode; 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_cistatic const BlockNode null_block= { //FIXME add border maybe 67cabdff1aSopenharmony_ci .color= {128,128,128}, 68cabdff1aSopenharmony_ci .mx= 0, 69cabdff1aSopenharmony_ci .my= 0, 70cabdff1aSopenharmony_ci .ref= 0, 71cabdff1aSopenharmony_ci .type= 0, 72cabdff1aSopenharmony_ci .level= 0, 73cabdff1aSopenharmony_ci}; 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci#define LOG2_MB_SIZE 4 76cabdff1aSopenharmony_ci#define MB_SIZE (1<<LOG2_MB_SIZE) 77cabdff1aSopenharmony_ci#define ENCODER_EXTRA_BITS 4 78cabdff1aSopenharmony_ci#define HTAPS_MAX 8 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_citypedef struct x_and_coeff{ 81cabdff1aSopenharmony_ci int16_t x; 82cabdff1aSopenharmony_ci uint16_t coeff; 83cabdff1aSopenharmony_ci} x_and_coeff; 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_citypedef struct SubBand{ 86cabdff1aSopenharmony_ci int level; 87cabdff1aSopenharmony_ci int stride; 88cabdff1aSopenharmony_ci int width; 89cabdff1aSopenharmony_ci int height; 90cabdff1aSopenharmony_ci int qlog; ///< log(qscale)/log[2^(1/6)] 91cabdff1aSopenharmony_ci DWTELEM *buf; 92cabdff1aSopenharmony_ci IDWTELEM *ibuf; 93cabdff1aSopenharmony_ci int buf_x_offset; 94cabdff1aSopenharmony_ci int buf_y_offset; 95cabdff1aSopenharmony_ci int stride_line; ///< Stride measured in lines, not pixels. 96cabdff1aSopenharmony_ci x_and_coeff * x_coeff; 97cabdff1aSopenharmony_ci struct SubBand *parent; 98cabdff1aSopenharmony_ci uint8_t state[/*7*2*/ 7 + 512][32]; 99cabdff1aSopenharmony_ci}SubBand; 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_citypedef struct Plane{ 102cabdff1aSopenharmony_ci int width; 103cabdff1aSopenharmony_ci int height; 104cabdff1aSopenharmony_ci SubBand band[MAX_DECOMPOSITIONS][4]; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci int htaps; 107cabdff1aSopenharmony_ci int8_t hcoeff[HTAPS_MAX/2]; 108cabdff1aSopenharmony_ci int diag_mc; 109cabdff1aSopenharmony_ci int fast_mc; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ci int last_htaps; 112cabdff1aSopenharmony_ci int8_t last_hcoeff[HTAPS_MAX/2]; 113cabdff1aSopenharmony_ci int last_diag_mc; 114cabdff1aSopenharmony_ci}Plane; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_citypedef struct SnowContext{ 117cabdff1aSopenharmony_ci AVClass *class; 118cabdff1aSopenharmony_ci AVCodecContext *avctx; 119cabdff1aSopenharmony_ci RangeCoder c; 120cabdff1aSopenharmony_ci MECmpContext mecc; 121cabdff1aSopenharmony_ci HpelDSPContext hdsp; 122cabdff1aSopenharmony_ci QpelDSPContext qdsp; 123cabdff1aSopenharmony_ci VideoDSPContext vdsp; 124cabdff1aSopenharmony_ci H264QpelContext h264qpel; 125cabdff1aSopenharmony_ci MpegvideoEncDSPContext mpvencdsp; 126cabdff1aSopenharmony_ci SnowDWTContext dwt; 127cabdff1aSopenharmony_ci AVFrame *input_picture; ///< new_picture with the internal linesizes 128cabdff1aSopenharmony_ci AVFrame *current_picture; 129cabdff1aSopenharmony_ci AVFrame *last_picture[MAX_REF_FRAMES]; 130cabdff1aSopenharmony_ci uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4]; 131cabdff1aSopenharmony_ci AVFrame *mconly_picture; 132cabdff1aSopenharmony_ci// uint8_t q_context[16]; 133cabdff1aSopenharmony_ci uint8_t header_state[32]; 134cabdff1aSopenharmony_ci uint8_t block_state[128 + 32*128]; 135cabdff1aSopenharmony_ci int keyframe; 136cabdff1aSopenharmony_ci int always_reset; 137cabdff1aSopenharmony_ci int version; 138cabdff1aSopenharmony_ci int spatial_decomposition_type; 139cabdff1aSopenharmony_ci int last_spatial_decomposition_type; 140cabdff1aSopenharmony_ci int temporal_decomposition_type; 141cabdff1aSopenharmony_ci int spatial_decomposition_count; 142cabdff1aSopenharmony_ci int last_spatial_decomposition_count; 143cabdff1aSopenharmony_ci int temporal_decomposition_count; 144cabdff1aSopenharmony_ci int max_ref_frames; 145cabdff1aSopenharmony_ci int ref_frames; 146cabdff1aSopenharmony_ci int16_t (*ref_mvs[MAX_REF_FRAMES])[2]; 147cabdff1aSopenharmony_ci uint32_t *ref_scores[MAX_REF_FRAMES]; 148cabdff1aSopenharmony_ci DWTELEM *spatial_dwt_buffer; 149cabdff1aSopenharmony_ci DWTELEM *temp_dwt_buffer; 150cabdff1aSopenharmony_ci IDWTELEM *spatial_idwt_buffer; 151cabdff1aSopenharmony_ci IDWTELEM *temp_idwt_buffer; 152cabdff1aSopenharmony_ci int *run_buffer; 153cabdff1aSopenharmony_ci int colorspace_type; 154cabdff1aSopenharmony_ci int chroma_h_shift; 155cabdff1aSopenharmony_ci int chroma_v_shift; 156cabdff1aSopenharmony_ci int spatial_scalability; 157cabdff1aSopenharmony_ci int qlog; 158cabdff1aSopenharmony_ci int last_qlog; 159cabdff1aSopenharmony_ci int lambda; 160cabdff1aSopenharmony_ci int lambda2; 161cabdff1aSopenharmony_ci int pass1_rc; 162cabdff1aSopenharmony_ci int mv_scale; 163cabdff1aSopenharmony_ci int last_mv_scale; 164cabdff1aSopenharmony_ci int qbias; 165cabdff1aSopenharmony_ci int last_qbias; 166cabdff1aSopenharmony_ci#define QBIAS_SHIFT 3 167cabdff1aSopenharmony_ci int b_width; 168cabdff1aSopenharmony_ci int b_height; 169cabdff1aSopenharmony_ci int block_max_depth; 170cabdff1aSopenharmony_ci int last_block_max_depth; 171cabdff1aSopenharmony_ci int nb_planes; 172cabdff1aSopenharmony_ci Plane plane[MAX_PLANES]; 173cabdff1aSopenharmony_ci BlockNode *block; 174cabdff1aSopenharmony_ci#define ME_CACHE_SIZE 1024 175cabdff1aSopenharmony_ci unsigned me_cache[ME_CACHE_SIZE]; 176cabdff1aSopenharmony_ci unsigned me_cache_generation; 177cabdff1aSopenharmony_ci slice_buffer sb; 178cabdff1aSopenharmony_ci int memc_only; 179cabdff1aSopenharmony_ci int no_bitstream; 180cabdff1aSopenharmony_ci int intra_penalty; 181cabdff1aSopenharmony_ci int motion_est; 182cabdff1aSopenharmony_ci int iterative_dia_size; 183cabdff1aSopenharmony_ci int scenechange_threshold; 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX) 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci uint8_t *scratchbuf; 188cabdff1aSopenharmony_ci uint8_t *emu_edge_buffer; 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_ci AVMotionVector *avmv; 191cabdff1aSopenharmony_ci unsigned avmv_size; 192cabdff1aSopenharmony_ci int avmv_index; 193cabdff1aSopenharmony_ci uint64_t encoding_error[SNOW_MAX_PLANES]; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci int pred; 196cabdff1aSopenharmony_ci}SnowContext; 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci/* Tables */ 199cabdff1aSopenharmony_ciextern const uint8_t * const ff_obmc_tab[4]; 200cabdff1aSopenharmony_ciextern const uint8_t ff_qexp[QROOT]; 201cabdff1aSopenharmony_ciextern int ff_scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES]; 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci/* C bits used by mmx/sse2/altivec */ 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_cistatic av_always_inline void snow_interleave_line_header(int * i, int width, IDWTELEM * low, IDWTELEM * high){ 206cabdff1aSopenharmony_ci (*i) = (width) - 2; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci if (width & 1){ 209cabdff1aSopenharmony_ci low[(*i)+1] = low[((*i)+1)>>1]; 210cabdff1aSopenharmony_ci (*i)--; 211cabdff1aSopenharmony_ci } 212cabdff1aSopenharmony_ci} 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_cistatic av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){ 215cabdff1aSopenharmony_ci for (; (*i)>=0; (*i)-=2){ 216cabdff1aSopenharmony_ci low[(*i)+1] = high[(*i)>>1]; 217cabdff1aSopenharmony_ci low[*i] = low[(*i)>>1]; 218cabdff1aSopenharmony_ci } 219cabdff1aSopenharmony_ci} 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_cistatic av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){ 222cabdff1aSopenharmony_ci for(; i<w; i++){ 223cabdff1aSopenharmony_ci dst[i] = src[i] - ((mul * (ref[i] + ref[i + 1]) + add) >> shift); 224cabdff1aSopenharmony_ci } 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci if((width^lift_high)&1){ 227cabdff1aSopenharmony_ci dst[w] = src[w] - ((mul * 2 * ref[w] + add) >> shift); 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci} 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_cistatic av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){ 232cabdff1aSopenharmony_ci for(; i<w; i++){ 233cabdff1aSopenharmony_ci dst[i] = src[i] + ((ref[i] + ref[(i+1)]+W_BO + 4 * src[i]) >> W_BS); 234cabdff1aSopenharmony_ci } 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci if(width&1){ 237cabdff1aSopenharmony_ci dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS); 238cabdff1aSopenharmony_ci } 239cabdff1aSopenharmony_ci} 240cabdff1aSopenharmony_ci 241cabdff1aSopenharmony_ci/* common code */ 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ciint ff_snow_common_init(AVCodecContext *avctx); 244cabdff1aSopenharmony_ciint ff_snow_common_init_after_header(AVCodecContext *avctx); 245cabdff1aSopenharmony_civoid ff_snow_common_end(SnowContext *s); 246cabdff1aSopenharmony_civoid ff_snow_release_buffer(AVCodecContext *avctx); 247cabdff1aSopenharmony_civoid ff_snow_reset_contexts(SnowContext *s); 248cabdff1aSopenharmony_ciint ff_snow_alloc_blocks(SnowContext *s); 249cabdff1aSopenharmony_ciint ff_snow_frame_start(SnowContext *s); 250cabdff1aSopenharmony_civoid ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, 251cabdff1aSopenharmony_ci int sx, int sy, int b_w, int b_h, const BlockNode *block, 252cabdff1aSopenharmony_ci int plane_index, int w, int h); 253cabdff1aSopenharmony_ciint ff_snow_get_buffer(SnowContext *s, AVFrame *frame); 254cabdff1aSopenharmony_ci/* common inline functions */ 255cabdff1aSopenharmony_ci//XXX doublecheck all of them should stay inlined 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_cistatic inline void pred_mv(SnowContext *s, int *mx, int *my, int ref, 258cabdff1aSopenharmony_ci const BlockNode *left, const BlockNode *top, const BlockNode *tr){ 259cabdff1aSopenharmony_ci if(s->ref_frames == 1){ 260cabdff1aSopenharmony_ci *mx = mid_pred(left->mx, top->mx, tr->mx); 261cabdff1aSopenharmony_ci *my = mid_pred(left->my, top->my, tr->my); 262cabdff1aSopenharmony_ci }else{ 263cabdff1aSopenharmony_ci const int *scale = ff_scale_mv_ref[ref]; 264cabdff1aSopenharmony_ci *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8, 265cabdff1aSopenharmony_ci (top ->mx * scale[top ->ref] + 128) >>8, 266cabdff1aSopenharmony_ci (tr ->mx * scale[tr ->ref] + 128) >>8); 267cabdff1aSopenharmony_ci *my = mid_pred((left->my * scale[left->ref] + 128) >>8, 268cabdff1aSopenharmony_ci (top ->my * scale[top ->ref] + 128) >>8, 269cabdff1aSopenharmony_ci (tr ->my * scale[tr ->ref] + 128) >>8); 270cabdff1aSopenharmony_ci } 271cabdff1aSopenharmony_ci} 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_cistatic av_always_inline int same_block(BlockNode *a, BlockNode *b){ 274cabdff1aSopenharmony_ci if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){ 275cabdff1aSopenharmony_ci return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2])); 276cabdff1aSopenharmony_ci }else{ 277cabdff1aSopenharmony_ci return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA)); 278cabdff1aSopenharmony_ci } 279cabdff1aSopenharmony_ci} 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci//FIXME name cleanup (b_w, block_w, b_width stuff) 282cabdff1aSopenharmony_ci//XXX should we really inline it? 283cabdff1aSopenharmony_cistatic av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){ 284cabdff1aSopenharmony_ci const int b_width = s->b_width << s->block_max_depth; 285cabdff1aSopenharmony_ci const int b_height= s->b_height << s->block_max_depth; 286cabdff1aSopenharmony_ci const int b_stride= b_width; 287cabdff1aSopenharmony_ci BlockNode *lt= &s->block[b_x + b_y*b_stride]; 288cabdff1aSopenharmony_ci BlockNode *rt= lt+1; 289cabdff1aSopenharmony_ci BlockNode *lb= lt+b_stride; 290cabdff1aSopenharmony_ci BlockNode *rb= lb+1; 291cabdff1aSopenharmony_ci uint8_t *block[4]; 292cabdff1aSopenharmony_ci // When src_stride is large enough, it is possible to interleave the blocks. 293cabdff1aSopenharmony_ci // Otherwise the blocks are written sequentially in the tmp buffer. 294cabdff1aSopenharmony_ci int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride; 295cabdff1aSopenharmony_ci uint8_t *tmp = s->scratchbuf; 296cabdff1aSopenharmony_ci uint8_t *ptmp; 297cabdff1aSopenharmony_ci int x,y; 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci if(b_x<0){ 300cabdff1aSopenharmony_ci lt= rt; 301cabdff1aSopenharmony_ci lb= rb; 302cabdff1aSopenharmony_ci }else if(b_x + 1 >= b_width){ 303cabdff1aSopenharmony_ci rt= lt; 304cabdff1aSopenharmony_ci rb= lb; 305cabdff1aSopenharmony_ci } 306cabdff1aSopenharmony_ci if(b_y<0){ 307cabdff1aSopenharmony_ci lt= lb; 308cabdff1aSopenharmony_ci rt= rb; 309cabdff1aSopenharmony_ci }else if(b_y + 1 >= b_height){ 310cabdff1aSopenharmony_ci lb= lt; 311cabdff1aSopenharmony_ci rb= rt; 312cabdff1aSopenharmony_ci } 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_ci if(src_x<0){ //FIXME merge with prev & always round internal width up to *16 315cabdff1aSopenharmony_ci obmc -= src_x; 316cabdff1aSopenharmony_ci b_w += src_x; 317cabdff1aSopenharmony_ci if(!sliced && !offset_dst) 318cabdff1aSopenharmony_ci dst -= src_x; 319cabdff1aSopenharmony_ci src_x=0; 320cabdff1aSopenharmony_ci } 321cabdff1aSopenharmony_ci if(src_x + b_w > w){ 322cabdff1aSopenharmony_ci b_w = w - src_x; 323cabdff1aSopenharmony_ci } 324cabdff1aSopenharmony_ci if(src_y<0){ 325cabdff1aSopenharmony_ci obmc -= src_y*obmc_stride; 326cabdff1aSopenharmony_ci b_h += src_y; 327cabdff1aSopenharmony_ci if(!sliced && !offset_dst) 328cabdff1aSopenharmony_ci dst -= src_y*dst_stride; 329cabdff1aSopenharmony_ci src_y=0; 330cabdff1aSopenharmony_ci } 331cabdff1aSopenharmony_ci if(src_y + b_h> h){ 332cabdff1aSopenharmony_ci b_h = h - src_y; 333cabdff1aSopenharmony_ci } 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci if(b_w<=0 || b_h<=0) return; 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci if(!sliced && offset_dst) 338cabdff1aSopenharmony_ci dst += src_x + src_y*dst_stride; 339cabdff1aSopenharmony_ci dst8+= src_x + src_y*src_stride; 340cabdff1aSopenharmony_ci// src += src_x + src_y*src_stride; 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci ptmp= tmp + 3*tmp_step; 343cabdff1aSopenharmony_ci block[0]= ptmp; 344cabdff1aSopenharmony_ci ptmp+=tmp_step; 345cabdff1aSopenharmony_ci ff_snow_pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ci if(same_block(lt, rt)){ 348cabdff1aSopenharmony_ci block[1]= block[0]; 349cabdff1aSopenharmony_ci }else{ 350cabdff1aSopenharmony_ci block[1]= ptmp; 351cabdff1aSopenharmony_ci ptmp+=tmp_step; 352cabdff1aSopenharmony_ci ff_snow_pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); 353cabdff1aSopenharmony_ci } 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci if(same_block(lt, lb)){ 356cabdff1aSopenharmony_ci block[2]= block[0]; 357cabdff1aSopenharmony_ci }else if(same_block(rt, lb)){ 358cabdff1aSopenharmony_ci block[2]= block[1]; 359cabdff1aSopenharmony_ci }else{ 360cabdff1aSopenharmony_ci block[2]= ptmp; 361cabdff1aSopenharmony_ci ptmp+=tmp_step; 362cabdff1aSopenharmony_ci ff_snow_pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); 363cabdff1aSopenharmony_ci } 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci if(same_block(lt, rb) ){ 366cabdff1aSopenharmony_ci block[3]= block[0]; 367cabdff1aSopenharmony_ci }else if(same_block(rt, rb)){ 368cabdff1aSopenharmony_ci block[3]= block[1]; 369cabdff1aSopenharmony_ci }else if(same_block(lb, rb)){ 370cabdff1aSopenharmony_ci block[3]= block[2]; 371cabdff1aSopenharmony_ci }else{ 372cabdff1aSopenharmony_ci block[3]= ptmp; 373cabdff1aSopenharmony_ci ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); 374cabdff1aSopenharmony_ci } 375cabdff1aSopenharmony_ci if(sliced){ 376cabdff1aSopenharmony_ci s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); 377cabdff1aSopenharmony_ci }else{ 378cabdff1aSopenharmony_ci for(y=0; y<b_h; y++){ 379cabdff1aSopenharmony_ci //FIXME ugly misuse of obmc_stride 380cabdff1aSopenharmony_ci const uint8_t *obmc1= obmc + y*obmc_stride; 381cabdff1aSopenharmony_ci const uint8_t *obmc2= obmc1+ (obmc_stride>>1); 382cabdff1aSopenharmony_ci const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); 383cabdff1aSopenharmony_ci const uint8_t *obmc4= obmc3+ (obmc_stride>>1); 384cabdff1aSopenharmony_ci for(x=0; x<b_w; x++){ 385cabdff1aSopenharmony_ci int v= obmc1[x] * block[3][x + y*src_stride] 386cabdff1aSopenharmony_ci +obmc2[x] * block[2][x + y*src_stride] 387cabdff1aSopenharmony_ci +obmc3[x] * block[1][x + y*src_stride] 388cabdff1aSopenharmony_ci +obmc4[x] * block[0][x + y*src_stride]; 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci v <<= 8 - LOG2_OBMC_MAX; 391cabdff1aSopenharmony_ci if(FRAC_BITS != 8){ 392cabdff1aSopenharmony_ci v >>= 8 - FRAC_BITS; 393cabdff1aSopenharmony_ci } 394cabdff1aSopenharmony_ci if(add){ 395cabdff1aSopenharmony_ci v += dst[x + y*dst_stride]; 396cabdff1aSopenharmony_ci v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS; 397cabdff1aSopenharmony_ci if(v&(~255)) v= ~(v>>31); 398cabdff1aSopenharmony_ci dst8[x + y*src_stride] = v; 399cabdff1aSopenharmony_ci }else{ 400cabdff1aSopenharmony_ci dst[x + y*dst_stride] -= v; 401cabdff1aSopenharmony_ci } 402cabdff1aSopenharmony_ci } 403cabdff1aSopenharmony_ci } 404cabdff1aSopenharmony_ci } 405cabdff1aSopenharmony_ci} 406cabdff1aSopenharmony_ci 407cabdff1aSopenharmony_cistatic av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){ 408cabdff1aSopenharmony_ci Plane *p= &s->plane[plane_index]; 409cabdff1aSopenharmony_ci const int mb_w= s->b_width << s->block_max_depth; 410cabdff1aSopenharmony_ci const int mb_h= s->b_height << s->block_max_depth; 411cabdff1aSopenharmony_ci int x, y, mb_x; 412cabdff1aSopenharmony_ci int block_size = MB_SIZE >> s->block_max_depth; 413cabdff1aSopenharmony_ci int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size; 414cabdff1aSopenharmony_ci int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size; 415cabdff1aSopenharmony_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]; 416cabdff1aSopenharmony_ci const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size; 417cabdff1aSopenharmony_ci int ref_stride= s->current_picture->linesize[plane_index]; 418cabdff1aSopenharmony_ci uint8_t *dst8= s->current_picture->data[plane_index]; 419cabdff1aSopenharmony_ci int w= p->width; 420cabdff1aSopenharmony_ci int h= p->height; 421cabdff1aSopenharmony_ci av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares 422cabdff1aSopenharmony_ci if(s->keyframe || (s->avctx->debug&512)){ 423cabdff1aSopenharmony_ci if(mb_y==mb_h) 424cabdff1aSopenharmony_ci return; 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_ci if(add){ 427cabdff1aSopenharmony_ci for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){ 428cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 429cabdff1aSopenharmony_ci int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1)); 430cabdff1aSopenharmony_ci v >>= FRAC_BITS; 431cabdff1aSopenharmony_ci if(v&(~255)) v= ~(v>>31); 432cabdff1aSopenharmony_ci dst8[x + y*ref_stride]= v; 433cabdff1aSopenharmony_ci } 434cabdff1aSopenharmony_ci } 435cabdff1aSopenharmony_ci }else{ 436cabdff1aSopenharmony_ci for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){ 437cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 438cabdff1aSopenharmony_ci buf[x + y*w]-= 128<<FRAC_BITS; 439cabdff1aSopenharmony_ci } 440cabdff1aSopenharmony_ci } 441cabdff1aSopenharmony_ci } 442cabdff1aSopenharmony_ci 443cabdff1aSopenharmony_ci return; 444cabdff1aSopenharmony_ci } 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci for(mb_x=0; mb_x<=mb_w; mb_x++){ 447cabdff1aSopenharmony_ci add_yblock(s, 0, NULL, buf, dst8, obmc, 448cabdff1aSopenharmony_ci block_w*mb_x - block_w/2, 449cabdff1aSopenharmony_ci block_h*mb_y - block_h/2, 450cabdff1aSopenharmony_ci block_w, block_h, 451cabdff1aSopenharmony_ci w, h, 452cabdff1aSopenharmony_ci w, ref_stride, obmc_stride, 453cabdff1aSopenharmony_ci mb_x - 1, mb_y - 1, 454cabdff1aSopenharmony_ci add, 1, plane_index); 455cabdff1aSopenharmony_ci } 456cabdff1aSopenharmony_ci} 457cabdff1aSopenharmony_ci 458cabdff1aSopenharmony_cistatic av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){ 459cabdff1aSopenharmony_ci const int mb_h= s->b_height << s->block_max_depth; 460cabdff1aSopenharmony_ci int mb_y; 461cabdff1aSopenharmony_ci for(mb_y=0; mb_y<=mb_h; mb_y++) 462cabdff1aSopenharmony_ci predict_slice(s, buf, plane_index, add, mb_y); 463cabdff1aSopenharmony_ci} 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_cistatic inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){ 466cabdff1aSopenharmony_ci const int w= s->b_width << s->block_max_depth; 467cabdff1aSopenharmony_ci const int rem_depth= s->block_max_depth - level; 468cabdff1aSopenharmony_ci const int index= (x + y*w) << rem_depth; 469cabdff1aSopenharmony_ci const int block_w= 1<<rem_depth; 470cabdff1aSopenharmony_ci const int block_h= 1<<rem_depth; //FIXME "w!=h" 471cabdff1aSopenharmony_ci BlockNode block; 472cabdff1aSopenharmony_ci int i,j; 473cabdff1aSopenharmony_ci 474cabdff1aSopenharmony_ci block.color[0]= l; 475cabdff1aSopenharmony_ci block.color[1]= cb; 476cabdff1aSopenharmony_ci block.color[2]= cr; 477cabdff1aSopenharmony_ci block.mx= mx; 478cabdff1aSopenharmony_ci block.my= my; 479cabdff1aSopenharmony_ci block.ref= ref; 480cabdff1aSopenharmony_ci block.type= type; 481cabdff1aSopenharmony_ci block.level= level; 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_ci for(j=0; j<block_h; j++){ 484cabdff1aSopenharmony_ci for(i=0; i<block_w; i++){ 485cabdff1aSopenharmony_ci s->block[index + i + j*w]= block; 486cabdff1aSopenharmony_ci } 487cabdff1aSopenharmony_ci } 488cabdff1aSopenharmony_ci} 489cabdff1aSopenharmony_ci 490cabdff1aSopenharmony_cistatic inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){ 491cabdff1aSopenharmony_ci SnowContext *s = c->avctx->priv_data; 492cabdff1aSopenharmony_ci const int offset[3]= { 493cabdff1aSopenharmony_ci y*c-> stride + x, 494cabdff1aSopenharmony_ci ((y*c->uvstride + x)>>s->chroma_h_shift), 495cabdff1aSopenharmony_ci ((y*c->uvstride + x)>>s->chroma_h_shift), 496cabdff1aSopenharmony_ci }; 497cabdff1aSopenharmony_ci int i; 498cabdff1aSopenharmony_ci for(i=0; i<3; i++){ 499cabdff1aSopenharmony_ci c->src[0][i]= src [i]; 500cabdff1aSopenharmony_ci c->ref[0][i]= ref [i] + offset[i]; 501cabdff1aSopenharmony_ci } 502cabdff1aSopenharmony_ci av_assert2(!ref_index); 503cabdff1aSopenharmony_ci} 504cabdff1aSopenharmony_ci 505cabdff1aSopenharmony_ci 506cabdff1aSopenharmony_ci/* bitstream functions */ 507cabdff1aSopenharmony_ci 508cabdff1aSopenharmony_ciextern const int8_t ff_quant3bA[256]; 509cabdff1aSopenharmony_ci 510cabdff1aSopenharmony_ci#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0 511cabdff1aSopenharmony_ci 512cabdff1aSopenharmony_cistatic inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ 513cabdff1aSopenharmony_ci int i; 514cabdff1aSopenharmony_ci 515cabdff1aSopenharmony_ci if(v){ 516cabdff1aSopenharmony_ci const int a= FFABS(v); 517cabdff1aSopenharmony_ci const int e= av_log2(a); 518cabdff1aSopenharmony_ci const int el= FFMIN(e, 10); 519cabdff1aSopenharmony_ci put_rac(c, state+0, 0); 520cabdff1aSopenharmony_ci 521cabdff1aSopenharmony_ci for(i=0; i<el; i++){ 522cabdff1aSopenharmony_ci put_rac(c, state+1+i, 1); //1..10 523cabdff1aSopenharmony_ci } 524cabdff1aSopenharmony_ci for(; i<e; i++){ 525cabdff1aSopenharmony_ci put_rac(c, state+1+9, 1); //1..10 526cabdff1aSopenharmony_ci } 527cabdff1aSopenharmony_ci put_rac(c, state+1+FFMIN(i,9), 0); 528cabdff1aSopenharmony_ci 529cabdff1aSopenharmony_ci for(i=e-1; i>=el; i--){ 530cabdff1aSopenharmony_ci put_rac(c, state+22+9, (a>>i)&1); //22..31 531cabdff1aSopenharmony_ci } 532cabdff1aSopenharmony_ci for(; i>=0; i--){ 533cabdff1aSopenharmony_ci put_rac(c, state+22+i, (a>>i)&1); //22..31 534cabdff1aSopenharmony_ci } 535cabdff1aSopenharmony_ci 536cabdff1aSopenharmony_ci if(is_signed) 537cabdff1aSopenharmony_ci put_rac(c, state+11 + el, v < 0); //11..21 538cabdff1aSopenharmony_ci }else{ 539cabdff1aSopenharmony_ci put_rac(c, state+0, 1); 540cabdff1aSopenharmony_ci } 541cabdff1aSopenharmony_ci} 542cabdff1aSopenharmony_ci 543cabdff1aSopenharmony_cistatic inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ 544cabdff1aSopenharmony_ci if(get_rac(c, state+0)) 545cabdff1aSopenharmony_ci return 0; 546cabdff1aSopenharmony_ci else{ 547cabdff1aSopenharmony_ci int i, e; 548cabdff1aSopenharmony_ci unsigned a; 549cabdff1aSopenharmony_ci e= 0; 550cabdff1aSopenharmony_ci while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 551cabdff1aSopenharmony_ci e++; 552cabdff1aSopenharmony_ci if (e > 31) 553cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 554cabdff1aSopenharmony_ci } 555cabdff1aSopenharmony_ci 556cabdff1aSopenharmony_ci a= 1; 557cabdff1aSopenharmony_ci for(i=e-1; i>=0; i--){ 558cabdff1aSopenharmony_ci a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 559cabdff1aSopenharmony_ci } 560cabdff1aSopenharmony_ci 561cabdff1aSopenharmony_ci e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21 562cabdff1aSopenharmony_ci return (a^e)-e; 563cabdff1aSopenharmony_ci } 564cabdff1aSopenharmony_ci} 565cabdff1aSopenharmony_ci 566cabdff1aSopenharmony_cistatic inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){ 567cabdff1aSopenharmony_ci int i; 568cabdff1aSopenharmony_ci int r= log2>=0 ? 1<<log2 : 1; 569cabdff1aSopenharmony_ci 570cabdff1aSopenharmony_ci av_assert2(v>=0); 571cabdff1aSopenharmony_ci av_assert2(log2>=-4); 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci while(v >= r){ 574cabdff1aSopenharmony_ci put_rac(c, state+4+log2, 1); 575cabdff1aSopenharmony_ci v -= r; 576cabdff1aSopenharmony_ci log2++; 577cabdff1aSopenharmony_ci if(log2>0) r+=r; 578cabdff1aSopenharmony_ci } 579cabdff1aSopenharmony_ci put_rac(c, state+4+log2, 0); 580cabdff1aSopenharmony_ci 581cabdff1aSopenharmony_ci for(i=log2-1; i>=0; i--){ 582cabdff1aSopenharmony_ci put_rac(c, state+31-i, (v>>i)&1); 583cabdff1aSopenharmony_ci } 584cabdff1aSopenharmony_ci} 585cabdff1aSopenharmony_ci 586cabdff1aSopenharmony_cistatic inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){ 587cabdff1aSopenharmony_ci int i; 588cabdff1aSopenharmony_ci int r= log2>=0 ? 1<<log2 : 1; 589cabdff1aSopenharmony_ci int v=0; 590cabdff1aSopenharmony_ci 591cabdff1aSopenharmony_ci av_assert2(log2>=-4); 592cabdff1aSopenharmony_ci 593cabdff1aSopenharmony_ci while(log2<28 && get_rac(c, state+4+log2)){ 594cabdff1aSopenharmony_ci v+= r; 595cabdff1aSopenharmony_ci log2++; 596cabdff1aSopenharmony_ci if(log2>0) r+=r; 597cabdff1aSopenharmony_ci } 598cabdff1aSopenharmony_ci 599cabdff1aSopenharmony_ci for(i=log2-1; i>=0; i--){ 600cabdff1aSopenharmony_ci v+= get_rac(c, state+31-i)<<i; 601cabdff1aSopenharmony_ci } 602cabdff1aSopenharmony_ci 603cabdff1aSopenharmony_ci return v; 604cabdff1aSopenharmony_ci} 605cabdff1aSopenharmony_ci 606cabdff1aSopenharmony_cistatic inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){ 607cabdff1aSopenharmony_ci const int w= b->width; 608cabdff1aSopenharmony_ci const int h= b->height; 609cabdff1aSopenharmony_ci int x,y; 610cabdff1aSopenharmony_ci 611cabdff1aSopenharmony_ci int run, runs; 612cabdff1aSopenharmony_ci x_and_coeff *xc= b->x_coeff; 613cabdff1aSopenharmony_ci x_and_coeff *prev_xc= NULL; 614cabdff1aSopenharmony_ci x_and_coeff *prev2_xc= xc; 615cabdff1aSopenharmony_ci x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL; 616cabdff1aSopenharmony_ci x_and_coeff *prev_parent_xc= parent_xc; 617cabdff1aSopenharmony_ci 618cabdff1aSopenharmony_ci runs= get_symbol2(&s->c, b->state[30], 0); 619cabdff1aSopenharmony_ci if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3); 620cabdff1aSopenharmony_ci else run= INT_MAX; 621cabdff1aSopenharmony_ci 622cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 623cabdff1aSopenharmony_ci int v=0; 624cabdff1aSopenharmony_ci int lt=0, t=0, rt=0; 625cabdff1aSopenharmony_ci 626cabdff1aSopenharmony_ci if(y && prev_xc->x == 0){ 627cabdff1aSopenharmony_ci rt= prev_xc->coeff; 628cabdff1aSopenharmony_ci } 629cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 630cabdff1aSopenharmony_ci int p=0; 631cabdff1aSopenharmony_ci const int l= v; 632cabdff1aSopenharmony_ci 633cabdff1aSopenharmony_ci lt= t; t= rt; 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_ci if(y){ 636cabdff1aSopenharmony_ci if(prev_xc->x <= x) 637cabdff1aSopenharmony_ci prev_xc++; 638cabdff1aSopenharmony_ci if(prev_xc->x == x + 1) 639cabdff1aSopenharmony_ci rt= prev_xc->coeff; 640cabdff1aSopenharmony_ci else 641cabdff1aSopenharmony_ci rt=0; 642cabdff1aSopenharmony_ci } 643cabdff1aSopenharmony_ci if(parent_xc){ 644cabdff1aSopenharmony_ci if(x>>1 > parent_xc->x){ 645cabdff1aSopenharmony_ci parent_xc++; 646cabdff1aSopenharmony_ci } 647cabdff1aSopenharmony_ci if(x>>1 == parent_xc->x){ 648cabdff1aSopenharmony_ci p= parent_xc->coeff; 649cabdff1aSopenharmony_ci } 650cabdff1aSopenharmony_ci } 651cabdff1aSopenharmony_ci if(/*ll|*/l|lt|t|rt|p){ 652cabdff1aSopenharmony_ci int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1)); 653cabdff1aSopenharmony_ci 654cabdff1aSopenharmony_ci v=get_rac(&s->c, &b->state[0][context]); 655cabdff1aSopenharmony_ci if(v){ 656cabdff1aSopenharmony_ci v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1); 657cabdff1aSopenharmony_ci v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]); 658cabdff1aSopenharmony_ci if ((uint16_t)v != v) { 659cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n"); 660cabdff1aSopenharmony_ci v = 1; 661cabdff1aSopenharmony_ci } 662cabdff1aSopenharmony_ci xc->x=x; 663cabdff1aSopenharmony_ci (xc++)->coeff= v; 664cabdff1aSopenharmony_ci } 665cabdff1aSopenharmony_ci }else{ 666cabdff1aSopenharmony_ci if(!run){ 667cabdff1aSopenharmony_ci if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3); 668cabdff1aSopenharmony_ci else run= INT_MAX; 669cabdff1aSopenharmony_ci v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1); 670cabdff1aSopenharmony_ci v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]); 671cabdff1aSopenharmony_ci if ((uint16_t)v != v) { 672cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n"); 673cabdff1aSopenharmony_ci v = 1; 674cabdff1aSopenharmony_ci } 675cabdff1aSopenharmony_ci 676cabdff1aSopenharmony_ci xc->x=x; 677cabdff1aSopenharmony_ci (xc++)->coeff= v; 678cabdff1aSopenharmony_ci }else{ 679cabdff1aSopenharmony_ci int max_run; 680cabdff1aSopenharmony_ci run--; 681cabdff1aSopenharmony_ci v=0; 682cabdff1aSopenharmony_ci av_assert2(run >= 0); 683cabdff1aSopenharmony_ci if(y) max_run= FFMIN(run, prev_xc->x - x - 2); 684cabdff1aSopenharmony_ci else max_run= FFMIN(run, w-x-1); 685cabdff1aSopenharmony_ci if(parent_xc) 686cabdff1aSopenharmony_ci max_run= FFMIN(max_run, 2*parent_xc->x - x - 1); 687cabdff1aSopenharmony_ci av_assert2(max_run >= 0 && max_run <= run); 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_ci x+= max_run; 690cabdff1aSopenharmony_ci run-= max_run; 691cabdff1aSopenharmony_ci } 692cabdff1aSopenharmony_ci } 693cabdff1aSopenharmony_ci } 694cabdff1aSopenharmony_ci (xc++)->x= w+1; //end marker 695cabdff1aSopenharmony_ci prev_xc= prev2_xc; 696cabdff1aSopenharmony_ci prev2_xc= xc; 697cabdff1aSopenharmony_ci 698cabdff1aSopenharmony_ci if(parent_xc){ 699cabdff1aSopenharmony_ci if(y&1){ 700cabdff1aSopenharmony_ci while(parent_xc->x != parent->width+1) 701cabdff1aSopenharmony_ci parent_xc++; 702cabdff1aSopenharmony_ci parent_xc++; 703cabdff1aSopenharmony_ci prev_parent_xc= parent_xc; 704cabdff1aSopenharmony_ci }else{ 705cabdff1aSopenharmony_ci parent_xc= prev_parent_xc; 706cabdff1aSopenharmony_ci } 707cabdff1aSopenharmony_ci } 708cabdff1aSopenharmony_ci } 709cabdff1aSopenharmony_ci 710cabdff1aSopenharmony_ci (xc++)->x= w+1; //end marker 711cabdff1aSopenharmony_ci} 712cabdff1aSopenharmony_ci 713cabdff1aSopenharmony_ci#endif /* AVCODEC_SNOW_H */ 714