/src/ffmpeg/libavcodec/roqvideo.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2003 Mike Melanson |
3 | | * Copyright (C) 2003 Dr. Tim Ferguson |
4 | | * |
5 | | * This file is part of FFmpeg. |
6 | | * |
7 | | * FFmpeg 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 | | * FFmpeg 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 FFmpeg; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 | | */ |
21 | | |
22 | | /** |
23 | | * @file |
24 | | * id RoQ Video common functions based on work by Dr. Tim Ferguson |
25 | | */ |
26 | | |
27 | | #include <stdint.h> |
28 | | #include <string.h> |
29 | | #include "roqvideo.h" |
30 | | |
31 | | static inline void block_copy(unsigned char *out, unsigned char *in, |
32 | | int outstride, int instride, int sz) |
33 | 108k | { |
34 | 108k | int rows = sz; |
35 | 750k | while(rows--) { |
36 | 642k | memcpy(out, in, sz); |
37 | 642k | out += outstride; |
38 | 642k | in += instride; |
39 | 642k | } |
40 | 108k | } |
41 | | |
42 | | void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) |
43 | 6.74M | { |
44 | 6.74M | unsigned char *bptr; |
45 | 6.74M | int boffs,stride; |
46 | | |
47 | 6.74M | stride = ri->current_frame->linesize[0]; |
48 | 6.74M | boffs = y*stride + x; |
49 | | |
50 | 6.74M | bptr = ri->current_frame->data[0] + boffs; |
51 | 6.74M | bptr[0 ] = cell->y[0]; |
52 | 6.74M | bptr[1 ] = cell->y[1]; |
53 | 6.74M | bptr[stride ] = cell->y[2]; |
54 | 6.74M | bptr[stride+1] = cell->y[3]; |
55 | | |
56 | 6.74M | stride = ri->current_frame->linesize[1]; |
57 | 6.74M | boffs = y*stride + x; |
58 | | |
59 | 6.74M | bptr = ri->current_frame->data[1] + boffs; |
60 | 6.74M | bptr[0 ] = |
61 | 6.74M | bptr[1 ] = |
62 | 6.74M | bptr[stride ] = |
63 | 6.74M | bptr[stride+1] = cell->u; |
64 | | |
65 | 6.74M | bptr = ri->current_frame->data[2] + boffs; |
66 | 6.74M | bptr[0 ] = |
67 | 6.74M | bptr[1 ] = |
68 | 6.74M | bptr[stride ] = |
69 | 6.74M | bptr[stride+1] = cell->v; |
70 | 6.74M | } |
71 | | |
72 | | void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) |
73 | 3.14M | { |
74 | 3.14M | unsigned char *bptr; |
75 | 3.14M | int boffs,stride; |
76 | | |
77 | 3.14M | stride = ri->current_frame->linesize[0]; |
78 | 3.14M | boffs = y*stride + x; |
79 | | |
80 | 3.14M | bptr = ri->current_frame->data[0] + boffs; |
81 | 3.14M | bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0]; |
82 | 3.14M | bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1]; |
83 | 3.14M | bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2]; |
84 | 3.14M | bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3]; |
85 | | |
86 | 3.14M | stride = ri->current_frame->linesize[1]; |
87 | 3.14M | boffs = y*stride + x; |
88 | | |
89 | 3.14M | bptr = ri->current_frame->data[1] + boffs; |
90 | 3.14M | bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = |
91 | 3.14M | bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = |
92 | 3.14M | bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = |
93 | 3.14M | bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u; |
94 | | |
95 | 3.14M | bptr = ri->current_frame->data[2] + boffs; |
96 | 3.14M | bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = |
97 | 3.14M | bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = |
98 | 3.14M | bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = |
99 | 3.14M | bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v; |
100 | 3.14M | } |
101 | | |
102 | | |
103 | | static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, |
104 | | int deltay, int sz) |
105 | 308k | { |
106 | 308k | int mx, my, cp; |
107 | | |
108 | 308k | mx = x + deltax; |
109 | 308k | my = y + deltay; |
110 | | |
111 | | /* check MV against frame boundaries */ |
112 | 308k | if ((mx < 0) || (mx > ri->width - sz) || |
113 | 288k | (my < 0) || (my > ri->height - sz)) { |
114 | 113k | av_log(ri->logctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", |
115 | 113k | mx, my, ri->width, ri->height); |
116 | 113k | return; |
117 | 113k | } |
118 | | |
119 | 195k | if (!ri->last_frame->data[0]) { |
120 | 159k | av_log(ri->logctx, AV_LOG_ERROR, "Invalid decode type. Invalid header?\n"); |
121 | 159k | return; |
122 | 159k | } |
123 | | |
124 | 144k | for(cp = 0; cp < 3; cp++) { |
125 | 108k | int outstride = ri->current_frame->linesize[cp]; |
126 | 108k | int instride = ri->last_frame ->linesize[cp]; |
127 | 108k | block_copy(ri->current_frame->data[cp] + y*outstride + x, |
128 | 108k | ri->last_frame->data[cp] + my*instride + mx, |
129 | 108k | outstride, instride, sz); |
130 | 108k | } |
131 | 36.0k | } |
132 | | |
133 | | |
134 | | void ff_apply_motion_4x4(RoqContext *ri, int x, int y, |
135 | | int deltax, int deltay) |
136 | 102k | { |
137 | 102k | apply_motion_generic(ri, x, y, deltax, deltay, 4); |
138 | 102k | } |
139 | | |
140 | | void ff_apply_motion_8x8(RoqContext *ri, int x, int y, |
141 | | int deltax, int deltay) |
142 | 206k | { |
143 | 206k | apply_motion_generic(ri, x, y, deltax, deltay, 8); |
144 | 206k | } |