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 "colorspace.h"
00036 #include "internal.h"
00037 #include "imgconvert.h"
00038 #include "libavutil/pixdesc.h"
00039
00040 #if HAVE_MMX
00041 #include "x86/mmx.h"
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 typedef struct PixFmtInfo {
00058 uint8_t nb_channels;
00059 uint8_t color_type;
00060 uint8_t pixel_type;
00061 uint8_t is_alpha : 1;
00062 uint8_t depth;
00063 } PixFmtInfo;
00064
00065
00066 static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
00067
00068 [PIX_FMT_YUV420P] = {
00069 .nb_channels = 3,
00070 .color_type = FF_COLOR_YUV,
00071 .pixel_type = FF_PIXEL_PLANAR,
00072 .depth = 8,
00073 },
00074 [PIX_FMT_YUV422P] = {
00075 .nb_channels = 3,
00076 .color_type = FF_COLOR_YUV,
00077 .pixel_type = FF_PIXEL_PLANAR,
00078 .depth = 8,
00079 },
00080 [PIX_FMT_YUV444P] = {
00081 .nb_channels = 3,
00082 .color_type = FF_COLOR_YUV,
00083 .pixel_type = FF_PIXEL_PLANAR,
00084 .depth = 8,
00085 },
00086 [PIX_FMT_YUYV422] = {
00087 .nb_channels = 1,
00088 .color_type = FF_COLOR_YUV,
00089 .pixel_type = FF_PIXEL_PACKED,
00090 .depth = 8,
00091 },
00092 [PIX_FMT_UYVY422] = {
00093 .nb_channels = 1,
00094 .color_type = FF_COLOR_YUV,
00095 .pixel_type = FF_PIXEL_PACKED,
00096 .depth = 8,
00097 },
00098 [PIX_FMT_YUV410P] = {
00099 .nb_channels = 3,
00100 .color_type = FF_COLOR_YUV,
00101 .pixel_type = FF_PIXEL_PLANAR,
00102 .depth = 8,
00103 },
00104 [PIX_FMT_YUV411P] = {
00105 .nb_channels = 3,
00106 .color_type = FF_COLOR_YUV,
00107 .pixel_type = FF_PIXEL_PLANAR,
00108 .depth = 8,
00109 },
00110 [PIX_FMT_YUV440P] = {
00111 .nb_channels = 3,
00112 .color_type = FF_COLOR_YUV,
00113 .pixel_type = FF_PIXEL_PLANAR,
00114 .depth = 8,
00115 },
00116 [PIX_FMT_YUV420P16LE] = {
00117 .nb_channels = 3,
00118 .color_type = FF_COLOR_YUV,
00119 .pixel_type = FF_PIXEL_PLANAR,
00120 .depth = 16,
00121 },
00122 [PIX_FMT_YUV422P16LE] = {
00123 .nb_channels = 3,
00124 .color_type = FF_COLOR_YUV,
00125 .pixel_type = FF_PIXEL_PLANAR,
00126 .depth = 16,
00127 },
00128 [PIX_FMT_YUV444P16LE] = {
00129 .nb_channels = 3,
00130 .color_type = FF_COLOR_YUV,
00131 .pixel_type = FF_PIXEL_PLANAR,
00132 .depth = 16,
00133 },
00134 [PIX_FMT_YUV420P16BE] = {
00135 .nb_channels = 3,
00136 .color_type = FF_COLOR_YUV,
00137 .pixel_type = FF_PIXEL_PLANAR,
00138 .depth = 16,
00139 },
00140 [PIX_FMT_YUV422P16BE] = {
00141 .nb_channels = 3,
00142 .color_type = FF_COLOR_YUV,
00143 .pixel_type = FF_PIXEL_PLANAR,
00144 .depth = 16,
00145 },
00146 [PIX_FMT_YUV444P16BE] = {
00147 .nb_channels = 3,
00148 .color_type = FF_COLOR_YUV,
00149 .pixel_type = FF_PIXEL_PLANAR,
00150 .depth = 16,
00151 },
00152
00153
00154
00155 [PIX_FMT_YUVA420P] = {
00156 .nb_channels = 4,
00157 .color_type = FF_COLOR_YUV,
00158 .pixel_type = FF_PIXEL_PLANAR,
00159 .depth = 8,
00160 },
00161
00162
00163 [PIX_FMT_YUVJ420P] = {
00164 .nb_channels = 3,
00165 .color_type = FF_COLOR_YUV_JPEG,
00166 .pixel_type = FF_PIXEL_PLANAR,
00167 .depth = 8,
00168 },
00169 [PIX_FMT_YUVJ422P] = {
00170 .nb_channels = 3,
00171 .color_type = FF_COLOR_YUV_JPEG,
00172 .pixel_type = FF_PIXEL_PLANAR,
00173 .depth = 8,
00174 },
00175 [PIX_FMT_YUVJ444P] = {
00176 .nb_channels = 3,
00177 .color_type = FF_COLOR_YUV_JPEG,
00178 .pixel_type = FF_PIXEL_PLANAR,
00179 .depth = 8,
00180 },
00181 [PIX_FMT_YUVJ440P] = {
00182 .nb_channels = 3,
00183 .color_type = FF_COLOR_YUV_JPEG,
00184 .pixel_type = FF_PIXEL_PLANAR,
00185 .depth = 8,
00186 },
00187
00188
00189 [PIX_FMT_RGB24] = {
00190 .nb_channels = 3,
00191 .color_type = FF_COLOR_RGB,
00192 .pixel_type = FF_PIXEL_PACKED,
00193 .depth = 8,
00194 },
00195 [PIX_FMT_BGR24] = {
00196 .nb_channels = 3,
00197 .color_type = FF_COLOR_RGB,
00198 .pixel_type = FF_PIXEL_PACKED,
00199 .depth = 8,
00200 },
00201 [PIX_FMT_ARGB] = {
00202 .nb_channels = 4, .is_alpha = 1,
00203 .color_type = FF_COLOR_RGB,
00204 .pixel_type = FF_PIXEL_PACKED,
00205 .depth = 8,
00206 },
00207 [PIX_FMT_RGB48BE] = {
00208 .nb_channels = 3,
00209 .color_type = FF_COLOR_RGB,
00210 .pixel_type = FF_PIXEL_PACKED,
00211 .depth = 16,
00212 },
00213 [PIX_FMT_RGB48LE] = {
00214 .nb_channels = 3,
00215 .color_type = FF_COLOR_RGB,
00216 .pixel_type = FF_PIXEL_PACKED,
00217 .depth = 16,
00218 },
00219 [PIX_FMT_RGB565BE] = {
00220 .nb_channels = 3,
00221 .color_type = FF_COLOR_RGB,
00222 .pixel_type = FF_PIXEL_PACKED,
00223 .depth = 5,
00224 },
00225 [PIX_FMT_RGB565LE] = {
00226 .nb_channels = 3,
00227 .color_type = FF_COLOR_RGB,
00228 .pixel_type = FF_PIXEL_PACKED,
00229 .depth = 5,
00230 },
00231 [PIX_FMT_RGB555BE] = {
00232 .nb_channels = 3,
00233 .color_type = FF_COLOR_RGB,
00234 .pixel_type = FF_PIXEL_PACKED,
00235 .depth = 5,
00236 },
00237 [PIX_FMT_RGB555LE] = {
00238 .nb_channels = 3,
00239 .color_type = FF_COLOR_RGB,
00240 .pixel_type = FF_PIXEL_PACKED,
00241 .depth = 5,
00242 },
00243 [PIX_FMT_RGB444BE] = {
00244 .nb_channels = 3,
00245 .color_type = FF_COLOR_RGB,
00246 .pixel_type = FF_PIXEL_PACKED,
00247 .depth = 4,
00248 },
00249 [PIX_FMT_RGB444LE] = {
00250 .nb_channels = 3,
00251 .color_type = FF_COLOR_RGB,
00252 .pixel_type = FF_PIXEL_PACKED,
00253 .depth = 4,
00254 },
00255
00256
00257 [PIX_FMT_GRAY16BE] = {
00258 .nb_channels = 1,
00259 .color_type = FF_COLOR_GRAY,
00260 .pixel_type = FF_PIXEL_PLANAR,
00261 .depth = 16,
00262 },
00263 [PIX_FMT_GRAY16LE] = {
00264 .nb_channels = 1,
00265 .color_type = FF_COLOR_GRAY,
00266 .pixel_type = FF_PIXEL_PLANAR,
00267 .depth = 16,
00268 },
00269 [PIX_FMT_GRAY8] = {
00270 .nb_channels = 1,
00271 .color_type = FF_COLOR_GRAY,
00272 .pixel_type = FF_PIXEL_PLANAR,
00273 .depth = 8,
00274 },
00275 [PIX_FMT_MONOWHITE] = {
00276 .nb_channels = 1,
00277 .color_type = FF_COLOR_GRAY,
00278 .pixel_type = FF_PIXEL_PLANAR,
00279 .depth = 1,
00280 },
00281 [PIX_FMT_MONOBLACK] = {
00282 .nb_channels = 1,
00283 .color_type = FF_COLOR_GRAY,
00284 .pixel_type = FF_PIXEL_PLANAR,
00285 .depth = 1,
00286 },
00287
00288
00289 [PIX_FMT_PAL8] = {
00290 .nb_channels = 4, .is_alpha = 1,
00291 .color_type = FF_COLOR_RGB,
00292 .pixel_type = FF_PIXEL_PALETTE,
00293 .depth = 8,
00294 },
00295 [PIX_FMT_UYYVYY411] = {
00296 .nb_channels = 1,
00297 .color_type = FF_COLOR_YUV,
00298 .pixel_type = FF_PIXEL_PACKED,
00299 .depth = 8,
00300 },
00301 [PIX_FMT_ABGR] = {
00302 .nb_channels = 4, .is_alpha = 1,
00303 .color_type = FF_COLOR_RGB,
00304 .pixel_type = FF_PIXEL_PACKED,
00305 .depth = 8,
00306 },
00307 [PIX_FMT_BGR565BE] = {
00308 .nb_channels = 3,
00309 .color_type = FF_COLOR_RGB,
00310 .pixel_type = FF_PIXEL_PACKED,
00311 .depth = 5,
00312 },
00313 [PIX_FMT_BGR565LE] = {
00314 .nb_channels = 3,
00315 .color_type = FF_COLOR_RGB,
00316 .pixel_type = FF_PIXEL_PACKED,
00317 .depth = 5,
00318 },
00319 [PIX_FMT_BGR555BE] = {
00320 .nb_channels = 3,
00321 .color_type = FF_COLOR_RGB,
00322 .pixel_type = FF_PIXEL_PACKED,
00323 .depth = 5,
00324 },
00325 [PIX_FMT_BGR555LE] = {
00326 .nb_channels = 3,
00327 .color_type = FF_COLOR_RGB,
00328 .pixel_type = FF_PIXEL_PACKED,
00329 .depth = 5,
00330 },
00331 [PIX_FMT_BGR444BE] = {
00332 .nb_channels = 3,
00333 .color_type = FF_COLOR_RGB,
00334 .pixel_type = FF_PIXEL_PACKED,
00335 .depth = 4,
00336 },
00337 [PIX_FMT_BGR444LE] = {
00338 .nb_channels = 3,
00339 .color_type = FF_COLOR_RGB,
00340 .pixel_type = FF_PIXEL_PACKED,
00341 .depth = 4,
00342 },
00343 [PIX_FMT_RGB8] = {
00344 .nb_channels = 1,
00345 .color_type = FF_COLOR_RGB,
00346 .pixel_type = FF_PIXEL_PACKED,
00347 .depth = 8,
00348 },
00349 [PIX_FMT_RGB4] = {
00350 .nb_channels = 1,
00351 .color_type = FF_COLOR_RGB,
00352 .pixel_type = FF_PIXEL_PACKED,
00353 .depth = 4,
00354 },
00355 [PIX_FMT_RGB4_BYTE] = {
00356 .nb_channels = 1,
00357 .color_type = FF_COLOR_RGB,
00358 .pixel_type = FF_PIXEL_PACKED,
00359 .depth = 8,
00360 },
00361 [PIX_FMT_BGR8] = {
00362 .nb_channels = 1,
00363 .color_type = FF_COLOR_RGB,
00364 .pixel_type = FF_PIXEL_PACKED,
00365 .depth = 8,
00366 },
00367 [PIX_FMT_BGR4] = {
00368 .nb_channels = 1,
00369 .color_type = FF_COLOR_RGB,
00370 .pixel_type = FF_PIXEL_PACKED,
00371 .depth = 4,
00372 },
00373 [PIX_FMT_BGR4_BYTE] = {
00374 .nb_channels = 1,
00375 .color_type = FF_COLOR_RGB,
00376 .pixel_type = FF_PIXEL_PACKED,
00377 .depth = 8,
00378 },
00379 [PIX_FMT_NV12] = {
00380 .nb_channels = 2,
00381 .color_type = FF_COLOR_YUV,
00382 .pixel_type = FF_PIXEL_PLANAR,
00383 .depth = 8,
00384 },
00385 [PIX_FMT_NV21] = {
00386 .nb_channels = 2,
00387 .color_type = FF_COLOR_YUV,
00388 .pixel_type = FF_PIXEL_PLANAR,
00389 .depth = 8,
00390 },
00391
00392 [PIX_FMT_BGRA] = {
00393 .nb_channels = 4, .is_alpha = 1,
00394 .color_type = FF_COLOR_RGB,
00395 .pixel_type = FF_PIXEL_PACKED,
00396 .depth = 8,
00397 },
00398 [PIX_FMT_RGBA] = {
00399 .nb_channels = 4, .is_alpha = 1,
00400 .color_type = FF_COLOR_RGB,
00401 .pixel_type = FF_PIXEL_PACKED,
00402 .depth = 8,
00403 },
00404 };
00405
00406 void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift)
00407 {
00408 *h_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
00409 *v_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
00410 }
00411
00412 const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt)
00413 {
00414 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
00415 return NULL;
00416 else
00417 return av_pix_fmt_descriptors[pix_fmt].name;
00418 }
00419
00420 #if LIBAVCODEC_VERSION_MAJOR < 53
00421 enum PixelFormat avcodec_get_pix_fmt(const char *name)
00422 {
00423 return av_get_pix_fmt(name);
00424 }
00425 #endif
00426
00427 void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt)
00428 {
00429
00430 if (pix_fmt < 0)
00431 snprintf (buf, buf_size,
00432 "name " " nb_channels" " depth" " is_alpha"
00433 );
00434 else{
00435 PixFmtInfo info= pix_fmt_info[pix_fmt];
00436
00437 char is_alpha_char= info.is_alpha ? 'y' : 'n';
00438
00439 snprintf (buf, buf_size,
00440 "%-11s %5d %9d %6c",
00441 av_pix_fmt_descriptors[pix_fmt].name,
00442 info.nb_channels,
00443 info.depth,
00444 is_alpha_char
00445 );
00446 }
00447 }
00448
00449 int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
00450 {
00451 return av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_HWACCEL;
00452 }
00453
00454 int ff_set_systematic_pal(uint32_t pal[256], enum PixelFormat pix_fmt){
00455 int i;
00456
00457 for(i=0; i<256; i++){
00458 int r,g,b;
00459
00460 switch(pix_fmt) {
00461 case PIX_FMT_RGB8:
00462 r= (i>>5 )*36;
00463 g= ((i>>2)&7)*36;
00464 b= (i&3 )*85;
00465 break;
00466 case PIX_FMT_BGR8:
00467 b= (i>>6 )*85;
00468 g= ((i>>3)&7)*36;
00469 r= (i&7 )*36;
00470 break;
00471 case PIX_FMT_RGB4_BYTE:
00472 r= (i>>3 )*255;
00473 g= ((i>>1)&3)*85;
00474 b= (i&1 )*255;
00475 break;
00476 case PIX_FMT_BGR4_BYTE:
00477 b= (i>>3 )*255;
00478 g= ((i>>1)&3)*85;
00479 r= (i&1 )*255;
00480 break;
00481 case PIX_FMT_GRAY8:
00482 r=b=g= i;
00483 break;
00484 default:
00485 return -1;
00486 }
00487 pal[i] = b + (g<<8) + (r<<16);
00488 }
00489
00490 return 0;
00491 }
00492
00493 int ff_fill_linesize(AVPicture *picture, enum PixelFormat pix_fmt, int width)
00494 {
00495 int i;
00496 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00497 int max_plane_step [4];
00498 int max_plane_step_comp[4];
00499
00500 memset(picture->linesize, 0, sizeof(picture->linesize));
00501
00502 if (desc->flags & PIX_FMT_HWACCEL)
00503 return -1;
00504
00505 if (desc->flags & PIX_FMT_BITSTREAM) {
00506 picture->linesize[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3;
00507 return 0;
00508 }
00509
00510 memset(max_plane_step , 0, sizeof(max_plane_step ));
00511 memset(max_plane_step_comp, 0, sizeof(max_plane_step_comp));
00512 for (i = 0; i < 4; i++) {
00513 const AVComponentDescriptor *comp = &(desc->comp[i]);
00514 if ((comp->step_minus1+1) > max_plane_step[comp->plane]) {
00515 max_plane_step [comp->plane] = comp->step_minus1+1;
00516 max_plane_step_comp[comp->plane] = i;
00517 }
00518 }
00519
00520 for (i = 0; i < 4; i++) {
00521 int s = (max_plane_step_comp[i] == 1 || max_plane_step_comp[i] == 2) ? desc->log2_chroma_w : 0;
00522 picture->linesize[i] = max_plane_step[i] * (((width + (1 << s) - 1)) >> s);
00523 }
00524
00525 return 0;
00526 }
00527
00528 int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, enum PixelFormat pix_fmt,
00529 int height)
00530 {
00531 int size, h2, size2;
00532 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00533
00534 size = picture->linesize[0] * height;
00535 switch(pix_fmt) {
00536 case PIX_FMT_YUV420P:
00537 case PIX_FMT_YUV422P:
00538 case PIX_FMT_YUV444P:
00539 case PIX_FMT_YUV410P:
00540 case PIX_FMT_YUV411P:
00541 case PIX_FMT_YUV440P:
00542 case PIX_FMT_YUVJ420P:
00543 case PIX_FMT_YUVJ422P:
00544 case PIX_FMT_YUVJ444P:
00545 case PIX_FMT_YUVJ440P:
00546 case PIX_FMT_YUV420P16LE:
00547 case PIX_FMT_YUV422P16LE:
00548 case PIX_FMT_YUV444P16LE:
00549 case PIX_FMT_YUV420P16BE:
00550 case PIX_FMT_YUV422P16BE:
00551 case PIX_FMT_YUV444P16BE:
00552 h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
00553 size2 = picture->linesize[1] * h2;
00554 picture->data[0] = ptr;
00555 picture->data[1] = picture->data[0] + size;
00556 picture->data[2] = picture->data[1] + size2;
00557 picture->data[3] = NULL;
00558 return size + 2 * size2;
00559 case PIX_FMT_YUVA420P:
00560 h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
00561 size2 = picture->linesize[1] * h2;
00562 picture->data[0] = ptr;
00563 picture->data[1] = picture->data[0] + size;
00564 picture->data[2] = picture->data[1] + size2;
00565 picture->data[3] = picture->data[1] + size2 + size2;
00566 return 2 * size + 2 * size2;
00567 case PIX_FMT_NV12:
00568 case PIX_FMT_NV21:
00569 h2 = (height + (1 << desc->log2_chroma_h) - 1) >> desc->log2_chroma_h;
00570 size2 = picture->linesize[1] * h2;
00571 picture->data[0] = ptr;
00572 picture->data[1] = picture->data[0] + size;
00573 picture->data[2] = NULL;
00574 picture->data[3] = NULL;
00575 return size + size2;
00576 case PIX_FMT_RGB24:
00577 case PIX_FMT_BGR24:
00578 case PIX_FMT_ARGB:
00579 case PIX_FMT_ABGR:
00580 case PIX_FMT_RGBA:
00581 case PIX_FMT_BGRA:
00582 case PIX_FMT_RGB48BE:
00583 case PIX_FMT_RGB48LE:
00584 case PIX_FMT_GRAY16BE:
00585 case PIX_FMT_GRAY16LE:
00586 case PIX_FMT_BGR444BE:
00587 case PIX_FMT_BGR444LE:
00588 case PIX_FMT_BGR555BE:
00589 case PIX_FMT_BGR555LE:
00590 case PIX_FMT_BGR565BE:
00591 case PIX_FMT_BGR565LE:
00592 case PIX_FMT_RGB444BE:
00593 case PIX_FMT_RGB444LE:
00594 case PIX_FMT_RGB555BE:
00595 case PIX_FMT_RGB555LE:
00596 case PIX_FMT_RGB565BE:
00597 case PIX_FMT_RGB565LE:
00598 case PIX_FMT_YUYV422:
00599 case PIX_FMT_UYVY422:
00600 case PIX_FMT_UYYVYY411:
00601 case PIX_FMT_RGB4:
00602 case PIX_FMT_BGR4:
00603 case PIX_FMT_MONOWHITE:
00604 case PIX_FMT_MONOBLACK:
00605 case PIX_FMT_Y400A:
00606 picture->data[0] = ptr;
00607 picture->data[1] = NULL;
00608 picture->data[2] = NULL;
00609 picture->data[3] = NULL;
00610 return size;
00611 case PIX_FMT_PAL8:
00612 case PIX_FMT_RGB8:
00613 case PIX_FMT_BGR8:
00614 case PIX_FMT_RGB4_BYTE:
00615 case PIX_FMT_BGR4_BYTE:
00616 case PIX_FMT_GRAY8:
00617 size2 = (size + 3) & ~3;
00618 picture->data[0] = ptr;
00619 picture->data[1] = ptr + size2;
00620 picture->data[2] = NULL;
00621 picture->data[3] = NULL;
00622 return size2 + 256 * 4;
00623 default:
00624 picture->data[0] = NULL;
00625 picture->data[1] = NULL;
00626 picture->data[2] = NULL;
00627 picture->data[3] = NULL;
00628 return -1;
00629 }
00630 }
00631
00632 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
00633 enum PixelFormat pix_fmt, int width, int height)
00634 {
00635
00636 if(avcodec_check_dimensions(NULL, width, height))
00637 return -1;
00638
00639 if (ff_fill_linesize(picture, pix_fmt, width))
00640 return -1;
00641
00642 return ff_fill_pointer(picture, ptr, pix_fmt, height);
00643 }
00644
00645 int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
00646 unsigned char *dest, int dest_size)
00647 {
00648 const PixFmtInfo* pf = &pix_fmt_info[pix_fmt];
00649 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00650 int i, j, w, ow, h, oh, data_planes;
00651 const unsigned char* s;
00652 int size = avpicture_get_size(pix_fmt, width, height);
00653
00654 if (size > dest_size || size < 0)
00655 return -1;
00656
00657 if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
00658 if (pix_fmt == PIX_FMT_YUYV422 ||
00659 pix_fmt == PIX_FMT_UYVY422 ||
00660 pix_fmt == PIX_FMT_BGR565BE ||
00661 pix_fmt == PIX_FMT_BGR565LE ||
00662 pix_fmt == PIX_FMT_BGR555BE ||
00663 pix_fmt == PIX_FMT_BGR555LE ||
00664 pix_fmt == PIX_FMT_BGR444BE ||
00665 pix_fmt == PIX_FMT_BGR444LE ||
00666 pix_fmt == PIX_FMT_RGB565BE ||
00667 pix_fmt == PIX_FMT_RGB565LE ||
00668 pix_fmt == PIX_FMT_RGB555BE ||
00669 pix_fmt == PIX_FMT_RGB555LE ||
00670 pix_fmt == PIX_FMT_RGB444BE ||
00671 pix_fmt == PIX_FMT_RGB444LE)
00672 w = width * 2;
00673 else if (pix_fmt == PIX_FMT_UYYVYY411)
00674 w = width + width/2;
00675 else if (pix_fmt == PIX_FMT_PAL8)
00676 w = width;
00677 else
00678 w = width * (pf->depth * pf->nb_channels / 8);
00679
00680 data_planes = 1;
00681 h = height;
00682 } else {
00683 data_planes = pf->nb_channels;
00684 w = (width*pf->depth + 7)/8;
00685 h = height;
00686 }
00687
00688 ow = w;
00689 oh = h;
00690
00691 for (i=0; i<data_planes; i++) {
00692 if (i == 1) {
00693 w = (- ((-width) >> desc->log2_chroma_w) * pf->depth + 7) / 8;
00694 h = -((-height) >> desc->log2_chroma_h);
00695 if (pix_fmt == PIX_FMT_NV12 || pix_fmt == PIX_FMT_NV21)
00696 w <<= 1;
00697 } else if (i == 3) {
00698 w = ow;
00699 h = oh;
00700 }
00701 s = src->data[i];
00702 for(j=0; j<h; j++) {
00703 memcpy(dest, s, w);
00704 dest += w;
00705 s += src->linesize[i];
00706 }
00707 }
00708
00709 if (pf->pixel_type == FF_PIXEL_PALETTE)
00710 memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
00711
00712 return size;
00713 }
00714
00715 int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
00716 {
00717 AVPicture dummy_pict;
00718 if(avcodec_check_dimensions(NULL, width, height))
00719 return -1;
00720 switch (pix_fmt) {
00721 case PIX_FMT_RGB8:
00722 case PIX_FMT_BGR8:
00723 case PIX_FMT_RGB4_BYTE:
00724 case PIX_FMT_BGR4_BYTE:
00725 case PIX_FMT_GRAY8:
00726
00727 return width * height;
00728 }
00729 return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
00730 }
00731
00732 int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt,
00733 int has_alpha)
00734 {
00735 const PixFmtInfo *pf, *ps;
00736 const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt];
00737 const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt];
00738 int loss;
00739
00740 ps = &pix_fmt_info[src_pix_fmt];
00741
00742
00743 loss = 0;
00744 pf = &pix_fmt_info[dst_pix_fmt];
00745 if (pf->depth < ps->depth ||
00746 ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE ||
00747 dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) &&
00748 (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE ||
00749 src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE)))
00750 loss |= FF_LOSS_DEPTH;
00751 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
00752 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
00753 loss |= FF_LOSS_RESOLUTION;
00754 switch(pf->color_type) {
00755 case FF_COLOR_RGB:
00756 if (ps->color_type != FF_COLOR_RGB &&
00757 ps->color_type != FF_COLOR_GRAY)
00758 loss |= FF_LOSS_COLORSPACE;
00759 break;
00760 case FF_COLOR_GRAY:
00761 if (ps->color_type != FF_COLOR_GRAY)
00762 loss |= FF_LOSS_COLORSPACE;
00763 break;
00764 case FF_COLOR_YUV:
00765 if (ps->color_type != FF_COLOR_YUV)
00766 loss |= FF_LOSS_COLORSPACE;
00767 break;
00768 case FF_COLOR_YUV_JPEG:
00769 if (ps->color_type != FF_COLOR_YUV_JPEG &&
00770 ps->color_type != FF_COLOR_YUV &&
00771 ps->color_type != FF_COLOR_GRAY)
00772 loss |= FF_LOSS_COLORSPACE;
00773 break;
00774 default:
00775
00776 if (ps->color_type != pf->color_type)
00777 loss |= FF_LOSS_COLORSPACE;
00778 break;
00779 }
00780 if (pf->color_type == FF_COLOR_GRAY &&
00781 ps->color_type != FF_COLOR_GRAY)
00782 loss |= FF_LOSS_CHROMA;
00783 if (!pf->is_alpha && (ps->is_alpha && has_alpha))
00784 loss |= FF_LOSS_ALPHA;
00785 if (pf->pixel_type == FF_PIXEL_PALETTE &&
00786 (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
00787 loss |= FF_LOSS_COLORQUANT;
00788 return loss;
00789 }
00790
00791 static int avg_bits_per_pixel(enum PixelFormat pix_fmt)
00792 {
00793 int bits;
00794 const PixFmtInfo *pf;
00795 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00796
00797 pf = &pix_fmt_info[pix_fmt];
00798 switch(pf->pixel_type) {
00799 case FF_PIXEL_PACKED:
00800 switch(pix_fmt) {
00801 case PIX_FMT_YUYV422:
00802 case PIX_FMT_UYVY422:
00803 case PIX_FMT_RGB565BE:
00804 case PIX_FMT_RGB565LE:
00805 case PIX_FMT_RGB555BE:
00806 case PIX_FMT_RGB555LE:
00807 case PIX_FMT_RGB444BE:
00808 case PIX_FMT_RGB444LE:
00809 case PIX_FMT_BGR565BE:
00810 case PIX_FMT_BGR565LE:
00811 case PIX_FMT_BGR555BE:
00812 case PIX_FMT_BGR555LE:
00813 case PIX_FMT_BGR444BE:
00814 case PIX_FMT_BGR444LE:
00815 bits = 16;
00816 break;
00817 case PIX_FMT_UYYVYY411:
00818 bits = 12;
00819 break;
00820 default:
00821 bits = pf->depth * pf->nb_channels;
00822 break;
00823 }
00824 break;
00825 case FF_PIXEL_PLANAR:
00826 if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
00827 bits = pf->depth * pf->nb_channels;
00828 } else {
00829 bits = pf->depth + ((2 * pf->depth) >>
00830 (desc->log2_chroma_w + desc->log2_chroma_h));
00831 }
00832 break;
00833 case FF_PIXEL_PALETTE:
00834 bits = 8;
00835 break;
00836 default:
00837 bits = -1;
00838 break;
00839 }
00840 return bits;
00841 }
00842
00843 static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask,
00844 enum PixelFormat src_pix_fmt,
00845 int has_alpha,
00846 int loss_mask)
00847 {
00848 int dist, i, loss, min_dist;
00849 enum PixelFormat dst_pix_fmt;
00850
00851
00852 dst_pix_fmt = PIX_FMT_NONE;
00853 min_dist = 0x7fffffff;
00854
00855 for (i = 0; i < 64; i++) {
00856 if (pix_fmt_mask & (1ULL << i)) {
00857 loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
00858 if (loss == 0) {
00859 dist = avg_bits_per_pixel(i);
00860 if (dist < min_dist) {
00861 min_dist = dist;
00862 dst_pix_fmt = i;
00863 }
00864 }
00865 }
00866 }
00867 return dst_pix_fmt;
00868 }
00869
00870 enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt,
00871 int has_alpha, int *loss_ptr)
00872 {
00873 enum PixelFormat dst_pix_fmt;
00874 int loss_mask, i;
00875 static const int loss_mask_order[] = {
00876 ~0,
00877 ~FF_LOSS_ALPHA,
00878 ~FF_LOSS_RESOLUTION,
00879 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
00880 ~FF_LOSS_COLORQUANT,
00881 ~FF_LOSS_DEPTH,
00882 0,
00883 };
00884
00885
00886 i = 0;
00887 for(;;) {
00888 loss_mask = loss_mask_order[i++];
00889 dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt,
00890 has_alpha, loss_mask);
00891 if (dst_pix_fmt >= 0)
00892 goto found;
00893 if (loss_mask == 0)
00894 break;
00895 }
00896 return PIX_FMT_NONE;
00897 found:
00898 if (loss_ptr)
00899 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
00900 return dst_pix_fmt;
00901 }
00902
00903 void ff_img_copy_plane(uint8_t *dst, int dst_wrap,
00904 const uint8_t *src, int src_wrap,
00905 int width, int height)
00906 {
00907 if((!dst) || (!src))
00908 return;
00909 for(;height > 0; height--) {
00910 memcpy(dst, src, width);
00911 dst += dst_wrap;
00912 src += src_wrap;
00913 }
00914 }
00915
00916 int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane)
00917 {
00918 int bits;
00919 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00920 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00921
00922 pf = &pix_fmt_info[pix_fmt];
00923 switch(pf->pixel_type) {
00924 case FF_PIXEL_PACKED:
00925 switch(pix_fmt) {
00926 case PIX_FMT_YUYV422:
00927 case PIX_FMT_UYVY422:
00928 case PIX_FMT_RGB565BE:
00929 case PIX_FMT_RGB565LE:
00930 case PIX_FMT_RGB555BE:
00931 case PIX_FMT_RGB555LE:
00932 case PIX_FMT_RGB444BE:
00933 case PIX_FMT_RGB444LE:
00934 case PIX_FMT_BGR565BE:
00935 case PIX_FMT_BGR565LE:
00936 case PIX_FMT_BGR555BE:
00937 case PIX_FMT_BGR555LE:
00938 case PIX_FMT_BGR444BE:
00939 case PIX_FMT_BGR444LE:
00940 bits = 16;
00941 break;
00942 case PIX_FMT_UYYVYY411:
00943 bits = 12;
00944 break;
00945 default:
00946 bits = pf->depth * pf->nb_channels;
00947 break;
00948 }
00949 return (width * bits + 7) >> 3;
00950 break;
00951 case FF_PIXEL_PLANAR:
00952 if (plane == 1 || plane == 2)
00953 width= -((-width)>>desc->log2_chroma_w);
00954
00955 return (width * pf->depth + 7) >> 3;
00956 break;
00957 case FF_PIXEL_PALETTE:
00958 if (plane == 0)
00959 return width;
00960 break;
00961 }
00962
00963 return -1;
00964 }
00965
00966 void av_picture_copy(AVPicture *dst, const AVPicture *src,
00967 enum PixelFormat pix_fmt, int width, int height)
00968 {
00969 int i;
00970 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
00971 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
00972
00973 switch(pf->pixel_type) {
00974 case FF_PIXEL_PACKED:
00975 case FF_PIXEL_PLANAR:
00976 for(i = 0; i < pf->nb_channels; i++) {
00977 int h;
00978 int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i);
00979 h = height;
00980 if (i == 1 || i == 2) {
00981 h= -((-height)>>desc->log2_chroma_h);
00982 }
00983 ff_img_copy_plane(dst->data[i], dst->linesize[i],
00984 src->data[i], src->linesize[i],
00985 bwidth, h);
00986 }
00987 break;
00988 case FF_PIXEL_PALETTE:
00989 ff_img_copy_plane(dst->data[0], dst->linesize[0],
00990 src->data[0], src->linesize[0],
00991 width, height);
00992
00993 memcpy(dst->data[1], src->data[1], 4*256);
00994 break;
00995 }
00996 }
00997
00998
00999 void ff_shrink22(uint8_t *dst, int dst_wrap,
01000 const uint8_t *src, int src_wrap,
01001 int width, int height)
01002 {
01003 int w;
01004 const uint8_t *s1, *s2;
01005 uint8_t *d;
01006
01007 for(;height > 0; height--) {
01008 s1 = src;
01009 s2 = s1 + src_wrap;
01010 d = dst;
01011 for(w = width;w >= 4; w-=4) {
01012 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
01013 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
01014 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
01015 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
01016 s1 += 8;
01017 s2 += 8;
01018 d += 4;
01019 }
01020 for(;w > 0; w--) {
01021 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
01022 s1 += 2;
01023 s2 += 2;
01024 d++;
01025 }
01026 src += 2 * src_wrap;
01027 dst += dst_wrap;
01028 }
01029 }
01030
01031
01032 void ff_shrink44(uint8_t *dst, int dst_wrap,
01033 const uint8_t *src, int src_wrap,
01034 int width, int height)
01035 {
01036 int w;
01037 const uint8_t *s1, *s2, *s3, *s4;
01038 uint8_t *d;
01039
01040 for(;height > 0; height--) {
01041 s1 = src;
01042 s2 = s1 + src_wrap;
01043 s3 = s2 + src_wrap;
01044 s4 = s3 + src_wrap;
01045 d = dst;
01046 for(w = width;w > 0; w--) {
01047 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
01048 s2[0] + s2[1] + s2[2] + s2[3] +
01049 s3[0] + s3[1] + s3[2] + s3[3] +
01050 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
01051 s1 += 4;
01052 s2 += 4;
01053 s3 += 4;
01054 s4 += 4;
01055 d++;
01056 }
01057 src += 4 * src_wrap;
01058 dst += dst_wrap;
01059 }
01060 }
01061
01062
01063 void ff_shrink88(uint8_t *dst, int dst_wrap,
01064 const uint8_t *src, int src_wrap,
01065 int width, int height)
01066 {
01067 int w, i;
01068
01069 for(;height > 0; height--) {
01070 for(w = width;w > 0; w--) {
01071 int tmp=0;
01072 for(i=0; i<8; i++){
01073 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
01074 src += src_wrap;
01075 }
01076 *(dst++) = (tmp + 32)>>6;
01077 src += 8 - 8*src_wrap;
01078 }
01079 src += 8*src_wrap - 8*width;
01080 dst += dst_wrap - width;
01081 }
01082 }
01083
01084
01085 int avpicture_alloc(AVPicture *picture,
01086 enum PixelFormat pix_fmt, int width, int height)
01087 {
01088 int size;
01089 void *ptr;
01090
01091 size = avpicture_fill(picture, NULL, pix_fmt, width, height);
01092 if(size<0)
01093 goto fail;
01094 ptr = av_malloc(size);
01095 if (!ptr)
01096 goto fail;
01097 avpicture_fill(picture, ptr, pix_fmt, width, height);
01098 if(picture->data[1] && !picture->data[2])
01099 ff_set_systematic_pal((uint32_t*)picture->data[1], pix_fmt);
01100
01101 return 0;
01102 fail:
01103 memset(picture, 0, sizeof(AVPicture));
01104 return -1;
01105 }
01106
01107 void avpicture_free(AVPicture *picture)
01108 {
01109 av_free(picture->data[0]);
01110 }
01111
01112
01113 static inline int is_yuv_planar(const PixFmtInfo *ps)
01114 {
01115 return (ps->color_type == FF_COLOR_YUV ||
01116 ps->color_type == FF_COLOR_YUV_JPEG) &&
01117 ps->pixel_type == FF_PIXEL_PLANAR;
01118 }
01119
01120 int av_picture_crop(AVPicture *dst, const AVPicture *src,
01121 enum PixelFormat pix_fmt, int top_band, int left_band)
01122 {
01123 int y_shift;
01124 int x_shift;
01125
01126 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
01127 return -1;
01128
01129 y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h;
01130 x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w;
01131
01132 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
01133 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
01134 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
01135
01136 dst->linesize[0] = src->linesize[0];
01137 dst->linesize[1] = src->linesize[1];
01138 dst->linesize[2] = src->linesize[2];
01139 return 0;
01140 }
01141
01142 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
01143 enum PixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
01144 int *color)
01145 {
01146 uint8_t *optr;
01147 int y_shift;
01148 int x_shift;
01149 int yheight;
01150 int i, y;
01151
01152 if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB ||
01153 !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
01154
01155 for (i = 0; i < 3; i++) {
01156 x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0;
01157 y_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_h : 0;
01158
01159 if (padtop || padleft) {
01160 memset(dst->data[i], color[i],
01161 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
01162 }
01163
01164 if (padleft || padright) {
01165 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
01166 (dst->linesize[i] - (padright >> x_shift));
01167 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
01168 for (y = 0; y < yheight; y++) {
01169 memset(optr, color[i], (padleft + padright) >> x_shift);
01170 optr += dst->linesize[i];
01171 }
01172 }
01173
01174 if (src) {
01175 uint8_t *iptr = src->data[i];
01176 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
01177 (padleft >> x_shift);
01178 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
01179 iptr += src->linesize[i];
01180 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
01181 (dst->linesize[i] - (padright >> x_shift));
01182 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
01183 for (y = 0; y < yheight; y++) {
01184 memset(optr, color[i], (padleft + padright) >> x_shift);
01185 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
01186 (width - padleft - padright) >> x_shift);
01187 iptr += src->linesize[i];
01188 optr += dst->linesize[i];
01189 }
01190 }
01191
01192 if (padbottom || padright) {
01193 optr = dst->data[i] + dst->linesize[i] *
01194 ((height - padbottom) >> y_shift) - (padright >> x_shift);
01195 memset(optr, color[i],dst->linesize[i] *
01196 (padbottom >> y_shift) + (padright >> x_shift));
01197 }
01198 }
01199 return 0;
01200 }
01201
01202
01203 static int get_alpha_info_pal8(const AVPicture *src, int width, int height)
01204 {
01205 const unsigned char *p;
01206 int src_wrap, ret, x, y;
01207 unsigned int a;
01208 uint32_t *palette = (uint32_t *)src->data[1];
01209
01210 p = src->data[0];
01211 src_wrap = src->linesize[0] - width;
01212 ret = 0;
01213 for(y=0;y<height;y++) {
01214 for(x=0;x<width;x++) {
01215 a = palette[p[0]] >> 24;
01216 if (a == 0x00) {
01217 ret |= FF_ALPHA_TRANSP;
01218 } else if (a != 0xff) {
01219 ret |= FF_ALPHA_SEMI_TRANSP;
01220 }
01221 p++;
01222 }
01223 p += src_wrap;
01224 }
01225 return ret;
01226 }
01227
01228 int img_get_alpha_info(const AVPicture *src,
01229 enum PixelFormat pix_fmt, int width, int height)
01230 {
01231 const PixFmtInfo *pf = &pix_fmt_info[pix_fmt];
01232 int ret;
01233
01234
01235 if (!pf->is_alpha)
01236 return 0;
01237 switch(pix_fmt) {
01238 case PIX_FMT_PAL8:
01239 ret = get_alpha_info_pal8(src, width, height);
01240 break;
01241 default:
01242
01243 ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;
01244 break;
01245 }
01246 return ret;
01247 }
01248
01249 #if HAVE_MMX
01250 #define DEINT_INPLACE_LINE_LUM \
01251 movd_m2r(lum_m4[0],mm0);\
01252 movd_m2r(lum_m3[0],mm1);\
01253 movd_m2r(lum_m2[0],mm2);\
01254 movd_m2r(lum_m1[0],mm3);\
01255 movd_m2r(lum[0],mm4);\
01256 punpcklbw_r2r(mm7,mm0);\
01257 movd_r2m(mm2,lum_m4[0]);\
01258 punpcklbw_r2r(mm7,mm1);\
01259 punpcklbw_r2r(mm7,mm2);\
01260 punpcklbw_r2r(mm7,mm3);\
01261 punpcklbw_r2r(mm7,mm4);\
01262 paddw_r2r(mm3,mm1);\
01263 psllw_i2r(1,mm2);\
01264 paddw_r2r(mm4,mm0);\
01265 psllw_i2r(2,mm1);\
01266 paddw_r2r(mm6,mm2);\
01267 paddw_r2r(mm2,mm1);\
01268 psubusw_r2r(mm0,mm1);\
01269 psrlw_i2r(3,mm1);\
01270 packuswb_r2r(mm7,mm1);\
01271 movd_r2m(mm1,lum_m2[0]);
01272
01273 #define DEINT_LINE_LUM \
01274 movd_m2r(lum_m4[0],mm0);\
01275 movd_m2r(lum_m3[0],mm1);\
01276 movd_m2r(lum_m2[0],mm2);\
01277 movd_m2r(lum_m1[0],mm3);\
01278 movd_m2r(lum[0],mm4);\
01279 punpcklbw_r2r(mm7,mm0);\
01280 punpcklbw_r2r(mm7,mm1);\
01281 punpcklbw_r2r(mm7,mm2);\
01282 punpcklbw_r2r(mm7,mm3);\
01283 punpcklbw_r2r(mm7,mm4);\
01284 paddw_r2r(mm3,mm1);\
01285 psllw_i2r(1,mm2);\
01286 paddw_r2r(mm4,mm0);\
01287 psllw_i2r(2,mm1);\
01288 paddw_r2r(mm6,mm2);\
01289 paddw_r2r(mm2,mm1);\
01290 psubusw_r2r(mm0,mm1);\
01291 psrlw_i2r(3,mm1);\
01292 packuswb_r2r(mm7,mm1);\
01293 movd_r2m(mm1,dst[0]);
01294 #endif
01295
01296
01297 static void deinterlace_line(uint8_t *dst,
01298 const uint8_t *lum_m4, const uint8_t *lum_m3,
01299 const uint8_t *lum_m2, const uint8_t *lum_m1,
01300 const uint8_t *lum,
01301 int size)
01302 {
01303 #if !HAVE_MMX
01304 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
01305 int sum;
01306
01307 for(;size > 0;size--) {
01308 sum = -lum_m4[0];
01309 sum += lum_m3[0] << 2;
01310 sum += lum_m2[0] << 1;
01311 sum += lum_m1[0] << 2;
01312 sum += -lum[0];
01313 dst[0] = cm[(sum + 4) >> 3];
01314 lum_m4++;
01315 lum_m3++;
01316 lum_m2++;
01317 lum_m1++;
01318 lum++;
01319 dst++;
01320 }
01321 #else
01322
01323 {
01324 pxor_r2r(mm7,mm7);
01325 movq_m2r(ff_pw_4,mm6);
01326 }
01327 for (;size > 3; size-=4) {
01328 DEINT_LINE_LUM
01329 lum_m4+=4;
01330 lum_m3+=4;
01331 lum_m2+=4;
01332 lum_m1+=4;
01333 lum+=4;
01334 dst+=4;
01335 }
01336 #endif
01337 }
01338 static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,
01339 int size)
01340 {
01341 #if !HAVE_MMX
01342 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
01343 int sum;
01344
01345 for(;size > 0;size--) {
01346 sum = -lum_m4[0];
01347 sum += lum_m3[0] << 2;
01348 sum += lum_m2[0] << 1;
01349 lum_m4[0]=lum_m2[0];
01350 sum += lum_m1[0] << 2;
01351 sum += -lum[0];
01352 lum_m2[0] = cm[(sum + 4) >> 3];
01353 lum_m4++;
01354 lum_m3++;
01355 lum_m2++;
01356 lum_m1++;
01357 lum++;
01358 }
01359 #else
01360
01361 {
01362 pxor_r2r(mm7,mm7);
01363 movq_m2r(ff_pw_4,mm6);
01364 }
01365 for (;size > 3; size-=4) {
01366 DEINT_INPLACE_LINE_LUM
01367 lum_m4+=4;
01368 lum_m3+=4;
01369 lum_m2+=4;
01370 lum_m1+=4;
01371 lum+=4;
01372 }
01373 #endif
01374 }
01375
01376
01377
01378
01379 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
01380 const uint8_t *src1, int src_wrap,
01381 int width, int height)
01382 {
01383 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
01384 int y;
01385
01386 src_m2 = src1;
01387 src_m1 = src1;
01388 src_0=&src_m1[src_wrap];
01389 src_p1=&src_0[src_wrap];
01390 src_p2=&src_p1[src_wrap];
01391 for(y=0;y<(height-2);y+=2) {
01392 memcpy(dst,src_m1,width);
01393 dst += dst_wrap;
01394 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
01395 src_m2 = src_0;
01396 src_m1 = src_p1;
01397 src_0 = src_p2;
01398 src_p1 += 2*src_wrap;
01399 src_p2 += 2*src_wrap;
01400 dst += dst_wrap;
01401 }
01402 memcpy(dst,src_m1,width);
01403 dst += dst_wrap;
01404
01405 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
01406 }
01407
01408 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
01409 int width, int height)
01410 {
01411 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
01412 int y;
01413 uint8_t *buf;
01414 buf = (uint8_t*)av_malloc(width);
01415
01416 src_m1 = src1;
01417 memcpy(buf,src_m1,width);
01418 src_0=&src_m1[src_wrap];
01419 src_p1=&src_0[src_wrap];
01420 src_p2=&src_p1[src_wrap];
01421 for(y=0;y<(height-2);y+=2) {
01422 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
01423 src_m1 = src_p1;
01424 src_0 = src_p2;
01425 src_p1 += 2*src_wrap;
01426 src_p2 += 2*src_wrap;
01427 }
01428
01429 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
01430 av_free(buf);
01431 }
01432
01433 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
01434 enum PixelFormat pix_fmt, int width, int height)
01435 {
01436 int i;
01437
01438 if (pix_fmt != PIX_FMT_YUV420P &&
01439 pix_fmt != PIX_FMT_YUV422P &&
01440 pix_fmt != PIX_FMT_YUV444P &&
01441 pix_fmt != PIX_FMT_YUV411P &&
01442 pix_fmt != PIX_FMT_GRAY8)
01443 return -1;
01444 if ((width & 3) != 0 || (height & 3) != 0)
01445 return -1;
01446
01447 for(i=0;i<3;i++) {
01448 if (i == 1) {
01449 switch(pix_fmt) {
01450 case PIX_FMT_YUV420P:
01451 width >>= 1;
01452 height >>= 1;
01453 break;
01454 case PIX_FMT_YUV422P:
01455 width >>= 1;
01456 break;
01457 case PIX_FMT_YUV411P:
01458 width >>= 2;
01459 break;
01460 default:
01461 break;
01462 }
01463 if (pix_fmt == PIX_FMT_GRAY8) {
01464 break;
01465 }
01466 }
01467 if (src == dst) {
01468 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
01469 width, height);
01470 } else {
01471 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
01472 src->data[i], src->linesize[i],
01473 width, height);
01474 }
01475 }
01476 emms_c();
01477 return 0;
01478 }
01479