1/* 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 12/**************************************************************************** 13* 14* Module Title : preproc.c 15* 16* Description : Simple pre-processor. 17* 18****************************************************************************/ 19 20/**************************************************************************** 21* Header Files 22****************************************************************************/ 23 24#include "memory.h" 25#include "preproc7.h" 26#include "vpx_mem/vpx_mem.h" 27 28/**************************************************************************** 29* Macros 30****************************************************************************/ 31#define FRAMECOUNT 7 32#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) ) 33 34/**************************************************************************** 35* Imports 36****************************************************************************/ 37extern void vp8_get_processor_flags(int *mmx_enabled, int *xmm_enabled, int *wmt_enabled); 38 39/**************************************************************************** 40* Exported Global Variables 41****************************************************************************/ 42void (*temp_filter)(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int bytes, int strength); 43void temp_filter_mmx 44( 45 pre_proc_instance *ppi, 46 unsigned char *s, 47 unsigned char *d, 48 int bytes, 49 int strength 50); 51void temp_filter_wmt 52( 53 pre_proc_instance *ppi, 54 unsigned char *s, 55 unsigned char *d, 56 int bytes, 57 int strength 58); 59 60/**************************************************************************** 61 * 62 * ROUTINE : temp_filter_c 63 * 64 * INPUTS : pre_proc_instance *ppi : Pointer to pre-processor instance. 65 * unsigned char *s : Pointer to source frame. 66 * unsigned char *d : Pointer to destination frame. 67 * int bytes : Number of bytes to filter. 68 * int strength : Strength of filter to apply. 69 * 70 * OUTPUTS : None. 71 * 72 * RETURNS : void 73 * 74 * FUNCTION : Performs a closesness adjusted temporarl blur 75 * 76 * SPECIAL NOTES : Destination frame can be same as source frame. 77 * 78 ****************************************************************************/ 79void temp_filter_c 80( 81 pre_proc_instance *ppi, 82 unsigned char *s, 83 unsigned char *d, 84 int bytes, 85 int strength 86) 87{ 88 int byte = 0; 89 unsigned char *frameptr = ppi->frame_buffer; 90 91 if (ppi->frame == 0) 92 { 93 do 94 { 95 int frame = 0; 96 97 do 98 { 99 *frameptr = s[byte]; 100 ++frameptr; 101 ++frame; 102 } 103 while (frame < FRAMECOUNT); 104 105 d[byte] = s[byte]; 106 107 ++byte; 108 } 109 while (byte < bytes); 110 } 111 else 112 { 113 int modifier; 114 int offset = (ppi->frame % FRAMECOUNT); 115 116 do 117 { 118 int accumulator = 0; 119 int count = 0; 120 int frame = 0; 121 122 frameptr[offset] = s[byte]; 123 124 do 125 { 126 int pixel_value = *frameptr; 127 128 modifier = s[byte]; 129 modifier -= pixel_value; 130 modifier *= modifier; 131 modifier >>= strength; 132 modifier *= 3; 133 134 if (modifier > 16) 135 modifier = 16; 136 137 modifier = 16 - modifier; 138 139 accumulator += modifier * pixel_value; 140 141 count += modifier; 142 143 frameptr++; 144 145 ++frame; 146 } 147 while (frame < FRAMECOUNT); 148 149 accumulator += (count >> 1); 150 accumulator *= ppi->fixed_divide[count]; 151 accumulator >>= 16; 152 153 d[byte] = accumulator; 154 155 ++byte; 156 } 157 while (byte < bytes); 158 } 159 160 ++ppi->frame; 161} 162/**************************************************************************** 163 * 164 * ROUTINE : delete_pre_proc 165 * 166 * INPUTS : pre_proc_instance *ppi : Pointer to pre-processor instance. 167 * 168 * OUTPUTS : None. 169 * 170 * RETURNS : void 171 * 172 * FUNCTION : Deletes a pre-processing instance. 173 * 174 * SPECIAL NOTES : None. 175 * 176 ****************************************************************************/ 177void delete_pre_proc(pre_proc_instance *ppi) 178{ 179 if (ppi->frame_buffer_alloc) 180 vpx_free(ppi->frame_buffer_alloc); 181 182 ppi->frame_buffer_alloc = 0; 183 ppi->frame_buffer = 0; 184 185 if (ppi->fixed_divide_alloc) 186 vpx_free(ppi->fixed_divide_alloc); 187 188 ppi->fixed_divide_alloc = 0; 189 ppi->fixed_divide = 0; 190} 191 192/**************************************************************************** 193 * 194 * ROUTINE : init_pre_proc 195 * 196 * INPUTS : pre_proc_instance *ppi : Pointer to pre-processor instance. 197 * int frame_size : Number of bytes in one frame. 198 * 199 * OUTPUTS : None. 200 * 201 * RETURNS : int: 1 if successful, 0 if failed. 202 * 203 * FUNCTION : Initializes prepprocessor instance. 204 * 205 * SPECIAL NOTES : None. 206 * 207 ****************************************************************************/ 208int init_pre_proc7(pre_proc_instance *ppi, int frame_size) 209{ 210 int i; 211 int mmx_enabled; 212 int xmm_enabled; 213 int wmt_enabled; 214 215 vp8_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled); 216 217 if (wmt_enabled) 218 temp_filter = temp_filter_wmt; 219 else if (mmx_enabled) 220 temp_filter = temp_filter_mmx; 221 else 222 temp_filter = temp_filter_c; 223 224 225 delete_pre_proc(ppi); 226 227 ppi->frame_buffer_alloc = vpx_malloc(32 + frame_size * FRAMECOUNT * sizeof(unsigned char)); 228 229 if (!ppi->frame_buffer_alloc) 230 { 231 delete_pre_proc(ppi); 232 return 0; 233 } 234 235 ppi->frame_buffer = (unsigned char *) ROUNDUP32(ppi->frame_buffer_alloc); 236 237 ppi->fixed_divide_alloc = vpx_malloc(32 + 255 * sizeof(unsigned int)); 238 239 if (!ppi->fixed_divide_alloc) 240 { 241 delete_pre_proc(ppi); 242 return 0; 243 } 244 245 ppi->fixed_divide = (unsigned int *) ROUNDUP32(ppi->fixed_divide_alloc); 246 247 for (i = 1; i < 255; i++) 248 ppi->fixed_divide[i] = 0x10000 / i; 249 250 return 1; 251} 252