2
2
* Copyright (C) 2003 the ffmpeg project
4
* This library is free software; you can redistribute it and/or
4
* This file is part of FFmpeg.
6
* FFmpeg is free software; you can redistribute it and/or
5
7
* modify it under the terms of the GNU Lesser General Public
6
8
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* version 2.1 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
11
* FFmpeg is distributed in the hope that it will be useful,
10
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
14
* Lesser General Public License for more details.
14
16
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
* License along with FFmpeg; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
83
89
unsigned char *yptr;
85
yptr = ri->current_frame.data[0] + (y * ri->y_stride) + x;
91
yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
86
92
*yptr++ = cell->y0;
87
93
*yptr++ = cell->y1;
88
94
yptr += (ri->y_stride - 2);
89
95
*yptr++ = cell->y2;
90
96
*yptr++ = cell->y3;
91
ri->current_frame.data[1][(y/2) * (ri->c_stride) + x/2] = cell->u;
92
ri->current_frame.data[2][(y/2) * (ri->c_stride) + x/2] = cell->v;
97
ri->current_frame->data[1][(y/2) * (ri->c_stride) + x/2] = cell->u;
98
ri->current_frame->data[2][(y/2) * (ri->c_stride) + x/2] = cell->v;
95
101
static void apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell)
98
104
register unsigned char y0, y1, u, v;
99
105
unsigned char *yptr, *uptr, *vptr;
101
yptr = ri->current_frame.data[0] + (y * ri->y_stride) + x;
102
uptr = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;
103
vptr = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;
107
yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x;
108
uptr = ri->current_frame->data[1] + (y/2) * (ri->c_stride) + x/2;
109
vptr = ri->current_frame->data[2] + (y/2) * (ri->c_stride) + x/2;
105
111
row_inc = ri->y_stride - 4;
106
112
c_row_inc = (ri->c_stride) - 2;
134
140
static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv,
135
char mean_x, char mean_y)
141
signed char mean_x, signed char mean_y)
138
144
unsigned char *pa, *pb;
140
146
mx = x + 8 - (mv >> 4) - mean_x;
141
147
my = y + 8 - (mv & 0xf) - mean_y;
143
pa = ri->current_frame.data[0] + (y * ri->y_stride) + x;
144
pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx;
149
/* check MV against frame boundaries */
150
if ((mx < 0) || (mx > ri->avctx->width - 4) ||
151
(my < 0) || (my > ri->avctx->height - 4)) {
152
av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
153
mx, my, ri->avctx->width, ri->avctx->height);
157
pa = ri->current_frame->data[0] + (y * ri->y_stride) + x;
158
pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx;
145
159
for(i = 0; i < 4; i++) {
151
165
pb += ri->y_stride;
154
pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;
155
pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2;
156
for(i = 0; i < 2; i++) {
163
pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;
164
pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2;
165
for(i = 0; i < 2; i++) {
169
pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2;
170
pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
172
for(i = 0; i < 2; i++) {
173
switch(((my & 0x01) << 1) | (mx & 0x01)) {
183
pa[0] = avg2(pb[0], pb[1]);
184
pa[1] = avg2(pb[1], pb[2]);
185
pa[hw] = avg2(pb[hw], pb[hw+1]);
186
pa[hw+1] = avg2(pb[hw+1], pb[hw+2]);
190
pa[0] = avg2(pb[0], pb[hw]);
191
pa[1] = avg2(pb[1], pb[hw+1]);
192
pa[hw] = avg2(pb[hw], pb[hw*2]);
193
pa[hw+1] = avg2(pb[hw+1], pb[(hw*2)+1]);
197
pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]);
198
pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]);
199
pa[hw] = avg4(pb[hw], pb[hw+1], pb[hw*2], pb[(hw*2)+1]);
200
pa[hw+1] = avg4(pb[hw+1], pb[hw+2], pb[(hw*2)+1], pb[(hw*2)+1]);
204
pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
205
pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
173
209
static void apply_motion_8x8(RoqContext *ri, int x, int y,
174
unsigned char mv, char mean_x, char mean_y)
210
unsigned char mv, signed char mean_x, signed char mean_y)
212
int mx, my, i, j, hw;
177
213
unsigned char *pa, *pb;
179
215
mx = x + 8 - (mv >> 4) - mean_x;
180
216
my = y + 8 - (mv & 0xf) - mean_y;
182
pa = ri->current_frame.data[0] + (y * ri->y_stride) + x;
183
pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx;
218
/* check MV against frame boundaries */
219
if ((mx < 0) || (mx > ri->avctx->width - 8) ||
220
(my < 0) || (my > ri->avctx->height - 8)) {
221
av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",
222
mx, my, ri->avctx->width, ri->avctx->height);
226
pa = ri->current_frame->data[0] + (y * ri->y_stride) + x;
227
pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx;
184
228
for(i = 0; i < 8; i++) {
194
238
pb += ri->y_stride;
197
pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;
198
pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2;
199
for(i = 0; i < 4; i++) {
208
pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;
209
pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2;
210
for(i = 0; i < 4; i++) {
242
pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2;
243
pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
244
for(j = 0; j < 2; j++) {
245
for(i = 0; i < 4; i++) {
246
switch(((my & 0x01) << 1) | (mx & 0x01)) {
256
pa[0] = avg2(pb[0], pb[1]);
257
pa[1] = avg2(pb[1], pb[2]);
258
pa[2] = avg2(pb[2], pb[3]);
259
pa[3] = avg2(pb[3], pb[4]);
263
pa[0] = avg2(pb[0], pb[hw]);
264
pa[1] = avg2(pb[1], pb[hw+1]);
265
pa[2] = avg2(pb[2], pb[hw+2]);
266
pa[3] = avg2(pb[3], pb[hw+3]);
270
pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]);
271
pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]);
272
pa[2] = avg4(pb[2], pb[3], pb[hw+2], pb[hw+3]);
273
pa[3] = avg4(pb[3], pb[4], pb[hw+3], pb[hw+4]);
280
pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2;
281
pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;
300
365
apply_motion_4x4(ri, x, y, 0, 8, 8);
303
apply_motion_4x4(ri, x, y, buf[bpos++],
368
apply_motion_4x4(ri, x, y, buf[bpos++],
304
369
chunk_arg >> 8, chunk_arg & 0xff);
339
404
static int roq_decode_init(AVCodecContext *avctx)
341
406
RoqContext *s = avctx->priv_data;
343
409
s->avctx = avctx;
344
410
s->first_frame = 1;
411
s->last_frame = &s->frames[0];
412
s->current_frame = &s->frames[1];
345
413
avctx->pix_fmt = PIX_FMT_YUV420P;
346
414
avctx->has_b_frames = 0;
347
415
dsputil_init(&s->dsp, avctx);
418
for(i = -512; i < 512; i++)
419
uiclp[i] = (i < 0 ? 0 : (i > 255 ? 255 : i));
356
428
RoqContext *s = avctx->priv_data;
360
if (avctx->get_buffer(avctx, &s->current_frame)) {
361
printf (" RoQ: get_buffer() failed\n");
430
if (avctx->get_buffer(avctx, s->current_frame)) {
431
av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n");
364
s->y_stride = s->current_frame.linesize[0];
365
s->c_stride = s->current_frame.linesize[1];
434
s->y_stride = s->current_frame->linesize[0];
435
s->c_stride = s->current_frame->linesize[1];
368
438
s->size = buf_size;
372
442
if (s->first_frame)
373
443
s->first_frame = 0;
375
avctx->release_buffer(avctx, &s->last_frame);
445
avctx->release_buffer(avctx, s->last_frame);
447
*data_size = sizeof(AVFrame);
448
*(AVFrame*)data = *s->current_frame;
377
450
/* shuffle frames */
378
s->last_frame = s->current_frame;
380
*data_size = sizeof(AVFrame);
381
*(AVFrame*)data = s->current_frame;
451
FFSWAP(AVFrame *, s->current_frame, s->last_frame);