00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027
00028
00029
00030
00031
00032
00033 #include "avcodec.h"
00034 #include "dsputil.h"
00035 #include "internal.h"
00036 #include "imgconvert.h"
00037 #include "libavutil/colorspace.h"
00038 #include "libavutil/pixdesc.h"
00039 #include "libavutil/imgutils.h"
00040
00041 #if HAVE_MMX && HAVE_YASM
00042 #include "x86/dsputil_mmx.h"
00043 #endif
00044
00045 #define xglue(x, y) x ## y
00046 #define glue(x, y) xglue(x, y)
00047
00048 #define FF_COLOR_RGB 0
00049 #define FF_COLOR_GRAY 1
00050 #define FF_COLOR_YUV 2
00051 #define FF_COLOR_YUV_JPEG 3
00053 #define FF_PIXEL_PLANAR 0
00054 #define FF_PIXEL_PACKED 1
00055 #define FF_PIXEL_PALETTE 2
00057 #if HAVE_MMX && HAVE_YASM
00058 #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
00059 #define deinterlace_line ff_deinterlace_line_mmx
00060 #else
00061 #define deinterlace_line_inplace deinterlace_line_inplace_c
00062 #define deinterlace_line deinterlace_line_c
00063 #endif
00064
00065 typedef struct PixFmtInfo {
00066 uint8_t nb_channels;
00067 uint8_t color_type;
00068 uint8_t pixel_type;
00069 uint8_t is_alpha : 1;
00070 uint8_t depth;
00071 } PixFmtInfo;
00072
00073
00074 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
00075
00076 [PIX_FMT_YUV420P] = {
00077 .nb_channels = 3,
00078 .color_type = FF_COLOR_YUV,
00079 .pixel_type = FF_PIXEL_PLANAR,
00080 .depth = 8,
00081 },
00082 [PIX_FMT_YUV422P] = {
00083 .nb_channels = 3,
00084 .color_type = FF_COLOR_YUV,
00085 .pixel_type = FF_PIXEL_PLANAR,
00086 .depth = 8,
00087 },
00088 [PIX_FMT_YUV444P] = {
00089 .nb_channels = 3,
00090 .color_type = FF_COLOR_YUV,
00091 .pixel_type = FF_PIXEL_PLANAR,
00092 .depth = 8,
00093 },
00094 [PIX_FMT_YUYV422] = {
00095 .nb_channels = 1,
00096 .color_type = FF_COLOR_YUV,
00097 .pixel_type = FF_PIXEL_PACKED,
00098 .depth = 8,
00099 },
00100 [PIX_FMT_UYVY422] = {
00101 .nb_channels = 1,
00102 .color_type = FF_COLOR_YUV,
00103 .pixel_type = FF_PIXEL_PACKED,
00104 .depth = 8,
00105 },
00106 [PIX_FMT_YUV410P] = {
00107 .nb_channels = 3,
00108 .color_type = FF_COLOR_YUV,
00109 .pixel_type = FF_PIXEL_PLANAR,
00110 .depth = 8,
00111 },
00112 [PIX_FMT_YUV411P] = {
00113 .nb_channels = 3,
00114 .color_type = FF_COLOR_YUV,
00115 .pixel_type = FF_PIXEL_PLANAR,
00116 .depth = 8,
00117 },
00118 [PIX_FMT_YUV440P] = {
00119 .nb_channels = 3,
00120 .color_type = FF_COLOR_YUV,
00121 .pixel_type = FF_PIXEL_PLANAR,
00122 .depth = 8,
00123 },
00124 [PIX_FMT_YUV420P16LE] = {
00125 .nb_channels = 3,
00126 .color_type = FF_COLOR_YUV,
00127 .pixel_type = FF_PIXEL_PLANAR,
00128 .depth = 16,
00129 },
00130 [PIX_FMT_YUV422P16LE] = {
00131 .nb_channels = 3,
00132 .color_type = FF_COLOR_YUV,
00133 .pixel_type = FF_PIXEL_PLANAR,
00134 .depth = 16,
00135 },
00136 [PIX_FMT_YUV444P16LE] = {
00137 .nb_channels = 3,
00138 .color_type = FF_COLOR_YUV,
00139 .pixel_type = FF_PIXEL_PLANAR,
00140 .depth = 16,
00141 },
00142 [PIX_FMT_YUV420P16BE] = {
00143 .nb_channels = 3,
00144 .color_type = FF_COLOR_YUV,
00145 .pixel_type = FF_PIXEL_PLANAR,
00146 .depth = 16,
00147 },
00148 [PIX_FMT_YUV422P16BE] = {
00149 .nb_channels = 3,
00150 .color_type = FF_COLOR_YUV,
00151 .pixel_type = FF_PIXEL_PLANAR,
00152 .depth = 16,
00153 },
00154 [PIX_FMT_YUV444P16BE] = {
00155 .nb_channels = 3,
00156 .color_type = FF_COLOR_YUV,
00157 .pixel_type = FF_PIXEL_PLANAR,
00158 .depth = 16,
00159 },
00160
00161
00162
00163 [PIX_FMT_YUVA420P] = {
00164 .nb_channels = 4,
00165 .color_type = FF_COLOR_YUV,
00166 .pixel_type = FF_PIXEL_PLANAR,
00167 .depth = 8,
00168 },
00169
00170
00171 [PIX_FMT_YUVJ420P] = {
00172 .nb_channels = 3,
00173 .color_type = FF_COLOR_YUV_JPEG,
00174 .pixel_type = FF_PIXEL_PLANAR,
00175 .depth = 8,
00176 },
00177 [PIX_FMT_YUVJ422P] = {
00178 .nb_channels = 3,
00179 .color_type = FF_COLOR_YUV_JPEG,
00180 .pixel_type = FF_PIXEL_PLANAR,
00181 .depth = 8,
00182 },
00183 [PIX_FMT_YUVJ444P] = {
00184 .nb_channels = 3,
00185 .color_type = FF_COLOR_YUV_JPEG,
00186 .pixel_type = FF_PIXEL_PLANAR,
00187 .depth = 8,
00188 },
00189 [PIX_FMT_YUVJ440P] = {
00190 .nb_channels = 3,
00191 .color_type = FF_COLOR_YUV_JPEG,
00192 .pixel_type = FF_PIXEL_PLANAR,
00193 .depth = 8,
00194 },
00195
00196
00197 [PIX_FMT_RGB24] = {
00198 .nb_channels = 3,
00199 .color_type = FF_COLOR_RGB,
00200 .pixel_type = FF_PIXEL_PACKED,
00201 .depth = 8,
00202 },
00203 [PIX_FMT_BGR24] = {
00204 .nb_channels = 3,
00205 .color_type = FF_COLOR_RGB,
00206 .pixel_type = FF_PIXEL_PACKED,
00207 .depth = 8,
00208 },
00209 [PIX_FMT_ARGB] = {
00210 .nb_channels = 4, .is_alpha = 1,
00211 .color_type = FF_COLOR_RGB,
00212 .pixel_type = FF_PIXEL_PACKED,
00213 .depth = 8,
00214 },
00215 [PIX_FMT_RGB48BE] = {
00216 .nb_channels = 3,
00217 .color_type = FF_COLOR_RGB,
00218 .pixel_type = FF_PIXEL_PACKED,
00219 .depth = 16,
00220 },
00221 [PIX_FMT_RGB48LE] = {
00222 .nb_channels = 3,
00223 .color_type = FF_COLOR_RGB,
00224 .pixel_type = FF_PIXEL_PACKED,
00225 .depth = 16,
00226 },
00227 [PIX_FMT_RGB565BE] = {
00228 .nb_channels = 3,
00229 .color_type = FF_COLOR_RGB,
00230 .pixel_type = FF_PIXEL_PACKED,
00231 .depth = 5,
00232 },
00233 [PIX_FMT_RGB565LE] = {
00234 .nb_channels = 3,
00235 .color_type = FF_COLOR_RGB,
00236 .pixel_type = FF_PIXEL_PACKED,
00237 .depth = 5,
00238 },
00239 [PIX_FMT_RGB555BE] = {
00240 .nb_channels = 3,
00241 .color_type = FF_COLOR_RGB,
00242 .pixel_type = FF_PIXEL_PACKED,
00243 .depth = 5,
00244 },
00245 [PIX_FMT_RGB555LE] = {
00246 .nb_channels = 3,
00247 .color_type = FF_COLOR_RGB,
00248 .pixel_type = FF_PIXEL_PACKED,
00249 .depth = 5,
00250 },
00251 [PIX_FMT_RGB444BE] = {
00252 .nb_channels = 3,
00253 .color_type = FF_COLOR_RGB,
00254 .pixel_type = FF_PIXEL_PACKED,
00255 .depth = 4,
00256 },
00257 [PIX_FMT_RGB444LE] = {
00258 .nb_channels = 3,
00259 .color_type = FF_COLOR_RGB,
00260 .pixel_type = FF_PIXEL_PACKED,
00261 .depth = 4,
00262 },
00263
00264
00265 [PIX_FMT_GRAY16BE] = {
00266 .nb_channels = 1,
00267 .color_type = FF_COLOR_GRAY,
00268 .pixel_type = FF_PIXEL_PLANAR,
00269 .depth = 16,
00270 },
00271 [PIX_FMT_GRAY16LE] = {
00272 .nb_channels = 1,
00273 .color_type = FF_COLOR_GRAY,
00274 .pixel_type = FF_PIXEL_PLANAR,
00275 .depth = 16,
00276 },
00277 [PIX_FMT_GRAY8] = {
00278 .nb_channels = 1,
00279 .color_type = FF_COLOR_GRAY,
00280 .pixel_type = FF_PIXEL_PLANAR,
00281 .depth = 8,
00282 },
00283 [PIX_FMT_MONOWHITE] = {
00284 .nb_channels = 1,
00285 .color_type = FF_COLOR_GRAY,
00286 .pixel_type = FF_PIXEL_PLANAR,
00287 .depth = 1,
00288 },
00289 [PIX_FMT_MONOBLACK] = {
00290 .nb_channels = 1,
00291 .color_type = FF_COLOR_GRAY,
00292 .pixel_type = FF_PIXEL_PLANAR,
00293 .depth = 1,
00294 },
00295
00296
00297 [PIX_FMT_PAL8] = {
00298 .nb_channels = 4, .is_alpha = 1,
00299 .color_type = FF_COLOR_RGB,
00300 .pixel_type = FF_PIXEL_PALETTE,
00301 .depth = 8,
00302 },
00303 [PIX_FMT_UYYVYY411] = {
00304 .nb_channels = 1,
00305 .color_type = FF_COLOR_YUV,
00306 .pixel_type = FF_PIXEL_PACKED,
00307 .depth = 8,
00308 },
00309 [PIX_FMT_ABGR] = {
00310 .nb_channels = 4, .is_alpha = 1,
00311 .color_type = FF_COLOR_RGB,
00312 .pixel_type = FF_PIXEL_PACKED,
00313 .depth = 8,
00314 },
00315 [PIX_FMT_BGR565BE] = {
00316 .nb_channels = 3,
00317 .color_type = FF_COLOR_RGB,
00318 .pixel_type = FF_PIXEL_PACKED,
00319 .depth = 5,
00320 },
00321 [PIX_FMT_BGR565LE] = {
00322 .nb_channels = 3,
00323 .color_type = FF_COLOR_RGB,
00324 .pixel_type = FF_PIXEL_PACKED,
00325 .depth = 5,
00326 },
00327 [PIX_FMT_BGR555BE] = {
00328 .nb_channels = 3,
00329 .color_type = FF_COLOR_RGB,
00330 .pixel_type = FF_PIXEL_PACKED,
00331 .depth = 5,
00332 },
00333 [PIX_FMT_BGR555LE] = {
00334 .nb_channels = 3,
00335 .color_type = FF_COLOR_RGB,
00336 .pixel_type = FF_PIXEL_PACKED,
00337 .depth = 5,
00338 },
00339 [PIX_FMT_BGR444BE] = {
00340 .nb_channels = 3,
00341 .color_type = FF_COLOR_RGB,
00342 .pixel_type = FF_PIXEL_PACKED,
00343 .depth = 4,
00344 },
00345 [PIX_FMT_BGR444LE] = {
00346 .nb_channels = 3,
00347 .color_type = FF_COLOR_RGB,
00348 .pixel_type = FF_PIXEL_PACKED,
00349 .depth = 4,
00350 },
00351 [PIX_FMT_RGB8] = {
00352 .nb_channels = 1,
00353 .color_type = FF_COLOR_RGB,
00354 .pixel_type = FF_PIXEL_PACKED,
00355 .depth = 8,
00356 },
00357 [PIX_FMT_RGB4] = {
00358 .nb_channels = 1,
00359 .color_type = FF_COLOR_RGB,
00360 .pixel_type = FF_PIXEL_PACKED,
00361 .depth = 4,
00362 },
00363 [PIX_FMT_RGB4_BYTE] = {
00364 .nb_channels = 1,
00365 .color_type = FF_COLOR_RGB,
00366 .pixel_type = FF_PIXEL_PACKED,
00367 .depth = 8,
00368 },
00369 [PIX_FMT_BGR8] = {
00370 .nb_channels = 1,
00371 .color_type = FF_COLOR_RGB,
00372 .pixel_type = FF_PIXEL_PACKED,
00373 .depth = 8,
00374 },
00375 [PIX_FMT_BGR4] = {
00376 .nb_channels = 1,
00377 .color_type = FF_COLOR_RGB,
00378 .pixel_type = FF_PIXEL_PACKED,
00379 .depth = 4,
00380 },
00381 [PIX_FMT_BGR4_BYTE] = {
00382 .nb_channels = 1,
00383 .color_type = FF_COLOR_RGB,
00384 .pixel_type = FF_PIXEL_PACKED,
00385 .depth = 8,
00386 },
00387 [PIX_FMT_NV12] = {
00388 .nb_channels = 2,
00389 .color_type = FF_COLOR_YUV,
00390 .pixel_type = FF_PIXEL_PLANAR,
00391 .depth = 8,
00392 },
00393 [PIX_FMT_NV21] = {
00394 .nb_channels = 2,
00395 .color_type = FF_COLOR_YUV,
00396 .pixel_type = FF_PIXEL_PLANAR,
00397 .depth = 8,
00398 },
00399
00400 [PIX_FMT_BGRA] = {
00401 .nb_channels = 4, .is_alpha = 1,
00402 .color_type = FF_COLOR_RGB,
00403 .pixel_type = FF_PIXEL_PACKED,
00404 .depth = 8,
00405 },
00406 [PIX_FMT_RGBA] = {
00407 .nb_channels = 4, .is_alpha = 1,
00408 .color_type = FF_COLOR_RGB,
00409 .pixel_type = FF_PIXEL_PACKED,
00410 .depth = 8,
00411 },
00412 };
00413
00414 void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
00415 {
00416 *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
00417 *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
00418 }
00419
00420 #if FF_API_GET_PIX_FMT_NAME
00421 const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
00422 {
00423 return av_get_pix_fmt_name(pix_fmt);
00424 }
00425 #endif
00426
00427 #if LIBAVCODEC_VERSION_MAJOR < 53
00428 enum PixelFormat avcodec_get_pix_fmt(const char *name)
00429 {
00430 return av_get_pix_fmt(name);
00431 }
00432
00433 void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
00434 {
00435 av_get_pix_fmt_string(buf, buf_size, pix_fmt);
00436 }
00437 #endif
00438
00439 int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
00440 {
00441 return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
00442 }
00443
00444 #if LIBAVCODEC_VERSION_MAJOR < 53
00445 int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
00446 return ff_set_systematic_pal2(pal, pix_fmt);
00447 }
00448
00449 int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
00450 {
00451 return av_image_fill_linesizes(picture->linesize, pix_fmt, width);
00452 }
00453
00454 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
00455 int height)
00456 {
00457 return av_image_fill_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
00458 }
00459 #endif
00460
00461 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
00462 enum PixelFormat pix_fmt, int width, int height)
00463 {
00464 int ret;
00465
00466 if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
00467 return ret;
00468
00469 if ((ret = av_image_fill_linesizes(picture->linesize, pix_fmt, width)) < 0)
00470 return ret;
00471
00472 return av_image_fill_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
00473 }
00474
00475 int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
00476 unsigned char *dest, int dest_size)
00477 {
00478 int i, j, nb_planes = 0, linesizes[4];
00479 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00480 int size = avpicture_get_size(pix_fmt, width, height);
00481
00482 if (size > dest_size || size < 0)
00483 return AVERROR(EINVAL);
00484
00485 for (i = 0; i < desc->nb_components; i++)
00486 nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
00487 nb_planes++;
00488
00489 av_image_fill_linesizes(linesizes, pix_fmt, width);
00490 for (i = 0; i < nb_planes; i++) {
00491 int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
00492 const unsigned char *s = src->data[i];
00493 h = (height + (1 << shift) - 1) >> shift;
00494
00495 for (j = 0; j < h; j++) {
00496 memcpy(dest, s, linesizes[i]);
00497 dest += linesizes[i];
00498 s += src->linesize[i];
00499 }
00500 }
00501
00502 switch (pix_fmt) {
00503 case PIX_FMT_RGB8:
00504 case PIX_FMT_BGR8:
00505 case PIX_FMT_RGB4_BYTE:
00506 case PIX_FMT_BGR4_BYTE:
00507 case PIX_FMT_GRAY8:
00508
00509 return size;
00510 }
00511
00512 if (desc->flags & PIX_FMT_PAL)
00513 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
00514
00515 return size;
00516 }
00517
00518 int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
00519 {
00520 AVPicture dummy_pict;
00521 if(av_image_check_size(width, height, 0, NULL))
00522 return -1;
00523 switch (pix_fmt) {
00524 case PIX_FMT_RGB8:
00525 case PIX_FMT_BGR8:
00526 case PIX_FMT_RGB4_BYTE:
00527 case PIX_FMT_BGR4_BYTE:
00528 case PIX_FMT_GRAY8:
00529
00530 return width * height;
00531 }
00532 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
00533 }
00534
00535 int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
00536 int has_alpha)
00537 {
00538 const PixFmtInfo *pf, *ps;
00539 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
00540 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
00541 int loss;
00542
00543 ps = &pix_fmt_info[src_pix_fmt];
00544
00545
00546 loss = 0;
00547 pf = &pix_fmt_info[dst_pix_fmt];
00548 if (pf->depth < ps->depth ||
00549 ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
00550 dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
00551 (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
00552 src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
00553 loss |= FF_LOSS_DEPTH;
00554 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
00555 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
00556 loss |= FF_LOSS_RESOLUTION;
00557 switch(pf->color_type) {
00558 case FF_COLOR_RGB:
00559 if (ps->color_type != FF_COLOR_RGB &&
00560 ps->color_type != FF_COLOR_GRAY)
00561 loss |= FF_LOSS_COLORSPACE;
00562 break;
00563 case FF_COLOR_GRAY:
00564 if (ps->color_type != FF_COLOR_GRAY)
00565 loss |= FF_LOSS_COLORSPACE;
00566 break;
00567 case FF_COLOR_YUV:
00568 if (ps->color_type != FF_COLOR_YUV)
00569 loss |= FF_LOSS_COLORSPACE;
00570 break;
00571 case FF_COLOR_YUV_JPEG:
00572 if (ps->color_type != FF_COLOR_YUV_JPEG &&
00573 ps->color_type != FF_COLOR_YUV &&
00574 ps->color_type != FF_COLOR_GRAY)
00575 loss |= FF_LOSS_COLORSPACE;
00576 break;
00577 default:
00578
00579 if (ps->color_type != pf->color_type)
00580 loss |= FF_LOSS_COLORSPACE;
00581 break;
00582 }
00583 if (pf->color_type == FF_COLOR_GRAY &&
00584 ps->color_type != FF_COLOR_GRAY)
00585 loss |= FF_LOSS_CHROMA;
00586 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
00587 loss |= FF_LOSS_ALPHA;
00588 if (pf->pixel_type == FF_PIXEL_PALETTE &&
00589 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
00590 loss |= FF_LOSS_COLORQUANT;
00591 return loss;
00592 }
00593
00594 static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
00595 {
00596 int bits;
00597 const PixFmtInfo *pf;
00598 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00599
00600 pf = &pix_fmt_info[pix_fmt];
00601 switch(pf->pixel_type) {
00602 case FF_PIXEL_PACKED:
00603 switch(pix_fmt) {
00604 case PIX_FMT_YUYV422:
00605 case PIX_FMT_UYVY422:
00606 case PIX_FMT_RGB565BE:
00607 case PIX_FMT_RGB565LE:
00608 case PIX_FMT_RGB555BE:
00609 case PIX_FMT_RGB555LE:
00610 case PIX_FMT_RGB444BE:
00611 case PIX_FMT_RGB444LE:
00612 case PIX_FMT_BGR565BE:
00613 case PIX_FMT_BGR565LE:
00614 case PIX_FMT_BGR555BE:
00615 case PIX_FMT_BGR555LE:
00616 case PIX_FMT_BGR444BE:
00617 case PIX_FMT_BGR444LE:
00618 bits = 16;
00619 break;
00620 case PIX_FMT_UYYVYY411:
00621 bits = 12;
00622 break;
00623 default:
00624 bits = pf->depth * pf->nb_channels;
00625 break;
00626 }
00627 break;
00628 case FF_PIXEL_PLANAR:
00629 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
00630 bits = pf->depth * pf->nb_channels;
00631 } else {
00632 bits = pf->depth + ((2 * pf->depth) >>
00633 (desc->log2_chroma_w + desc->log2_chroma_h));
00634 }
00635 break;
00636 case FF_PIXEL_PALETTE:
00637 bits = 8;
00638 break;
00639 default:
00640 bits = -1;
00641 break;
00642 }
00643 return bits;
00644 }
00645
00646 static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
00647 enum PixelFormat src_pix_fmt,
00648 int has_alpha,
00649 int loss_mask)
00650 {
00651 int dist, i, loss, min_dist;
00652 enum PixelFormat dst_pix_fmt;
00653
00654
00655 dst_pix_fmt = PIX_FMT_NONE;
00656 min_dist = 0x7fffffff;
00657
00658 for (i = 0; i < 64; i++) {
00659 if (pix_fmt_mask & (1ULL << i)) {
00660 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
00661 if (loss == 0) {
00662 dist = avg_bits_per_pixel(i);
00663 if (dist < min_dist) {
00664 min_dist = dist;
00665 dst_pix_fmt = i;
00666 }
00667 }
00668 }
00669 }
00670 return dst_pix_fmt;
00671 }
00672
00673 enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
00674 int has_alpha, int *loss_ptr)
00675 {
00676 enum PixelFormat dst_pix_fmt;
00677 int loss_mask, i;
00678 static const int loss_mask_order[] = {
00679 ~0,
00680 ~FF_LOSS_ALPHA,
00681 ~FF_LOSS_RESOLUTION,
00682 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
00683 ~FF_LOSS_COLORQUANT,
00684 ~FF_LOSS_DEPTH,
00685 0,
00686 };
00687
00688
00689 i = 0;
00690 for(;;) {
00691 loss_mask = loss_mask_order[i++];
00692 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
00693 has_alpha, loss_mask);
00694 if (dst_pix_fmt >= 0)
00695 goto found;
00696 if (loss_mask == 0)
00697 break;
00698 }
00699 return PIX_FMT_NONE;
00700 found:
00701 if (loss_ptr)
00702 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
00703 return dst_pix_fmt;
00704 }
00705
00706 #if LIBAVCODEC_VERSION_MAJOR < 53
00707 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
00708 const uint8_t *src, int src_wrap,
00709 int width, int height)
00710 {
00711 av_image_copy_plane(dst, dst_wrap, src, src_wrap, width, height);
00712 }
00713
00714 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
00715 {
00716 return av_image_get_linesize(pix_fmt, width, plane);
00717 }
00718
00719 void av_picture_data_copy(uint8_t *dst_data[4], int dst_linesize[4],
00720 uint8_t *src_data[4], int src_linesize[4],
00721 enum PixelFormat pix_fmt, int width, int height)
00722 {
00723 av_image_copy(dst_data, dst_linesize, src_data, src_linesize,
00724 pix_fmt, width, height);
00725 }
00726 #endif
00727
00728 void av_picture_copy(AVPicture *dst, const AVPicture *src,
00729 enum PixelFormat pix_fmt, int width, int height)
00730 {
00731 av_image_copy(dst->data, dst->linesize, src->data,
00732 src->linesize, pix_fmt, width, height);
00733 }
00734
00735
00736 void ff_shrink22(uint8_t *dst, int dst_wrap,
00737 const uint8_t *src, int src_wrap,
00738 int width, int height)
00739 {
00740 int w;
00741 const uint8_t *s1, *s2;
00742 uint8_t *d;
00743
00744 for(;height > 0; height--) {
00745 s1 = src;
00746 s2 = s1 + src_wrap;
00747 d = dst;
00748 for(w = width;w >= 4; w-=4) {
00749 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
00750 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
00751 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
00752 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
00753 s1 += 8;
00754 s2 += 8;
00755 d += 4;
00756 }
00757 for(;w > 0; w--) {
00758 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
00759 s1 += 2;
00760 s2 += 2;
00761 d++;
00762 }
00763 src += 2 * src_wrap;
00764 dst += dst_wrap;
00765 }
00766 }
00767
00768
00769 void ff_shrink44(uint8_t *dst, int dst_wrap,
00770 const uint8_t *src, int src_wrap,
00771 int width, int height)
00772 {
00773 int w;
00774 const uint8_t *s1, *s2, *s3, *s4;
00775 uint8_t *d;
00776
00777 for(;height > 0; height--) {
00778 s1 = src;
00779 s2 = s1 + src_wrap;
00780 s3 = s2 + src_wrap;
00781 s4 = s3 + src_wrap;
00782 d = dst;
00783 for(w = width;w > 0; w--) {
00784 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
00785 s2[0] + s2[1] + s2[2] + s2[3] +
00786 s3[0] + s3[1] + s3[2] + s3[3] +
00787 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
00788 s1 += 4;
00789 s2 += 4;
00790 s3 += 4;
00791 s4 += 4;
00792 d++;
00793 }
00794 src += 4 * src_wrap;
00795 dst += dst_wrap;
00796 }
00797 }
00798
00799
00800 void ff_shrink88(uint8_t *dst, int dst_wrap,
00801 const uint8_t *src, int src_wrap,
00802 int width, int height)
00803 {
00804 int w, i;
00805
00806 for(;height > 0; height--) {
00807 for(w = width;w > 0; w--) {
00808 int tmp=0;
00809 for(i=0; i<8; i++){
00810 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
00811 src += src_wrap;
00812 }
00813 *(dst++) = (tmp + 32)>>6;
00814 src += 8 - 8*src_wrap;
00815 }
00816 src += 8*src_wrap - 8*width;
00817 dst += dst_wrap - width;
00818 }
00819 }
00820
00821
00822 int avpicture_alloc(AVPicture *picture,
00823 enum PixelFormat pix_fmt, int width, int height)
00824 {
00825 int ret;
00826
00827 if ((ret = av_image_alloc(picture->data, picture->linesize, width, height, pix_fmt, 1)) < 0) {
00828 memset(picture, 0, sizeof(AVPicture));
00829 return ret;
00830 }
00831
00832 return 0;
00833 }
00834
00835 void avpicture_free(AVPicture *picture)
00836 {
00837 av_free(picture->data[0]);
00838 }
00839
00840
00841 static inline int is_yuv_planar(const PixFmtInfo *ps)
00842 {
00843 return (ps->color_type == FF_COLOR_YUV ||
00844 ps->color_type == FF_COLOR_YUV_JPEG) &&
00845 ps->pixel_type == FF_PIXEL_PLANAR;
00846 }
00847
00848 int av_picture_crop(AVPicture *dst, const AVPicture *src,
00849 enum PixelFormat pix_fmt, int top_band, int left_band)
00850 {
00851 int y_shift;
00852 int x_shift;
00853
00854 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
00855 return -1;
00856
00857 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
00858 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
00859
00860 if (is_yuv_planar(&pix_fmt_info[pix_fmt])) {
00861 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
00862 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
00863 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
00864 } else{
00865 if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
00866 return -1;
00867 if(left_band)
00868 return -1;
00869 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
00870 }
00871
00872 dst->linesize[0] = src->linesize[0];
00873 dst->linesize[1] = src->linesize[1];
00874 dst->linesize[2] = src->linesize[2];
00875 return 0;
00876 }
00877
00878 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
00879 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
00880 int *color)
00881 {
00882 uint8_t *optr;
00883 int y_shift;
00884 int x_shift;
00885 int yheight;
00886 int i, y;
00887
00888 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
00889 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
00890
00891 for (i = 0; i < 3; i++) {
00892 x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
00893 y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
00894
00895 if (padtop || padleft) {
00896 memset(dst->data[i], color[i],
00897 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
00898 }
00899
00900 if (padleft || padright) {
00901 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
00902 (dst->linesize[i] - (padright >> x_shift));
00903 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
00904 for (y = 0; y < yheight; y++) {
00905 memset(optr, color[i], (padleft + padright) >> x_shift);
00906 optr += dst->linesize[i];
00907 }
00908 }
00909
00910 if (src) {
00911 uint8_t *iptr = src->data[i];
00912 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
00913 (padleft >> x_shift);
00914 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
00915 iptr += src->linesize[i];
00916 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
00917 (dst->linesize[i] - (padright >> x_shift));
00918 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
00919 for (y = 0; y < yheight; y++) {
00920 memset(optr, color[i], (padleft + padright) >> x_shift);
00921 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
00922 (width - padleft - padright) >> x_shift);
00923 iptr += src->linesize[i];
00924 optr += dst->linesize[i];
00925 }
00926 }
00927
00928 if (padbottom || padright) {
00929 optr = dst->data[i] + dst->linesize[i] *
00930 ((height - padbottom) >> y_shift) - (padright >> x_shift);
00931 memset(optr, color[i],dst->linesize[i] *
00932 (padbottom >> y_shift) + (padright >> x_shift));
00933 }
00934 }
00935 return 0;
00936 }
00937
00938
00939 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
00940 {
00941 const unsigned char *p;
00942 int src_wrap, ret, x, y;
00943 unsigned int a;
00944 uint32_t *palette = (uint32_t *)src->data[1];
00945
00946 p = src->data[0];
00947 src_wrap = src->linesize[0] - width;
00948 ret = 0;
00949 for(y=0;y<height;y++) {
00950 for(x=0;x<width;x++) {
00951 a = palette[p[0]] >> 24;
00952 if (a == 0x00) {
00953 ret |= FF_ALPHA_TRANSP;
00954 } else if (a != 0xff) {
00955 ret |= FF_ALPHA_SEMI_TRANSP;
00956 }
00957 p++;
00958 }
00959 p += src_wrap;
00960 }
00961 return ret;
00962 }
00963
00964 int img_get_alpha_info(const AVPicture *src,
00965 enum PixelFormat pix_fmt, int width, int height)
00966 {
00967 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00968 int ret;
00969
00970
00971 if (!pf->is_alpha)
00972 return 0;
00973 switch(pix_fmt) {
00974 case PIX_FMT_PAL8:
00975 ret = get_alpha_info_pal8(src, width, height);
00976 break;
00977 default:
00978
00979 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
00980 break;
00981 }
00982 return ret;
00983 }
00984
00985 #if !(HAVE_MMX && HAVE_YASM)
00986
00987 static void deinterlace_line_c(uint8_t *dst,
00988 const uint8_t *lum_m4, const uint8_t *lum_m3,
00989 const uint8_t *lum_m2, const uint8_t *lum_m1,
00990 const uint8_t *lum,
00991 int size)
00992 {
00993 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00994 int sum;
00995
00996 for(;size > 0;size--) {
00997 sum = -lum_m4[0];
00998 sum += lum_m3[0] << 2;
00999 sum += lum_m2[0] << 1;
01000 sum += lum_m1[0] << 2;
01001 sum += -lum[0];
01002 dst[0] = cm[(sum + 4) >> 3];
01003 lum_m4++;
01004 lum_m3++;
01005 lum_m2++;
01006 lum_m1++;
01007 lum++;
01008 dst++;
01009 }
01010 }
01011
01012 static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
01013 uint8_t *lum_m2, uint8_t *lum_m1,
01014 uint8_t *lum, int size)
01015 {
01016 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
01017 int sum;
01018
01019 for(;size > 0;size--) {
01020 sum = -lum_m4[0];
01021 sum += lum_m3[0] << 2;
01022 sum += lum_m2[0] << 1;
01023 lum_m4[0]=lum_m2[0];
01024 sum += lum_m1[0] << 2;
01025 sum += -lum[0];
01026 lum_m2[0] = cm[(sum + 4) >> 3];
01027 lum_m4++;
01028 lum_m3++;
01029 lum_m2++;
01030 lum_m1++;
01031 lum++;
01032 }
01033 }
01034 #endif
01035
01036
01037
01038
01039 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
01040 const uint8_t *src1, int src_wrap,
01041 int width, int height)
01042 {
01043 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
01044 int y;
01045
01046 src_m2 = src1;
01047 src_m1 = src1;
01048 src_0=&src_m1[src_wrap];
01049 src_p1=&src_0[src_wrap];
01050 src_p2=&src_p1[src_wrap];
01051 for(y=0;y<(height-2);y+=2) {
01052 memcpy(dst,src_m1,width);
01053 dst += dst_wrap;
01054 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
01055 src_m2 = src_0;
01056 src_m1 = src_p1;
01057 src_0 = src_p2;
01058 src_p1 += 2*src_wrap;
01059 src_p2 += 2*src_wrap;
01060 dst += dst_wrap;
01061 }
01062 memcpy(dst,src_m1,width);
01063 dst += dst_wrap;
01064
01065 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
01066 }
01067
01068 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
01069 int width, int height)
01070 {
01071 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
01072 int y;
01073 uint8_t *buf;
01074 buf = (uint8_t*)av_malloc(width);
01075
01076 src_m1 = src1;
01077 memcpy(buf,src_m1,width);
01078 src_0=&src_m1[src_wrap];
01079 src_p1=&src_0[src_wrap];
01080 src_p2=&src_p1[src_wrap];
01081 for(y=0;y<(height-2);y+=2) {
01082 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
01083 src_m1 = src_p1;
01084 src_0 = src_p2;
01085 src_p1 += 2*src_wrap;
01086 src_p2 += 2*src_wrap;
01087 }
01088
01089 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
01090 av_free(buf);
01091 }
01092
01093 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
01094 enum PixelFormat pix_fmt, int width, int height)
01095 {
01096 int i;
01097
01098 if (pix_fmt != PIX_FMT_YUV420P &&
01099 pix_fmt != PIX_FMT_YUVJ420P &&
01100 pix_fmt != PIX_FMT_YUV422P &&
01101 pix_fmt != PIX_FMT_YUVJ422P &&
01102 pix_fmt != PIX_FMT_YUV444P &&
01103 pix_fmt != PIX_FMT_YUV411P &&
01104 pix_fmt != PIX_FMT_GRAY8)
01105 return -1;
01106 if ((width & 3) != 0 || (height & 3) != 0)
01107 return -1;
01108
01109 for(i=0;i<3;i++) {
01110 if (i == 1) {
01111 switch(pix_fmt) {
01112 case PIX_FMT_YUVJ420P:
01113 case PIX_FMT_YUV420P:
01114 width >>= 1;
01115 height >>= 1;
01116 break;
01117 case PIX_FMT_YUV422P:
01118 case PIX_FMT_YUVJ422P:
01119 width >>= 1;
01120 break;
01121 case PIX_FMT_YUV411P:
01122 width >>= 2;
01123 break;
01124 default:
01125 break;
01126 }
01127 if (pix_fmt == PIX_FMT_GRAY8) {
01128 break;
01129 }
01130 }
01131 if (src == dst) {
01132 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
01133 width, height);
01134 } else {
01135 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
01136 src->data[i], src->linesize[i],
01137 width, height);
01138 }
01139 }
01140 emms_c();
01141 return 0;
01142 }
01143