summaryrefslogtreecommitdiff
path: root/contrib/ffmpeg/libavcodec/roqvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ffmpeg/libavcodec/roqvideo.c')
-rw-r--r--contrib/ffmpeg/libavcodec/roqvideo.c138
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);
+}