PageRenderTime 63ms CodeModel.GetById 14ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 0ms

/libavcodec/roqvideo.c

http://github.com/FFmpeg/FFmpeg
C | 143 lines | 94 code | 24 blank | 25 comment | 5 complexity | 5075220529ab642b214765a7fdb280e8 MD5 | raw file
  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 "avcodec.h"
 28#include "roqvideo.h"
 29
 30static 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
 41void 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
 71void 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
102static 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]) {
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
133void 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
139void 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}