00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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 if (ri->last_frame->data[0] == NULL) {
00119 av_log(ri->avctx, AV_LOG_ERROR, "Invalid decode type. Invalid header?\n");
00120 return;
00121 }
00122
00123 for(cp = 0; cp < 3; cp++) {
00124 int outstride = ri->current_frame->linesize[cp];
00125 int instride = ri->last_frame ->linesize[cp];
00126 block_copy(ri->current_frame->data[cp] + y*outstride + x,
00127 ri->last_frame->data[cp] + my*instride + mx,
00128 outstride, instride, sz);
00129 }
00130 }
00131
00132
00133 void ff_apply_motion_4x4(RoqContext *ri, int x, int y,
00134 int deltax, int deltay)
00135 {
00136 apply_motion_generic(ri, x, y, deltax, deltay, 4);
00137 }
00138
00139 void ff_apply_motion_8x8(RoqContext *ri, int x, int y,
00140 int deltax, int deltay)
00141 {
00142 apply_motion_generic(ri, x, y, deltax, deltay, 8);
00143 }