1/* 2 * Misc image conversion routines 3 * Copyright (c) 2001, 2002, 2003 Fabrice Bellard 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 * misc image conversion routines 25 */ 26 27/* TODO: 28 * - write 'ffimg' program to test all the image related stuff 29 * - move all api to slice based system 30 * - integrate deinterlacing, postprocessing and scaling in the conversion process 31 */ 32 33#include "avcodec.h" 34#include "dsputil.h" 35#include "internal.h" 36#include "imgconvert.h" 37#include "libavutil/colorspace.h" 38#include "libavutil/pixdesc.h" 39#include "libavutil/imgutils.h" 40 41#if HAVE_MMX && HAVE_YASM 42#include "x86/dsputil_mmx.h" 43#endif 44 45#define FF_COLOR_RGB 0 /**< RGB color space */ 46#define FF_COLOR_GRAY 1 /**< gray color space */ 47#define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ 48#define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ 49 50#define FF_PIXEL_PLANAR 0 /**< each channel has one component in AVPicture */ 51#define FF_PIXEL_PACKED 1 /**< only one components containing all the channels */ 52#define FF_PIXEL_PALETTE 2 /**< one components containing indexes for a palette */ 53 54#if HAVE_MMX && HAVE_YASM 55#define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx 56#define deinterlace_line ff_deinterlace_line_mmx 57#else 58#define deinterlace_line_inplace deinterlace_line_inplace_c 59#define deinterlace_line deinterlace_line_c 60#endif 61 62typedef struct PixFmtInfo { 63 uint8_t nb_channels; /**< number of channels (including alpha) */ 64 uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */ 65 uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */ 66 uint8_t is_alpha : 1; /**< true if alpha can be specified */ 67 uint8_t depth; /**< bit depth of the color components */ 68} PixFmtInfo; 69 70/* this table gives more information about formats */ 71static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { 72 /* YUV formats */ 73 [PIX_FMT_YUV420P] = { 74 .nb_channels = 3, 75 .color_type = FF_COLOR_YUV, 76 .pixel_type = FF_PIXEL_PLANAR, 77 .depth = 8, 78 }, 79 [PIX_FMT_YUV422P] = { 80 .nb_channels = 3, 81 .color_type = FF_COLOR_YUV, 82 .pixel_type = FF_PIXEL_PLANAR, 83 .depth = 8, 84 }, 85 [PIX_FMT_YUV444P] = { 86 .nb_channels = 3, 87 .color_type = FF_COLOR_YUV, 88 .pixel_type = FF_PIXEL_PLANAR, 89 .depth = 8, 90 }, 91 [PIX_FMT_YUYV422] = { 92 .nb_channels = 1, 93 .color_type = FF_COLOR_YUV, 94 .pixel_type = FF_PIXEL_PACKED, 95 .depth = 8, 96 }, 97 [PIX_FMT_UYVY422] = { 98 .nb_channels = 1, 99 .color_type = FF_COLOR_YUV, 100 .pixel_type = FF_PIXEL_PACKED, 101 .depth = 8, 102 }, 103 [PIX_FMT_YUV410P] = { 104 .nb_channels = 3, 105 .color_type = FF_COLOR_YUV, 106 .pixel_type = FF_PIXEL_PLANAR, 107 .depth = 8, 108 }, 109 [PIX_FMT_YUV411P] = { 110 .nb_channels = 3, 111 .color_type = FF_COLOR_YUV, 112 .pixel_type = FF_PIXEL_PLANAR, 113 .depth = 8, 114 }, 115 [PIX_FMT_YUV440P] = { 116 .nb_channels = 3, 117 .color_type = FF_COLOR_YUV, 118 .pixel_type = FF_PIXEL_PLANAR, 119 .depth = 8, 120 }, 121 [PIX_FMT_YUV420P16LE] = { 122 .nb_channels = 3, 123 .color_type = FF_COLOR_YUV, 124 .pixel_type = FF_PIXEL_PLANAR, 125 .depth = 16, 126 }, 127 [PIX_FMT_YUV422P16LE] = { 128 .nb_channels = 3, 129 .color_type = FF_COLOR_YUV, 130 .pixel_type = FF_PIXEL_PLANAR, 131 .depth = 16, 132 }, 133 [PIX_FMT_YUV444P16LE] = { 134 .nb_channels = 3, 135 .color_type = FF_COLOR_YUV, 136 .pixel_type = FF_PIXEL_PLANAR, 137 .depth = 16, 138 }, 139 [PIX_FMT_YUV420P16BE] = { 140 .nb_channels = 3, 141 .color_type = FF_COLOR_YUV, 142 .pixel_type = FF_PIXEL_PLANAR, 143 .depth = 16, 144 }, 145 [PIX_FMT_YUV422P16BE] = { 146 .nb_channels = 3, 147 .color_type = FF_COLOR_YUV, 148 .pixel_type = FF_PIXEL_PLANAR, 149 .depth = 16, 150 }, 151 [PIX_FMT_YUV444P16BE] = { 152 .nb_channels = 3, 153 .color_type = FF_COLOR_YUV, 154 .pixel_type = FF_PIXEL_PLANAR, 155 .depth = 16, 156 }, 157 158 159 /* YUV formats with alpha plane */ 160 [PIX_FMT_YUVA420P] = { 161 .nb_channels = 4, 162 .color_type = FF_COLOR_YUV, 163 .pixel_type = FF_PIXEL_PLANAR, 164 .depth = 8, 165 }, 166 167 /* JPEG YUV */ 168 [PIX_FMT_YUVJ420P] = { 169 .nb_channels = 3, 170 .color_type = FF_COLOR_YUV_JPEG, 171 .pixel_type = FF_PIXEL_PLANAR, 172 .depth = 8, 173 }, 174 [PIX_FMT_YUVJ422P] = { 175 .nb_channels = 3, 176 .color_type = FF_COLOR_YUV_JPEG, 177 .pixel_type = FF_PIXEL_PLANAR, 178 .depth = 8, 179 }, 180 [PIX_FMT_YUVJ444P] = { 181 .nb_channels = 3, 182 .color_type = FF_COLOR_YUV_JPEG, 183 .pixel_type = FF_PIXEL_PLANAR, 184 .depth = 8, 185 }, 186 [PIX_FMT_YUVJ440P] = { 187 .nb_channels = 3, 188 .color_type = FF_COLOR_YUV_JPEG, 189 .pixel_type = FF_PIXEL_PLANAR, 190 .depth = 8, 191 }, 192 193 /* RGB formats */ 194 [PIX_FMT_RGB24] = { 195 .nb_channels = 3, 196 .color_type = FF_COLOR_RGB, 197 .pixel_type = FF_PIXEL_PACKED, 198 .depth = 8, 199 }, 200 [PIX_FMT_BGR24] = { 201 .nb_channels = 3, 202 .color_type = FF_COLOR_RGB, 203 .pixel_type = FF_PIXEL_PACKED, 204 .depth = 8, 205 }, 206 [PIX_FMT_ARGB] = { 207 .nb_channels = 4, .is_alpha = 1, 208 .color_type = FF_COLOR_RGB, 209 .pixel_type = FF_PIXEL_PACKED, 210 .depth = 8, 211 }, 212 [PIX_FMT_RGB48BE] = { 213 .nb_channels = 3, 214 .color_type = FF_COLOR_RGB, 215 .pixel_type = FF_PIXEL_PACKED, 216 .depth = 16, 217 }, 218 [PIX_FMT_RGB48LE] = { 219 .nb_channels = 3, 220 .color_type = FF_COLOR_RGB, 221 .pixel_type = FF_PIXEL_PACKED, 222 .depth = 16, 223 }, 224 [PIX_FMT_RGB565BE] = { 225 .nb_channels = 3, 226 .color_type = FF_COLOR_RGB, 227 .pixel_type = FF_PIXEL_PACKED, 228 .depth = 5, 229 }, 230 [PIX_FMT_RGB565LE] = { 231 .nb_channels = 3, 232 .color_type = FF_COLOR_RGB, 233 .pixel_type = FF_PIXEL_PACKED, 234 .depth = 5, 235 }, 236 [PIX_FMT_RGB555BE] = { 237 .nb_channels = 3, 238 .color_type = FF_COLOR_RGB, 239 .pixel_type = FF_PIXEL_PACKED, 240 .depth = 5, 241 }, 242 [PIX_FMT_RGB555LE] = { 243 .nb_channels = 3, 244 .color_type = FF_COLOR_RGB, 245 .pixel_type = FF_PIXEL_PACKED, 246 .depth = 5, 247 }, 248 [PIX_FMT_RGB444BE] = { 249 .nb_channels = 3, 250 .color_type = FF_COLOR_RGB, 251 .pixel_type = FF_PIXEL_PACKED, 252 .depth = 4, 253 }, 254 [PIX_FMT_RGB444LE] = { 255 .nb_channels = 3, 256 .color_type = FF_COLOR_RGB, 257 .pixel_type = FF_PIXEL_PACKED, 258 .depth = 4, 259 }, 260 261 /* gray / mono formats */ 262 [PIX_FMT_GRAY16BE] = { 263 .nb_channels = 1, 264 .color_type = FF_COLOR_GRAY, 265 .pixel_type = FF_PIXEL_PLANAR, 266 .depth = 16, 267 }, 268 [PIX_FMT_GRAY16LE] = { 269 .nb_channels = 1, 270 .color_type = FF_COLOR_GRAY, 271 .pixel_type = FF_PIXEL_PLANAR, 272 .depth = 16, 273 }, 274 [PIX_FMT_GRAY8] = { 275 .nb_channels = 1, 276 .color_type = FF_COLOR_GRAY, 277 .pixel_type = FF_PIXEL_PLANAR, 278 .depth = 8, 279 }, 280 [PIX_FMT_MONOWHITE] = { 281 .nb_channels = 1, 282 .color_type = FF_COLOR_GRAY, 283 .pixel_type = FF_PIXEL_PLANAR, 284 .depth = 1, 285 }, 286 [PIX_FMT_MONOBLACK] = { 287 .nb_channels = 1, 288 .color_type = FF_COLOR_GRAY, 289 .pixel_type = FF_PIXEL_PLANAR, 290 .depth = 1, 291 }, 292 293 /* paletted formats */ 294 [PIX_FMT_PAL8] = { 295 .nb_channels = 4, .is_alpha = 1, 296 .color_type = FF_COLOR_RGB, 297 .pixel_type = FF_PIXEL_PALETTE, 298 .depth = 8, 299 }, 300 [PIX_FMT_UYYVYY411] = { 301 .nb_channels = 1, 302 .color_type = FF_COLOR_YUV, 303 .pixel_type = FF_PIXEL_PACKED, 304 .depth = 8, 305 }, 306 [PIX_FMT_ABGR] = { 307 .nb_channels = 4, .is_alpha = 1, 308 .color_type = FF_COLOR_RGB, 309 .pixel_type = FF_PIXEL_PACKED, 310 .depth = 8, 311 }, 312 [PIX_FMT_BGR565BE] = { 313 .nb_channels = 3, 314 .color_type = FF_COLOR_RGB, 315 .pixel_type = FF_PIXEL_PACKED, 316 .depth = 5, 317 }, 318 [PIX_FMT_BGR565LE] = { 319 .nb_channels = 3, 320 .color_type = FF_COLOR_RGB, 321 .pixel_type = FF_PIXEL_PACKED, 322 .depth = 5, 323 }, 324 [PIX_FMT_BGR555BE] = { 325 .nb_channels = 3, 326 .color_type = FF_COLOR_RGB, 327 .pixel_type = FF_PIXEL_PACKED, 328 .depth = 5, 329 }, 330 [PIX_FMT_BGR555LE] = { 331 .nb_channels = 3, 332 .color_type = FF_COLOR_RGB, 333 .pixel_type = FF_PIXEL_PACKED, 334 .depth = 5, 335 }, 336 [PIX_FMT_BGR444BE] = { 337 .nb_channels = 3, 338 .color_type = FF_COLOR_RGB, 339 .pixel_type = FF_PIXEL_PACKED, 340 .depth = 4, 341 }, 342 [PIX_FMT_BGR444LE] = { 343 .nb_channels = 3, 344 .color_type = FF_COLOR_RGB, 345 .pixel_type = FF_PIXEL_PACKED, 346 .depth = 4, 347 }, 348 [PIX_FMT_RGB8] = { 349 .nb_channels = 1, 350 .color_type = FF_COLOR_RGB, 351 .pixel_type = FF_PIXEL_PACKED, 352 .depth = 8, 353 }, 354 [PIX_FMT_RGB4] = { 355 .nb_channels = 1, 356 .color_type = FF_COLOR_RGB, 357 .pixel_type = FF_PIXEL_PACKED, 358 .depth = 4, 359 }, 360 [PIX_FMT_RGB4_BYTE] = { 361 .nb_channels = 1, 362 .color_type = FF_COLOR_RGB, 363 .pixel_type = FF_PIXEL_PACKED, 364 .depth = 8, 365 }, 366 [PIX_FMT_BGR8] = { 367 .nb_channels = 1, 368 .color_type = FF_COLOR_RGB, 369 .pixel_type = FF_PIXEL_PACKED, 370 .depth = 8, 371 }, 372 [PIX_FMT_BGR4] = { 373 .nb_channels = 1, 374 .color_type = FF_COLOR_RGB, 375 .pixel_type = FF_PIXEL_PACKED, 376 .depth = 4, 377 }, 378 [PIX_FMT_BGR4_BYTE] = { 379 .nb_channels = 1, 380 .color_type = FF_COLOR_RGB, 381 .pixel_type = FF_PIXEL_PACKED, 382 .depth = 8, 383 }, 384 [PIX_FMT_NV12] = { 385 .nb_channels = 2, 386 .color_type = FF_COLOR_YUV, 387 .pixel_type = FF_PIXEL_PLANAR, 388 .depth = 8, 389 }, 390 [PIX_FMT_NV21] = { 391 .nb_channels = 2, 392 .color_type = FF_COLOR_YUV, 393 .pixel_type = FF_PIXEL_PLANAR, 394 .depth = 8, 395 }, 396 397 [PIX_FMT_BGRA] = { 398 .nb_channels = 4, .is_alpha = 1, 399 .color_type = FF_COLOR_RGB, 400 .pixel_type = FF_PIXEL_PACKED, 401 .depth = 8, 402 }, 403 [PIX_FMT_RGBA] = { 404 .nb_channels = 4, .is_alpha = 1, 405 .color_type = FF_COLOR_RGB, 406 .pixel_type = FF_PIXEL_PACKED, 407 .depth = 8, 408 }, 409}; 410 411void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift) 412{ 413 *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w; 414 *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h; 415} 416 417#if FF_API_GET_PIX_FMT_NAME 418const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt) 419{ 420 return av_get_pix_fmt_name(pix_fmt); 421} 422#endif 423 424int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt) 425{ 426 return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL; 427} 428 429int avpicture_fill(AVPicture *picture, uint8_t *ptr, 430 enum PixelFormat pix_fmt, int width, int height) 431{ 432 int ret; 433 434 if ((ret = av_image_check_size(width, height, 0, NULL)) < 0) 435 return ret; 436 437 if ((ret = av_image_fill_linesizes(picture->linesize, pix_fmt, width)) < 0) 438 return ret; 439 440 return av_image_fill_pointers(picture->data, pix_fmt, height, ptr, picture->linesize); 441} 442 443int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, 444 unsigned char *dest, int dest_size) 445{ 446 int i, j, nb_planes = 0, linesizes[4]; 447 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; 448 int size = avpicture_get_size(pix_fmt, width, height); 449 450 if (size > dest_size || size < 0) 451 return AVERROR(EINVAL); 452 453 for (i = 0; i < desc->nb_components; i++) 454 nb_planes = FFMAX(desc->comp[i].plane, nb_planes); 455 nb_planes++; 456 457 av_image_fill_linesizes(linesizes, pix_fmt, width); 458 for (i = 0; i < nb_planes; i++) { 459 int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; 460 const unsigned char *s = src->data[i]; 461 h = (height + (1 << shift) - 1) >> shift; 462 463 for (j = 0; j < h; j++) { 464 memcpy(dest, s, linesizes[i]); 465 dest += linesizes[i]; 466 s += src->linesize[i]; 467 } 468 } 469 470 if (desc->flags & PIX_FMT_PAL) 471 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4); 472 473 return size; 474} 475 476int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height) 477{ 478 AVPicture dummy_pict; 479 if(av_image_check_size(width, height, 0, NULL)) 480 return -1; 481 switch (pix_fmt) { 482 case PIX_FMT_RGB8: 483 case PIX_FMT_BGR8: 484 case PIX_FMT_RGB4_BYTE: 485 case PIX_FMT_BGR4_BYTE: 486 case PIX_FMT_GRAY8: 487 // do not include palette for these pseudo-paletted formats 488 return width * height; 489 } 490 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); 491} 492 493int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, 494 int has_alpha) 495{ 496 const PixFmtInfo *pf, *ps; 497 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt]; 498 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt]; 499 int loss; 500 501 ps = &pix_fmt_info[src_pix_fmt]; 502 503 /* compute loss */ 504 loss = 0; 505 pf = &pix_fmt_info[dst_pix_fmt]; 506 if (pf->depth < ps->depth || 507 ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE || 508 dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) && 509 (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE || 510 src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE))) 511 loss |= FF_LOSS_DEPTH; 512 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w || 513 dst_desc->log2_chroma_h > src_desc->log2_chroma_h) 514 loss |= FF_LOSS_RESOLUTION; 515 switch(pf->color_type) { 516 case FF_COLOR_RGB: 517 if (ps->color_type != FF_COLOR_RGB && 518 ps->color_type != FF_COLOR_GRAY) 519 loss |= FF_LOSS_COLORSPACE; 520 break; 521 case FF_COLOR_GRAY: 522 if (ps->color_type != FF_COLOR_GRAY) 523 loss |= FF_LOSS_COLORSPACE; 524 break; 525 case FF_COLOR_YUV: 526 if (ps->color_type != FF_COLOR_YUV) 527 loss |= FF_LOSS_COLORSPACE; 528 break; 529 case FF_COLOR_YUV_JPEG: 530 if (ps->color_type != FF_COLOR_YUV_JPEG && 531 ps->color_type != FF_COLOR_YUV && 532 ps->color_type != FF_COLOR_GRAY) 533 loss |= FF_LOSS_COLORSPACE; 534 break; 535 default: 536 /* fail safe test */ 537 if (ps->color_type != pf->color_type) 538 loss |= FF_LOSS_COLORSPACE; 539 break; 540 } 541 if (pf->color_type == FF_COLOR_GRAY && 542 ps->color_type != FF_COLOR_GRAY) 543 loss |= FF_LOSS_CHROMA; 544 if (!pf->is_alpha && (ps->is_alpha && has_alpha)) 545 loss |= FF_LOSS_ALPHA; 546 if (pf->pixel_type == FF_PIXEL_PALETTE && 547 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY)) 548 loss |= FF_LOSS_COLORQUANT; 549 return loss; 550} 551 552static int avg_bits_per_pixel(enum PixelFormat pix_fmt) 553{ 554 int bits; 555 const PixFmtInfo *pf; 556 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; 557 558 pf = &pix_fmt_info[pix_fmt]; 559 switch(pf->pixel_type) { 560 case FF_PIXEL_PACKED: 561 switch(pix_fmt) { 562 case PIX_FMT_YUYV422: 563 case PIX_FMT_UYVY422: 564 case PIX_FMT_RGB565BE: 565 case PIX_FMT_RGB565LE: 566 case PIX_FMT_RGB555BE: 567 case PIX_FMT_RGB555LE: 568 case PIX_FMT_RGB444BE: 569 case PIX_FMT_RGB444LE: 570 case PIX_FMT_BGR565BE: 571 case PIX_FMT_BGR565LE: 572 case PIX_FMT_BGR555BE: 573 case PIX_FMT_BGR555LE: 574 case PIX_FMT_BGR444BE: 575 case PIX_FMT_BGR444LE: 576 bits = 16; 577 break; 578 case PIX_FMT_UYYVYY411: 579 bits = 12; 580 break; 581 default: 582 bits = pf->depth * pf->nb_channels; 583 break; 584 } 585 break; 586 case FF_PIXEL_PLANAR: 587 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) { 588 bits = pf->depth * pf->nb_channels; 589 } else { 590 bits = pf->depth + ((2 * pf->depth) >> 591 (desc->log2_chroma_w + desc->log2_chroma_h)); 592 } 593 break; 594 case FF_PIXEL_PALETTE: 595 bits = 8; 596 break; 597 default: 598 bits = -1; 599 break; 600 } 601 return bits; 602} 603 604static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, 605 enum PixelFormat src_pix_fmt, 606 int has_alpha, 607 int loss_mask) 608{ 609 int dist, i, loss, min_dist; 610 enum PixelFormat dst_pix_fmt; 611 612 /* find exact color match with smallest size */ 613 dst_pix_fmt = PIX_FMT_NONE; 614 min_dist = 0x7fffffff; 615 /* test only the first 64 pixel formats to avoid undefined behaviour */ 616 for (i = 0; i < 64; i++) { 617 if (pix_fmt_mask & (1ULL << i)) { 618 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; 619 if (loss == 0) { 620 dist = avg_bits_per_pixel(i); 621 if (dist < min_dist) { 622 min_dist = dist; 623 dst_pix_fmt = i; 624 } 625 } 626 } 627 } 628 return dst_pix_fmt; 629} 630 631enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, 632 int has_alpha, int *loss_ptr) 633{ 634 enum PixelFormat dst_pix_fmt; 635 int loss_mask, i; 636 static const int loss_mask_order[] = { 637 ~0, /* no loss first */ 638 ~FF_LOSS_ALPHA, 639 ~FF_LOSS_RESOLUTION, 640 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), 641 ~FF_LOSS_COLORQUANT, 642 ~FF_LOSS_DEPTH, 643 0, 644 }; 645 646 /* try with successive loss */ 647 i = 0; 648 for(;;) { 649 loss_mask = loss_mask_order[i++]; 650 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, 651 has_alpha, loss_mask); 652 if (dst_pix_fmt >= 0) 653 goto found; 654 if (loss_mask == 0) 655 break; 656 } 657 return PIX_FMT_NONE; 658 found: 659 if (loss_ptr) 660 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); 661 return dst_pix_fmt; 662} 663 664void av_picture_copy(AVPicture *dst, const AVPicture *src, 665 enum PixelFormat pix_fmt, int width, int height) 666{ 667 av_image_copy(dst->data, dst->linesize, src->data, 668 src->linesize, pix_fmt, width, height); 669} 670 671/* 2x2 -> 1x1 */ 672void ff_shrink22(uint8_t *dst, int dst_wrap, 673 const uint8_t *src, int src_wrap, 674 int width, int height) 675{ 676 int w; 677 const uint8_t *s1, *s2; 678 uint8_t *d; 679 680 for(;height > 0; height--) { 681 s1 = src; 682 s2 = s1 + src_wrap; 683 d = dst; 684 for(w = width;w >= 4; w-=4) { 685 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; 686 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2; 687 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2; 688 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2; 689 s1 += 8; 690 s2 += 8; 691 d += 4; 692 } 693 for(;w > 0; w--) { 694 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; 695 s1 += 2; 696 s2 += 2; 697 d++; 698 } 699 src += 2 * src_wrap; 700 dst += dst_wrap; 701 } 702} 703 704/* 4x4 -> 1x1 */ 705void ff_shrink44(uint8_t *dst, int dst_wrap, 706 const uint8_t *src, int src_wrap, 707 int width, int height) 708{ 709 int w; 710 const uint8_t *s1, *s2, *s3, *s4; 711 uint8_t *d; 712 713 for(;height > 0; height--) { 714 s1 = src; 715 s2 = s1 + src_wrap; 716 s3 = s2 + src_wrap; 717 s4 = s3 + src_wrap; 718 d = dst; 719 for(w = width;w > 0; w--) { 720 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] + 721 s2[0] + s2[1] + s2[2] + s2[3] + 722 s3[0] + s3[1] + s3[2] + s3[3] + 723 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4; 724 s1 += 4; 725 s2 += 4; 726 s3 += 4; 727 s4 += 4; 728 d++; 729 } 730 src += 4 * src_wrap; 731 dst += dst_wrap; 732 } 733} 734 735/* 8x8 -> 1x1 */ 736void ff_shrink88(uint8_t *dst, int dst_wrap, 737 const uint8_t *src, int src_wrap, 738 int width, int height) 739{ 740 int w, i; 741 742 for(;height > 0; height--) { 743 for(w = width;w > 0; w--) { 744 int tmp=0; 745 for(i=0; i<8; i++){ 746 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7]; 747 src += src_wrap; 748 } 749 *(dst++) = (tmp + 32)>>6; 750 src += 8 - 8*src_wrap; 751 } 752 src += 8*src_wrap - 8*width; 753 dst += dst_wrap - width; 754 } 755} 756 757 758int avpicture_alloc(AVPicture *picture, 759 enum PixelFormat pix_fmt, int width, int height) 760{ 761 int ret; 762 763 if ((ret = av_image_alloc(picture->data, picture->linesize, width, height, pix_fmt, 1)) < 0) { 764 memset(picture, 0, sizeof(AVPicture)); 765 return ret; 766 } 767 768 return 0; 769} 770 771void avpicture_free(AVPicture *picture) 772{ 773 av_free(picture->data[0]); 774} 775 776/* return true if yuv planar */ 777static inline int is_yuv_planar(const PixFmtInfo *ps) 778{ 779 return (ps->color_type == FF_COLOR_YUV || 780 ps->color_type == FF_COLOR_YUV_JPEG) && 781 ps->pixel_type == FF_PIXEL_PLANAR; 782} 783 784int av_picture_crop(AVPicture *dst, const AVPicture *src, 785 enum PixelFormat pix_fmt, int top_band, int left_band) 786{ 787 int y_shift; 788 int x_shift; 789 790 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) 791 return -1; 792 793 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h; 794 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w; 795 796 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; 797 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift); 798 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift); 799 800 dst->linesize[0] = src->linesize[0]; 801 dst->linesize[1] = src->linesize[1]; 802 dst->linesize[2] = src->linesize[2]; 803 return 0; 804} 805 806int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, 807 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright, 808 int *color) 809{ 810 uint8_t *optr; 811 int y_shift; 812 int x_shift; 813 int yheight; 814 int i, y; 815 816 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || 817 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1; 818 819 for (i = 0; i < 3; i++) { 820 x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0; 821 y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0; 822 823 if (padtop || padleft) { 824 memset(dst->data[i], color[i], 825 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); 826 } 827 828 if (padleft || padright) { 829 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + 830 (dst->linesize[i] - (padright >> x_shift)); 831 yheight = (height - 1 - (padtop + padbottom)) >> y_shift; 832 for (y = 0; y < yheight; y++) { 833 memset(optr, color[i], (padleft + padright) >> x_shift); 834 optr += dst->linesize[i]; 835 } 836 } 837 838 if (src) { /* first line */ 839 uint8_t *iptr = src->data[i]; 840 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + 841 (padleft >> x_shift); 842 memcpy(optr, iptr, (width - padleft - padright) >> x_shift); 843 iptr += src->linesize[i]; 844 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + 845 (dst->linesize[i] - (padright >> x_shift)); 846 yheight = (height - 1 - (padtop + padbottom)) >> y_shift; 847 for (y = 0; y < yheight; y++) { 848 memset(optr, color[i], (padleft + padright) >> x_shift); 849 memcpy(optr + ((padleft + padright) >> x_shift), iptr, 850 (width - padleft - padright) >> x_shift); 851 iptr += src->linesize[i]; 852 optr += dst->linesize[i]; 853 } 854 } 855 856 if (padbottom || padright) { 857 optr = dst->data[i] + dst->linesize[i] * 858 ((height - padbottom) >> y_shift) - (padright >> x_shift); 859 memset(optr, color[i],dst->linesize[i] * 860 (padbottom >> y_shift) + (padright >> x_shift)); 861 } 862 } 863 return 0; 864} 865 866#if FF_API_GET_ALPHA_INFO 867/* NOTE: we scan all the pixels to have an exact information */ 868static int get_alpha_info_pal8(const AVPicture *src, int width, int height) 869{ 870 const unsigned char *p; 871 int src_wrap, ret, x, y; 872 unsigned int a; 873 uint32_t *palette = (uint32_t *)src->data[1]; 874 875 p = src->data[0]; 876 src_wrap = src->linesize[0] - width; 877 ret = 0; 878 for(y=0;y<height;y++) { 879 for(x=0;x<width;x++) { 880 a = palette[p[0]] >> 24; 881 if (a == 0x00) { 882 ret |= FF_ALPHA_TRANSP; 883 } else if (a != 0xff) { 884 ret |= FF_ALPHA_SEMI_TRANSP; 885 } 886 p++; 887 } 888 p += src_wrap; 889 } 890 return ret; 891} 892 893int img_get_alpha_info(const AVPicture *src, 894 enum PixelFormat pix_fmt, int width, int height) 895{ 896 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; 897 int ret; 898 899 /* no alpha can be represented in format */ 900 if (!pf->is_alpha) 901 return 0; 902 switch(pix_fmt) { 903 case PIX_FMT_PAL8: 904 ret = get_alpha_info_pal8(src, width, height); 905 break; 906 default: 907 /* we do not know, so everything is indicated */ 908 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP; 909 break; 910 } 911 return ret; 912} 913#endif 914 915#if !(HAVE_MMX && HAVE_YASM) 916/* filter parameters: [-1 4 2 4 -1] // 8 */ 917static void deinterlace_line_c(uint8_t *dst, 918 const uint8_t *lum_m4, const uint8_t *lum_m3, 919 const uint8_t *lum_m2, const uint8_t *lum_m1, 920 const uint8_t *lum, 921 int size) 922{ 923 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; 924 int sum; 925 926 for(;size > 0;size--) { 927 sum = -lum_m4[0]; 928 sum += lum_m3[0] << 2; 929 sum += lum_m2[0] << 1; 930 sum += lum_m1[0] << 2; 931 sum += -lum[0]; 932 dst[0] = cm[(sum + 4) >> 3]; 933 lum_m4++; 934 lum_m3++; 935 lum_m2++; 936 lum_m1++; 937 lum++; 938 dst++; 939 } 940} 941 942static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3, 943 uint8_t *lum_m2, uint8_t *lum_m1, 944 uint8_t *lum, int size) 945{ 946 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; 947 int sum; 948 949 for(;size > 0;size--) { 950 sum = -lum_m4[0]; 951 sum += lum_m3[0] << 2; 952 sum += lum_m2[0] << 1; 953 lum_m4[0]=lum_m2[0]; 954 sum += lum_m1[0] << 2; 955 sum += -lum[0]; 956 lum_m2[0] = cm[(sum + 4) >> 3]; 957 lum_m4++; 958 lum_m3++; 959 lum_m2++; 960 lum_m1++; 961 lum++; 962 } 963} 964#endif 965 966/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The 967 top field is copied as is, but the bottom field is deinterlaced 968 against the top field. */ 969static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap, 970 const uint8_t *src1, int src_wrap, 971 int width, int height) 972{ 973 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2; 974 int y; 975 976 src_m2 = src1; 977 src_m1 = src1; 978 src_0=&src_m1[src_wrap]; 979 src_p1=&src_0[src_wrap]; 980 src_p2=&src_p1[src_wrap]; 981 for(y=0;y<(height-2);y+=2) { 982 memcpy(dst,src_m1,width); 983 dst += dst_wrap; 984 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width); 985 src_m2 = src_0; 986 src_m1 = src_p1; 987 src_0 = src_p2; 988 src_p1 += 2*src_wrap; 989 src_p2 += 2*src_wrap; 990 dst += dst_wrap; 991 } 992 memcpy(dst,src_m1,width); 993 dst += dst_wrap; 994 /* do last line */ 995 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width); 996} 997 998static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, 999 int width, int height) 1000{ 1001 uint8_t *src_m1, *src_0, *src_p1, *src_p2; 1002 int y; 1003 uint8_t *buf; 1004 buf = av_malloc(width); 1005 1006 src_m1 = src1; 1007 memcpy(buf,src_m1,width); 1008 src_0=&src_m1[src_wrap]; 1009 src_p1=&src_0[src_wrap]; 1010 src_p2=&src_p1[src_wrap]; 1011 for(y=0;y<(height-2);y+=2) { 1012 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width); 1013 src_m1 = src_p1; 1014 src_0 = src_p2; 1015 src_p1 += 2*src_wrap; 1016 src_p2 += 2*src_wrap; 1017 } 1018 /* do last line */ 1019 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width); 1020 av_free(buf); 1021} 1022 1023int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, 1024 enum PixelFormat pix_fmt, int width, int height) 1025{ 1026 int i; 1027 1028 if (pix_fmt != PIX_FMT_YUV420P && 1029 pix_fmt != PIX_FMT_YUVJ420P && 1030 pix_fmt != PIX_FMT_YUV422P && 1031 pix_fmt != PIX_FMT_YUVJ422P && 1032 pix_fmt != PIX_FMT_YUV444P && 1033 pix_fmt != PIX_FMT_YUV411P && 1034 pix_fmt != PIX_FMT_GRAY8) 1035 return -1; 1036 if ((width & 3) != 0 || (height & 3) != 0) 1037 return -1; 1038 1039 for(i=0;i<3;i++) { 1040 if (i == 1) { 1041 switch(pix_fmt) { 1042 case PIX_FMT_YUVJ420P: 1043 case PIX_FMT_YUV420P: 1044 width >>= 1; 1045 height >>= 1; 1046 break; 1047 case PIX_FMT_YUV422P: 1048 case PIX_FMT_YUVJ422P: 1049 width >>= 1; 1050 break; 1051 case PIX_FMT_YUV411P: 1052 width >>= 2; 1053 break; 1054 default: 1055 break; 1056 } 1057 if (pix_fmt == PIX_FMT_GRAY8) { 1058 break; 1059 } 1060 } 1061 if (src == dst) { 1062 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], 1063 width, height); 1064 } else { 1065 deinterlace_bottom_field(dst->data[i],dst->linesize[i], 1066 src->data[i], src->linesize[i], 1067 width, height); 1068 } 1069 } 1070 emms_c(); 1071 return 0; 1072} 1073 1074