Mercurial > libavcodec.hg
comparison roqvideo.c @ 2828:2aae25679885 libavcodec
tinfoil patch: validate motion vectors and do not free frame on exit if
frame is NULL; also removed some ancient MC code that did not perform
half-pel C-plane MC
author | melanson |
---|---|
date | Sat, 13 Aug 2005 18:25:17 +0000 |
parents | 141a9539e270 |
children | ef2149182f1c |
comparison
equal
deleted
inserted
replaced
2827:deaf39d8381b | 2828:2aae25679885 |
---|---|
141 unsigned char *pa, *pb; | 141 unsigned char *pa, *pb; |
142 | 142 |
143 mx = x + 8 - (mv >> 4) - mean_x; | 143 mx = x + 8 - (mv >> 4) - mean_x; |
144 my = y + 8 - (mv & 0xf) - mean_y; | 144 my = y + 8 - (mv & 0xf) - mean_y; |
145 | 145 |
146 /* check MV against frame boundaries */ | |
147 if ((mx < 0) || (mx > ri->avctx->width - 4) || | |
148 (my < 0) || (my > ri->avctx->height - 4)) { | |
149 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", | |
150 mx, my, ri->avctx->width, ri->avctx->height); | |
151 return; | |
152 } | |
153 | |
146 pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; | 154 pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; |
147 pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; | 155 pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; |
148 for(i = 0; i < 4; i++) { | 156 for(i = 0; i < 4; i++) { |
149 pa[0] = pb[0]; | 157 pa[0] = pb[0]; |
150 pa[1] = pb[1]; | 158 pa[1] = pb[1]; |
152 pa[3] = pb[3]; | 160 pa[3] = pb[3]; |
153 pa += ri->y_stride; | 161 pa += ri->y_stride; |
154 pb += ri->y_stride; | 162 pb += ri->y_stride; |
155 } | 163 } |
156 | 164 |
157 #if 0 | |
158 pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2; | |
159 pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2; | |
160 for(i = 0; i < 2; i++) { | |
161 pa[0] = pb[0]; | |
162 pa[1] = pb[1]; | |
163 pa += ri->c_stride; | |
164 pb += ri->c_stride; | |
165 } | |
166 | |
167 pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2; | |
168 pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2; | |
169 for(i = 0; i < 2; i++) { | |
170 pa[0] = pb[0]; | |
171 pa[1] = pb[1]; | |
172 pa += ri->c_stride; | |
173 pb += ri->c_stride; | |
174 } | |
175 #else | |
176 hw = ri->y_stride/2; | 165 hw = ri->y_stride/2; |
177 pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; | 166 pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; |
178 pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; | 167 pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; |
179 | 168 |
180 for(i = 0; i < 2; i++) { | 169 for(i = 0; i < 2; i++) { |
210 } | 199 } |
211 | 200 |
212 pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; | 201 pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; |
213 pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; | 202 pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; |
214 } | 203 } |
215 #endif | |
216 } | 204 } |
217 | 205 |
218 static void apply_motion_8x8(RoqContext *ri, int x, int y, | 206 static void apply_motion_8x8(RoqContext *ri, int x, int y, |
219 unsigned char mv, signed char mean_x, signed char mean_y) | 207 unsigned char mv, signed char mean_x, signed char mean_y) |
220 { | 208 { |
221 int mx, my, i, j, hw; | 209 int mx, my, i, j, hw; |
222 unsigned char *pa, *pb; | 210 unsigned char *pa, *pb; |
223 | 211 |
224 mx = x + 8 - (mv >> 4) - mean_x; | 212 mx = x + 8 - (mv >> 4) - mean_x; |
225 my = y + 8 - (mv & 0xf) - mean_y; | 213 my = y + 8 - (mv & 0xf) - mean_y; |
214 | |
215 /* check MV against frame boundaries */ | |
216 if ((mx < 0) || (mx > ri->avctx->width - 8) || | |
217 (my < 0) || (my > ri->avctx->height - 8)) { | |
218 av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", | |
219 mx, my, ri->avctx->width, ri->avctx->height); | |
220 return; | |
221 } | |
226 | 222 |
227 pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; | 223 pa = ri->current_frame.data[0] + (y * ri->y_stride) + x; |
228 pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; | 224 pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx; |
229 for(i = 0; i < 8; i++) { | 225 for(i = 0; i < 8; i++) { |
230 pa[0] = pb[0]; | 226 pa[0] = pb[0]; |
237 pa[7] = pb[7]; | 233 pa[7] = pb[7]; |
238 pa += ri->y_stride; | 234 pa += ri->y_stride; |
239 pb += ri->y_stride; | 235 pb += ri->y_stride; |
240 } | 236 } |
241 | 237 |
242 #if 0 | |
243 pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2; | |
244 pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2; | |
245 for(i = 0; i < 4; i++) { | |
246 pa[0] = pb[0]; | |
247 pa[1] = pb[1]; | |
248 pa[2] = pb[2]; | |
249 pa[3] = pb[3]; | |
250 pa += ri->c_stride; | |
251 pb += ri->c_stride; | |
252 } | |
253 | |
254 pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2; | |
255 pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2; | |
256 for(i = 0; i < 4; i++) { | |
257 pa[0] = pb[0]; | |
258 pa[1] = pb[1]; | |
259 pa[2] = pb[2]; | |
260 pa[3] = pb[3]; | |
261 pa += ri->c_stride; | |
262 pb += ri->c_stride; | |
263 } | |
264 #else | |
265 hw = ri->c_stride; | 238 hw = ri->c_stride; |
266 pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; | 239 pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2; |
267 pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; | 240 pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; |
268 for(j = 0; j < 2; j++) { | 241 for(j = 0; j < 2; j++) { |
269 for(i = 0; i < 4; i++) { | 242 for(i = 0; i < 4; i++) { |
302 } | 275 } |
303 | 276 |
304 pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; | 277 pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2; |
305 pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; | 278 pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; |
306 } | 279 } |
307 #endif | |
308 } | 280 } |
309 | 281 |
310 static void roqvideo_decode_frame(RoqContext *ri) | 282 static void roqvideo_decode_frame(RoqContext *ri) |
311 { | 283 { |
312 unsigned int chunk_id = 0, chunk_arg = 0; | 284 unsigned int chunk_id = 0, chunk_arg = 0; |
479 static int roq_decode_end(AVCodecContext *avctx) | 451 static int roq_decode_end(AVCodecContext *avctx) |
480 { | 452 { |
481 RoqContext *s = avctx->priv_data; | 453 RoqContext *s = avctx->priv_data; |
482 | 454 |
483 /* release the last frame */ | 455 /* release the last frame */ |
484 avctx->release_buffer(avctx, &s->last_frame); | 456 if (s->last_frame.data[0]) |
457 avctx->release_buffer(avctx, &s->last_frame); | |
485 | 458 |
486 return 0; | 459 return 0; |
487 } | 460 } |
488 | 461 |
489 AVCodec roq_decoder = { | 462 AVCodec roq_decoder = { |