1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
|
/*****************************************************************
* gavl - a general purpose audio/video processing library
*
* Copyright (c) 2001 - 2012 Members of the Gmerlin project
* gmerlin-general@lists.sourceforge.net
* http://gmerlin.sourceforge.net
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* *****************************************************************/
#ifndef _GAVL_SCALE_H_
#define _GAVL_SCALE_H_
#include <config.h>
#include "video.h"
#include "attributes.h"
/* Typedefs */
typedef struct gavl_video_scale_context_s gavl_video_scale_context_t;
typedef struct
{
int index; /* Index of the first row/column */
int32_t * factor_i;
float * factor_f;
} gavl_video_scale_pixel_t;
typedef struct
{
int pixels_alloc;
int factors_alloc;
int num_pixels; /* Number of pixels (rows/columns) in the output area */
float * factors_f;
int32_t * factors_i;
gavl_video_scale_pixel_t * pixels;
int factors_per_pixel;
int do_clip; /* Use routines with clipping */
int normalized;
} gavl_video_scale_table_t;
typedef void
(*gavl_video_scale_scanline_func)(gavl_video_scale_context_t*, int scanline, uint8_t * dst);
typedef float
(*gavl_video_scale_get_weight)(gavl_video_options_t * opt, double t);
gavl_video_scale_get_weight
gavl_video_scale_get_weight_func(gavl_video_options_t * opt,
int * num_points)
__attribute__ ((visibility("default")));
/* Scale functions */
typedef struct
{
gavl_video_scale_scanline_func scale_rgb_15;
gavl_video_scale_scanline_func scale_rgb_16;
gavl_video_scale_scanline_func scale_uint8_x_1_noadvance;
gavl_video_scale_scanline_func scale_uint8_x_1_advance;
gavl_video_scale_scanline_func scale_uint8_x_2;
gavl_video_scale_scanline_func scale_uint8_x_3;
gavl_video_scale_scanline_func scale_uint8_x_4;
gavl_video_scale_scanline_func scale_uint16_x_1;
gavl_video_scale_scanline_func scale_uint16_x_2;
gavl_video_scale_scanline_func scale_uint16_x_3;
gavl_video_scale_scanline_func scale_uint16_x_4;
gavl_video_scale_scanline_func scale_float_x_1;
gavl_video_scale_scanline_func scale_float_x_2;
gavl_video_scale_scanline_func scale_float_x_3;
gavl_video_scale_scanline_func scale_float_x_4;
/* Bits needed for the integer scaling coefficient */
int bits_rgb_15;
int bits_rgb_16;
int bits_uint8_noadvance;
int bits_uint8_advance;
int bits_uint16;
} gavl_scale_func_tab_t;
typedef struct
{
gavl_scale_func_tab_t funcs_x;
gavl_scale_func_tab_t funcs_y;
gavl_scale_func_tab_t funcs_xy;
} gavl_scale_funcs_t;
void gavl_init_scale_funcs_nearest_c(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bilinear_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bilinear_noclip_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bilinear_fast_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_quadratic_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_quadratic_noclip_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bicubic_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bicubic_noclip_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_generic_c(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_generic_noclip_c(gavl_scale_funcs_t * tab);
#ifdef HAVE_MMX
void gavl_init_scale_funcs_bicubic_y_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_quadratic_y_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_generic_y_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bilinear_y_mmx(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
void gavl_init_scale_funcs_bicubic_x_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_quadratic_x_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bicubic_noclip_x_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_generic_x_mmx(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bilinear_x_mmx(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
/* */
void gavl_init_scale_funcs_bicubic_y_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_quadratic_y_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_generic_y_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bilinear_y_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bicubic_x_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_quadratic_x_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bicubic_noclip_x_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_generic_x_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bilinear_x_mmxext(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
#endif
#ifdef HAVE_SSE
void gavl_init_scale_funcs_quadratic_y_sse(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
void gavl_init_scale_funcs_bicubic_y_sse(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
void gavl_init_scale_funcs_bicubic_y_noclip_sse(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
void gavl_init_scale_funcs_generic_y_sse(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
void gavl_init_scale_funcs_bilinear_y_sse(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
void gavl_init_scale_funcs_quadratic_x_sse(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bicubic_x_sse(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bicubic_x_noclip_sse(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_generic_x_sse(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bilinear_x_sse(gavl_scale_funcs_t * tab);
#endif
#ifdef HAVE_SSE2
void gavl_init_scale_funcs_bicubic_y_sse2(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bicubic_y_noclip_sse2(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_quadratic_y_sse2(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_generic_y_sse2(gavl_scale_funcs_t * tab,
int src_advance,
int dst_advance);
void gavl_init_scale_funcs_bilinear_y_sse2(gavl_scale_funcs_t * tab,
int src_advance, int dst_advance);
#endif
#ifdef HAVE_SSE3
void gavl_init_scale_funcs_bicubic_x_sse3(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_bicubic_x_noclip_sse3(gavl_scale_funcs_t * tab);
void gavl_init_scale_funcs_generic_x_sse3(gavl_scale_funcs_t * tab);
#endif
void gavl_init_scale_funcs(gavl_scale_funcs_t * tab,
gavl_video_options_t * opt,
int src_advance,
int dst_advance,
gavl_video_scale_table_t * tab_h,
gavl_video_scale_table_t * tab_v);
void gavl_video_scale_table_init(gavl_video_scale_table_t * tab,
gavl_video_options_t * opt,
double src_off, double src_size,
int dst_size,
int src_width);
void
gavl_video_scale_table_init_convolve(gavl_video_scale_table_t * tab,
gavl_video_options_t * opt,
int num_coeffs, const float * coeffs,
int size);
void gavl_video_scale_table_init_int(gavl_video_scale_table_t * tab,
int bits);
void gavl_video_scale_table_get_src_indices(gavl_video_scale_table_t * tab,
int * start, int * size);
void gavl_video_scale_table_shift_indices(gavl_video_scale_table_t * tab,
int shift);
void gavl_video_scale_table_cleanup(gavl_video_scale_table_t * tab);
/* For debugging */
void gavl_video_scale_table_dump(gavl_video_scale_table_t * tab);
/* Data needed by the scaline function. */
typedef struct
{
/* Offsets and advances are ALWAYS in bytes */
int src_advance, dst_advance;
int src_offset, dst_offset;
} gavl_video_scale_offsets_t;
/*
* Scale context is for one plane of one field.
* This means, that depending on the video format, we have 1 - 6 scale contexts.
*/
struct gavl_video_scale_context_s
{
/* Data initialized at start */
gavl_video_scale_table_t table_h;
gavl_video_scale_table_t table_v;
gavl_video_scale_scanline_func func1;
gavl_video_scale_scanline_func func2;
gavl_video_scale_offsets_t offset1;
gavl_video_scale_offsets_t offset2;
/* Rectangles */
gavl_rectangle_f_t src_rect;
gavl_rectangle_i_t dst_rect;
/* Indices of source and destination planes inside the frame. Can be 0 for chroma channels of
packed YUV formats */
int src_frame_plane, dst_frame_plane;
int plane; /* Plane */
/* Advances */
gavl_video_scale_offsets_t * offset;
/* Temporary buffer */
uint8_t * buffer;
int buffer_alloc;
int buffer_stride;
/* Size of temporary buffer in pixels */
int buffer_width;
int buffer_height;
int num_directions;
/* Minimum and maximum values for clipping.
Values can be different for different components */
int min_values_h[4];
int max_values_h[4];
int min_values_v[4];
int max_values_v[4];
float min_values_f[4];
float max_values_f[4];
/* For copying */
int bytes_per_line;
uint8_t * src;
int src_stride;
gavl_video_frame_t * dst_frame;
const gavl_video_options_t * opt;
// uint8_t * dst;
// int scanline;
int dst_size;
int first_scanline;
#ifdef HAVE_MMX
int need_emms;
#endif
};
int gavl_video_scale_context_init(gavl_video_scale_context_t*,
gavl_video_options_t * opt,
int plane,
const gavl_video_format_t * input_format,
const gavl_video_format_t * output_format,
int src_field, int dst_field,
int src_fields, int dst_fields);
int gavl_video_scale_context_init_convolve(gavl_video_scale_context_t*,
gavl_video_options_t * opt,
int plane,
const gavl_video_format_t * format,
int num_fields,
int h_radius, const float * h_coeffs,
int v_radius, const float * v_coeffs);
void gavl_video_scale_context_cleanup(gavl_video_scale_context_t * ctx);
void gavl_video_scale_context_scale(gavl_video_scale_context_t * ctx,
const gavl_video_frame_t * src,
gavl_video_frame_t * dst);
struct gavl_video_scaler_s
{
gavl_video_options_t opt;
/*
* a context is obtained with contexts[field][plane].
* field == 2 contains a progressive scaler, which might be
* required for frame based interlacing
*/
gavl_video_scale_context_t contexts[3][GAVL_MAX_PLANES];
int num_planes;
/* If src_fields > dst_fields, we deinterlace */
int src_fields;
int dst_fields;
gavl_video_frame_t * src;
gavl_video_frame_t * dst;
gavl_video_frame_t * src_field;
gavl_video_frame_t * dst_field;
gavl_video_format_t src_format;
gavl_video_format_t dst_format;
gavl_rectangle_i_t dst_rect;
// gavl_rectangle_f_t src_rect;
};
#endif // _GAVL_SCALE_H_
|