yading@10
|
1 /*
|
yading@10
|
2 * Copyright (C) 2003 Mike Melanson
|
yading@10
|
3 * Copyright (C) 2003 Dr. Tim Ferguson
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 /**
|
yading@10
|
23 * @file
|
yading@10
|
24 * id RoQ Video common functions based on work by Dr. Tim Ferguson
|
yading@10
|
25 */
|
yading@10
|
26
|
yading@10
|
27 #include "avcodec.h"
|
yading@10
|
28 #include "roqvideo.h"
|
yading@10
|
29
|
yading@10
|
30 static inline void block_copy(unsigned char *out, unsigned char *in,
|
yading@10
|
31 int outstride, int instride, int sz)
|
yading@10
|
32 {
|
yading@10
|
33 int rows = sz;
|
yading@10
|
34 while(rows--) {
|
yading@10
|
35 memcpy(out, in, sz);
|
yading@10
|
36 out += outstride;
|
yading@10
|
37 in += instride;
|
yading@10
|
38 }
|
yading@10
|
39 }
|
yading@10
|
40
|
yading@10
|
41 void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell)
|
yading@10
|
42 {
|
yading@10
|
43 unsigned char *bptr;
|
yading@10
|
44 int boffs,stride;
|
yading@10
|
45
|
yading@10
|
46 stride = ri->current_frame->linesize[0];
|
yading@10
|
47 boffs = y*stride + x;
|
yading@10
|
48
|
yading@10
|
49 bptr = ri->current_frame->data[0] + boffs;
|
yading@10
|
50 bptr[0 ] = cell->y[0];
|
yading@10
|
51 bptr[1 ] = cell->y[1];
|
yading@10
|
52 bptr[stride ] = cell->y[2];
|
yading@10
|
53 bptr[stride+1] = cell->y[3];
|
yading@10
|
54
|
yading@10
|
55 stride = ri->current_frame->linesize[1];
|
yading@10
|
56 boffs = y*stride + x;
|
yading@10
|
57
|
yading@10
|
58 bptr = ri->current_frame->data[1] + boffs;
|
yading@10
|
59 bptr[0 ] =
|
yading@10
|
60 bptr[1 ] =
|
yading@10
|
61 bptr[stride ] =
|
yading@10
|
62 bptr[stride+1] = cell->u;
|
yading@10
|
63
|
yading@10
|
64 bptr = ri->current_frame->data[2] + boffs;
|
yading@10
|
65 bptr[0 ] =
|
yading@10
|
66 bptr[1 ] =
|
yading@10
|
67 bptr[stride ] =
|
yading@10
|
68 bptr[stride+1] = cell->v;
|
yading@10
|
69 }
|
yading@10
|
70
|
yading@10
|
71 void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
|
yading@10
|
72 {
|
yading@10
|
73 unsigned char *bptr;
|
yading@10
|
74 int boffs,stride;
|
yading@10
|
75
|
yading@10
|
76 stride = ri->current_frame->linesize[0];
|
yading@10
|
77 boffs = y*stride + x;
|
yading@10
|
78
|
yading@10
|
79 bptr = ri->current_frame->data[0] + boffs;
|
yading@10
|
80 bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0];
|
yading@10
|
81 bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1];
|
yading@10
|
82 bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2];
|
yading@10
|
83 bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3];
|
yading@10
|
84
|
yading@10
|
85 stride = ri->current_frame->linesize[1];
|
yading@10
|
86 boffs = y*stride + x;
|
yading@10
|
87
|
yading@10
|
88 bptr = ri->current_frame->data[1] + boffs;
|
yading@10
|
89 bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] =
|
yading@10
|
90 bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] =
|
yading@10
|
91 bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] =
|
yading@10
|
92 bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u;
|
yading@10
|
93
|
yading@10
|
94 bptr = ri->current_frame->data[2] + boffs;
|
yading@10
|
95 bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] =
|
yading@10
|
96 bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] =
|
yading@10
|
97 bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] =
|
yading@10
|
98 bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v;
|
yading@10
|
99 }
|
yading@10
|
100
|
yading@10
|
101
|
yading@10
|
102 static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax,
|
yading@10
|
103 int deltay, int sz)
|
yading@10
|
104 {
|
yading@10
|
105 int mx, my, cp;
|
yading@10
|
106
|
yading@10
|
107 mx = x + deltax;
|
yading@10
|
108 my = y + deltay;
|
yading@10
|
109
|
yading@10
|
110 /* check MV against frame boundaries */
|
yading@10
|
111 if ((mx < 0) || (mx > ri->width - sz) ||
|
yading@10
|
112 (my < 0) || (my > ri->height - sz)) {
|
yading@10
|
113 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
|
yading@10
|
114 mx, my, ri->width, ri->height);
|
yading@10
|
115 return;
|
yading@10
|
116 }
|
yading@10
|
117
|
yading@10
|
118 if (ri->last_frame->data[0] == NULL) {
|
yading@10
|
119 av_log(ri->avctx, AV_LOG_ERROR, "Invalid decode type. Invalid header?\n");
|
yading@10
|
120 return;
|
yading@10
|
121 }
|
yading@10
|
122
|
yading@10
|
123 for(cp = 0; cp < 3; cp++) {
|
yading@10
|
124 int outstride = ri->current_frame->linesize[cp];
|
yading@10
|
125 int instride = ri->last_frame ->linesize[cp];
|
yading@10
|
126 block_copy(ri->current_frame->data[cp] + y*outstride + x,
|
yading@10
|
127 ri->last_frame->data[cp] + my*instride + mx,
|
yading@10
|
128 outstride, instride, sz);
|
yading@10
|
129 }
|
yading@10
|
130 }
|
yading@10
|
131
|
yading@10
|
132
|
yading@10
|
133 void ff_apply_motion_4x4(RoqContext *ri, int x, int y,
|
yading@10
|
134 int deltax, int deltay)
|
yading@10
|
135 {
|
yading@10
|
136 apply_motion_generic(ri, x, y, deltax, deltay, 4);
|
yading@10
|
137 }
|
yading@10
|
138
|
yading@10
|
139 void ff_apply_motion_8x8(RoqContext *ri, int x, int y,
|
yading@10
|
140 int deltax, int deltay)
|
yading@10
|
141 {
|
yading@10
|
142 apply_motion_generic(ri, x, y, deltax, deltay, 8);
|
yading@10
|
143 }
|