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/log.h" 23cabdff1aSopenharmony_ci#include "libavutil/opt.h" 24cabdff1aSopenharmony_ci#include "libavutil/thread.h" 25cabdff1aSopenharmony_ci#include "avcodec.h" 26cabdff1aSopenharmony_ci#include "encode.h" 27cabdff1aSopenharmony_ci#include "me_cmp.h" 28cabdff1aSopenharmony_ci#include "snow_dwt.h" 29cabdff1aSopenharmony_ci#include "internal.h" 30cabdff1aSopenharmony_ci#include "snow.h" 31cabdff1aSopenharmony_ci#include "snowdata.h" 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "rangecoder.h" 34cabdff1aSopenharmony_ci#include "mathops.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_civoid ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, 38cabdff1aSopenharmony_ci int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ 39cabdff1aSopenharmony_ci int y, x; 40cabdff1aSopenharmony_ci IDWTELEM * dst; 41cabdff1aSopenharmony_ci for(y=0; y<b_h; y++){ 42cabdff1aSopenharmony_ci //FIXME ugly misuse of obmc_stride 43cabdff1aSopenharmony_ci const uint8_t *obmc1= obmc + y*obmc_stride; 44cabdff1aSopenharmony_ci const uint8_t *obmc2= obmc1+ (obmc_stride>>1); 45cabdff1aSopenharmony_ci const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); 46cabdff1aSopenharmony_ci const uint8_t *obmc4= obmc3+ (obmc_stride>>1); 47cabdff1aSopenharmony_ci dst = slice_buffer_get_line(sb, src_y + y); 48cabdff1aSopenharmony_ci for(x=0; x<b_w; x++){ 49cabdff1aSopenharmony_ci int v= obmc1[x] * block[3][x + y*src_stride] 50cabdff1aSopenharmony_ci +obmc2[x] * block[2][x + y*src_stride] 51cabdff1aSopenharmony_ci +obmc3[x] * block[1][x + y*src_stride] 52cabdff1aSopenharmony_ci +obmc4[x] * block[0][x + y*src_stride]; 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci v <<= 8 - LOG2_OBMC_MAX; 55cabdff1aSopenharmony_ci if(FRAC_BITS != 8){ 56cabdff1aSopenharmony_ci v >>= 8 - FRAC_BITS; 57cabdff1aSopenharmony_ci } 58cabdff1aSopenharmony_ci if(add){ 59cabdff1aSopenharmony_ci v += dst[x + src_x]; 60cabdff1aSopenharmony_ci v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS; 61cabdff1aSopenharmony_ci if(v&(~255)) v= ~(v>>31); 62cabdff1aSopenharmony_ci dst8[x + y*src_stride] = v; 63cabdff1aSopenharmony_ci }else{ 64cabdff1aSopenharmony_ci dst[x + src_x] -= v; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci } 67cabdff1aSopenharmony_ci } 68cabdff1aSopenharmony_ci} 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ciint ff_snow_get_buffer(SnowContext *s, AVFrame *frame) 71cabdff1aSopenharmony_ci{ 72cabdff1aSopenharmony_ci int ret, i; 73cabdff1aSopenharmony_ci int edges_needed = av_codec_is_encoder(s->avctx->codec); 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci frame->width = s->avctx->width ; 76cabdff1aSopenharmony_ci frame->height = s->avctx->height; 77cabdff1aSopenharmony_ci if (edges_needed) { 78cabdff1aSopenharmony_ci frame->width += 2 * EDGE_WIDTH; 79cabdff1aSopenharmony_ci frame->height += 2 * EDGE_WIDTH; 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci ret = ff_encode_alloc_frame(s->avctx, frame); 82cabdff1aSopenharmony_ci } else 83cabdff1aSopenharmony_ci ret = ff_get_buffer(s->avctx, frame, AV_GET_BUFFER_FLAG_REF); 84cabdff1aSopenharmony_ci if (ret < 0) 85cabdff1aSopenharmony_ci return ret; 86cabdff1aSopenharmony_ci if (edges_needed) { 87cabdff1aSopenharmony_ci for (i = 0; frame->data[i]; i++) { 88cabdff1aSopenharmony_ci int offset = (EDGE_WIDTH >> (i ? s->chroma_v_shift : 0)) * 89cabdff1aSopenharmony_ci frame->linesize[i] + 90cabdff1aSopenharmony_ci (EDGE_WIDTH >> (i ? s->chroma_h_shift : 0)); 91cabdff1aSopenharmony_ci frame->data[i] += offset; 92cabdff1aSopenharmony_ci } 93cabdff1aSopenharmony_ci frame->width = s->avctx->width; 94cabdff1aSopenharmony_ci frame->height = s->avctx->height; 95cabdff1aSopenharmony_ci } 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci return 0; 98cabdff1aSopenharmony_ci} 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_civoid ff_snow_reset_contexts(SnowContext *s){ //FIXME better initial contexts 101cabdff1aSopenharmony_ci int plane_index, level, orientation; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci for(plane_index=0; plane_index<3; plane_index++){ 104cabdff1aSopenharmony_ci for(level=0; level<MAX_DECOMPOSITIONS; level++){ 105cabdff1aSopenharmony_ci for(orientation=level ? 1:0; orientation<4; orientation++){ 106cabdff1aSopenharmony_ci memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state)); 107cabdff1aSopenharmony_ci } 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci } 110cabdff1aSopenharmony_ci memset(s->header_state, MID_STATE, sizeof(s->header_state)); 111cabdff1aSopenharmony_ci memset(s->block_state, MID_STATE, sizeof(s->block_state)); 112cabdff1aSopenharmony_ci} 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ciint ff_snow_alloc_blocks(SnowContext *s){ 115cabdff1aSopenharmony_ci int w= AV_CEIL_RSHIFT(s->avctx->width, LOG2_MB_SIZE); 116cabdff1aSopenharmony_ci int h= AV_CEIL_RSHIFT(s->avctx->height, LOG2_MB_SIZE); 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci s->b_width = w; 119cabdff1aSopenharmony_ci s->b_height= h; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci av_free(s->block); 122cabdff1aSopenharmony_ci s->block = av_calloc(w * h, sizeof(*s->block) << (s->block_max_depth*2)); 123cabdff1aSopenharmony_ci if (!s->block) 124cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci return 0; 127cabdff1aSopenharmony_ci} 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_cistatic void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int b_w, int b_h, int dx, int dy){ 130cabdff1aSopenharmony_ci static const uint8_t weight[64]={ 131cabdff1aSopenharmony_ci 8,7,6,5,4,3,2,1, 132cabdff1aSopenharmony_ci 7,7,0,0,0,0,0,1, 133cabdff1aSopenharmony_ci 6,0,6,0,0,0,2,0, 134cabdff1aSopenharmony_ci 5,0,0,5,0,3,0,0, 135cabdff1aSopenharmony_ci 4,0,0,0,4,0,0,0, 136cabdff1aSopenharmony_ci 3,0,0,5,0,3,0,0, 137cabdff1aSopenharmony_ci 2,0,6,0,0,0,2,0, 138cabdff1aSopenharmony_ci 1,7,0,0,0,0,0,1, 139cabdff1aSopenharmony_ci }; 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci static const uint8_t brane[256]={ 142cabdff1aSopenharmony_ci 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x11,0x12,0x12,0x12,0x12,0x12,0x12,0x12, 143cabdff1aSopenharmony_ci 0x04,0x05,0xcc,0xcc,0xcc,0xcc,0xcc,0x41,0x15,0x16,0xcc,0xcc,0xcc,0xcc,0xcc,0x52, 144cabdff1aSopenharmony_ci 0x04,0xcc,0x05,0xcc,0xcc,0xcc,0x41,0xcc,0x15,0xcc,0x16,0xcc,0xcc,0xcc,0x52,0xcc, 145cabdff1aSopenharmony_ci 0x04,0xcc,0xcc,0x05,0xcc,0x41,0xcc,0xcc,0x15,0xcc,0xcc,0x16,0xcc,0x52,0xcc,0xcc, 146cabdff1aSopenharmony_ci 0x04,0xcc,0xcc,0xcc,0x41,0xcc,0xcc,0xcc,0x15,0xcc,0xcc,0xcc,0x16,0xcc,0xcc,0xcc, 147cabdff1aSopenharmony_ci 0x04,0xcc,0xcc,0x41,0xcc,0x05,0xcc,0xcc,0x15,0xcc,0xcc,0x52,0xcc,0x16,0xcc,0xcc, 148cabdff1aSopenharmony_ci 0x04,0xcc,0x41,0xcc,0xcc,0xcc,0x05,0xcc,0x15,0xcc,0x52,0xcc,0xcc,0xcc,0x16,0xcc, 149cabdff1aSopenharmony_ci 0x04,0x41,0xcc,0xcc,0xcc,0xcc,0xcc,0x05,0x15,0x52,0xcc,0xcc,0xcc,0xcc,0xcc,0x16, 150cabdff1aSopenharmony_ci 0x44,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x55,0x56,0x56,0x56,0x56,0x56,0x56,0x56, 151cabdff1aSopenharmony_ci 0x48,0x49,0xcc,0xcc,0xcc,0xcc,0xcc,0x85,0x59,0x5A,0xcc,0xcc,0xcc,0xcc,0xcc,0x96, 152cabdff1aSopenharmony_ci 0x48,0xcc,0x49,0xcc,0xcc,0xcc,0x85,0xcc,0x59,0xcc,0x5A,0xcc,0xcc,0xcc,0x96,0xcc, 153cabdff1aSopenharmony_ci 0x48,0xcc,0xcc,0x49,0xcc,0x85,0xcc,0xcc,0x59,0xcc,0xcc,0x5A,0xcc,0x96,0xcc,0xcc, 154cabdff1aSopenharmony_ci 0x48,0xcc,0xcc,0xcc,0x49,0xcc,0xcc,0xcc,0x59,0xcc,0xcc,0xcc,0x96,0xcc,0xcc,0xcc, 155cabdff1aSopenharmony_ci 0x48,0xcc,0xcc,0x85,0xcc,0x49,0xcc,0xcc,0x59,0xcc,0xcc,0x96,0xcc,0x5A,0xcc,0xcc, 156cabdff1aSopenharmony_ci 0x48,0xcc,0x85,0xcc,0xcc,0xcc,0x49,0xcc,0x59,0xcc,0x96,0xcc,0xcc,0xcc,0x5A,0xcc, 157cabdff1aSopenharmony_ci 0x48,0x85,0xcc,0xcc,0xcc,0xcc,0xcc,0x49,0x59,0x96,0xcc,0xcc,0xcc,0xcc,0xcc,0x5A, 158cabdff1aSopenharmony_ci }; 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci static const uint8_t needs[16]={ 161cabdff1aSopenharmony_ci 0,1,0,0, 162cabdff1aSopenharmony_ci 2,4,2,0, 163cabdff1aSopenharmony_ci 0,1,0,0, 164cabdff1aSopenharmony_ci 15 165cabdff1aSopenharmony_ci }; 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_ci int x, y, b, r, l; 168cabdff1aSopenharmony_ci int16_t tmpIt [64*(32+HTAPS_MAX)]; 169cabdff1aSopenharmony_ci uint8_t tmp2t[3][64*(32+HTAPS_MAX)]; 170cabdff1aSopenharmony_ci int16_t *tmpI= tmpIt; 171cabdff1aSopenharmony_ci uint8_t *tmp2= tmp2t[0]; 172cabdff1aSopenharmony_ci const uint8_t *hpel[11]; 173cabdff1aSopenharmony_ci av_assert2(dx<16 && dy<16); 174cabdff1aSopenharmony_ci r= brane[dx + 16*dy]&15; 175cabdff1aSopenharmony_ci l= brane[dx + 16*dy]>>4; 176cabdff1aSopenharmony_ci 177cabdff1aSopenharmony_ci b= needs[l] | needs[r]; 178cabdff1aSopenharmony_ci if(p && !p->diag_mc) 179cabdff1aSopenharmony_ci b= 15; 180cabdff1aSopenharmony_ci 181cabdff1aSopenharmony_ci if(b&5){ 182cabdff1aSopenharmony_ci for(y=0; y < b_h+HTAPS_MAX-1; y++){ 183cabdff1aSopenharmony_ci for(x=0; x < b_w; x++){ 184cabdff1aSopenharmony_ci int a_1=src[x + HTAPS_MAX/2-4]; 185cabdff1aSopenharmony_ci int a0= src[x + HTAPS_MAX/2-3]; 186cabdff1aSopenharmony_ci int a1= src[x + HTAPS_MAX/2-2]; 187cabdff1aSopenharmony_ci int a2= src[x + HTAPS_MAX/2-1]; 188cabdff1aSopenharmony_ci int a3= src[x + HTAPS_MAX/2+0]; 189cabdff1aSopenharmony_ci int a4= src[x + HTAPS_MAX/2+1]; 190cabdff1aSopenharmony_ci int a5= src[x + HTAPS_MAX/2+2]; 191cabdff1aSopenharmony_ci int a6= src[x + HTAPS_MAX/2+3]; 192cabdff1aSopenharmony_ci int am=0; 193cabdff1aSopenharmony_ci if(!p || p->fast_mc){ 194cabdff1aSopenharmony_ci am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5); 195cabdff1aSopenharmony_ci tmpI[x]= am; 196cabdff1aSopenharmony_ci am= (am+16)>>5; 197cabdff1aSopenharmony_ci }else{ 198cabdff1aSopenharmony_ci am= p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6); 199cabdff1aSopenharmony_ci tmpI[x]= am; 200cabdff1aSopenharmony_ci am= (am+32)>>6; 201cabdff1aSopenharmony_ci } 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci if(am&(~255)) am= ~(am>>31); 204cabdff1aSopenharmony_ci tmp2[x]= am; 205cabdff1aSopenharmony_ci } 206cabdff1aSopenharmony_ci tmpI+= 64; 207cabdff1aSopenharmony_ci tmp2+= 64; 208cabdff1aSopenharmony_ci src += stride; 209cabdff1aSopenharmony_ci } 210cabdff1aSopenharmony_ci src -= stride*y; 211cabdff1aSopenharmony_ci } 212cabdff1aSopenharmony_ci src += HTAPS_MAX/2 - 1; 213cabdff1aSopenharmony_ci tmp2= tmp2t[1]; 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci if(b&2){ 216cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 217cabdff1aSopenharmony_ci for(x=0; x < b_w+1; x++){ 218cabdff1aSopenharmony_ci int a_1=src[x + (HTAPS_MAX/2-4)*stride]; 219cabdff1aSopenharmony_ci int a0= src[x + (HTAPS_MAX/2-3)*stride]; 220cabdff1aSopenharmony_ci int a1= src[x + (HTAPS_MAX/2-2)*stride]; 221cabdff1aSopenharmony_ci int a2= src[x + (HTAPS_MAX/2-1)*stride]; 222cabdff1aSopenharmony_ci int a3= src[x + (HTAPS_MAX/2+0)*stride]; 223cabdff1aSopenharmony_ci int a4= src[x + (HTAPS_MAX/2+1)*stride]; 224cabdff1aSopenharmony_ci int a5= src[x + (HTAPS_MAX/2+2)*stride]; 225cabdff1aSopenharmony_ci int a6= src[x + (HTAPS_MAX/2+3)*stride]; 226cabdff1aSopenharmony_ci int am=0; 227cabdff1aSopenharmony_ci if(!p || p->fast_mc) 228cabdff1aSopenharmony_ci am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 16)>>5; 229cabdff1aSopenharmony_ci else 230cabdff1aSopenharmony_ci am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 32)>>6; 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci if(am&(~255)) am= ~(am>>31); 233cabdff1aSopenharmony_ci tmp2[x]= am; 234cabdff1aSopenharmony_ci } 235cabdff1aSopenharmony_ci src += stride; 236cabdff1aSopenharmony_ci tmp2+= 64; 237cabdff1aSopenharmony_ci } 238cabdff1aSopenharmony_ci src -= stride*y; 239cabdff1aSopenharmony_ci } 240cabdff1aSopenharmony_ci src += stride*(HTAPS_MAX/2 - 1); 241cabdff1aSopenharmony_ci tmp2= tmp2t[2]; 242cabdff1aSopenharmony_ci tmpI= tmpIt; 243cabdff1aSopenharmony_ci if(b&4){ 244cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 245cabdff1aSopenharmony_ci for(x=0; x < b_w; x++){ 246cabdff1aSopenharmony_ci int a_1=tmpI[x + (HTAPS_MAX/2-4)*64]; 247cabdff1aSopenharmony_ci int a0= tmpI[x + (HTAPS_MAX/2-3)*64]; 248cabdff1aSopenharmony_ci int a1= tmpI[x + (HTAPS_MAX/2-2)*64]; 249cabdff1aSopenharmony_ci int a2= tmpI[x + (HTAPS_MAX/2-1)*64]; 250cabdff1aSopenharmony_ci int a3= tmpI[x + (HTAPS_MAX/2+0)*64]; 251cabdff1aSopenharmony_ci int a4= tmpI[x + (HTAPS_MAX/2+1)*64]; 252cabdff1aSopenharmony_ci int a5= tmpI[x + (HTAPS_MAX/2+2)*64]; 253cabdff1aSopenharmony_ci int a6= tmpI[x + (HTAPS_MAX/2+3)*64]; 254cabdff1aSopenharmony_ci int am=0; 255cabdff1aSopenharmony_ci if(!p || p->fast_mc) 256cabdff1aSopenharmony_ci am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 512)>>10; 257cabdff1aSopenharmony_ci else 258cabdff1aSopenharmony_ci am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 2048)>>12; 259cabdff1aSopenharmony_ci if(am&(~255)) am= ~(am>>31); 260cabdff1aSopenharmony_ci tmp2[x]= am; 261cabdff1aSopenharmony_ci } 262cabdff1aSopenharmony_ci tmpI+= 64; 263cabdff1aSopenharmony_ci tmp2+= 64; 264cabdff1aSopenharmony_ci } 265cabdff1aSopenharmony_ci } 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci hpel[ 0]= src; 268cabdff1aSopenharmony_ci hpel[ 1]= tmp2t[0] + 64*(HTAPS_MAX/2-1); 269cabdff1aSopenharmony_ci hpel[ 2]= src + 1; 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci hpel[ 4]= tmp2t[1]; 272cabdff1aSopenharmony_ci hpel[ 5]= tmp2t[2]; 273cabdff1aSopenharmony_ci hpel[ 6]= tmp2t[1] + 1; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci hpel[ 8]= src + stride; 276cabdff1aSopenharmony_ci hpel[ 9]= hpel[1] + 64; 277cabdff1aSopenharmony_ci hpel[10]= hpel[8] + 1; 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci#define MC_STRIDE(x) (needs[x] ? 64 : stride) 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci if(b==15){ 282cabdff1aSopenharmony_ci int dxy = dx / 8 + dy / 8 * 4; 283cabdff1aSopenharmony_ci const uint8_t *src1 = hpel[dxy ]; 284cabdff1aSopenharmony_ci const uint8_t *src2 = hpel[dxy + 1]; 285cabdff1aSopenharmony_ci const uint8_t *src3 = hpel[dxy + 4]; 286cabdff1aSopenharmony_ci const uint8_t *src4 = hpel[dxy + 5]; 287cabdff1aSopenharmony_ci int stride1 = MC_STRIDE(dxy); 288cabdff1aSopenharmony_ci int stride2 = MC_STRIDE(dxy + 1); 289cabdff1aSopenharmony_ci int stride3 = MC_STRIDE(dxy + 4); 290cabdff1aSopenharmony_ci int stride4 = MC_STRIDE(dxy + 5); 291cabdff1aSopenharmony_ci dx&=7; 292cabdff1aSopenharmony_ci dy&=7; 293cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 294cabdff1aSopenharmony_ci for(x=0; x < b_w; x++){ 295cabdff1aSopenharmony_ci dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+ 296cabdff1aSopenharmony_ci (8-dx)* dy *src3[x] + dx* dy *src4[x]+32)>>6; 297cabdff1aSopenharmony_ci } 298cabdff1aSopenharmony_ci src1+=stride1; 299cabdff1aSopenharmony_ci src2+=stride2; 300cabdff1aSopenharmony_ci src3+=stride3; 301cabdff1aSopenharmony_ci src4+=stride4; 302cabdff1aSopenharmony_ci dst +=stride; 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci }else{ 305cabdff1aSopenharmony_ci const uint8_t *src1= hpel[l]; 306cabdff1aSopenharmony_ci const uint8_t *src2= hpel[r]; 307cabdff1aSopenharmony_ci int stride1 = MC_STRIDE(l); 308cabdff1aSopenharmony_ci int stride2 = MC_STRIDE(r); 309cabdff1aSopenharmony_ci int a= weight[((dx&7) + (8*(dy&7)))]; 310cabdff1aSopenharmony_ci int b= 8-a; 311cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 312cabdff1aSopenharmony_ci for(x=0; x < b_w; x++){ 313cabdff1aSopenharmony_ci dst[x]= (a*src1[x] + b*src2[x] + 4)>>3; 314cabdff1aSopenharmony_ci } 315cabdff1aSopenharmony_ci src1+=stride1; 316cabdff1aSopenharmony_ci src2+=stride2; 317cabdff1aSopenharmony_ci dst +=stride; 318cabdff1aSopenharmony_ci } 319cabdff1aSopenharmony_ci } 320cabdff1aSopenharmony_ci} 321cabdff1aSopenharmony_ci 322cabdff1aSopenharmony_civoid ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, int sx, int sy, int b_w, int b_h, const BlockNode *block, int plane_index, int w, int h){ 323cabdff1aSopenharmony_ci if(block->type & BLOCK_INTRA){ 324cabdff1aSopenharmony_ci int x, y; 325cabdff1aSopenharmony_ci const unsigned color = block->color[plane_index]; 326cabdff1aSopenharmony_ci const unsigned color4 = color*0x01010101; 327cabdff1aSopenharmony_ci if(b_w==32){ 328cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 329cabdff1aSopenharmony_ci *(uint32_t*)&dst[0 + y*stride]= color4; 330cabdff1aSopenharmony_ci *(uint32_t*)&dst[4 + y*stride]= color4; 331cabdff1aSopenharmony_ci *(uint32_t*)&dst[8 + y*stride]= color4; 332cabdff1aSopenharmony_ci *(uint32_t*)&dst[12+ y*stride]= color4; 333cabdff1aSopenharmony_ci *(uint32_t*)&dst[16+ y*stride]= color4; 334cabdff1aSopenharmony_ci *(uint32_t*)&dst[20+ y*stride]= color4; 335cabdff1aSopenharmony_ci *(uint32_t*)&dst[24+ y*stride]= color4; 336cabdff1aSopenharmony_ci *(uint32_t*)&dst[28+ y*stride]= color4; 337cabdff1aSopenharmony_ci } 338cabdff1aSopenharmony_ci }else if(b_w==16){ 339cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 340cabdff1aSopenharmony_ci *(uint32_t*)&dst[0 + y*stride]= color4; 341cabdff1aSopenharmony_ci *(uint32_t*)&dst[4 + y*stride]= color4; 342cabdff1aSopenharmony_ci *(uint32_t*)&dst[8 + y*stride]= color4; 343cabdff1aSopenharmony_ci *(uint32_t*)&dst[12+ y*stride]= color4; 344cabdff1aSopenharmony_ci } 345cabdff1aSopenharmony_ci }else if(b_w==8){ 346cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 347cabdff1aSopenharmony_ci *(uint32_t*)&dst[0 + y*stride]= color4; 348cabdff1aSopenharmony_ci *(uint32_t*)&dst[4 + y*stride]= color4; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci }else if(b_w==4){ 351cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 352cabdff1aSopenharmony_ci *(uint32_t*)&dst[0 + y*stride]= color4; 353cabdff1aSopenharmony_ci } 354cabdff1aSopenharmony_ci }else{ 355cabdff1aSopenharmony_ci for(y=0; y < b_h; y++){ 356cabdff1aSopenharmony_ci for(x=0; x < b_w; x++){ 357cabdff1aSopenharmony_ci dst[x + y*stride]= color; 358cabdff1aSopenharmony_ci } 359cabdff1aSopenharmony_ci } 360cabdff1aSopenharmony_ci } 361cabdff1aSopenharmony_ci }else{ 362cabdff1aSopenharmony_ci uint8_t *src= s->last_picture[block->ref]->data[plane_index]; 363cabdff1aSopenharmony_ci const int scale= plane_index ? (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale; 364cabdff1aSopenharmony_ci int mx= block->mx*scale; 365cabdff1aSopenharmony_ci int my= block->my*scale; 366cabdff1aSopenharmony_ci const int dx= mx&15; 367cabdff1aSopenharmony_ci const int dy= my&15; 368cabdff1aSopenharmony_ci const int tab_index= 3 - (b_w>>2) + (b_w>>4); 369cabdff1aSopenharmony_ci sx += (mx>>4) - (HTAPS_MAX/2-1); 370cabdff1aSopenharmony_ci sy += (my>>4) - (HTAPS_MAX/2-1); 371cabdff1aSopenharmony_ci src += sx + sy*stride; 372cabdff1aSopenharmony_ci if( (unsigned)sx >= FFMAX(w - b_w - (HTAPS_MAX-2), 0) 373cabdff1aSopenharmony_ci || (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){ 374cabdff1aSopenharmony_ci s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, 375cabdff1aSopenharmony_ci stride, stride, 376cabdff1aSopenharmony_ci b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, 377cabdff1aSopenharmony_ci sx, sy, w, h); 378cabdff1aSopenharmony_ci src= tmp + MB_SIZE; 379cabdff1aSopenharmony_ci } 380cabdff1aSopenharmony_ci 381cabdff1aSopenharmony_ci av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale 382cabdff1aSopenharmony_ci 383cabdff1aSopenharmony_ci av_assert2((tab_index>=0 && tab_index<4) || b_w==32); 384cabdff1aSopenharmony_ci if( (dx&3) || (dy&3) 385cabdff1aSopenharmony_ci || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) 386cabdff1aSopenharmony_ci || (b_w&(b_w-1)) 387cabdff1aSopenharmony_ci || b_w == 1 388cabdff1aSopenharmony_ci || b_h == 1 389cabdff1aSopenharmony_ci || !s->plane[plane_index].fast_mc ) 390cabdff1aSopenharmony_ci mc_block(&s->plane[plane_index], dst, src, stride, b_w, b_h, dx, dy); 391cabdff1aSopenharmony_ci else if(b_w==32){ 392cabdff1aSopenharmony_ci int y; 393cabdff1aSopenharmony_ci for(y=0; y<b_h; y+=16){ 394cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride); 395cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride); 396cabdff1aSopenharmony_ci } 397cabdff1aSopenharmony_ci }else if(b_w==b_h) 398cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride); 399cabdff1aSopenharmony_ci else if(b_w==2*b_h){ 400cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst ,src + 3 + 3*stride,stride); 401cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride); 402cabdff1aSopenharmony_ci }else{ 403cabdff1aSopenharmony_ci av_assert2(2*b_w==b_h); 404cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst ,src + 3 + 3*stride ,stride); 405cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride); 406cabdff1aSopenharmony_ci } 407cabdff1aSopenharmony_ci } 408cabdff1aSopenharmony_ci} 409cabdff1aSopenharmony_ci 410cabdff1aSopenharmony_ci#define mca(dx,dy,b_w)\ 411cabdff1aSopenharmony_cistatic void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h){\ 412cabdff1aSopenharmony_ci av_assert2(h==b_w);\ 413cabdff1aSopenharmony_ci mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\ 414cabdff1aSopenharmony_ci} 415cabdff1aSopenharmony_ci 416cabdff1aSopenharmony_cimca( 0, 0,16) 417cabdff1aSopenharmony_cimca( 8, 0,16) 418cabdff1aSopenharmony_cimca( 0, 8,16) 419cabdff1aSopenharmony_cimca( 8, 8,16) 420cabdff1aSopenharmony_cimca( 0, 0,8) 421cabdff1aSopenharmony_cimca( 8, 0,8) 422cabdff1aSopenharmony_cimca( 0, 8,8) 423cabdff1aSopenharmony_cimca( 8, 8,8) 424cabdff1aSopenharmony_ci 425cabdff1aSopenharmony_cistatic av_cold void snow_static_init(void) 426cabdff1aSopenharmony_ci{ 427cabdff1aSopenharmony_ci for (int i = 0; i < MAX_REF_FRAMES; i++) 428cabdff1aSopenharmony_ci for (int j = 0; j < MAX_REF_FRAMES; j++) 429cabdff1aSopenharmony_ci ff_scale_mv_ref[i][j] = 256 * (i + 1) / (j + 1); 430cabdff1aSopenharmony_ci} 431cabdff1aSopenharmony_ci 432cabdff1aSopenharmony_ciav_cold int ff_snow_common_init(AVCodecContext *avctx){ 433cabdff1aSopenharmony_ci static AVOnce init_static_once = AV_ONCE_INIT; 434cabdff1aSopenharmony_ci SnowContext *s = avctx->priv_data; 435cabdff1aSopenharmony_ci int width, height; 436cabdff1aSopenharmony_ci int i; 437cabdff1aSopenharmony_ci 438cabdff1aSopenharmony_ci s->avctx= avctx; 439cabdff1aSopenharmony_ci s->max_ref_frames=1; //just make sure it's not an invalid value in case of no initial keyframe 440cabdff1aSopenharmony_ci s->spatial_decomposition_count = 1; 441cabdff1aSopenharmony_ci 442cabdff1aSopenharmony_ci ff_me_cmp_init(&s->mecc, avctx); 443cabdff1aSopenharmony_ci ff_hpeldsp_init(&s->hdsp, avctx->flags); 444cabdff1aSopenharmony_ci ff_videodsp_init(&s->vdsp, 8); 445cabdff1aSopenharmony_ci ff_dwt_init(&s->dwt); 446cabdff1aSopenharmony_ci ff_h264qpel_init(&s->h264qpel, 8); 447cabdff1aSopenharmony_ci 448cabdff1aSopenharmony_ci#define mcf(dx,dy)\ 449cabdff1aSopenharmony_ci s->qdsp.put_qpel_pixels_tab [0][dy+dx/4]=\ 450cabdff1aSopenharmony_ci s->qdsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\ 451cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[0][dy+dx/4];\ 452cabdff1aSopenharmony_ci s->qdsp.put_qpel_pixels_tab [1][dy+dx/4]=\ 453cabdff1aSopenharmony_ci s->qdsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\ 454cabdff1aSopenharmony_ci s->h264qpel.put_h264_qpel_pixels_tab[1][dy+dx/4]; 455cabdff1aSopenharmony_ci 456cabdff1aSopenharmony_ci mcf( 0, 0) 457cabdff1aSopenharmony_ci mcf( 4, 0) 458cabdff1aSopenharmony_ci mcf( 8, 0) 459cabdff1aSopenharmony_ci mcf(12, 0) 460cabdff1aSopenharmony_ci mcf( 0, 4) 461cabdff1aSopenharmony_ci mcf( 4, 4) 462cabdff1aSopenharmony_ci mcf( 8, 4) 463cabdff1aSopenharmony_ci mcf(12, 4) 464cabdff1aSopenharmony_ci mcf( 0, 8) 465cabdff1aSopenharmony_ci mcf( 4, 8) 466cabdff1aSopenharmony_ci mcf( 8, 8) 467cabdff1aSopenharmony_ci mcf(12, 8) 468cabdff1aSopenharmony_ci mcf( 0,12) 469cabdff1aSopenharmony_ci mcf( 4,12) 470cabdff1aSopenharmony_ci mcf( 8,12) 471cabdff1aSopenharmony_ci mcf(12,12) 472cabdff1aSopenharmony_ci 473cabdff1aSopenharmony_ci#define mcfh(dx,dy)\ 474cabdff1aSopenharmony_ci s->hdsp.put_pixels_tab [0][dy/4+dx/8]=\ 475cabdff1aSopenharmony_ci s->hdsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\ 476cabdff1aSopenharmony_ci mc_block_hpel ## dx ## dy ## 16;\ 477cabdff1aSopenharmony_ci s->hdsp.put_pixels_tab [1][dy/4+dx/8]=\ 478cabdff1aSopenharmony_ci s->hdsp.put_no_rnd_pixels_tab[1][dy/4+dx/8]=\ 479cabdff1aSopenharmony_ci mc_block_hpel ## dx ## dy ## 8; 480cabdff1aSopenharmony_ci 481cabdff1aSopenharmony_ci mcfh(0, 0) 482cabdff1aSopenharmony_ci mcfh(8, 0) 483cabdff1aSopenharmony_ci mcfh(0, 8) 484cabdff1aSopenharmony_ci mcfh(8, 8) 485cabdff1aSopenharmony_ci 486cabdff1aSopenharmony_ci// dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift); 487cabdff1aSopenharmony_ci 488cabdff1aSopenharmony_ci width= s->avctx->width; 489cabdff1aSopenharmony_ci height= s->avctx->height; 490cabdff1aSopenharmony_ci 491cabdff1aSopenharmony_ci if (!FF_ALLOCZ_TYPED_ARRAY(s->spatial_idwt_buffer, width * height) || 492cabdff1aSopenharmony_ci !FF_ALLOCZ_TYPED_ARRAY(s->spatial_dwt_buffer, width * height) || //FIXME this does not belong here 493cabdff1aSopenharmony_ci !FF_ALLOCZ_TYPED_ARRAY(s->temp_dwt_buffer, width) || 494cabdff1aSopenharmony_ci !FF_ALLOCZ_TYPED_ARRAY(s->temp_idwt_buffer, width) || 495cabdff1aSopenharmony_ci !FF_ALLOCZ_TYPED_ARRAY(s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1))) 496cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 497cabdff1aSopenharmony_ci 498cabdff1aSopenharmony_ci for(i=0; i<MAX_REF_FRAMES; i++) { 499cabdff1aSopenharmony_ci s->last_picture[i] = av_frame_alloc(); 500cabdff1aSopenharmony_ci if (!s->last_picture[i]) 501cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 502cabdff1aSopenharmony_ci } 503cabdff1aSopenharmony_ci 504cabdff1aSopenharmony_ci s->mconly_picture = av_frame_alloc(); 505cabdff1aSopenharmony_ci s->current_picture = av_frame_alloc(); 506cabdff1aSopenharmony_ci if (!s->mconly_picture || !s->current_picture) 507cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 508cabdff1aSopenharmony_ci 509cabdff1aSopenharmony_ci ff_thread_once(&init_static_once, snow_static_init); 510cabdff1aSopenharmony_ci 511cabdff1aSopenharmony_ci return 0; 512cabdff1aSopenharmony_ci} 513cabdff1aSopenharmony_ci 514cabdff1aSopenharmony_ciint ff_snow_common_init_after_header(AVCodecContext *avctx) { 515cabdff1aSopenharmony_ci SnowContext *s = avctx->priv_data; 516cabdff1aSopenharmony_ci int plane_index, level, orientation; 517cabdff1aSopenharmony_ci int ret, emu_buf_size; 518cabdff1aSopenharmony_ci 519cabdff1aSopenharmony_ci if(!s->scratchbuf) { 520cabdff1aSopenharmony_ci if (av_codec_is_decoder(avctx->codec)) { 521cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(s->avctx, s->mconly_picture, 522cabdff1aSopenharmony_ci AV_GET_BUFFER_FLAG_REF)) < 0) 523cabdff1aSopenharmony_ci return ret; 524cabdff1aSopenharmony_ci } 525cabdff1aSopenharmony_ci 526cabdff1aSopenharmony_ci emu_buf_size = FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1); 527cabdff1aSopenharmony_ci if (!FF_ALLOCZ_TYPED_ARRAY(s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * 7 * MB_SIZE) || 528cabdff1aSopenharmony_ci !FF_ALLOCZ_TYPED_ARRAY(s->emu_edge_buffer, emu_buf_size)) 529cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 530cabdff1aSopenharmony_ci } 531cabdff1aSopenharmony_ci 532cabdff1aSopenharmony_ci if (av_codec_is_decoder(avctx->codec) && 533cabdff1aSopenharmony_ci s->mconly_picture->format != avctx->pix_fmt) { 534cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "pixel format changed\n"); 535cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 536cabdff1aSopenharmony_ci } 537cabdff1aSopenharmony_ci 538cabdff1aSopenharmony_ci for(plane_index=0; plane_index < s->nb_planes; plane_index++){ 539cabdff1aSopenharmony_ci int w= s->avctx->width; 540cabdff1aSopenharmony_ci int h= s->avctx->height; 541cabdff1aSopenharmony_ci 542cabdff1aSopenharmony_ci if(plane_index){ 543cabdff1aSopenharmony_ci w = AV_CEIL_RSHIFT(w, s->chroma_h_shift); 544cabdff1aSopenharmony_ci h = AV_CEIL_RSHIFT(h, s->chroma_v_shift); 545cabdff1aSopenharmony_ci } 546cabdff1aSopenharmony_ci s->plane[plane_index].width = w; 547cabdff1aSopenharmony_ci s->plane[plane_index].height= h; 548cabdff1aSopenharmony_ci 549cabdff1aSopenharmony_ci for(level=s->spatial_decomposition_count-1; level>=0; level--){ 550cabdff1aSopenharmony_ci for(orientation=level ? 1 : 0; orientation<4; orientation++){ 551cabdff1aSopenharmony_ci SubBand *b= &s->plane[plane_index].band[level][orientation]; 552cabdff1aSopenharmony_ci 553cabdff1aSopenharmony_ci b->buf= s->spatial_dwt_buffer; 554cabdff1aSopenharmony_ci b->level= level; 555cabdff1aSopenharmony_ci b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level); 556cabdff1aSopenharmony_ci b->width = (w + !(orientation&1))>>1; 557cabdff1aSopenharmony_ci b->height= (h + !(orientation>1))>>1; 558cabdff1aSopenharmony_ci 559cabdff1aSopenharmony_ci b->stride_line = 1 << (s->spatial_decomposition_count - level); 560cabdff1aSopenharmony_ci b->buf_x_offset = 0; 561cabdff1aSopenharmony_ci b->buf_y_offset = 0; 562cabdff1aSopenharmony_ci 563cabdff1aSopenharmony_ci if(orientation&1){ 564cabdff1aSopenharmony_ci b->buf += (w+1)>>1; 565cabdff1aSopenharmony_ci b->buf_x_offset = (w+1)>>1; 566cabdff1aSopenharmony_ci } 567cabdff1aSopenharmony_ci if(orientation>1){ 568cabdff1aSopenharmony_ci b->buf += b->stride>>1; 569cabdff1aSopenharmony_ci b->buf_y_offset = b->stride_line >> 1; 570cabdff1aSopenharmony_ci } 571cabdff1aSopenharmony_ci b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer); 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci if(level) 574cabdff1aSopenharmony_ci b->parent= &s->plane[plane_index].band[level-1][orientation]; 575cabdff1aSopenharmony_ci //FIXME avoid this realloc 576cabdff1aSopenharmony_ci av_freep(&b->x_coeff); 577cabdff1aSopenharmony_ci b->x_coeff = av_calloc((b->width + 1) * b->height + 1, 578cabdff1aSopenharmony_ci sizeof(*b->x_coeff)); 579cabdff1aSopenharmony_ci if (!b->x_coeff) 580cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 581cabdff1aSopenharmony_ci } 582cabdff1aSopenharmony_ci w= (w+1)>>1; 583cabdff1aSopenharmony_ci h= (h+1)>>1; 584cabdff1aSopenharmony_ci } 585cabdff1aSopenharmony_ci } 586cabdff1aSopenharmony_ci 587cabdff1aSopenharmony_ci return 0; 588cabdff1aSopenharmony_ci} 589cabdff1aSopenharmony_ci 590cabdff1aSopenharmony_ci#define USE_HALFPEL_PLANE 0 591cabdff1aSopenharmony_ci 592cabdff1aSopenharmony_cistatic int halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ 593cabdff1aSopenharmony_ci int p,x,y; 594cabdff1aSopenharmony_ci 595cabdff1aSopenharmony_ci for(p=0; p < s->nb_planes; p++){ 596cabdff1aSopenharmony_ci int is_chroma= !!p; 597cabdff1aSopenharmony_ci int w= is_chroma ? AV_CEIL_RSHIFT(s->avctx->width, s->chroma_h_shift) : s->avctx->width; 598cabdff1aSopenharmony_ci int h= is_chroma ? AV_CEIL_RSHIFT(s->avctx->height, s->chroma_v_shift) : s->avctx->height; 599cabdff1aSopenharmony_ci int ls= frame->linesize[p]; 600cabdff1aSopenharmony_ci uint8_t *src= frame->data[p]; 601cabdff1aSopenharmony_ci 602cabdff1aSopenharmony_ci halfpel[1][p] = av_malloc_array(ls, (h + 2 * EDGE_WIDTH)); 603cabdff1aSopenharmony_ci halfpel[2][p] = av_malloc_array(ls, (h + 2 * EDGE_WIDTH)); 604cabdff1aSopenharmony_ci halfpel[3][p] = av_malloc_array(ls, (h + 2 * EDGE_WIDTH)); 605cabdff1aSopenharmony_ci if (!halfpel[1][p] || !halfpel[2][p] || !halfpel[3][p]) { 606cabdff1aSopenharmony_ci av_freep(&halfpel[1][p]); 607cabdff1aSopenharmony_ci av_freep(&halfpel[2][p]); 608cabdff1aSopenharmony_ci av_freep(&halfpel[3][p]); 609cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 610cabdff1aSopenharmony_ci } 611cabdff1aSopenharmony_ci halfpel[1][p] += EDGE_WIDTH * (1 + ls); 612cabdff1aSopenharmony_ci halfpel[2][p] += EDGE_WIDTH * (1 + ls); 613cabdff1aSopenharmony_ci halfpel[3][p] += EDGE_WIDTH * (1 + ls); 614cabdff1aSopenharmony_ci 615cabdff1aSopenharmony_ci halfpel[0][p]= src; 616cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 617cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 618cabdff1aSopenharmony_ci int i= y*ls + x; 619cabdff1aSopenharmony_ci 620cabdff1aSopenharmony_ci halfpel[1][p][i]= (20*(src[i] + src[i+1]) - 5*(src[i-1] + src[i+2]) + (src[i-2] + src[i+3]) + 16 )>>5; 621cabdff1aSopenharmony_ci } 622cabdff1aSopenharmony_ci } 623cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 624cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 625cabdff1aSopenharmony_ci int i= y*ls + x; 626cabdff1aSopenharmony_ci 627cabdff1aSopenharmony_ci halfpel[2][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5; 628cabdff1aSopenharmony_ci } 629cabdff1aSopenharmony_ci } 630cabdff1aSopenharmony_ci src= halfpel[1][p]; 631cabdff1aSopenharmony_ci for(y=0; y<h; y++){ 632cabdff1aSopenharmony_ci for(x=0; x<w; x++){ 633cabdff1aSopenharmony_ci int i= y*ls + x; 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_ci halfpel[3][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5; 636cabdff1aSopenharmony_ci } 637cabdff1aSopenharmony_ci } 638cabdff1aSopenharmony_ci 639cabdff1aSopenharmony_ci//FIXME border! 640cabdff1aSopenharmony_ci } 641cabdff1aSopenharmony_ci return 0; 642cabdff1aSopenharmony_ci} 643cabdff1aSopenharmony_ci 644cabdff1aSopenharmony_civoid ff_snow_release_buffer(AVCodecContext *avctx) 645cabdff1aSopenharmony_ci{ 646cabdff1aSopenharmony_ci SnowContext *s = avctx->priv_data; 647cabdff1aSopenharmony_ci int i; 648cabdff1aSopenharmony_ci 649cabdff1aSopenharmony_ci if(s->last_picture[s->max_ref_frames-1]->data[0]){ 650cabdff1aSopenharmony_ci av_frame_unref(s->last_picture[s->max_ref_frames-1]); 651cabdff1aSopenharmony_ci for(i=0; i<9; i++) 652cabdff1aSopenharmony_ci if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3]) { 653cabdff1aSopenharmony_ci av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture->linesize[i%3])); 654cabdff1aSopenharmony_ci s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] = NULL; 655cabdff1aSopenharmony_ci } 656cabdff1aSopenharmony_ci } 657cabdff1aSopenharmony_ci} 658cabdff1aSopenharmony_ci 659cabdff1aSopenharmony_ciint ff_snow_frame_start(SnowContext *s){ 660cabdff1aSopenharmony_ci AVFrame *tmp; 661cabdff1aSopenharmony_ci int i, ret; 662cabdff1aSopenharmony_ci 663cabdff1aSopenharmony_ci ff_snow_release_buffer(s->avctx); 664cabdff1aSopenharmony_ci 665cabdff1aSopenharmony_ci tmp= s->last_picture[s->max_ref_frames-1]; 666cabdff1aSopenharmony_ci for(i=s->max_ref_frames-1; i>0; i--) 667cabdff1aSopenharmony_ci s->last_picture[i] = s->last_picture[i-1]; 668cabdff1aSopenharmony_ci memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4); 669cabdff1aSopenharmony_ci if(USE_HALFPEL_PLANE && s->current_picture->data[0]) { 670cabdff1aSopenharmony_ci if((ret = halfpel_interpol(s, s->halfpel_plane[0], s->current_picture)) < 0) 671cabdff1aSopenharmony_ci return ret; 672cabdff1aSopenharmony_ci } 673cabdff1aSopenharmony_ci s->last_picture[0] = s->current_picture; 674cabdff1aSopenharmony_ci s->current_picture = tmp; 675cabdff1aSopenharmony_ci 676cabdff1aSopenharmony_ci if(s->keyframe){ 677cabdff1aSopenharmony_ci s->ref_frames= 0; 678cabdff1aSopenharmony_ci }else{ 679cabdff1aSopenharmony_ci int i; 680cabdff1aSopenharmony_ci for(i=0; i<s->max_ref_frames && s->last_picture[i]->data[0]; i++) 681cabdff1aSopenharmony_ci if(i && s->last_picture[i-1]->key_frame) 682cabdff1aSopenharmony_ci break; 683cabdff1aSopenharmony_ci s->ref_frames= i; 684cabdff1aSopenharmony_ci if(s->ref_frames==0){ 685cabdff1aSopenharmony_ci av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n"); 686cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 687cabdff1aSopenharmony_ci } 688cabdff1aSopenharmony_ci } 689cabdff1aSopenharmony_ci if ((ret = ff_snow_get_buffer(s, s->current_picture)) < 0) 690cabdff1aSopenharmony_ci return ret; 691cabdff1aSopenharmony_ci 692cabdff1aSopenharmony_ci s->current_picture->key_frame= s->keyframe; 693cabdff1aSopenharmony_ci 694cabdff1aSopenharmony_ci return 0; 695cabdff1aSopenharmony_ci} 696cabdff1aSopenharmony_ci 697cabdff1aSopenharmony_ciav_cold void ff_snow_common_end(SnowContext *s) 698cabdff1aSopenharmony_ci{ 699cabdff1aSopenharmony_ci int plane_index, level, orientation, i; 700cabdff1aSopenharmony_ci 701cabdff1aSopenharmony_ci av_freep(&s->spatial_dwt_buffer); 702cabdff1aSopenharmony_ci av_freep(&s->temp_dwt_buffer); 703cabdff1aSopenharmony_ci av_freep(&s->spatial_idwt_buffer); 704cabdff1aSopenharmony_ci av_freep(&s->temp_idwt_buffer); 705cabdff1aSopenharmony_ci av_freep(&s->run_buffer); 706cabdff1aSopenharmony_ci 707cabdff1aSopenharmony_ci s->m.me.temp= NULL; 708cabdff1aSopenharmony_ci av_freep(&s->m.me.scratchpad); 709cabdff1aSopenharmony_ci av_freep(&s->m.me.map); 710cabdff1aSopenharmony_ci av_freep(&s->m.me.score_map); 711cabdff1aSopenharmony_ci av_freep(&s->m.sc.obmc_scratchpad); 712cabdff1aSopenharmony_ci 713cabdff1aSopenharmony_ci av_freep(&s->block); 714cabdff1aSopenharmony_ci av_freep(&s->scratchbuf); 715cabdff1aSopenharmony_ci av_freep(&s->emu_edge_buffer); 716cabdff1aSopenharmony_ci 717cabdff1aSopenharmony_ci for(i=0; i<MAX_REF_FRAMES; i++){ 718cabdff1aSopenharmony_ci av_freep(&s->ref_mvs[i]); 719cabdff1aSopenharmony_ci av_freep(&s->ref_scores[i]); 720cabdff1aSopenharmony_ci if(s->last_picture[i] && s->last_picture[i]->data[0]) { 721cabdff1aSopenharmony_ci av_assert0(s->last_picture[i]->data[0] != s->current_picture->data[0]); 722cabdff1aSopenharmony_ci } 723cabdff1aSopenharmony_ci av_frame_free(&s->last_picture[i]); 724cabdff1aSopenharmony_ci } 725cabdff1aSopenharmony_ci 726cabdff1aSopenharmony_ci for(plane_index=0; plane_index < MAX_PLANES; plane_index++){ 727cabdff1aSopenharmony_ci for(level=MAX_DECOMPOSITIONS-1; level>=0; level--){ 728cabdff1aSopenharmony_ci for(orientation=level ? 1 : 0; orientation<4; orientation++){ 729cabdff1aSopenharmony_ci SubBand *b= &s->plane[plane_index].band[level][orientation]; 730cabdff1aSopenharmony_ci 731cabdff1aSopenharmony_ci av_freep(&b->x_coeff); 732cabdff1aSopenharmony_ci } 733cabdff1aSopenharmony_ci } 734cabdff1aSopenharmony_ci } 735cabdff1aSopenharmony_ci av_frame_free(&s->mconly_picture); 736cabdff1aSopenharmony_ci av_frame_free(&s->current_picture); 737cabdff1aSopenharmony_ci} 738