diff options
Diffstat (limited to 'contrib/ffmpeg/libavcodec/roqvideo.c')
-rw-r--r-- | contrib/ffmpeg/libavcodec/roqvideo.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/contrib/ffmpeg/libavcodec/roqvideo.c b/contrib/ffmpeg/libavcodec/roqvideo.c new file mode 100644 index 000000000..53d60a19e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/roqvideo.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2003 Mike Melanson + * Copyright (C) 2003 Dr. Tim Ferguson + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file roqvideo.c + * Id RoQ Video common functions based on work by Dr. Tim Ferguson + */ + +#include "avcodec.h" +#include "roqvideo.h" + +static inline void block_copy(unsigned char *out, unsigned char *in, + int outstride, int instride, int sz) +{ + int rows = sz; + while(rows--) { + memcpy(out, in, sz); + out += outstride; + in += instride; + } +} + +void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) +{ + unsigned char *bptr; + int boffs,stride; + + stride = ri->current_frame->linesize[0]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[0] + boffs; + bptr[0 ] = cell->y[0]; + bptr[1 ] = cell->y[1]; + bptr[stride ] = cell->y[2]; + bptr[stride+1] = cell->y[3]; + + stride = ri->current_frame->linesize[1]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[1] + boffs; + bptr[0 ] = + bptr[1 ] = + bptr[stride ] = + bptr[stride+1] = cell->u; + + bptr = ri->current_frame->data[2] + boffs; + bptr[0 ] = + bptr[1 ] = + bptr[stride ] = + bptr[stride+1] = cell->v; +} + +void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) +{ + unsigned char *bptr; + int boffs,stride; + + stride = ri->current_frame->linesize[0]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[0] + boffs; + bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0]; + bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1]; + bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2]; + bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3]; + + stride = ri->current_frame->linesize[1]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[1] + boffs; + bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = + bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = + bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = + bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u; + + bptr = ri->current_frame->data[2] + boffs; + bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = + bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = + bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = + bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v; +} + + +static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, + int deltay, int sz) +{ + int mx, my, cp; + + mx = x + deltax; + my = y + deltay; + + /* check MV against frame boundaries */ + if ((mx < 0) || (mx > ri->width - sz) || + (my < 0) || (my > ri->height - sz)) { + av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", + mx, my, ri->width, ri->height); + return; + } + + for(cp = 0; cp < 3; cp++) { + int outstride = ri->current_frame->linesize[cp]; + int instride = ri->last_frame ->linesize[cp]; + block_copy(ri->current_frame->data[cp] + y*outstride + x, + ri->last_frame->data[cp] + my*instride + mx, + outstride, instride, sz); + } +} + + +void ff_apply_motion_4x4(RoqContext *ri, int x, int y, + int deltax, int deltay) +{ + apply_motion_generic(ri, x, y, deltax, deltay, 4); +} + +void ff_apply_motion_8x8(RoqContext *ri, int x, int y, + int deltax, int deltay) +{ + apply_motion_generic(ri, x, y, deltax, deltay, 8); +} |