1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2003 Mike Melanson 3cabdff1aSopenharmony_ci * Copyright (C) 2003 Dr. Tim Ferguson 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/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * id RoQ Video common functions based on work by Dr. Tim Ferguson 25cabdff1aSopenharmony_ci */ 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include <stdint.h> 28cabdff1aSopenharmony_ci#include <string.h> 29cabdff1aSopenharmony_ci#include "roqvideo.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_cistatic inline void block_copy(unsigned char *out, unsigned char *in, 32cabdff1aSopenharmony_ci int outstride, int instride, int sz) 33cabdff1aSopenharmony_ci{ 34cabdff1aSopenharmony_ci int rows = sz; 35cabdff1aSopenharmony_ci while(rows--) { 36cabdff1aSopenharmony_ci memcpy(out, in, sz); 37cabdff1aSopenharmony_ci out += outstride; 38cabdff1aSopenharmony_ci in += instride; 39cabdff1aSopenharmony_ci } 40cabdff1aSopenharmony_ci} 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_civoid ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) 43cabdff1aSopenharmony_ci{ 44cabdff1aSopenharmony_ci unsigned char *bptr; 45cabdff1aSopenharmony_ci int boffs,stride; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci stride = ri->current_frame->linesize[0]; 48cabdff1aSopenharmony_ci boffs = y*stride + x; 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ci bptr = ri->current_frame->data[0] + boffs; 51cabdff1aSopenharmony_ci bptr[0 ] = cell->y[0]; 52cabdff1aSopenharmony_ci bptr[1 ] = cell->y[1]; 53cabdff1aSopenharmony_ci bptr[stride ] = cell->y[2]; 54cabdff1aSopenharmony_ci bptr[stride+1] = cell->y[3]; 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci stride = ri->current_frame->linesize[1]; 57cabdff1aSopenharmony_ci boffs = y*stride + x; 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci bptr = ri->current_frame->data[1] + boffs; 60cabdff1aSopenharmony_ci bptr[0 ] = 61cabdff1aSopenharmony_ci bptr[1 ] = 62cabdff1aSopenharmony_ci bptr[stride ] = 63cabdff1aSopenharmony_ci bptr[stride+1] = cell->u; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci bptr = ri->current_frame->data[2] + boffs; 66cabdff1aSopenharmony_ci bptr[0 ] = 67cabdff1aSopenharmony_ci bptr[1 ] = 68cabdff1aSopenharmony_ci bptr[stride ] = 69cabdff1aSopenharmony_ci bptr[stride+1] = cell->v; 70cabdff1aSopenharmony_ci} 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_civoid ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) 73cabdff1aSopenharmony_ci{ 74cabdff1aSopenharmony_ci unsigned char *bptr; 75cabdff1aSopenharmony_ci int boffs,stride; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci stride = ri->current_frame->linesize[0]; 78cabdff1aSopenharmony_ci boffs = y*stride + x; 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci bptr = ri->current_frame->data[0] + boffs; 81cabdff1aSopenharmony_ci bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0]; 82cabdff1aSopenharmony_ci bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1]; 83cabdff1aSopenharmony_ci bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2]; 84cabdff1aSopenharmony_ci bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3]; 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci stride = ri->current_frame->linesize[1]; 87cabdff1aSopenharmony_ci boffs = y*stride + x; 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci bptr = ri->current_frame->data[1] + boffs; 90cabdff1aSopenharmony_ci bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = 91cabdff1aSopenharmony_ci bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = 92cabdff1aSopenharmony_ci bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = 93cabdff1aSopenharmony_ci bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u; 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci bptr = ri->current_frame->data[2] + boffs; 96cabdff1aSopenharmony_ci bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = 97cabdff1aSopenharmony_ci bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = 98cabdff1aSopenharmony_ci bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = 99cabdff1aSopenharmony_ci bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v; 100cabdff1aSopenharmony_ci} 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_cistatic inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, 104cabdff1aSopenharmony_ci int deltay, int sz) 105cabdff1aSopenharmony_ci{ 106cabdff1aSopenharmony_ci int mx, my, cp; 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci mx = x + deltax; 109cabdff1aSopenharmony_ci my = y + deltay; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ci /* check MV against frame boundaries */ 112cabdff1aSopenharmony_ci if ((mx < 0) || (mx > ri->width - sz) || 113cabdff1aSopenharmony_ci (my < 0) || (my > ri->height - sz)) { 114cabdff1aSopenharmony_ci av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", 115cabdff1aSopenharmony_ci mx, my, ri->width, ri->height); 116cabdff1aSopenharmony_ci return; 117cabdff1aSopenharmony_ci } 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci if (!ri->last_frame->data[0]) { 120cabdff1aSopenharmony_ci av_log(ri->avctx, AV_LOG_ERROR, "Invalid decode type. Invalid header?\n"); 121cabdff1aSopenharmony_ci return; 122cabdff1aSopenharmony_ci } 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci for(cp = 0; cp < 3; cp++) { 125cabdff1aSopenharmony_ci int outstride = ri->current_frame->linesize[cp]; 126cabdff1aSopenharmony_ci int instride = ri->last_frame ->linesize[cp]; 127cabdff1aSopenharmony_ci block_copy(ri->current_frame->data[cp] + y*outstride + x, 128cabdff1aSopenharmony_ci ri->last_frame->data[cp] + my*instride + mx, 129cabdff1aSopenharmony_ci outstride, instride, sz); 130cabdff1aSopenharmony_ci } 131cabdff1aSopenharmony_ci} 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_civoid ff_apply_motion_4x4(RoqContext *ri, int x, int y, 135cabdff1aSopenharmony_ci int deltax, int deltay) 136cabdff1aSopenharmony_ci{ 137cabdff1aSopenharmony_ci apply_motion_generic(ri, x, y, deltax, deltay, 4); 138cabdff1aSopenharmony_ci} 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_civoid ff_apply_motion_8x8(RoqContext *ri, int x, int y, 141cabdff1aSopenharmony_ci int deltax, int deltay) 142cabdff1aSopenharmony_ci{ 143cabdff1aSopenharmony_ci apply_motion_generic(ri, x, y, deltax, deltay, 8); 144cabdff1aSopenharmony_ci} 145