Statistics
| Branch: | Revision:

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 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 "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
}