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 "libavutil/avassert.h"
00037 #include "libavutil/colorspace.h"
00038 #include "libavutil/common.h"
00039 #include "libavutil/pixdesc.h"
00040 #include "libavutil/imgutils.h"
00041
00042 #if HAVE_MMX_EXTERNAL
00043 #include "x86/dsputil_mmx.h"
00044 #endif
00045
00046 #define FF_COLOR_NA -1
00047 #define FF_COLOR_RGB 0
00048 #define FF_COLOR_GRAY 1
00049 #define FF_COLOR_YUV 2
00050 #define FF_COLOR_YUV_JPEG 3
00052 #if HAVE_MMX_EXTERNAL
00053 #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
00054 #define deinterlace_line ff_deinterlace_line_mmx
00055 #else
00056 #define deinterlace_line_inplace deinterlace_line_inplace_c
00057 #define deinterlace_line deinterlace_line_c
00058 #endif
00059
00060 #define pixdesc_has_alpha(pixdesc) \
00061 ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & PIX_FMT_PAL)
00062
00063
00064 void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
00065 {
00066 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
00067 av_assert0(desc);
00068 *h_shift = desc->log2_chroma_w;
00069 *v_shift = desc->log2_chroma_h;
00070 }
00071
00072 static get_color_type(AVPixFmtDescriptor *desc) {
00073 if(desc->nb_components == 1 || desc->nb_components == 2)
00074 return FF_COLOR_GRAY;
00075
00076 if(desc->name && !strncmp(desc->name, "yuvj", 4))
00077 return FF_COLOR_YUV_JPEG;
00078
00079 if(desc->flags & PIX_FMT_RGB)
00080 return FF_COLOR_RGB;
00081
00082 if(desc->nb_components == 0)
00083 return FF_COLOR_NA;
00084
00085 return FF_COLOR_YUV;
00086 }
00087
00088 static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt)
00089 {
00090 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
00091 int i;
00092
00093 if (!desc || !desc->nb_components) {
00094 *min = *max = 0;
00095 return AVERROR(EINVAL);
00096 }
00097
00098 *min = INT_MAX, *max = -INT_MAX;
00099 for (i = 0; i < desc->nb_components; i++) {
00100 *min = FFMIN(desc->comp[i].depth_minus1+1, *min);
00101 *max = FFMAX(desc->comp[i].depth_minus1+1, *max);
00102 }
00103 return 0;
00104 }
00105
00106 int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
00107 enum AVPixelFormat src_pix_fmt,
00108 int has_alpha)
00109 {
00110 const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(src_pix_fmt);
00111 const AVPixFmtDescriptor *dst_desc = av_pix_fmt_desc_get(dst_pix_fmt);
00112 int src_color, dst_color;
00113 int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
00114 int ret, loss, i, nb_components;
00115
00116 if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
00117 return ~0;
00118
00119
00120 loss = 0;
00121
00122 if (dst_pix_fmt == src_pix_fmt)
00123 return 0;
00124
00125 if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
00126 return ret;
00127 if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0)
00128 return ret;
00129
00130 src_color = get_color_type(src_desc);
00131 dst_color = get_color_type(dst_desc);
00132 nb_components = FFMIN(src_desc->nb_components, dst_desc->nb_components);
00133
00134 for (i = 0; i < nb_components; i++)
00135 if (src_desc->comp[i].depth_minus1 > dst_desc->comp[i].depth_minus1)
00136 loss |= FF_LOSS_DEPTH;
00137
00138 if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
00139 dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
00140 loss |= FF_LOSS_RESOLUTION;
00141
00142 switch(dst_color) {
00143 case FF_COLOR_RGB:
00144 if (src_color != FF_COLOR_RGB &&
00145 src_color != FF_COLOR_GRAY)
00146 loss |= FF_LOSS_COLORSPACE;
00147 break;
00148 case FF_COLOR_GRAY:
00149 if (src_color != FF_COLOR_GRAY)
00150 loss |= FF_LOSS_COLORSPACE;
00151 break;
00152 case FF_COLOR_YUV:
00153 if (src_color != FF_COLOR_YUV)
00154 loss |= FF_LOSS_COLORSPACE;
00155 break;
00156 case FF_COLOR_YUV_JPEG:
00157 if (src_color != FF_COLOR_YUV_JPEG &&
00158 src_color != FF_COLOR_YUV &&
00159 src_color != FF_COLOR_GRAY)
00160 loss |= FF_LOSS_COLORSPACE;
00161 break;
00162 default:
00163
00164 if (src_color != dst_color)
00165 loss |= FF_LOSS_COLORSPACE;
00166 break;
00167 }
00168 if (dst_color == FF_COLOR_GRAY &&
00169 src_color != FF_COLOR_GRAY)
00170 loss |= FF_LOSS_CHROMA;
00171 if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && has_alpha))
00172 loss |= FF_LOSS_ALPHA;
00173 if (dst_pix_fmt == AV_PIX_FMT_PAL8 &&
00174 (src_pix_fmt != AV_PIX_FMT_PAL8 && (src_color != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && has_alpha))))
00175 loss |= FF_LOSS_COLORQUANT;
00176
00177 return loss;
00178 }
00179
00180 #if FF_API_FIND_BEST_PIX_FMT
00181 enum AVPixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum AVPixelFormat src_pix_fmt,
00182 int has_alpha, int *loss_ptr)
00183 {
00184 enum AVPixelFormat dst_pix_fmt;
00185 int i;
00186
00187 if (loss_ptr)
00188 *loss_ptr = 0;
00189
00190 dst_pix_fmt = AV_PIX_FMT_NONE;
00191 for(i = 0; i< FFMIN(AV_PIX_FMT_NB, 64); i++){
00192 if (pix_fmt_mask & (1ULL << i))
00193 dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt, i, src_pix_fmt, has_alpha, loss_ptr);
00194 }
00195 return dst_pix_fmt;
00196 }
00197 #endif
00198
00199 enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
00200 enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
00201 {
00202 enum AVPixelFormat dst_pix_fmt;
00203 int loss1, loss2, loss_order1, loss_order2, i, loss_mask;
00204 const AVPixFmtDescriptor *desc1 = av_pix_fmt_desc_get(dst_pix_fmt1);
00205 const AVPixFmtDescriptor *desc2 = av_pix_fmt_desc_get(dst_pix_fmt2);
00206 static const int loss_mask_order[] = {
00207 ~0,
00208 ~FF_LOSS_ALPHA,
00209 ~FF_LOSS_RESOLUTION,
00210 ~FF_LOSS_COLORSPACE,
00211 ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
00212 ~FF_LOSS_COLORQUANT,
00213 ~FF_LOSS_DEPTH,
00214 ~(FF_LOSS_DEPTH|FF_LOSS_COLORSPACE),
00215 ~(FF_LOSS_RESOLUTION | FF_LOSS_DEPTH | FF_LOSS_COLORSPACE | FF_LOSS_ALPHA |
00216 FF_LOSS_COLORQUANT | FF_LOSS_CHROMA),
00217 0x80000,
00218 0,
00219 };
00220
00221 loss_mask= loss_ptr?~*loss_ptr:~0;
00222 dst_pix_fmt = AV_PIX_FMT_NONE;
00223 loss1 = avcodec_get_pix_fmt_loss(dst_pix_fmt1, src_pix_fmt, has_alpha) & loss_mask;
00224 loss2 = avcodec_get_pix_fmt_loss(dst_pix_fmt2, src_pix_fmt, has_alpha) & loss_mask;
00225
00226
00227 for(i = 0;loss_mask_order[i] != 0 && dst_pix_fmt == AV_PIX_FMT_NONE;i++) {
00228 loss_order1 = loss1 & loss_mask_order[i];
00229 loss_order2 = loss2 & loss_mask_order[i];
00230
00231 if (loss_order1 == 0 && loss_order2 == 0 && dst_pix_fmt2 != AV_PIX_FMT_NONE && dst_pix_fmt1 != AV_PIX_FMT_NONE){
00232 if(av_get_padded_bits_per_pixel(desc2) != av_get_padded_bits_per_pixel(desc1)) {
00233 dst_pix_fmt = av_get_padded_bits_per_pixel(desc2) < av_get_padded_bits_per_pixel(desc1) ? dst_pix_fmt2 : dst_pix_fmt1;
00234 } else {
00235 dst_pix_fmt = desc2->nb_components < desc1->nb_components ? dst_pix_fmt2 : dst_pix_fmt1;
00236 }
00237 } else if (loss_order1 == 0 || loss_order2 == 0) {
00238 dst_pix_fmt = loss_order2 ? dst_pix_fmt1 : dst_pix_fmt2;
00239 }
00240 }
00241
00242 if (loss_ptr)
00243 *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
00244 return dst_pix_fmt;
00245 }
00246
00247 #if AV_HAVE_INCOMPATIBLE_FORK_ABI
00248 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
00249 enum AVPixelFormat src_pix_fmt,
00250 int has_alpha, int *loss_ptr){
00251 return avcodec_find_best_pix_fmt_of_list(pix_fmt_list, src_pix_fmt, has_alpha, loss_ptr);
00252 }
00253 #else
00254 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
00255 enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
00256 {
00257 return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
00258 }
00259 #endif
00260
00261 enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list,
00262 enum AVPixelFormat src_pix_fmt,
00263 int has_alpha, int *loss_ptr){
00264 int i;
00265
00266 enum AVPixelFormat best = AV_PIX_FMT_NONE;
00267
00268 for(i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++)
00269 best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, loss_ptr);
00270
00271 return best;
00272 }
00273
00274
00275 void ff_shrink22(uint8_t *dst, int dst_wrap,
00276 const uint8_t *src, int src_wrap,
00277 int width, int height)
00278 {
00279 int w;
00280 const uint8_t *s1, *s2;
00281 uint8_t *d;
00282
00283 for(;height > 0; height--) {
00284 s1 = src;
00285 s2 = s1 + src_wrap;
00286 d = dst;
00287 for(w = width;w >= 4; w-=4) {
00288 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
00289 d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2;
00290 d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2;
00291 d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2;
00292 s1 += 8;
00293 s2 += 8;
00294 d += 4;
00295 }
00296 for(;w > 0; w--) {
00297 d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2;
00298 s1 += 2;
00299 s2 += 2;
00300 d++;
00301 }
00302 src += 2 * src_wrap;
00303 dst += dst_wrap;
00304 }
00305 }
00306
00307
00308 void ff_shrink44(uint8_t *dst, int dst_wrap,
00309 const uint8_t *src, int src_wrap,
00310 int width, int height)
00311 {
00312 int w;
00313 const uint8_t *s1, *s2, *s3, *s4;
00314 uint8_t *d;
00315
00316 for(;height > 0; height--) {
00317 s1 = src;
00318 s2 = s1 + src_wrap;
00319 s3 = s2 + src_wrap;
00320 s4 = s3 + src_wrap;
00321 d = dst;
00322 for(w = width;w > 0; w--) {
00323 d[0] = (s1[0] + s1[1] + s1[2] + s1[3] +
00324 s2[0] + s2[1] + s2[2] + s2[3] +
00325 s3[0] + s3[1] + s3[2] + s3[3] +
00326 s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4;
00327 s1 += 4;
00328 s2 += 4;
00329 s3 += 4;
00330 s4 += 4;
00331 d++;
00332 }
00333 src += 4 * src_wrap;
00334 dst += dst_wrap;
00335 }
00336 }
00337
00338
00339 void ff_shrink88(uint8_t *dst, int dst_wrap,
00340 const uint8_t *src, int src_wrap,
00341 int width, int height)
00342 {
00343 int w, i;
00344
00345 for(;height > 0; height--) {
00346 for(w = width;w > 0; w--) {
00347 int tmp=0;
00348 for(i=0; i<8; i++){
00349 tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7];
00350 src += src_wrap;
00351 }
00352 *(dst++) = (tmp + 32)>>6;
00353 src += 8 - 8*src_wrap;
00354 }
00355 src += 8*src_wrap - 8*width;
00356 dst += dst_wrap - width;
00357 }
00358 }
00359
00360
00361 static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
00362 {
00363 int i;
00364 int planes[4] = { 0 };
00365
00366 if ( desc->flags & PIX_FMT_RGB
00367 || !(desc->flags & PIX_FMT_PLANAR))
00368 return 0;
00369
00370
00371 for (i = 0; i < desc->nb_components; i++)
00372 planes[desc->comp[i].plane] = 1;
00373
00374
00375 for (i = 0; i < desc->nb_components; i++)
00376 if (!planes[i])
00377 return 0;
00378 return 1;
00379 }
00380
00381 int av_picture_crop(AVPicture *dst, const AVPicture *src,
00382 enum AVPixelFormat pix_fmt, int top_band, int left_band)
00383 {
00384 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
00385 int y_shift;
00386 int x_shift;
00387
00388 if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
00389 return -1;
00390
00391 y_shift = desc->log2_chroma_h;
00392 x_shift = desc->log2_chroma_w;
00393
00394 if (is_yuv_planar(desc)) {
00395 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
00396 dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
00397 dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
00398 } else{
00399 if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
00400 return -1;
00401 if(left_band)
00402 return -1;
00403 dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
00404 }
00405
00406 dst->linesize[0] = src->linesize[0];
00407 dst->linesize[1] = src->linesize[1];
00408 dst->linesize[2] = src->linesize[2];
00409 return 0;
00410 }
00411
00412 int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
00413 enum AVPixelFormat pix_fmt, int padtop, int padbottom, int padleft, int padright,
00414 int *color)
00415 {
00416 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
00417 uint8_t *optr;
00418 int y_shift;
00419 int x_shift;
00420 int yheight;
00421 int i, y;
00422
00423 if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB ||
00424 !is_yuv_planar(desc)) return -1;
00425
00426 for (i = 0; i < 3; i++) {
00427 x_shift = i ? desc->log2_chroma_w : 0;
00428 y_shift = i ? desc->log2_chroma_h : 0;
00429
00430 if (padtop || padleft) {
00431 memset(dst->data[i], color[i],
00432 dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift));
00433 }
00434
00435 if (padleft || padright) {
00436 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
00437 (dst->linesize[i] - (padright >> x_shift));
00438 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
00439 for (y = 0; y < yheight; y++) {
00440 memset(optr, color[i], (padleft + padright) >> x_shift);
00441 optr += dst->linesize[i];
00442 }
00443 }
00444
00445 if (src) {
00446 uint8_t *iptr = src->data[i];
00447 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
00448 (padleft >> x_shift);
00449 memcpy(optr, iptr, (width - padleft - padright) >> x_shift);
00450 iptr += src->linesize[i];
00451 optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) +
00452 (dst->linesize[i] - (padright >> x_shift));
00453 yheight = (height - 1 - (padtop + padbottom)) >> y_shift;
00454 for (y = 0; y < yheight; y++) {
00455 memset(optr, color[i], (padleft + padright) >> x_shift);
00456 memcpy(optr + ((padleft + padright) >> x_shift), iptr,
00457 (width - padleft - padright) >> x_shift);
00458 iptr += src->linesize[i];
00459 optr += dst->linesize[i];
00460 }
00461 }
00462
00463 if (padbottom || padright) {
00464 optr = dst->data[i] + dst->linesize[i] *
00465 ((height - padbottom) >> y_shift) - (padright >> x_shift);
00466 memset(optr, color[i],dst->linesize[i] *
00467 (padbottom >> y_shift) + (padright >> x_shift));
00468 }
00469 }
00470 return 0;
00471 }
00472
00473 #if !HAVE_MMX_EXTERNAL
00474
00475 static void deinterlace_line_c(uint8_t *dst,
00476 const uint8_t *lum_m4, const uint8_t *lum_m3,
00477 const uint8_t *lum_m2, const uint8_t *lum_m1,
00478 const uint8_t *lum,
00479 int size)
00480 {
00481 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00482 int sum;
00483
00484 for(;size > 0;size--) {
00485 sum = -lum_m4[0];
00486 sum += lum_m3[0] << 2;
00487 sum += lum_m2[0] << 1;
00488 sum += lum_m1[0] << 2;
00489 sum += -lum[0];
00490 dst[0] = cm[(sum + 4) >> 3];
00491 lum_m4++;
00492 lum_m3++;
00493 lum_m2++;
00494 lum_m1++;
00495 lum++;
00496 dst++;
00497 }
00498 }
00499
00500 static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
00501 uint8_t *lum_m2, uint8_t *lum_m1,
00502 uint8_t *lum, int size)
00503 {
00504 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00505 int sum;
00506
00507 for(;size > 0;size--) {
00508 sum = -lum_m4[0];
00509 sum += lum_m3[0] << 2;
00510 sum += lum_m2[0] << 1;
00511 lum_m4[0]=lum_m2[0];
00512 sum += lum_m1[0] << 2;
00513 sum += -lum[0];
00514 lum_m2[0] = cm[(sum + 4) >> 3];
00515 lum_m4++;
00516 lum_m3++;
00517 lum_m2++;
00518 lum_m1++;
00519 lum++;
00520 }
00521 }
00522 #endif
00523
00524
00525
00526
00527 static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
00528 const uint8_t *src1, int src_wrap,
00529 int width, int height)
00530 {
00531 const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
00532 int y;
00533
00534 src_m2 = src1;
00535 src_m1 = src1;
00536 src_0=&src_m1[src_wrap];
00537 src_p1=&src_0[src_wrap];
00538 src_p2=&src_p1[src_wrap];
00539 for(y=0;y<(height-2);y+=2) {
00540 memcpy(dst,src_m1,width);
00541 dst += dst_wrap;
00542 deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
00543 src_m2 = src_0;
00544 src_m1 = src_p1;
00545 src_0 = src_p2;
00546 src_p1 += 2*src_wrap;
00547 src_p2 += 2*src_wrap;
00548 dst += dst_wrap;
00549 }
00550 memcpy(dst,src_m1,width);
00551 dst += dst_wrap;
00552
00553 deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
00554 }
00555
00556 static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap,
00557 int width, int height)
00558 {
00559 uint8_t *src_m1, *src_0, *src_p1, *src_p2;
00560 int y;
00561 uint8_t *buf;
00562 buf = av_malloc(width);
00563
00564 src_m1 = src1;
00565 memcpy(buf,src_m1,width);
00566 src_0=&src_m1[src_wrap];
00567 src_p1=&src_0[src_wrap];
00568 src_p2=&src_p1[src_wrap];
00569 for(y=0;y<(height-2);y+=2) {
00570 deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width);
00571 src_m1 = src_p1;
00572 src_0 = src_p2;
00573 src_p1 += 2*src_wrap;
00574 src_p2 += 2*src_wrap;
00575 }
00576
00577 deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width);
00578 av_free(buf);
00579 }
00580
00581 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
00582 enum AVPixelFormat pix_fmt, int width, int height)
00583 {
00584 int i;
00585
00586 if (pix_fmt != AV_PIX_FMT_YUV420P &&
00587 pix_fmt != AV_PIX_FMT_YUVJ420P &&
00588 pix_fmt != AV_PIX_FMT_YUV422P &&
00589 pix_fmt != AV_PIX_FMT_YUVJ422P &&
00590 pix_fmt != AV_PIX_FMT_YUV444P &&
00591 pix_fmt != AV_PIX_FMT_YUV411P &&
00592 pix_fmt != AV_PIX_FMT_GRAY8)
00593 return -1;
00594 if ((width & 3) != 0 || (height & 3) != 0)
00595 return -1;
00596
00597 for(i=0;i<3;i++) {
00598 if (i == 1) {
00599 switch(pix_fmt) {
00600 case AV_PIX_FMT_YUVJ420P:
00601 case AV_PIX_FMT_YUV420P:
00602 width >>= 1;
00603 height >>= 1;
00604 break;
00605 case AV_PIX_FMT_YUV422P:
00606 case AV_PIX_FMT_YUVJ422P:
00607 width >>= 1;
00608 break;
00609 case AV_PIX_FMT_YUV411P:
00610 width >>= 2;
00611 break;
00612 default:
00613 break;
00614 }
00615 if (pix_fmt == AV_PIX_FMT_GRAY8) {
00616 break;
00617 }
00618 }
00619 if (src == dst) {
00620 deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i],
00621 width, height);
00622 } else {
00623 deinterlace_bottom_field(dst->data[i],dst->linesize[i],
00624 src->data[i], src->linesize[i],
00625 width, height);
00626 }
00627 }
00628 emms_c();
00629 return 0;
00630 }
00631
00632 #ifdef TEST
00633
00634 int main(void){
00635 int i;
00636 int err=0;
00637 int skip = 0;
00638
00639 for (i=0; i<AV_PIX_FMT_NB*2; i++) {
00640 AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
00641 if(!desc || !desc->name) {
00642 skip ++;
00643 continue;
00644 }
00645 if (skip) {
00646 av_log(NULL, AV_LOG_INFO, "%3d unused pixel format values\n", skip);
00647 skip = 0;
00648 }
00649 av_log(NULL, AV_LOG_INFO, "pix fmt %s yuv_plan:%d avg_bpp:%d colortype:%d\n", desc->name, is_yuv_planar(desc), av_get_padded_bits_per_pixel(desc), get_color_type(desc));
00650 if ((!(desc->flags & PIX_FMT_ALPHA)) != (desc->nb_components != 2 && desc->nb_components != 4)) {
00651 av_log(NULL, AV_LOG_ERROR, "Alpha flag mismatch\n");
00652 err = 1;
00653 }
00654 }
00655 return err;
00656 }
00657
00658 #endif