Libav
|
00001 /* 00002 * Copyright (C) 2003 Mike Melanson 00003 * Copyright (C) 2003 Dr. Tim Ferguson 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #include "avcodec.h" 00028 #include "roqvideo.h" 00029 00030 static inline void block_copy(unsigned char *out, unsigned char *in, 00031 int outstride, int instride, int sz) 00032 { 00033 int rows = sz; 00034 while(rows--) { 00035 memcpy(out, in, sz); 00036 out += outstride; 00037 in += instride; 00038 } 00039 } 00040 00041 void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) 00042 { 00043 unsigned char *bptr; 00044 int boffs,stride; 00045 00046 stride = ri->current_frame->linesize[0]; 00047 boffs = y*stride + x; 00048 00049 bptr = ri->current_frame->data[0] + boffs; 00050 bptr[0 ] = cell->y[0]; 00051 bptr[1 ] = cell->y[1]; 00052 bptr[stride ] = cell->y[2]; 00053 bptr[stride+1] = cell->y[3]; 00054 00055 stride = ri->current_frame->linesize[1]; 00056 boffs = y*stride + x; 00057 00058 bptr = ri->current_frame->data[1] + boffs; 00059 bptr[0 ] = 00060 bptr[1 ] = 00061 bptr[stride ] = 00062 bptr[stride+1] = cell->u; 00063 00064 bptr = ri->current_frame->data[2] + boffs; 00065 bptr[0 ] = 00066 bptr[1 ] = 00067 bptr[stride ] = 00068 bptr[stride+1] = cell->v; 00069 } 00070 00071 void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) 00072 { 00073 unsigned char *bptr; 00074 int boffs,stride; 00075 00076 stride = ri->current_frame->linesize[0]; 00077 boffs = y*stride + x; 00078 00079 bptr = ri->current_frame->data[0] + boffs; 00080 bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0]; 00081 bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1]; 00082 bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2]; 00083 bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3]; 00084 00085 stride = ri->current_frame->linesize[1]; 00086 boffs = y*stride + x; 00087 00088 bptr = ri->current_frame->data[1] + boffs; 00089 bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = 00090 bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = 00091 bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = 00092 bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u; 00093 00094 bptr = ri->current_frame->data[2] + boffs; 00095 bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = 00096 bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = 00097 bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = 00098 bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v; 00099 } 00100 00101 00102 static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, 00103 int deltay, int sz) 00104 { 00105 int mx, my, cp; 00106 00107 mx = x + deltax; 00108 my = y + deltay; 00109 00110 /* check MV against frame boundaries */ 00111 if ((mx < 0) || (mx > ri->width - sz) || 00112 (my < 0) || (my > ri->height - sz)) { 00113 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", 00114 mx, my, ri->width, ri->height); 00115 return; 00116 } 00117 00118 for(cp = 0; cp < 3; cp++) { 00119 int outstride = ri->current_frame->linesize[cp]; 00120 int instride = ri->last_frame ->linesize[cp]; 00121 block_copy(ri->current_frame->data[cp] + y*outstride + x, 00122 ri->last_frame->data[cp] + my*instride + mx, 00123 outstride, instride, sz); 00124 } 00125 } 00126 00127 00128 void ff_apply_motion_4x4(RoqContext *ri, int x, int y, 00129 int deltax, int deltay) 00130 { 00131 apply_motion_generic(ri, x, y, deltax, deltay, 4); 00132 } 00133 00134 void ff_apply_motion_8x8(RoqContext *ri, int x, int y, 00135 int deltax, int deltay) 00136 { 00137 apply_motion_generic(ri, x, y, deltax, deltay, 8); 00138 }