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

📄 imgresample.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
        else#endif            v_resample(output, owidth,                       s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth,                       &s->v_filters[phase_y][0]);        src_y += s->v_incr;        output += owrap;    }}ImgReSampleContext *img_resample_init(int owidth, int oheight,                                      int iwidth, int iheight){    return img_resample_full_init(owidth, oheight, iwidth, iheight,            0, 0, 0, 0, 0, 0, 0, 0);}ImgReSampleContext *img_resample_full_init(int owidth, int oheight,                                      int iwidth, int iheight,                                      int topBand, int bottomBand,        int leftBand, int rightBand,        int padtop, int padbottom,        int padleft, int padright){    ImgReSampleContext *s;    if (!owidth || !oheight || !iwidth || !iheight)        return NULL;    s = av_mallocz(sizeof(ImgReSampleContext));    if (!s)        return NULL;    if((unsigned)owidth >= UINT_MAX / (LINE_BUF_HEIGHT + NB_TAPS))        return NULL;    s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS));    if (!s->line_buf)        goto fail;    s->owidth = owidth;    s->oheight = oheight;    s->iwidth = iwidth;    s->iheight = iheight;    s->topBand = topBand;    s->bottomBand = bottomBand;    s->leftBand = leftBand;    s->rightBand = rightBand;    s->padtop = padtop;    s->padbottom = padbottom;    s->padleft = padleft;    s->padright = padright;    s->pad_owidth = owidth - (padleft + padright);    s->pad_oheight = oheight - (padtop + padbottom);    s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth;    s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight;    av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth  /            (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);    av_build_filter(&s->v_filters[0][0], (float) s->pad_oheight /            (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);    return s;fail:    av_free(s);    return NULL;}void img_resample(ImgReSampleContext *s,                  AVPicture *output, const AVPicture *input){    int i, shift;    uint8_t* optr;    for (i=0;i<3;i++) {        shift = (i == 0) ? 0 : 1;        optr = output->data[i] + (((output->linesize[i] *                        s->padtop) + s->padleft) >> shift);        component_resample(s, optr, output->linesize[i],                s->pad_owidth >> shift, s->pad_oheight >> shift,                input->data[i] + (input->linesize[i] *                    (s->topBand >> shift)) + (s->leftBand >> shift),                input->linesize[i], ((s->iwidth - s->leftBand -                        s->rightBand) >> shift),                           (s->iheight - s->topBand - s->bottomBand) >> shift);    }}void img_resample_close(ImgReSampleContext *s){    av_free(s->line_buf);    av_free(s);}struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat,                                  int dstW, int dstH, int dstFormat,                                  int flags, SwsFilter *srcFilter,                                  SwsFilter *dstFilter, double *param){    struct SwsContext *ctx;    ctx = av_malloc(sizeof(struct SwsContext));    if (ctx)        ctx->av_class = av_mallocz(sizeof(AVClass));    if (!ctx || !ctx->av_class) {        av_log(NULL, AV_LOG_ERROR, "Cannot allocate a resampling context!\n");        return NULL;    }    if ((srcH != dstH) || (srcW != dstW)) {        if ((srcFormat != PIX_FMT_YUV420P) || (dstFormat != PIX_FMT_YUV420P)) {            av_log(NULL, AV_LOG_INFO, "PIX_FMT_YUV420P will be used as an intermediate format for rescaling\n");        }        ctx->resampling_ctx = img_resample_init(dstW, dstH, srcW, srcH);    } else {        ctx->resampling_ctx = av_malloc(sizeof(ImgReSampleContext));        ctx->resampling_ctx->iheight = srcH;        ctx->resampling_ctx->iwidth = srcW;        ctx->resampling_ctx->oheight = dstH;        ctx->resampling_ctx->owidth = dstW;    }    ctx->src_pix_fmt = srcFormat;    ctx->dst_pix_fmt = dstFormat;    return ctx;}void sws_freeContext(struct SwsContext *ctx){    if (!ctx)        return;    if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) ||        (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) {        img_resample_close(ctx->resampling_ctx);    } else {        av_free(ctx->resampling_ctx);    }    av_free(ctx->av_class);    av_free(ctx);}/** * Checks if context is valid or reallocs a new one instead. * If context is NULL, just calls sws_getContext() to get a new one. * Otherwise, checks if the parameters are the same already saved in context. * If that is the case, returns the current context. * Otherwise, frees context and gets a new one. * * Be warned that srcFilter, dstFilter are not checked, they are * asumed to remain valid. */struct SwsContext *sws_getCachedContext(struct SwsContext *ctx,                        int srcW, int srcH, int srcFormat,                        int dstW, int dstH, int dstFormat, int flags,                        SwsFilter *srcFilter, SwsFilter *dstFilter, double *param){    if (ctx != NULL) {        if ((ctx->resampling_ctx->iwidth != srcW) ||                        (ctx->resampling_ctx->iheight != srcH) ||                        (ctx->src_pix_fmt != srcFormat) ||                        (ctx->resampling_ctx->owidth != dstW) ||                        (ctx->resampling_ctx->oheight != dstH) ||                        (ctx->dst_pix_fmt != dstFormat))        {            sws_freeContext(ctx);            ctx = NULL;        }    }    if (ctx == NULL) {        return sws_getContext(srcW, srcH, srcFormat,                        dstW, dstH, dstFormat, flags,                        srcFilter, dstFilter, param);    }    return ctx;}int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[],              int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]){    AVPicture src_pict, dst_pict;    int i, res = 0;    AVPicture picture_format_temp;    AVPicture picture_resample_temp, *formatted_picture, *resampled_picture;    uint8_t *buf1 = NULL, *buf2 = NULL;    enum PixelFormat current_pix_fmt;    for (i = 0; i < 4; i++) {        src_pict.data[i] = src[i];        src_pict.linesize[i] = srcStride[i];        dst_pict.data[i] = dst[i];        dst_pict.linesize[i] = dstStride[i];    }    if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) ||        (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) {        /* We have to rescale the picture, but only YUV420P rescaling is supported... */        if (ctx->src_pix_fmt != PIX_FMT_YUV420P) {            int size;            /* create temporary picture for rescaling input*/            size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight);            buf1 = av_malloc(size);            if (!buf1) {                res = -1;                goto the_end;            }            formatted_picture = &picture_format_temp;            avpicture_fill((AVPicture*)formatted_picture, buf1,                           PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight);            if (img_convert((AVPicture*)formatted_picture, PIX_FMT_YUV420P,                            &src_pict, ctx->src_pix_fmt,                            ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight) < 0) {                av_log(NULL, AV_LOG_ERROR, "pixel format conversion not handled\n");                res = -1;                goto the_end;            }        } else {            formatted_picture = &src_pict;        }        if (ctx->dst_pix_fmt != PIX_FMT_YUV420P) {            int size;            /* create temporary picture for rescaling output*/            size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight);            buf2 = av_malloc(size);            if (!buf2) {                res = -1;                goto the_end;            }            resampled_picture = &picture_resample_temp;            avpicture_fill((AVPicture*)resampled_picture, buf2,                           PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight);        } else {            resampled_picture = &dst_pict;        }        /* ...and finally rescale!!! */        img_resample(ctx->resampling_ctx, resampled_picture, formatted_picture);        current_pix_fmt = PIX_FMT_YUV420P;    } else {        resampled_picture = &src_pict;        current_pix_fmt = ctx->src_pix_fmt;    }    if (current_pix_fmt != ctx->dst_pix_fmt) {        if (img_convert(&dst_pict, ctx->dst_pix_fmt,                        resampled_picture, current_pix_fmt,                        ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight) < 0) {            av_log(NULL, AV_LOG_ERROR, "pixel format conversion not handled\n");            res = -1;            goto the_end;        }    } else if (resampled_picture != &dst_pict) {        av_picture_copy(&dst_pict, resampled_picture, current_pix_fmt,                        ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight);    }the_end:    av_free(buf1);    av_free(buf2);    return res;}#ifdef TEST#include <stdio.h>#undef exit/* input */#define XSIZE 256#define YSIZE 256uint8_t img[XSIZE * YSIZE];/* output */#define XSIZE1 512#define YSIZE1 512uint8_t img1[XSIZE1 * YSIZE1];uint8_t img2[XSIZE1 * YSIZE1];void save_pgm(const char *filename, uint8_t *img, int xsize, int ysize){#undef fprintf    FILE *f;    f=fopen(filename,"w");    fprintf(f,"P5\n%d %d\n%d\n", xsize, ysize, 255);    fwrite(img,1, xsize * ysize,f);    fclose(f);#define fprintf please_use_av_log}static void dump_filter(int16_t *filter){    int i, ph;    for(ph=0;ph<NB_PHASES;ph++) {        av_log(NULL, AV_LOG_INFO, "%2d: ", ph);        for(i=0;i<NB_TAPS;i++) {            av_log(NULL, AV_LOG_INFO, " %5.2f", filter[ph * NB_TAPS + i] / 256.0);        }        av_log(NULL, AV_LOG_INFO, "\n");    }}#ifdef HAVE_MMXint mm_flags;#endifint main(int argc, char **argv){    int x, y, v, i, xsize, ysize;    ImgReSampleContext *s;    float fact, factors[] = { 1/2.0, 3.0/4.0, 1.0, 4.0/3.0, 16.0/9.0, 2.0 };    char buf[256];    /* build test image */    for(y=0;y<YSIZE;y++) {        for(x=0;x<XSIZE;x++) {            if (x < XSIZE/2 && y < YSIZE/2) {                if (x < XSIZE/4 && y < YSIZE/4) {                    if ((x % 10) <= 6 &&                        (y % 10) <= 6)                        v = 0xff;                    else                        v = 0x00;                } else if (x < XSIZE/4) {                    if (x & 1)                        v = 0xff;                    else                        v = 0;                } else if (y < XSIZE/4) {                    if (y & 1)                        v = 0xff;                    else                        v = 0;                } else {                    if (y < YSIZE*3/8) {                        if ((y+x) & 1)                            v = 0xff;                        else                            v = 0;                    } else {                        if (((x+3) % 4) <= 1 &&                            ((y+3) % 4) <= 1)                            v = 0xff;                        else                            v = 0x00;                    }                }            } else if (x < XSIZE/2) {                v = ((x - (XSIZE/2)) * 255) / (XSIZE/2);            } else if (y < XSIZE/2) {                v = ((y - (XSIZE/2)) * 255) / (XSIZE/2);            } else {                v = ((x + y - XSIZE) * 255) / XSIZE;            }            img[(YSIZE - y) * XSIZE + (XSIZE - x)] = v;        }    }    save_pgm("/tmp/in.pgm", img, XSIZE, YSIZE);    for(i=0;i<sizeof(factors)/sizeof(float);i++) {        fact = factors[i];        xsize = (int)(XSIZE * fact);        ysize = (int)((YSIZE - 100) * fact);        s = img_resample_full_init(xsize, ysize, XSIZE, YSIZE, 50 ,50, 0, 0, 0, 0, 0, 0);        av_log(NULL, AV_LOG_INFO, "Factor=%0.2f\n", fact);        dump_filter(&s->h_filters[0][0]);        component_resample(s, img1, xsize, xsize, ysize,                           img + 50 * XSIZE, XSIZE, XSIZE, YSIZE - 100);        img_resample_close(s);        snprintf(buf, sizeof(buf), "/tmp/out%d.pgm", i);        save_pgm(buf, img1, xsize, ysize);    }    /* mmx test */#ifdef HAVE_MMX    av_log(NULL, AV_LOG_INFO, "MMX test\n");    fact = 0.72;    xsize = (int)(XSIZE * fact);    ysize = (int)(YSIZE * fact);    mm_flags = MM_MMX;    s = img_resample_init(xsize, ysize, XSIZE, YSIZE);    component_resample(s, img1, xsize, xsize, ysize,                       img, XSIZE, XSIZE, YSIZE);    mm_flags = 0;    s = img_resample_init(xsize, ysize, XSIZE, YSIZE);    component_resample(s, img2, xsize, xsize, ysize,                       img, XSIZE, XSIZE, YSIZE);    if (memcmp(img1, img2, xsize * ysize) != 0) {        av_log(NULL, AV_LOG_ERROR, "mmx error\n");        exit(1);    }    av_log(NULL, AV_LOG_INFO, "MMX OK\n");#endif /* HAVE_MMX */    return 0;}#endif /* TEST */

⌨️ 快捷键说明

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