⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imgconvert.c

📁 现在关于h.264的源码很多
💻 C
📖 第 1 页 / 共 5 页
字号:
        [PIX_FMT_RGB24] = {            .convert = pal8_to_rgb24        },        [PIX_FMT_RGBA32] = {            .convert = pal8_to_rgba32        },    },    [PIX_FMT_UYVY411] = {        [PIX_FMT_YUV411P] = {            .convert = uyvy411_to_yuv411p,        },    },};int avpicture_alloc(AVPicture *picture,                           int pix_fmt, int width, int height){    unsigned int size;    void *ptr;    size = avpicture_get_size(pix_fmt, width, height);    if(size<0)        goto fail;    ptr = av_malloc(size);    if (!ptr)        goto fail;    avpicture_fill(picture, ptr, pix_fmt, width, height);    return 0; fail:    memset(picture, 0, sizeof(AVPicture));    return -1;}void avpicture_free(AVPicture *picture){    av_free(picture->data[0]);}/* return true if yuv planar */static inline int is_yuv_planar(PixFmtInfo *ps){    return (ps->color_type == FF_COLOR_YUV ||            ps->color_type == FF_COLOR_YUV_JPEG) &&        ps->pixel_type == FF_PIXEL_PLANAR;}/** * Crop image top and left side */int img_crop(AVPicture *dst, const AVPicture *src,              int pix_fmt, int top_band, int left_band){    int y_shift;    int x_shift;    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))        return -1;    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);    dst->linesize[0] = src->linesize[0];    dst->linesize[1] = src->linesize[1];    dst->linesize[2] = src->linesize[2];    return 0;}/* XXX: always use linesize. Return -1 if not supported */int img_convert(AVPicture *dst, int dst_pix_fmt,                const AVPicture *src, int src_pix_fmt,                int src_width, int src_height){    static int inited;    int i, ret, dst_width, dst_height, int_pix_fmt;    PixFmtInfo *src_pix, *dst_pix;    ConvertEntry *ce;    AVPicture tmp1, *tmp = &tmp1;    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)        return -1;    if (src_width <= 0 || src_height <= 0)        return 0;    if (!inited) {        inited = 1;        img_convert_init();    }    dst_width = src_width;    dst_height = src_height;    dst_pix = &pix_fmt_info[dst_pix_fmt];    src_pix = &pix_fmt_info[src_pix_fmt];    if (src_pix_fmt == dst_pix_fmt) {        /* no conversion needed: just copy */        img_copy(dst, src, dst_pix_fmt, dst_width, dst_height);        return 0;    }    ce = &convert_table[src_pix_fmt][dst_pix_fmt];    if (ce->convert) {        /* specific conversion routine */        ce->convert(dst, src, dst_width, dst_height);        return 0;    }    /* gray to YUV */    if (is_yuv_planar(dst_pix) &&        src_pix_fmt == PIX_FMT_GRAY8) {        int w, h, y;        uint8_t *d;        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {            ff_img_copy_plane(dst->data[0], dst->linesize[0],                     src->data[0], src->linesize[0],                     dst_width, dst_height);        } else {            img_apply_table(dst->data[0], dst->linesize[0],                            src->data[0], src->linesize[0],                            dst_width, dst_height,                            y_jpeg_to_ccir);        }        /* fill U and V with 128 */        w = dst_width;        h = dst_height;        w >>= dst_pix->x_chroma_shift;        h >>= dst_pix->y_chroma_shift;        for(i = 1; i <= 2; i++) {            d = dst->data[i];            for(y = 0; y< h; y++) {                memset(d, 128, w);                d += dst->linesize[i];            }        }        return 0;    }    /* YUV to gray */    if (is_yuv_planar(src_pix) &&        dst_pix_fmt == PIX_FMT_GRAY8) {        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {            ff_img_copy_plane(dst->data[0], dst->linesize[0],                     src->data[0], src->linesize[0],                     dst_width, dst_height);        } else {            img_apply_table(dst->data[0], dst->linesize[0],                            src->data[0], src->linesize[0],                            dst_width, dst_height,                            y_ccir_to_jpeg);        }        return 0;    }    /* YUV to YUV planar */    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {        int x_shift, y_shift, w, h, xy_shift;        void (*resize_func)(uint8_t *dst, int dst_wrap,                            const uint8_t *src, int src_wrap,                            int width, int height);        /* compute chroma size of the smallest dimensions */        w = dst_width;        h = dst_height;        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)            w >>= dst_pix->x_chroma_shift;        else            w >>= src_pix->x_chroma_shift;        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)            h >>= dst_pix->y_chroma_shift;        else            h >>= src_pix->y_chroma_shift;        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);        /* there must be filters for conversion at least from and to           YUV444 format */        switch(xy_shift) {        case 0x00:            resize_func = ff_img_copy_plane;            break;        case 0x10:            resize_func = shrink21;            break;        case 0x20:            resize_func = shrink41;            break;        case 0x01:            resize_func = shrink12;            break;        case 0x11:            resize_func = ff_shrink22;            break;        case 0x22:            resize_func = ff_shrink44;            break;        case 0xf0:            resize_func = grow21;            break;        case 0xe0:            resize_func = grow41;            break;        case 0xff:            resize_func = grow22;            break;        case 0xee:            resize_func = grow44;            break;        case 0xf1:            resize_func = conv411;            break;        default:            /* currently not handled */            goto no_chroma_filter;        }        ff_img_copy_plane(dst->data[0], dst->linesize[0],                       src->data[0], src->linesize[0],                       dst_width, dst_height);        for(i = 1;i <= 2; i++)            resize_func(dst->data[i], dst->linesize[i],                        src->data[i], src->linesize[i],                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);        /* if yuv color space conversion is needed, we do it here on           the destination image */        if (dst_pix->color_type != src_pix->color_type) {            const uint8_t *y_table, *c_table;            if (dst_pix->color_type == FF_COLOR_YUV) {                y_table = y_jpeg_to_ccir;                c_table = c_jpeg_to_ccir;            } else {                y_table = y_ccir_to_jpeg;                c_table = c_ccir_to_jpeg;            }            img_apply_table(dst->data[0], dst->linesize[0],                            dst->data[0], dst->linesize[0],                            dst_width, dst_height,                            y_table);            for(i = 1;i <= 2; i++)                img_apply_table(dst->data[i], dst->linesize[i],                                dst->data[i], dst->linesize[i],                                dst_width>>dst_pix->x_chroma_shift,                                dst_height>>dst_pix->y_chroma_shift,                                c_table);        }        return 0;    } no_chroma_filter:    /* try to use an intermediate format */    if (src_pix_fmt == PIX_FMT_YUV422 ||        dst_pix_fmt == PIX_FMT_YUV422) {        /* specific case: convert to YUV422P first */        int_pix_fmt = PIX_FMT_YUV422P;    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||        dst_pix_fmt == PIX_FMT_UYVY422) {        /* specific case: convert to YUV422P first */        int_pix_fmt = PIX_FMT_YUV422P;    } else if (src_pix_fmt == PIX_FMT_UYVY411 ||        dst_pix_fmt == PIX_FMT_UYVY411) {        /* specific case: convert to YUV411P first */        int_pix_fmt = PIX_FMT_YUV411P;    } else if ((src_pix->color_type == FF_COLOR_GRAY &&                src_pix_fmt != PIX_FMT_GRAY8) ||               (dst_pix->color_type == FF_COLOR_GRAY &&                dst_pix_fmt != PIX_FMT_GRAY8)) {        /* gray8 is the normalized format */        int_pix_fmt = PIX_FMT_GRAY8;    } else if ((is_yuv_planar(src_pix) &&                src_pix_fmt != PIX_FMT_YUV444P &&                src_pix_fmt != PIX_FMT_YUVJ444P)) {        /* yuv444 is the normalized format */        if (src_pix->color_type == FF_COLOR_YUV_JPEG)            int_pix_fmt = PIX_FMT_YUVJ444P;        else            int_pix_fmt = PIX_FMT_YUV444P;    } else if ((is_yuv_planar(dst_pix) &&                dst_pix_fmt != PIX_FMT_YUV444P &&                dst_pix_fmt != PIX_FMT_YUVJ444P)) {        /* yuv444 is the normalized format */        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)            int_pix_fmt = PIX_FMT_YUVJ444P;        else            int_pix_fmt = PIX_FMT_YUV444P;    } else {        /* the two formats are rgb or gray8 or yuv[j]444p */        if (src_pix->is_alpha && dst_pix->is_alpha)            int_pix_fmt = PIX_FMT_RGBA32;        else            int_pix_fmt = PIX_FMT_RGB24;    }    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)        return -1;    ret = -1;    if (img_convert(tmp, int_pix_fmt,                    src, src_pix_fmt, src_width, src_height) < 0)        goto fail1;    if (img_convert(dst, dst_pix_fmt,                    tmp, int_pix_fmt, dst_width, dst_height) < 0)        goto fail1;    ret = 0; fail1:    avpicture_free(tmp);    return ret;}/* NOTE: we scan all the pixels to have an exact information */static int get_alpha_info_pal8(const AVPicture *src, int width, int height){    const unsigned char *p;    int src_wrap, ret, x, y;    unsigned int a;    uint32_t *palette = (uint32_t *)src->data[1];    p = src->data[0];    src_wrap = src->linesize[0] - width;    ret = 0;    for(y=0;y<height;y++) {        for(x=0;x<width;x++) {            a = palette[p[0]] >> 24;            if (a == 0x00) {                ret |= FF_ALPHA_TRANSP;            } else if (a != 0xff) {                ret |= FF_ALPHA_SEMI_TRANSP;            }            p++;        }        p += src_wrap;    }    return ret;}/** * Tell if an image really has transparent alpha values. * @return ored mask of FF_ALPHA_xxx constants */int img_get_alpha_info(const AVPicture *src,                       int pix_fmt, int width, int height){    PixFmtInfo *pf = &pix_fmt_info[pix_fmt];    int ret;    pf = &pix_fmt_info[pix_fmt];    /* no alpha can be represented in format */    if (!pf->is_alpha)        return 0;    switch(pix_fmt) {    case PIX_FMT_RGBA32:        ret = get_alpha_info_rgba32(src, width, height);        break;    case PIX_FMT_RGB555:        ret = get_alpha_info_rgb555(src, width, height);        break;    case PIX_FMT_PAL8:        ret = get_alpha_info_pal8(src, width, height);        break;    default:        /* we do not know, so everything is indicated */        ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP;        break;    }    return ret;}#ifdef HAVE_MMX#define DEINT_INPLACE_LINE_LUM \                    movd_m2r(lum_m4[0],mm0);\                    movd_m2r(lum_m3[0],mm1);\                    movd_m2r(lum_m2[0],mm2);\                    movd_m2r(lum_m1[0],mm3);\                    movd_m2r(lum[0],mm4);\                    punpcklbw_r2r(mm7,mm0);\                    movd_r2m(mm2,lum_m4[0]);\                    punpcklbw_r2r(mm7,mm1);\                    punpcklbw_r2r(mm7,mm2);\                    punpcklbw_r2r(mm7,mm3);\                    punpcklbw_r2r(mm7,mm4);\                    paddw_r2r(mm3,mm1);\                    psllw_i2r(1,mm2);\                    paddw_r2r(mm4,mm0);\                    psllw_i2r(2,mm1);\                    paddw_r2r(mm6,mm2);\                    paddw_r2r(mm2,mm1);\                    psubusw_r2r(mm0,mm1);\                    psrlw_i2r(3,mm1);\                    packuswb_r2r(mm7,mm1);\                    movd_r2m(mm1,lum_m2[0]);#define DEINT_LINE_LUM \                    movd_m2r(lum_m4[0],mm0);\                    movd_m2r(lum_m3[0],mm1);\                    movd_m2r(lum_m2[0],mm2);\                    movd_m2r(lum_m1[0],mm3);\                    movd_m2r(lum[0],mm4);\                    punpcklbw_r2r(mm7,mm0);\                    punpcklbw_r2r(mm7,mm1);\                    punpcklbw_r2r(mm7,mm2);\                    punpcklbw_r2r(mm7,mm3);\                    punpcklbw_r2r(mm7,mm4);\                    paddw_r2r(mm3,mm1);\                    psllw_i2r(1,mm2);\                    paddw_r2r(mm4,mm0);\                    psllw_i2r(2,mm1);\                    paddw_r2r(mm6,mm2);\                    paddw_r2r(mm2,mm1);\                    psubusw_r2r(mm0,mm1);\                    psrlw_i2r(3,mm1);\                    packuswb_r2r(mm7,mm1);\                    movd_r2m(mm1,dst[0]);#endif/* filter parameters: [-1 4 2 4 -1] // 8 */static void deinterlace_line(uint8_t *dst,                             const uint8_t *lum_m4, const uint8_t *lum_m3,                             const uint8_t *lum_m2, const uint8_t *lum_m1,                             const uint8_t *lum,                             int size){#ifndef HAVE_MMX    uint8_t *cm = cropTbl + MAX_NEG_CROP;    int sum;    for(;size > 0;size--) {        sum = -lum_m4[0];        sum += lum_m3[0] << 2;        sum += lum_m2[0] << 1;        sum += lum_m1[0] << 2;        sum += -lum[0];        dst[0] = cm[(sum + 4) >> 3];        lum_m4++;        lum_m3++;        lum_m2++;        lum_m1++;        lum++;        dst++;    }#else    {        mmx_t rounder;        rounder.uw[0]=4;        rounder.uw[1]=4;        rounder.uw[2]=4;        rounder.uw[3]=4;        pxor_r2r(mm7,mm7);        movq_m2r(rounder,mm6);    }    for (;size > 3; size-=4) {        DEINT_LINE_LUM        lum_m4+=4;        lum_m3+=4;        lum_m2+=4;        lum_m1+=4;        lum+=4;        dst+=4;    }#endif}static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum,                             int size){#ifndef HAVE_MMX    uint8_t *cm = cropTbl + MAX_NEG_CROP;    int sum;    for(;size > 0;size--) {        sum = -lum_m4[0];        sum += lum_m3[0] << 2;        sum += lum_m2[0] << 1;        lum_m4[0]=lum_m2[0];  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -