ffmpeg / libavcodec / roqvideo.c @ 2912e87a
History  View  Annotate  Download (4.63 KB)
1 
/*


2 
* Copyright (C) 2003 Mike Melanson

3 
* Copyright (C) 2003 Dr. Tim Ferguson

4 
*

5 
* This file is part of Libav.

6 
*

7 
* Libav is free software; you can redistribute it and/or

8 
* modify it under the terms of the GNU Lesser General Public

9 
* License as published by the Free Software Foundation; either

10 
* version 2.1 of the License, or (at your option) any later version.

11 
*

12 
* Libav is distributed in the hope that it will be useful,

13 
* but WITHOUT ANY WARRANTY; without even the implied warranty of

14 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

15 
* Lesser General Public License for more details.

16 
*

17 
* You should have received a copy of the GNU Lesser General Public

18 
* License along with Libav; if not, write to the Free Software

19 
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301 USA

20 
*/

21  
22 
/**

23 
* @file

24 
* id RoQ Video common functions based on work by Dr. Tim Ferguson

25 
*/

26  
27 
#include "avcodec.h" 
28 
#include "roqvideo.h" 
29  
30 
static inline void block_copy(unsigned char *out, unsigned char *in, 
31 
int outstride, int instride, int sz) 
32 
{ 
33 
int rows = sz;

34 
while(rows) {

35 
memcpy(out, in, sz); 
36 
out += outstride; 
37 
in += instride; 
38 
} 
39 
} 
40  
41 
void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) 
42 
{ 
43 
unsigned char *bptr; 
44 
int boffs,stride;

45  
46 
stride = ri>current_frame>linesize[0];

47 
boffs = y*stride + x; 
48  
49 
bptr = ri>current_frame>data[0] + boffs;

50 
bptr[0 ] = cell>y[0]; 
51 
bptr[1 ] = cell>y[1]; 
52 
bptr[stride ] = cell>y[2];

53 
bptr[stride+1] = cell>y[3]; 
54  
55 
stride = ri>current_frame>linesize[1];

56 
boffs = y*stride + x; 
57  
58 
bptr = ri>current_frame>data[1] + boffs;

59 
bptr[0 ] =

60 
bptr[1 ] =

61 
bptr[stride ] = 
62 
bptr[stride+1] = cell>u;

63  
64 
bptr = ri>current_frame>data[2] + boffs;

65 
bptr[0 ] =

66 
bptr[1 ] =

67 
bptr[stride ] = 
68 
bptr[stride+1] = cell>v;

69 
} 
70  
71 
void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) 
72 
{ 
73 
unsigned char *bptr; 
74 
int boffs,stride;

75  
76 
stride = ri>current_frame>linesize[0];

77 
boffs = y*stride + x; 
78  
79 
bptr = ri>current_frame>data[0] + boffs;

80 
bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell>y[0]; 
81 
bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell>y[1]; 
82 
bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell>y[2]; 
83 
bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell>y[3]; 
84  
85 
stride = ri>current_frame>linesize[1];

86 
boffs = y*stride + x; 
87  
88 
bptr = ri>current_frame>data[1] + boffs;

89 
bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = 
90 
bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = 
91 
bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = 
92 
bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell>u; 
93  
94 
bptr = ri>current_frame>data[2] + boffs;

95 
bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = 
96 
bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = 
97 
bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = 
98 
bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell>v; 
99 
} 
100  
101  
102 
static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, 
103 
int deltay, int sz) 
104 
{ 
105 
int mx, my, cp;

106  
107 
mx = x + deltax; 
108 
my = y + deltay; 
109  
110 
/* check MV against frame boundaries */

111 
if ((mx < 0)  (mx > ri>width  sz)  
112 
(my < 0)  (my > ri>height  sz)) {

113 
av_log(ri>avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",

114 
mx, my, ri>width, ri>height); 
115 
return;

116 
} 
117  
118 
if (ri>last_frame>data[0] == NULL) { 
119 
av_log(ri>avctx, AV_LOG_ERROR, "Invalid decode type. Invalid header?\n");

120 
return;

121 
} 
122  
123 
for(cp = 0; cp < 3; cp++) { 
124 
int outstride = ri>current_frame>linesize[cp];

125 
int instride = ri>last_frame >linesize[cp];

126 
block_copy(ri>current_frame>data[cp] + y*outstride + x, 
127 
ri>last_frame>data[cp] + my*instride + mx, 
128 
outstride, instride, sz); 
129 
} 
130 
} 
131  
132  
133 
void ff_apply_motion_4x4(RoqContext *ri, int x, int y, 
134 
int deltax, int deltay) 
135 
{ 
136 
apply_motion_generic(ri, x, y, deltax, deltay, 4);

137 
} 
138  
139 
void ff_apply_motion_8x8(RoqContext *ri, int x, int y, 
140 
int deltax, int deltay) 
141 
{ 
142 
apply_motion_generic(ri, x, y, deltax, deltay, 8);

143 
} 